blob: 5dbbef5e9cd3b4efa431eacab77a2263075e4be5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2013 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0, which accompanies this distribution
* and is available at https://www.eclipse.org/legal/epl-2.0/.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.jpa.ui.internal.handlers;
import java.util.Map;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jpt.common.core.internal.utility.PlatformTools;
import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.context.SpecifiedPersistentAttribute;
import org.eclipse.jpt.jpa.ui.selection.JpaSelectionManager;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* Lock the project to postpone any "updates" and set the JPA selection
* afterwards.
*/
public abstract class JpaStructureViewHandler
extends AbstractHandler
{
/**
* Lock the project while executing to postpone any "updates"
* until we are finished; then set the JPA selection.
*/
public final Object execute(ExecutionEvent event) throws ExecutionException {
IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
Object[] items = selection.toArray();
if (items.length == 0) {
return null; // not sure this can happen...
}
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
IProject project = ((JpaStructureNode) items[0]).getJpaProject().getProject();
@SuppressWarnings("unchecked")
Map<String, String> parameters = event.getParameters();
try {
Job.getJobManager().beginRule(project, null);
this.execute_(items, parameters, window);
} finally {
Job.getJobManager().endRule(project);
}
// re-get the first item as it might have been replaced by execute_(...)
this.setJpaSelection(window, (JpaStructureNode) items[0]);
return null;
}
protected abstract void execute_(Object[] items, Map<String, String> parameters, IWorkbenchWindow window);
/**
* When we are changing an attribute mapping in the <code>orm.xml</code>
* file (by calling {@link SpecifiedPersistentAttribute#setMappingKey(String)},
* the following happens synchronously during the call:<ul>
* <li>The mapping (persistent attribute) is removed from the XML file.
* <li>The cursor moves to the empty position where the mapping used to be,
* between the remaining, surrounding mappings, effectively changing the
* JPA selection to the persistent type that contained the selected
* persistent attribute.
* <li>The new mapping (persistent attribute) is added to the XML file in
* the appropriate position, usually not at the same location as the old
* mapping.
* </ul>
* At this point, the JPA selection is still the selected persistent
* attribute; but a text editor event has been fired (with a half-second
* delay - see
* {@link org.eclipse.jface.text.TextViewer#queuePostSelectionChanged(boolean)})
* that will change the JPA selection to the persistent type that contains
* the selected persistent attribute (as calculated from the current cursor
* position). We short-circuit this event by setting the JPA selection to
* <code>null</code> and back to the selected persistent attribute. We set
* the JPA selection to <code>null</code> and back because we
* must <em>change</em> the JPA selection (as opposed to simply re-setting
* it to the same persistent attribute) or no change event will be fired
* (since nothing changed). This double change should be invisible to the
* user....
*/
private void setJpaSelection(IWorkbenchWindow window, JpaStructureNode jpaSelection) {
JpaSelectionManager mgr = PlatformTools.getAdapter(window, JpaSelectionManager.class);
mgr.setSelection(null);
mgr.setSelection(jpaSelection);
}
}