/******************************************************************************* * Copyright (c) 2012, 2014 Wind River Systems, Inc. and others. All rights reserved. * This program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.ui.internal.adapters; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.core.interfaces.IConnectable; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistableNodeProperties; import org.eclipse.tcf.te.runtime.persistence.interfaces.IURIPersistenceService; import org.eclipse.tcf.te.runtime.services.ServiceManager; import org.eclipse.tcf.te.tcf.core.peers.Peer; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelLookupService; import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelRefreshService; import org.eclipse.tcf.te.tcf.locator.model.ModelManager; import org.eclipse.tcf.te.tcf.ui.nls.Messages; import org.eclipse.tcf.te.ui.dialogs.RenameDialog; import org.eclipse.tcf.te.ui.views.ViewsUtil; import org.eclipse.tcf.te.ui.views.interfaces.IEditorSaveAsAdapter; import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.PlatformUI; /** * EditorSaveAsAdapter */ public class EditorSaveAsAdapter implements IEditorSaveAsAdapter { /** * Constructor. */ public EditorSaveAsAdapter() { } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.views.interfaces.IEditorSaveAsAdapter#isSaveAsAllowed(org.eclipse.ui.IEditorInput) */ @Override public boolean isSaveAsAllowed(IEditorInput input) { IPeerNode peerNode = (IPeerNode)input.getAdapter(IPeerNode.class); if (peerNode != null && peerNode.getConnectState() == IConnectable.STATE_DISCONNECTED) return true; return false; } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.views.interfaces.IEditorSaveAsAdapter#doSaveAs(org.eclipse.ui.IEditorInput) */ @Override public Object doSaveAs(IEditorInput input) { IPeerNode peerNode = (IPeerNode)input.getAdapter(IPeerNode.class); if (peerNode != null) { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); // Create the peer attributes final Map<String, String> attrs = new HashMap<String, String>(peerNode.getPeer().getAttributes()); attrs.put(IPeer.ATTR_ID, UUID.randomUUID().toString()); final List<String> usedNames = getUsedNameList(); String title = Messages.EditorSaveAsAdapter_title; String prompt = Messages.EditorSaveAsAdapter_message; String usedError = Messages.EditorSaveAsAdapter_nameInUse_error; String label = Messages.EditorSaveAsAdapter_label; RenameDialog dialog = new RenameDialog(shell, title, null, prompt, usedError, null, label, attrs.get(IPeer.ATTR_NAME), null, usedNames.toArray(new String[usedNames.size()]), null); if (dialog.open() != Window.OK) { return null; } attrs.put(IPeer.ATTR_NAME, dialog.getNewName()); attrs.remove(IPersistableNodeProperties.PROPERTY_URI); try { // Save the new peer IURIPersistenceService persistenceService = ServiceManager.getInstance().getService(IURIPersistenceService.class); if (persistenceService == null) { throw new IOException("Persistence service instance unavailable."); //$NON-NLS-1$ } persistenceService.write(new Peer(attrs), null); final AtomicReference<IPeerNode> newPeer = new AtomicReference<IPeerNode>(); final Callback cb = new Callback() { @Override protected void internalDone(Object caller, IStatus status) { // Get the peer model node from the model and select it in the tree IPeerNode peerNode = ModelManager.getPeerModel().getService(IPeerModelLookupService.class).lkupPeerModelById(attrs.get(IPeer.ATTR_ID)); newPeer.set(peerNode); if (peerNode != null) { // Refresh the viewer ViewsUtil.refresh(IUIConstants.ID_EXPLORER); // Create the selection ISelection selection = new StructuredSelection(peerNode); // Set the selection ViewsUtil.setSelection(IUIConstants.ID_EXPLORER, selection); // And open the properties on the selection } } }; // Trigger a refresh of the model to read in the newly created static peer Protocol.invokeLater(new Runnable() { @Override public void run() { IPeerModelRefreshService service = ModelManager.getPeerModel().getService(IPeerModelRefreshService.class); // Refresh the model now (must be executed within the TCF dispatch thread) if (service != null) { service.refresh(cb); } } }); ExecutorsUtil.waitAndExecute(0, cb.getDoneConditionTester(null)); return newPeer.get(); } catch (IOException e) { } } return null; } /** * Initialize the used name list. */ protected List<String> getUsedNameList() { final List<String> usedNames = new ArrayList<String>(); Runnable runnable = new Runnable() { @Override public void run() { // Get all peer model objects IPeerNode[] peers = ModelManager.getPeerModel().getPeerNodes(); // Loop them and find the ones which are of our handled types for (IPeerNode peerNode : peers) { String name = peerNode.getPeer().getName(); Assert.isNotNull(name); if (!"".equals(name) && !usedNames.contains(name)) { //$NON-NLS-1$ usedNames.add(name.trim().toUpperCase()); } } } }; if (Protocol.isDispatchThread()) { runnable.run(); } else { Protocol.invokeAndWait(runnable); } return usedNames; } }