AgeXtextUtil.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.ge.internal.ui.xtext;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.osate.aadl2.NamedElement;
/**
* Utility class for working with Xtext models. Unlike most utility classes, this class has internal state. It provides a global
* means for listening for model changes and tracking the open Xtext documents.
*
*/
public class AgeXtextUtil {
private static final OpenAadlResources openAadlResources = new OpenAadlResources();
private static final AtomicBoolean initialized = new AtomicBoolean(false);
/**
* Registers listeners to listen to model changes from all Xtext editors and to be notified of newly opened xtext editors.
*
*/
private static void ensureInitialized() {
if (!initialized.getAndSet(true)) {
Display.getDefault().asyncExec(() -> {
// Listen for the opening of new windows
PlatformUI.getWorkbench().addWindowListener(new IWindowListener() {
@Override
public void windowActivated(IWorkbenchWindow window) {
}
@Override
public void windowDeactivated(IWorkbenchWindow window) {
}
@Override
public void windowClosed(IWorkbenchWindow window) {
}
@Override
public void windowOpened(IWorkbenchWindow window) {
registerListenersForWindow(window);
}
});
// Register existing windows
for (final IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
registerListenersForWindow(window);
}
});
}
}
/**
* Register listeners for the window
* @param window
*/
private static void registerListenersForWindow(final IWorkbenchWindow window) {
window.addPageListener(new IPageListener() {
@Override
public void pageActivated(IWorkbenchPage page) {
}
@Override
public void pageClosed(IWorkbenchPage page) {
}
@Override
public void pageOpened(IWorkbenchPage page) {
registerListenerForPage(page);
}
});
for(final IWorkbenchPage page : window.getPages()) {
registerListenerForPage(page);
}
}
/**
* Register part listeners for a page
* @param page
*/
private static void registerListenerForPage(final IWorkbenchPage page) {
page.addPartListener(new EditorListener(page, openAadlResources));
}
/**
* Returns the Xtext document with a root element which has a qualified name and resource that matches the specified element
* @param element the root element for which to return the document.
* @return the last document updated for the qualified name and resource or null if one does not exist
* @see #getDocumentByRootElement(NamedElement)
*/
public static IXtextDocument getDocumentByRootElement(final NamedElement element) {
ensureInitialized();
final Resource elementResource = element.eResource();
if (elementResource == null) {
return null;
}
return getDocumentByRootElement(element.getQualifiedName(), elementResource.getURI());
}
/**
* Returns the Xtext document for the specified root element.
* @param elementQualifiedName the qualified name of the root element
* @param resourceUri the resource URI of the resource containing the element
* @return the last document updated for the qualified name and resource or null if one does not exist
*/
public static IXtextDocument getDocumentByRootElement(final String elementQualifiedName, final URI resourceUri) {
ensureInitialized();
return openAadlResources.getDocument(elementQualifiedName, resourceUri);
}
/**
* Adds a listener which will be called when an Xtext document changes
* @param listener the listener to add
* @see #removeDocumentListener(XtextDocumentChangeListener)
*/
public static void addDocumentListener(final XtextDocumentChangeListener listener) {
ensureInitialized();
openAadlResources.addDocumentListener(listener);
}
/**
* Removes a listener previously registered by {@link #addDocumentListener(XtextDocumentChangeListener)}
* @param listener the listener to remove
* @see #addDocumentListener(XtextDocumentChangeListener)
*/
public static void removeDocumentListener(final XtextDocumentChangeListener listener) {
ensureInitialized();
openAadlResources.removeDocumentListener(listener);
}
}