cross-file reference and link in xtext [message #1716632] |
Mon, 07 December 2015 02:10 |
Dongho Yang Messages: 10 Registered: August 2015 |
Junior Member |
|
|
I created a new DSL by using xtext as follows. (Actually I will access the DSL on RCP application.)
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "...www.xtext.org/example/mydsl/MyDsl"
Configuration:
components+=(Component)*;
Component:
'Component' name=ID
'{'
(('display' display=STRING) &
('dependency' dependency=[Component|ID])?)
'}'
;
I have two files: sample1.mydsl
Component comp1 {
display "comp1"
children comp2
}
sampl2.mydsl
Component comp2 {
display "comp2"
}
On RCP Application, I will compose a tree view with the Configuration model. But when I get comp2 object from getChildren() method of comp1 object, sometimes I couldn't get the comp2 object exactly.
I loaded the model data as below:
private List<ConfigurationItem> itemList;
void loadData() {
project = ResourcesPlugin.getWorkspace().getRoot().getProject("test");
XtextResourceSet resourceSet = (XtextResourceSet) injector
.getInstance(XtextResourceSetProvider.class)
.get(project);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
IFile[] samples = findFiles(resources);
List<Resource> resourceList = new ArrayList<Resource>();
for (IFile sample : samples) {
Resource resourceSample = resourceSet.getResource(
URI.createURI(sample.getLocationURI().toString(), true), true);
resourceList.add(resourceSample);
}
for (Resource resource : resourceList) {
System.out.println("resource = " + resource.toString());
try {
resource.load(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EcoreUtil.resolveAll(resource);
}
// add all to configuration item list
for (Resource rc : resourceList) {
Configuration config = (Configuration) rc.getContents().get(0);
itemList.addAll(config.getConfigurationItems().toArray(new ConfigurationItem[config.getConfigurationItems().size()]));
}
}
test code
for (ConfigurationItem item : itemList) {
if (item.getName().equals("comp1") {
Component[] comps = item.getChildren();
for (Component comp : comps) {
if (comp != null) {
System.out.println("comp display : " + comp.getDisplay());
}
}
}
}
result
I expected the result to be "comp display : comp2".
But Sometimes the result is "comp display : comp2"
and sometimes the result is "comp display : null"
I think it is because of the lazy linking of xtext.
How can always I get correct result -> "comp display : comp2"?
I Hope someone can help me solve it. Thanks.
[Updated on: Mon, 07 December 2015 03:39] Report message to a moderator
|
|
|
|
|
|
Re: cross-file reference and link in xtext [message #1716640 is a reply to message #1716637] |
Mon, 07 December 2015 06:03 |
Dongho Yang Messages: 10 Registered: August 2015 |
Junior Member |
|
|
Hi Christian,
Because I use xtext models in RCP Application, I don't use the mydslstandalone. Instead, I created a injector as below and used it when it load models.
final private static Injector injector = ConfigDSLActivator.getInstance().getInjector("com.xxx.kcdsl.ConfigDSL");
public void loadData() {
XtextResourceSet resourceSet = (XtextResourceSet) injector
.getInstance(XtextResourceSetProvider.class)
.get(project);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
}
I don't know what i did wrong.
[Updated on: Mon, 07 December 2015 06:12] Report message to a moderator
|
|
|
|
Re: cross-file reference and link in xtext [message #1716643 is a reply to message #1716642] |
Mon, 07 December 2015 06:37 |
Dongho Yang Messages: 10 Registered: August 2015 |
Junior Member |
|
|
Thanx Christian.
As you said, I Modified codes as below.
IFile[] samples = findFiles(resources);
List<Resource> resourceList = new ArrayList<Resource>();
for (IFile sample : samples) {
Resource resourceSample = resourceSet.getResource(
URI.createURI(sample.getLocationURI().toString(), true), true);
resourceList.add(resourceSample);
}
for (Resource resource : resourceList) {
try {
resource.load(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
EcoreUtil.resolveAll(resourceSet);
// add all to configuration item list
for (Resource rc : resourceList) {
Configuration config = (Configuration) rc.getContents().get(0);
itemList.addAll(config.getConfigurationItems().toArray(new ConfigurationItem[config.getConfigurationItems().size()]));
}
but The test code still returns "comp display : null".
[Updated on: Mon, 07 December 2015 06:39] Report message to a moderator
|
|
|
|
|
|
|
Re: cross-file reference and link in xtext [message #1716817 is a reply to message #1716665] |
Tue, 08 December 2015 11:44 |
Dongho Yang Messages: 10 Registered: August 2015 |
Junior Member |
|
|
I made up a sample for analysis.
Please check below.
1. The code below is my sample test code. I call
new SampleConfigLoadOperation3().run(monitor); on my RCP Application.
SampleConfigLoadOperation3.java
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.operation.IRunnableWithProgress;
import com.mdstec.ide.kcdsl.ConfigDSL.ConfigurationItem;
import com.mdstec.ide.kcdsl.ConfigDSL.Configuration;
public class SampleConfigLoadOperation3 implements IRunnableWithProgress {
// Progress message
final String loadConfigTaskBeginMsg = "load configuration.";
IProject project;
DataListener dataListener;
/**
* Constructor for project configuration object
*
* @param prjConfig
* the project configuration object
*/
public SampleConfigLoadOperation3() {
// TODO Auto-generated constructor stub
}
public SampleConfigLoadOperation3(IProject project, DataListener listner) {
// TODO Auto-generated constructor stub
this.project = project;
this.dataListener = listner;
}
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
// TODO Auto-generated method stub
if (monitor != null) {
monitor.beginTask(loadConfigTaskBeginMsg, IProgressMonitor.UNKNOWN);
}
try {
loadConfigData(monitor);
} catch (Exception e) {
throw new InvocationTargetException(e, "Loading error" + ": "
+ e.getMessage());
} finally {
if (monitor != null) {
monitor.done();
}
}
if (monitor != null) {
if (monitor.isCanceled()) {
throw new InterruptedException("Cancel loading");
}
}
}
private void loadConfigData(IProgressMonitor monitor) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot workspaceRoot = workspace.getRoot();
project = workspaceRoot.getProject("testproject");
IFolder sampleFolder = project.getFolder("data");
//at this point, no resources have been created
try {
if (!project.exists())
project.create(null);
if (!project.isOpen())
project.open(null);
} catch (CoreException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
if (!sampleFolder.exists()) {
try {
sampleFolder.create(IResource.NONE, true, null);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
copyDataFileToProject("sample1.cdl", "data");
copyDataFileToProject("sample2.cdl", "data");
// copyDataFileToProject("sample3.cdl", "data");
ResourceSet resourceSet = new ResourceSetImpl();
IResource[] resources = null;
try {
resources = sampleFolder.members();
} catch (CoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (resources != null) {
IFile[] samples = findFiles(resources);
List<Resource> resourceList = new ArrayList<Resource>();
for (IFile sample : samples) {
Resource resourceSample = resourceSet.getResource(
URI.createURI(sample.getFullPath().toString()), true);
resourceList.add(resourceSample);
}
// add all to configuration item list
List<ConfigurationItem> configItemList = new ArrayList<ConfigurationItem>();
for (Resource rc : resourceList) {
Configuration config = (Configuration) rc
.getContents().get(0);
configItemList.addAll(config.getConfigurationItems());
}
// root model
List<ConfigurationItem> rootItemList = new ArrayList<ConfigurationItem>();
// set root list in configuration item list
for (int i = 0; i < configItemList.size(); i++) {
ConfigurationItem item = configItemList.get(i);
if (item instanceof com.mdstec.ide.kcdsl.ConfigDSL.Package) {
if (((com.mdstec.ide.kcdsl.ConfigDSL.Package) item)
.isIsRoot()) {
rootItemList.add(item);
}
}
}
// set parents
for (int i = 0; i < rootItemList.size(); i++) {
ConfigurationItem root = rootItemList.get(i);
ConfigurationItem[] children = (ConfigurationItem[]) root
.getChildren().toArray();
setParent(children, root);
}
System.out.println("root size = " + rootItemList.size());
for (ConfigurationItem item : rootItemList) {
findChildren(item);
}
}
}
private void copyDataFileToProject(String fileName, String prjDir) {
// TODO Auto-generated method stub
File file = new File("C:/test/data/" + fileName);
URL sourceURL = null;
try {
sourceURL = file.toURL(); // using .toURI().toURL()
// fails,
// due to
// spaces substitution
} catch (MalformedURLException e) {
e.printStackTrace();
}
InputStream in = null;
try {
in = sourceURL.openStream();
} catch (IOException e) {
e.printStackTrace();
}
IFile iFile = project.getFile(prjDir + "/" + fileName);
if (!iFile.exists()) {
try {
iFile.create(in, true, null);
iFile.refreshLocal(IResource.DEPTH_ONE, null);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void findChildren(ConfigurationItem item) {
// TODO Auto-generated method stub
ConfigurationItem[] children = (ConfigurationItem[]) item.getChildren()
.toArray();
if (children != null && children.length > 0) {
for (ConfigurationItem child : children) {
System.out.println("child name of " + item.getName() + " : "
+ child.getName());
findChildren(child);
}
}
}
private void setParent(ConfigurationItem[] children,
ConfigurationItem parent) {
// TODO Auto-generated method stub
if (children != null && children.length > 0) {
for (ConfigurationItem child : children) {
child.setParent(parent);
setParent((ConfigurationItem[]) child.getChildren().toArray(),
child);
}
}
}
private IFile[] findFiles(IResource[] resources) {
List<IFile> fileList = new ArrayList<IFile>();
find(resources, fileList);
return fileList.toArray(new IFile[fileList.size()]);
}
private void find(IResource[] resources, List<IFile> fileList) {
// TODO Auto-generated method stub
if (resources != null && resources.length > 0) {
for (IResource res : resources) {
if (res instanceof IFile) {
fileList.add((IFile) res);
} else if (res instanceof IFolder) {
IResource[] reses;
try {
reses = ((IFolder) res).members();
find(reses, fileList);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
2. I defined my DSL using xtext as below and generated the models and parser.
ConfigDSL.xtext
generate ConfigDSL "............."
Configuration:
((configurationItems+=ConfigurationItem)*
;
ConfigurationItem:
Package | Component
;
Package:
'Package' name=ID
'{'
(('display' display=STRING) &
('description' description=STRING)? &
('children' children += [ConfigurationItem|ID] (',' children += [ConfigurationItem|ID])*)? &
('parent' parent = [ConfigurationItem|ID])? &
('isRoot' isRoot=BOOLEAN)?
)
'}'
;
Component:
'Component' name=ID
'{'
(('display' display=STRING) &
('parent' parent = [ConfigurationItem|ID])?
)
'}'
;
terminal BOOLEAN returns ecore::EBoolean
: 'true' | 'false';
3. I created two DSL files (sample1.cdl, sample2.cdl) as below and located in "C:/test/data" directory.
sample1.cdl
Component ds1 {
display "ds1"
}
Component ds2 {
display "ds2"
}
Package pk1 {
display "pk1"
children ds1, ds2, ds3
isRoot true
}
sample2.cdl
Component ds3 {
display "ds3"
}
4. When I call "new SampleConfigLoadOperation3().run(monitor);" on my RCP Application, the result is as follows.
root size = 1
child name of pk1 : ds1
child name of pk1 : ds2
child name of pk1 : null
I don't know why the result of the 3rd line is "child name of pk1 : null".
I expected the result is "child name of pk1 : ds3".
|
|
|
Re: cross-file reference and link in xtext [message #1716820 is a reply to message #1716817] |
Tue, 08 December 2015 12:06 |
|
- the code does not compile. even if i remove the datalistener
- why do you copy files around? i always asumed you try to load model files from an xtext project that is clean built (xtext nature, incr. build was run after copy)
- after you read the model you seem to make a model 2 model transformation
so this is not really code i can simply import and execute
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: cross-file reference and link in xtext [message #1716908 is a reply to message #1716820] |
Wed, 09 December 2015 01:05 |
Dongho Yang Messages: 10 Registered: August 2015 |
Junior Member |
|
|
Sorry Christian. I don't know why the sample isn't compiled. I use the sample. Anyway, My RCP application will provide a function that can create a CProject. The created CProject has a treeview. When user creates a CProject and select a menu in the project, the application will collect one more DSL files In a specific folder (outside the project) and display the models on the treeview. Also user can edit the model data on the treeview. Is that possible using xtext? If that is impossible, is there an alternative for that?
In addition, I want a flat DSL to express a tree structure. That means that I want a DSL using not containment reference (layered DSL). So I will transform the models parsed by xtext to models that can be displayed on tree view.
[Updated on: Wed, 09 December 2015 01:20] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04331 seconds