/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal.protocols;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.xmind.core.Core;
import org.xmind.core.IFileEntry;
import org.xmind.core.IManifest;
import org.xmind.core.INamed;
import org.xmind.core.ITitled;
import org.xmind.core.IWorkbook;
import org.xmind.core.event.ICoreEventListener;
import org.xmind.core.event.ICoreEventSource2;
import org.xmind.core.util.FileUtils;
import org.xmind.core.util.HyperlinkUtils;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.editor.MME;
import org.xmind.ui.mindmap.IMindMapImages;
import org.xmind.ui.mindmap.IProtocol;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.util.Logger;
import org.xmind.ui.util.MindMapUtils;
public class AttachmentProtocol implements IProtocol {
private static class AttachmentAction extends Action {
private IWorkbenchWindow window;
private IWorkbook workbook;
private String path;
private String fileName;
private IWindowListener windowListener;
public AttachmentAction(IWorkbenchWindow window, IWorkbook workbook,
String path, String fileName) {
this.window = window;
this.workbook = workbook;
this.path = path;
this.fileName = fileName;
}
public void run() {
String hiberLoc = Core.getWorkspace()
.getAbsolutePath(".temp-attachments"); //$NON-NLS-1$
String[] tmps = path.split("/"); //$NON-NLS-1$
for (int i = 0; i < tmps.length - 1; i++)
hiberLoc = hiberLoc + File.separator + tmps[i];
File hiberDir = new File(hiberLoc);
if (!hiberDir.exists())
hiberDir.mkdirs();
String entryMediaType = path.substring(path.lastIndexOf(".")); //$NON-NLS-1$
String absolutelyFileName = fileName.endsWith(entryMediaType)
? fileName : fileName + entryMediaType;
File hiberFile = new File(hiberDir, absolutelyFileName);
IManifest manifest = workbook.getManifest();
IFileEntry fileEntry = manifest.getFileEntry(path);
try {
InputStream is = fileEntry.openInputStream();
OutputStream os = new FileOutputStream(hiberFile);
FileUtils.transfer(is, os);
} catch (IOException e) {
Logger.log(e,
"Failed to transfer attachment to temp-attachments dir."); //$NON-NLS-1$
return;
}
if (!hiberFile.exists())
return;
MME.launch(window, hiberFile.getAbsolutePath(), fileName);
if (workbook instanceof ICoreEventSource2) {
((ICoreEventSource2) workbook).registerOnceCoreEventListener(
Core.WorkbookPreSaveOnce, ICoreEventListener.NULL);
}
//write temp file back to entry.
if (window != null) {
window.getWorkbench().addWindowListener(
getWindowListener(fileEntry, hiberFile));
}
window.getActivePage().addPartListener(new IPartListener() {
@Override
public void partOpened(IWorkbenchPart part) {
}
@Override
public void partDeactivated(IWorkbenchPart part) {
}
@Override
public void partClosed(IWorkbenchPart part) {
window.getWorkbench().removeWindowListener(
getWindowListener(null, null));
}
@Override
public void partBroughtToTop(IWorkbenchPart part) {
}
@Override
public void partActivated(IWorkbenchPart part) {
}
});
}
private IWindowListener getWindowListener(final IFileEntry fileEntry,
final File hiberFile) {
if (windowListener == null) {
windowListener = new IWindowListener() {
@Override
public void windowOpened(IWorkbenchWindow window) {
}
@Override
public void windowDeactivated(IWorkbenchWindow window) {
}
@Override
public void windowClosed(IWorkbenchWindow window) {
}
@Override
public void windowActivated(IWorkbenchWindow window) {
try {
InputStream is = new FileInputStream(hiberFile);
OutputStream os = fileEntry.openOutputStream();
FileUtils.transfer(is, os);
} catch (IOException e) {
Logger.log(e,
"Failed to transfer temp-attachments to attachment dir."); //$NON-NLS-1$
return;
}
}
};
}
return windowListener;
}
}
private Map<IWorkbook, Map<String, IAction>> actions = null;
public IAction createOpenHyperlinkAction(Object context, String uri) {
if (uri == null)
return null;
String path = HyperlinkUtils.toAttachmentPath(uri);
if (path == null)
return null;
IWorkbook workbook = MindMapUtils.findWorkbook(context);
if (workbook == null)
return null;
if (actions == null)
actions = new HashMap<IWorkbook, Map<String, IAction>>();
Map<String, IAction> wbActions = actions.get(workbook);
if (wbActions == null) {
wbActions = new HashMap<String, IAction>();
actions.put(workbook, wbActions);
}
IAction action = wbActions.get(uri);
if (action == null) {
action = createOpenAttachmentAction(getWindow(context), workbook,
path, getFileName(context));
wbActions.put(uri, action);
}
return action;
}
private IAction createOpenAttachmentAction(IWorkbenchWindow window,
IWorkbook workbook, String path, String fileName) {
IAction action = new AttachmentAction(window, workbook, path, fileName);
action.setText(MindMapMessages.OpenAttachment_text);
action.setToolTipText(fileName);
ImageDescriptor image = MindMapUI.getImages().getFileIcon(path, true);
if (image == null) {
IFileEntry e = workbook.getManifest().getFileEntry(path);
if (e != null && e.isDirectory()) {
image = MindMapUI.getImages().get(IMindMapImages.OPEN, true);
} else {
image = MindMapUI.getImages().get(IMindMapImages.UNKNOWN_FILE,
true);
}
}
action.setImageDescriptor(image);
return action;
}
private static String getFileName(Object context) {
if (context instanceof IAdaptable) {
Object adapter = ((IAdaptable) context).getAdapter(ITitled.class);
if (adapter == null) {
adapter = ((IAdaptable) context).getAdapter(INamed.class);
}
if (adapter != null) {
context = adapter;
}
}
if (context instanceof ITitled)
return ((ITitled) context).getTitleText();
if (context instanceof INamed)
return ((INamed) context).getName();
return null;
}
private static IWorkbenchWindow getWindow(Object context) {
if (context instanceof IAdaptable) {
Object adapter = ((IAdaptable) context)
.getAdapter(IWorkbenchWindow.class);
if (adapter == null) {
adapter = ((IAdaptable) context).getAdapter(IEditorPart.class);
if (adapter == null) {
adapter = ((IAdaptable) context)
.getAdapter(IWorkbenchPart.class);
}
if (adapter instanceof IWorkbenchPart)
adapter = ((IWorkbenchPart) adapter).getSite()
.getWorkbenchWindow();
}
if (adapter instanceof IWorkbenchWindow)
return (IWorkbenchWindow) adapter;
}
if (context instanceof IWorkbenchWindow)
return (IWorkbenchWindow) context;
return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
}
public String getProtocolName() {
return HyperlinkUtils.getAttachmentProtocolName();
}
public boolean isHyperlinkModifiable(Object source, String uri) {
return false;
}
}