3
votes

I'm building a DSL using Xtext and I would like when a user writes a statement like that:

import "someFile.txt"

to be able to validate and check if that file already exists. If the import is defined like above, then the file should be in the same project as the DSL program that the user is writing. But he should also be able to specify absolute paths.

The problem is that I cannot find a way to access the filesystem in the validator! I saw a lot of people talking about ResourcesPlugin but I don't have access to it from the base project generated by Xtext (I cannot only access it in the ui generated project but the validator exists in the base project).

How can I do that?

2

2 Answers

0
votes

You could simply do it as you would do it in Java:

import java.io.File
import java.io.BufferedReader
import java.io.FileReader

class FileTest {
def static void main(String[] args) {
    try{    
        var testFile = new File(TheFilePathTheUserTypedAfterImportStatement)

        if(!testFile.exists){
            println("That file doesn't exist!")
        }else {
            var reader = new BufferedReader(new FileReader(testFile))

            var String line
            while((line = reader.readLine) != null) {
                println(line)
            }
        }
    }
    catch(Exception e) {
        println(e.stackTrace)
    }
}
}

Instead of printing the message that the file doesn't exist or printing the lineContent you can use the content/the fact that the file doesn't exist to compute something in your validation Method

Greeting Krzmbrzl

0
votes

You could write a little Interface like:

interface FileFinder {
    def boolean exists(String fileName, emf.Resource context)
}

And then have one implementation that uses java.io.File and one implementation that uses the Eclipse resource API. You can bind those in your language's RuntimeModule and UiModule respectively:

public Class<? extends FileFinder> bindFileFinder() {
    return JavaIOFileFinder.class;
}

Then use it in your validation rule:

@Inject FileFinder finder

@Check
def checkFiles(Model model) {
    for (file: model.files) {
        if (!finder.exists(file, model.eResource))
            error...
    }
}