/** * This file Copyright (c) 2005-2010 Aptana, Inc. This program is * dual-licensed under both the Aptana Public License and the GNU General * Public license. You may elect to use one or the other of these licenses. * * This program is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. Redistribution, except as permitted by whichever of * the GPL or APL you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or modify this * program under the terms of the GNU General Public License, * Version 3, as published by the Free Software Foundation. You should * have received a copy of the GNU General Public License, Version 3 along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Aptana provides a special exception to allow redistribution of this file * with certain Eclipse Public Licensed code and certain additional terms * pursuant to Section 7 of the GPL. You may view the exception and these * terms on the web at http://www.aptana.com/legal/gpl/. * * 2. For the Aptana Public License (APL), this program and the * accompanying materials are made available under the terms of the APL * v1.0 which accompanies this distribution, and is available at * http://www.aptana.com/legal/apl/. * * You may view the GPL, Aptana's exception and additional terms, and the * APL in the file titled license.html at the root of the corresponding * plugin containing this source file. * * Any modifications to this file must keep this entire header intact. */ package com.aptana.ide.server.portal.comet; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IPartService; import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.EditorHistory; import org.eclipse.ui.internal.EditorHistoryItem; import org.eclipse.ui.internal.Workbench; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.progress.UIJob; import com.aptana.ide.core.ui.CoreUIUtils; import com.aptana.ide.core.ui.PartListenerAdapter; import com.aptana.ide.server.jetty.comet.CometClient; import com.aptana.ide.server.jetty.comet.CometConstants; import dojox.cometd.Channel; /** * @author Sandip V. Chitale (schitale@aptana.com) */ public class RecentFilesClient extends CometClient { /** * LIST_RECENT_FILES */ public static final String LIST_RECENT_FILES = "listRecentFiles"; //$NON-NLS-1$ /** * RECENT_FILES_CHANNEL */ public static final String RECENT_FILES_CHANNEL = "/portal/recentFiles"; //$NON-NLS-1$ /** * PROJECTS */ public static final String PROJECTS = "projects"; //$NON-NLS-1$ /** * FILES */ public static final String FILES = "files"; //$NON-NLS-1$ /** * NAME */ public static final String NAME = "name"; //$NON-NLS-1$ /** * OPEN_FILE */ public static final String OPEN_FILE = "openFile"; //$NON-NLS-1$ /** * PROJECT */ public static final String PROJECT = "project"; //$NON-NLS-1$ /** * FILE */ public static final String FILE = "file"; //$NON-NLS-1$ private IPartListener partListener = new PartListenerAdapter() { @Override public void partOpened(IWorkbenchPart part) { if (part instanceof IEditorPart) { publishRecentFiles(); } } @Override public void partClosed(IWorkbenchPart part) { if (part instanceof IEditorPart) { publishRecentFiles(); } } }; private IWindowListener windowListener = new IWindowListener() { public void windowActivated(IWorkbenchWindow window) {} public void windowClosed(IWorkbenchWindow window) { IPartService partService = window.getPartService(); if (partService != null) { partService.removePartListener(partListener); } } public void windowDeactivated(IWorkbenchWindow window) {} public void windowOpened(IWorkbenchWindow window) { IPartService partService = window.getPartService(); if (partService != null) { partService.addPartListener(partListener); } } }; /** * RecentFiles client */ public RecentFilesClient() { init(); } private void init () { // Add actions to exiting windows. IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow workbenchWindow : workbenchWindows) { IPartService partService = workbenchWindow.getPartService(); if (partService != null) { partService.addPartListener(partListener); } } // Listen on any future windows PlatformUI.getWorkbench().addWindowListener(windowListener); } /** * @see com.aptana.ide.server.jetty.comet.CometClient#destroy() */ public void destroy() { super.destroy(); // Remove listener from windows. IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow workbenchWindow : workbenchWindows) { IPartService partService = workbenchWindow.getPartService(); if (partService != null) { partService.removePartListener(partListener); } } partListener = null; PlatformUI.getWorkbench().removeWindowListener(windowListener); windowListener = null; } /** * @see com.aptana.ide.server.jetty.comet.CometClient#getResponse(java.lang.String, java.lang.Object) */ protected Object getResponse(String toChannel, Object request) { if (RECENT_FILES_CHANNEL.equals(toChannel)) { Map requestData = (Map) request; if (LIST_RECENT_FILES.equals(requestData.get(CometConstants.REQUEST))) { return listRecentFiles(); } else if (OPEN_FILE.equals(requestData.get(CometConstants.REQUEST))) { String project = (String) requestData.get(PROJECT); String file = (String) requestData.get(FILE); if (project != null && file != null) { openFile(project, file); } } } return null; } /** * Publish recent files */ protected void publishRecentFiles() { if (bayeux == null) return; Channel listChannel = bayeux.getChannel(getRecentFilesChannel(), true); listChannel.publish(this.client, listRecentFiles(), Long.toString(System.currentTimeMillis())); } /** * List the recent files * * @return - map representing recent files model */ protected Map<Object, Object> listRecentFiles() { Map<Object, Object> returnData = new HashMap<Object, Object>(); returnData.put(CometConstants.RESPONSE, LIST_RECENT_FILES); Map<String, List<String>> projectFilesMap = new HashMap<String, List<String>>(); EditorHistory editorHistory = getEditorHistory(); if (editorHistory != null) { EditorHistoryItem[] editorHistoryItems = editorHistory.getItems(); for (EditorHistoryItem editorHistoryItem : editorHistoryItems) { try { if (!editorHistoryItem.isRestored()) { editorHistoryItem.restoreState(); } } catch (Exception e) { } IEditorInput editorInput = editorHistoryItem.getInput(); if (editorInput instanceof FileEditorInput) { FileEditorInput fileEditorInput = (FileEditorInput) editorInput; IFile file = fileEditorInput.getFile(); if (file != null) { IProject project = file.getProject(); String projectName = project.getName(); List<String> list = projectFilesMap.get(projectName); if (list == null) { list = new LinkedList<String>(); projectFilesMap.put(projectName, list); } list.add(editorHistoryItem.getName()); } } } } // Array of projects List<Map<String, Object>> projectMapsList = new LinkedList<Map<String, Object>>(); Set<String> projectNames = projectFilesMap.keySet(); for (String projectName : projectNames) { // Per project map Map<String, Object> projectMap = new HashMap<String, Object>(); // Project name projectMap.put(NAME, projectName); // Array file names List<Map<String, String>> fileMapsList = new LinkedList<Map<String, String>>(); List<String> projectFiles = projectFilesMap.get(projectName); for (String file : projectFiles) { Map<String, String> fileMap = new HashMap<String, String>(); fileMap.put(NAME, file); fileMapsList.add(fileMap); } projectMap.put(FILES, fileMapsList); projectMapsList.add(projectMap); } returnData.put(PROJECTS, projectMapsList); return returnData; } private void openFile(String project, String file) { EditorHistory editorHistory = getEditorHistory(); if (editorHistory != null) { EditorHistoryItem[] editorHistoryItems = editorHistory.getItems(); for (EditorHistoryItem editorHistoryItem : editorHistoryItems) { // File name matches if (editorHistoryItem.getName().equals(file)) { // Now check on project IEditorInput editorInput = editorHistoryItem.getInput(); if (editorInput instanceof FileEditorInput) { FileEditorInput fileEditorInput = (FileEditorInput) editorInput; IFile fileEditorInputFile = fileEditorInput.getFile(); if (fileEditorInputFile != null) { IProject fileEditorInputFileProject = fileEditorInputFile.getProject(); if (fileEditorInputFileProject.getName().equals(project)) { open(editorHistory, editorHistoryItem); } } } } } } } /** * Gets the recent files channel * * @return - recent files channel */ protected String getRecentFilesChannel() { return RECENT_FILES_CHANNEL; } /** * @see com.aptana.ide.server.jetty.comet.CometClient#getSubscriptionIDs() */ protected String[] getSubscriptionIDs() { return new String[] { getRecentFilesChannel() }; } /** * @see com.aptana.ide.server.jetty.comet.CometClient#getID(java.lang.String) */ protected String getID(String msgId) { return Long.toString(System.currentTimeMillis()); } private EditorHistory getEditorHistory() { return ((Workbench) PlatformUI.getWorkbench()).getEditorHistory(); } /** * Reopens the editor for the given history item. */ private void open(final EditorHistory history, final EditorHistoryItem item) { UIJob uiJob = new UIJob("Opening file.") { //$NON-NLS-1$ @Override public IStatus runInUIThread(IProgressMonitor monitor) { IWorkbenchPage page = CoreUIUtils.getActivePage(); if (page != null) { try { String itemName = item.getName(); if (!item.isRestored()) { item.restoreState(); } IEditorInput input = item.getInput(); IEditorDescriptor desc = item.getDescriptor(); if (input == null || desc == null) { history.remove(item); } else { page.openEditor(input, desc.getId()); } } catch (PartInitException pe) { CoreUIUtils.showError(pe.getMessage(), pe); history.remove(item); } } return Status.OK_STATUS; } }; uiJob.setPriority(UIJob.INTERACTIVE); uiJob.schedule(); } }