Skip to main content

Import folder structures

Comments

13 comments

  • Hilary Miller

    As a user of Geneious, you can just select all the files in a folder and drag and drop them in as a group and Geneious should call your importer for each file. For Geneious R9, which will be released later this year, Geneious will have a folder import option which will automatically call your importer for each file in a folder chosen by the user. I recommend you wait until then, but if you really need folder import now, you will probably need to implement a DocumentOperation in your plugin that prompts the user for a folder and produces the documents as output from the operation.

    0
  • VL

    Do you already know, when the latest version will be published ?

    0
  • Richard Moir

    It will be out later this year.

    0
  • VL

    Thank you. But as long it is unclear when a newer version will be released, I guess I better implement it on my own.
    Unfortunenately, I am a newbie to Geneious Plugins and do not quite understand how I should integrate my importers in the DocumentOperation. I have several importer classes like MegAlign, PrimerSelection ,... importer in my class MyImporter extends GeneiousPlugin. I do not really understand where I should integrate DocumentOperation. As I read the doumentation it seems as if GeneiousGridImporter[] getImporter() would be the right function. But again this function is never called in MyImporter.

    0
  • Hilary Miller

    Hi,

    Ignore the grid classes. These are for running on networks of computers.

    What you should do is implement GeneiousPlugin.getDocumentOperations() and define a DocumentOperation that requires no input and produces the documents you import as output. For example:

    public DocumentOperation[] getDocumentOperations() {
    DocumentOperation operation = new DocumentOperation() {
    @Override
    public GeneiousActionOptions getActionOptions() {
    return new GeneiousActionOptions("My custom format from folder").setMainMenuLocation(GeneiousActionOptions.MainMenu.Import);
    }

    @Override
    public String getHelp() {
    return null;
    }

    @Override
    public DocumentSelectionSignature[] getSelectionSignatures() {
    return new DocumentSelectionSignature[0];
    }

    @Override
    public void performOperation(AnnotatedPluginDocument[] annotatedDocuments, ProgressListener progressListener, Options options, SequenceSelection sequenceSelection, OperationCallback callback) throws DocumentOperationException {
    callback.addDocument(new DefaultNucleotideSequence("a", "GATT"), false, ProgressListener.EMPTY);
    }
    };
    return new DocumentOperation[]{operation};
    }


    You should fill in the details of performOperation to prompt the user for a folder and create the documents.

    0
  • VL

    It works now. But ideally I also want to keep my subfolders. I couldn't find out how to create new folders in a given path and write files in specific folders.

    Is it possible ?

     

    0
  • Hilary Miller

    You can use callback.setSubFolder(), but that doesn't support nested sub-folders. So if you need sub folders more than 1 level deep, you could do something like this inside your performOperation method:

     

    DefaultNucleotideSequence sequence = new DefaultNucleotideSequence("a", "GATT");
    GeneiousService selectedService = ServiceUtilities.getSelectedService();
    try {
    if (selectedService instanceof WritableDatabaseService) {
    WritableDatabaseService service = (WritableDatabaseService) selectedService;
    service = service.createChildFolder("folderName").createChildFolder("subFolderName");
    service.addDocumentCopy(DocumentUtilities.createAnnotatedPluginDocument(sequence),ProgressListener.EMPTY);
    }
    else {
    callback.setSubFolder("folderName"); // This doesn't support sub-folders
    callback.addDocument(sequence, false, ProgressListener.EMPTY);
    }
    } catch (DatabaseServiceException e) {
    throw new DocumentOperationException(e);
    }
    0
  • VL

    If no folder is selected, another window pops up and asks for a destination folder. However I cannot get this new folder by  ServiceUtilities.getSelectedService(). I tried to call ServiceUtilities.getResultsDestination(), but it asks for a path for a second time... How can I either suppress the first popup window or getting the path of it?

    0
  • Hilary Miller

    Once at the start of performOperation you should call ServiceUtilities.getSelectedService(). If that doesn't return a WritableDatabaseService then call ServiceUtilities.getResultsDestination(). Then import all your documents into to that service or child folders of it.

    0
  • VL

    This is what I tried. But the popup window for destination selections is already displayed before performOperation. When I call ServiceUtilities.getResultsDestination() the selection window pop ups for a second time, although I already chose a folder. When I call ServiceUtilities.getResultsDestination() there is no problem and I get my destination folder. But this function is called before (I didn't call it somewhere else) and I cannot catch it.

    This is what I got for performOperation:

     

    public void performOperation(AnnotatedPluginDocument[] annotatedDocuments, ProgressListener progressListener, Options options, SequenceSelection sequenceSelection, OperationCallback callback) throws DocumentOperationException {

                    // At this point ResultsDestination is already called
                    options.getOptions();
                    String pathname = options.getValueAsString("FolderToBeImported");
                    File[] files = new File(pathname).listFiles();

                    WritableDatabaseService service= (WritableDatabaseService) PluginUtilities.getGeneiousService("LocalDocuments");
                    GeneiousService selectedService = ServiceUtilities.getSelectedService();
                    if (!(selectedService instanceof WritableDatabaseService)) {
                        selectedService = ServiceUtilities.getResultsDestination();   // Here another ResultsDestination is called
                   }
                   
                    for(File file: files){
                        service =  (WritableDatabaseService) selectedService;

                        try {
                           parentFolder = file.getParentFile().getName();
                           service = service.createChildFolder(parentFolder);

                        }catch{...}

                }

     

     

    0
  • Hilary Miller

    Sorry, I didn't quite understand the problem initially. You can fix that by adding this to your DocumentOperation:

     

    @Override
    public boolean isDocumentGenerator() {
    return false;
    }
    0
  • VL

    This fixed one problem, but actually I return a PluginDocument (TextDocument) in case my importer fails to import some documents. I used callback.addDocument(), but this does not work if I set this to false; As far I could figure out, the service does not support PluginDocuments but only AnnotatedPluginDocuments.

    0
  • Hilary Miller

    When overriding isDocumentGenerator, you should ignore the callback and add all documents directly to the service. Any PluginDocument can be wrapped in an AnnotatedPluginDocument using DocumentUtilities.createAnnotatedPluginDocument().  

    0

Please sign in to leave a comment.