EmbeddedStyledTextXtextAdapter.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.ba.ui;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Optional;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
import org.eclipse.xtext.ui.editor.model.XtextDocument;
import org.osate.ge.ba.ui.properties.EditableEmbeddedTextValue;
import org.osate.ge.ba.util.BehaviorAnnexXtextUtil;
import org.osate.xtext.aadl2.ui.internal.Aadl2Activator;
import org.osate.xtext.aadl2.ui.propertyview.OsateStyledTextXtextAdapter;
import org.yakindu.base.xtext.utils.jface.viewers.context.IXtextFakeContextResourcesProvider;
import com.google.inject.Injector;
/**
* Embeds AADL source specified by {@link EditableEmbeddedTextValue} with Xtext highlighting in a {@link StyledText}
* @since 2.0
*/
class EmbeddedStyledTextXtextAdapter extends OsateStyledTextXtextAdapter {
private final static Injector injector = Aadl2Activator.getInstance()
.getInjector(Aadl2Activator.ORG_OSATE_XTEXT_AADL2_AADL2);
private final EditableEmbeddedTextValue embeddedTextValue;
private static final IXtextFakeContextResourcesProvider contextFakeResourceProvider = IXtextFakeContextResourcesProvider.NULL_CONTEXT_PROVIDER;
/**
* Instantiates the Embedded Styled Text Xtext Adapter for embedding AADL source in a {@link StyledText}
* @param embeddedTextValue the text information for the embedded AADL source
*/
public EmbeddedStyledTextXtextAdapter(final EditableEmbeddedTextValue embeddedTextValue) {
super(injector, contextFakeResourceProvider, embeddedTextValue.getProject());
this.embeddedTextValue = embeddedTextValue;
}
@Override
public void adapt(final StyledText styledText, final boolean decorate) {
super.adapt(styledText, decorate);
final XtextDocument xtextDoc = getXtextDocument();
final SourceViewer srcViewer = getXtextSourceviewer();
final String prefixWithNewLineEnding = embeddedTextValue.getPrefix() + "\n";
final String suffixWithNewLineBeginning = "\n" + embeddedTextValue.getSuffix();
final String editableText = embeddedTextValue.getEditableText();
final String wholeText = new StringBuilder(prefixWithNewLineEnding).append(editableText)
.append(suffixWithNewLineBeginning)
.toString();
xtextDoc.set(wholeText);
srcViewer.setDocument(xtextDoc, srcViewer.getAnnotationModel(), prefixWithNewLineEnding.length(),
editableText.length());
}
/**
* Returns the editable embedded text value
* @return the editable embedded text value
* @since 2.0
*/
public EditableEmbeddedTextValue getEmbeddedTextValue() {
return embeddedTextValue;
}
@Override
public void adapt(final StyledText styledText) {
adapt(styledText, false);
}
/**
* Returns an optional of the modified full AADL source if edited region is a valid modification. Empty if modification is invalid.
* @param newText the text to replace editable text region
* @return an optional of the modified full AADL source if edited region is a valid modification. Empty if modification is invalid.
* @since 2.0
*/
public Optional<String> getValidModifiedSource(final String newText) {
final String originalSrc = getOriginalSource();
String modifiedSrc = null;
try {
// AADL source text to load
modifiedSrc = embeddedTextValue.getModifiedAADLSourceForNewText(newText)
.orElse(serialize(getXtextParseResult().getRootASTElement()));
loadSource(modifiedSrc);
final EObject tmpBo = getFakeResource()
.getEObject(EcoreUtil.getURI(embeddedTextValue.getElementToModify()).fragment());
if (tmpBo == null || !embeddedTextValue.isValidModification(tmpBo, newText)) {
modifiedSrc = null;
}
} catch (final Exception ex) {
modifiedSrc = null;
} finally {
// Load original source
loadSource(originalSrc);
}
return Optional.ofNullable(modifiedSrc);
}
private String getOriginalSource() {
// Update save button based on whether the text entered into the
// styled text is a serializable condition
final EObject rootElement = getXtextParseResult().getRootASTElement();
final XtextResource resource = getFakeResource();
// Link model
resource.getLinker().linkModel(rootElement, new ListBasedDiagnosticConsumer());
// Original source text
return BehaviorAnnexXtextUtil.getText(null, resource);
}
private void loadSource(final String src) {
try {
getFakeResource().unload();
getFakeResource().load(new ByteArrayInputStream(src.getBytes()), null);
} catch (final IOException e) {
throw new RuntimeException("Serialized source cannot be loaded");
}
}
private XtextResource getFakeResource() {
return getFakeResourceContext().getFakeResource();
}
private String serialize(final EObject rootElement) {
return getFakeResource().getSerializer().serialize(rootElement);
}
}