Project Configurator for Jira Server and DC

Java Examples

What’s New

From version 3.3.1, the method getExportedFile from the interface ExportResult is deprecated. The method getExportedReturnFile should be used instead. This new method returns the export configuration file directly, so it is no longer necessary to write the XML string to a file.

Synchronous Export Example Version 3.3.1 and Newer

Synchronous-export-example.java (v.3.3.1 and newer)

package com.devoog.jira.plugin.actions;
​
​
​
import com.atlassian.jira.task.TaskProgressSink;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ExportResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigExporter;
​
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
​
@Scanned
public class SyncExportExample {
​
    private ProjectConfigExporter exporter;
​
    public SyncExportExample(@ComponentImport ProjectConfigExporter exporter){
        this.exporter = exporter;
    }
​
    public String doExport(){
        try {
            // Define the project keys to be exported in the set below
            Set projectKeys = new HashSet();
            projectKeys.add("DEMO");
            projectKeys.add("DEMO1");
​
            // Define the options for how you want to configure the export.
            Map<String, String> exportOptions = new HashMap<>();
            exportOptions.put("filterCFMode","filterUnusedCFExtended"); // Options: none, filterUnusedCFExtended, all
            exportOptions.put("jiraFilterExportMode", "none"); // Options: none, global, projects, global-or-projects, shared, all
            exportOptions.put("jiraDashboardExportMode", "none"); // Options: none, global, projects, global-or-projects, shared, all
            exportOptions.put("agileBoardsExportMode", "none"); // Options: none, projects, all
​
            // Run the export synchronously using the options specified above
            ExportResult exportFinalResult = (ExportResult) exporter.exportSynchronous(exportOptions, projectKeys, TaskProgressSink.NULL_SINK).getFinalResult();
​
            // Check if the export completed successfully and if so generate the XML file
​
            // If the export failed notify the user
            if (exportFinalResult == null || exportFinalResult.getReturnCode() != ProjectConfigExporter.ReturnOpCode.SUCCESS) {
                return "The export did not complete successfully";
            } else {
                // Return the location to the created export file
                return "Export file created at " + exportFinalResult.getExportedResultFile().toPath();
            }
        } catch (Exception e) {
            return "An unexpected error occurred. Please check your atlassian-jira.log for more information" + "<br/>" + e;
        }
    }
}

Synchronous Export Example Version 3.0.5 or Newer

Synchronous-export-example.java (v.3.0.5 or newer)

package com.devoog.jira.plugin.actions;
​
​
​
import com.atlassian.jira.task.TaskProgressSink;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ExportResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigExporter;
​
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
​
@Scanned
public class SyncExportExample {
​
    private ProjectConfigExporter exporter;
​
    public SyncExportExample(@ComponentImport ProjectConfigExporter exporter){
        this.exporter = exporter;
    }
​
    public String doExport(){
        try {
            // Define the project keys to be exported in the set below
            Set projectKeys = new HashSet();
            projectKeys.add("DEMO");
            projectKeys.add("DEMO1");
​
            // Define the options for how you want to configure the export.
            Map<String, String> exportOptions = new HashMap<>();
            exportOptions.put("filterCFMode","filterUnusedCFExtended"); // Options: none, filterUnusedCFExtended, all
            exportOptions.put("jiraFilterExportMode", "none"); // Options: none, global, projects, global-or-projects, shared, all
            exportOptions.put("jiraDashboardExportMode", "none"); // Options: none, global, projects, global-or-projects, shared, all
            exportOptions.put("agileBoardsExportMode", "none"); // Options: none, projects, all
​
            // Run the export synchronously using the options specified above
            ExportResult exportFinalResult = (ExportResult) exporter.exportSynchronous(exportOptions, projectKeys, TaskProgressSink.NULL_SINK).getFinalResult();
​
            // Check if the export completed successfully and if so generate the XML file
​
            // If the export failed notify the user
            if (exportFinalResult == null || exportFinalResult.getReturnCode() != ProjectConfigExporter.ReturnOpCode.SUCCESS) {
                return "The export did not complete successfully";
            } else {
                // If the export was successful write the XML out to a file and notify the user where the file is stored
                // Define the path and export filename to be used below
                Path path = Paths.get("/tmp/export.xml");
                // Write the generated xml out to a configuration export XML file.
                Files.write(path, exportFinalResult.getExportedFile().toString().getBytes());
                // Return the location to the created export file
                return "Export file created at " + path;
            }
        } catch (Exception e) {
            return "An unexpected error occurred. Please check your atlassian-jira.log for more information" + "<br/>" + e;
        }
    }
}

Synchronous Export Example version 3.0.4 or Older

Synchronous-export-example.java (v.3.0.4 or older)

package com.devoog.jira.plugin.actions;



import com.atlassian.jira.task.TaskProgressSink;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ExportResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigExporter;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Scanned
public class SyncExportExample {

    private ProjectConfigExporter exporter;

    public SyncExportExample(@ComponentImport ProjectConfigExporter exporter){
        this.exporter = exporter;
    }

    public String doExport(){
        try {
            // Define the project keys to be exported in the set below
            Set projectKeys = new HashSet();
            projectKeys.add("DEMO");
            projectKeys.add("DEMO1");

            // Define the options for how you want to configure the export.
            Map<String, String> exportOptions = new HashMap<>();
            exportOptions.put("filterCFMode","filterUnusedCFExtended"); // Options: none, filterUnusedCFExtended, all
            exportOptions.put("jiraFilterExportMode", "none"); // Options: none, global, projects, global-or-projects, shared, all
            exportOptions.put("jiraDashboardExportMode", "none"); // Options: none, global, projects, global-or-projects, shared, all
            exportOptions.put("agileBoardsExportMode", "none"); // Options: none, projects, all

            // Run the export synchronously using the options specified above
            ExportResult exportFinalResult = (ExportResult) exporter.exportSynchronous(exportOptions, projectKeys, TaskProgressSink.NULL_SINK).getFinalResult();

            // Check if the export completed successfully and if so generate the XML file

            // If the export failed notify the user
            if (exportFinalResult == null || exportFinalResult.getReturnCode() != ProjectConfigExporter.ReturnOpCode.SUCCESS) {
                return "The export did not complete successfully";
            } else {
                // If the export was successful write the XML out to a file and notify the user where the file is stored
                // Define the path and export filename to be used below
                Path path = Paths.get("/tmp/export.xml");
                // Write the generated xml out to a configuration export XML file.
                Files.write(path, exportFinalResult.getExportedXML().toString().getBytes());
                // Return the location to the created export file
                return "Export file created at " + path;
            }
        } catch (Exception e) {
            return "An unexpected error occurred. Please check your atlassian-jira.log for more information" + "<br/>" + e;
        }
    }
}

Synchronous Import Example

Synchronous-import-example.java(all versions)

package com.devoog.jira.plugin.actions;



import com.atlassian.jira.task.TaskProgressSink;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ConfigImportResult;
import com.awnaba.projectconfigurator.operationsapi.ConfigOpCallResult;
import com.awnaba.projectconfigurator.operationsapi.ConfigOpFullProcessResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigImporter;
import org.apache.commons.lang3.StringUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import static com.awnaba.projectconfigurator.operationsapi.ProjectConfigImporter.*;

@Scanned
public class SyncImportExample {

    private ProjectConfigImporter importer;

    public SyncImportExample (@ComponentImport ProjectConfigImporter importer) {
        this.importer = importer;
    }

    public String doImport(){
        // Specify the path to the export file
        String exportFile = "/tmp/export.xml";

        // Perform the import if the file is valid
        try {
            // Extract the contents of the export file to a String that the import method can use
            String fileContents = new String(Files.readAllBytes(Paths.get(exportFile)));

            // The booleans below allow you to configure the import options you require and match the checkboxes displayed inside the user interface

            // Set to true if you wish to apply the changes as by default only a simulated import is run.
            boolean applyChanges = true;

            // Set to true if you want to create any referenced projects as part of the import
            boolean createExtraProjects = false;

            // Set to true if you wish to use smart custom field contexts
            boolean smartCustomFieldContexts = false;

            // Set to true if you wish to try to publish drafs as part of the import
            boolean publishDrafts = false;

            // A list to specify any configuration objects which we do not wish to import.
            String[] doNotLoad = new String[]{};

            // Construct a new ConfigOpFullProcessResult object which will store the results of the configuration import
            // Requires the following parameters of XML config, applyChanges,createExtraProjects,smartCFContexts,publishDrafts,doNotLoadObjects as well as an instance of the TaskProgressSink object.
            Map<String, Serializable> importOptions = new HashMap<>();

            importOptions.put(IS_SIMULATION, !applyChanges);
            importOptions.put(CREATE_EXTRA_PROJECTS, createExtraProjects);
            importOptions.put(SMART_CF_CONTEXTS, smartCustomFieldContexts);
            importOptions.put(PUBLISH_DRAFTS, publishDrafts);
            importOptions.put(SKIP_OBJECTS, doNotLoad);
            ConfigOpFullProcessResult importResult = importer.importConfigurationSynchronously(fileContents, importOptions, TaskProgressSink.NULL_SINK);

            // Check if the import completed successfully and if so display the results
            ConfigOpCallResult callResult = importResult.getCallResult();
            Enum callReturnCode = callResult.getReturnCode();

            // If the import failed notify the user
            // Possible return codes that can be checked = IMPORT_STARTED, NOT_LOGGED_IN, UNAUTHORIZED, UNLICENSED, ERROR_READING_CONFIG_FILE, IMPORT_ALREADY_RUNNING
            if (callReturnCode != null && callReturnCode != ProjectConfigImporter.ReturnCallCode.IMPORT_STARTED) {
                return "The import did not launch succesfully. Launching failed with a return code of " + callReturnCode.toString();
                // If the import was successful display the results
            } else {
                // get the results of the import
                Enum opCode = importResult.getFinalResult().getReturnCode();
                ConfigImportResult configImportResult = (ConfigImportResult) importResult.getFinalResult();
                StringBuilder message = new StringBuilder();
                if(opCode == ProjectConfigImporter.ReturnOpCode.SUCCESS){
                    message.append(configImportResult.getCategoryTree().toReadableString());
                } else {
                    configImportResult.getErrors().stream().forEach(error -> message.append(error.getException().getMessage()).append(StringUtils.LF));
                }
                return opCode.name() + "<br/>" + message;
            }

            // If an invalid file is found print an exception on screen
        } catch (FileNotFoundException e) {
            return "You must provide a valid file: " + "<br/>" + e;
        } catch (IOException e) {
            return "Error reading the export file: " + "<br/>" + e;
        }
    }
}

Asynchronous Export Example Version 3.3.1 and Newer

Asynchronous-export-example.java(v.3.3.1 or newer)

package com.devoog.jira.plugin.actions;



import com.atlassian.jira.web.bean.TaskDescriptorBean;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ConfigOpCallResult;
import com.awnaba.projectconfigurator.operationsapi.ExportResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigExporter;
import com.awnaba.projectconfigurator.operationsapi.TaskHelper;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Scanned
public class AsyncExportExample {

    private ProjectConfigExporter exporter;
    private TaskHelper taskHelper;

    public AsyncExportExample(@ComponentImport ProjectConfigExporter exporter, @ComponentImport TaskHelper taskHelper){
        this.exporter = exporter;
        this.taskHelper = taskHelper;
    }

    public String doExport(){
        // Define a set to store the keys of all of the projects that we wish to export
        Set projectKeys = new HashSet();

        // Add the project keys that we want to export to our projectKeys set
        projectKeys.add("DEMO");
        projectKeys.add("DEMO1");

        // Define a map to store all of the export options that we require
        Map<String, String> exportOptions = new HashMap<String, String>();

        // Add values to our exportOptions map
        exportOptions.put("filterCFMode", "filterUnusedCFExtended"); // Options: none, filterUnusedCFExtended, all
        exportOptions.put("jiraFilterExportMode", "none");
        // Options: none, global, projects, global-or-projects, shared, all
        exportOptions.put("jiraDashboardExportMode", "none");
        // Options: none, global, projects, global-or-projects, shared, all
        exportOptions.put("agileBoardsExportMode", "none"); // Options: none, projects, all

        // Try to generate the export safely throwing an exception if generating the export fails.
        try {
            // Call the asynchronous export method passing in the export options map and the project keys set as paramaters
            ConfigOpCallResult exportResult = exporter.export(exportOptions, projectKeys);

            // Check if the export completed successfully and if so generate the XML file
            // If the export failed notify the user
            // Possible return codes that can be checked = EXPORT_STARTED, NOT_LOGGED_IN, UNAUTHORIZED, UNLICENSED, NO_PROJECTS,

            //EXPORT_ALREADY_RUNNING
            if (!"EXPORT_STARTED".equals(exportResult.getReturnCode().toString())) {
                return "The export did not start successfully with a return code of " + exportResult.getReturnCode().toString();
                // If the export was successful write the XML out to a file and notify the user where the file is stored
            } else {
                // Get the task ID of of the export from the Config Op Call Result object
                Long taskId = exportResult.getTaskId();

                // Get the task descriptor object for the current task provided by the task helper class
                TaskDescriptorBean<?> taskDescriptor = taskHelper.getTaskState(taskId);

                // Wait until the export task is finished
                while (taskDescriptor.isFinished() == false) {
                    // Wait 0.5 seconds before getting a new instance of the taskDescriptor
                    Thread.sleep(500);
                    // Get a new instance of the task descriptor
                    taskDescriptor = taskHelper.getTaskState(taskId);
                }

                //Return the location to the created export file
                return "Export file created at " + ((ExportResult) taskHelper.getResult(taskDescriptor)).getExportedResultFile().toPath();
            }
            // Throw an exception if the XML export file cannot be generated
        } catch (IOException e) {
            return "An unexpected error occurred. Please check your atlassian-jira.log for more information" + "<br/>" + e;
        } catch (InterruptedException e) {
            return "An error occurred while the thread sleep" + "<br/>" + e;
        }
    }
}

Asynchronous Export Example Version 3.0.5 or Newer

Asynchronous-export-example.java(v.3.0.5 or newer)

package com.devoog.jira.plugin.actions;



import com.atlassian.jira.web.bean.TaskDescriptorBean;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ConfigOpCallResult;
import com.awnaba.projectconfigurator.operationsapi.ExportResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigExporter;
import com.awnaba.projectconfigurator.operationsapi.TaskHelper;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Scanned
public class AsyncExportExample {

    private ProjectConfigExporter exporter;
    private TaskHelper taskHelper;

    public AsyncExportExample(@ComponentImport ProjectConfigExporter exporter, @ComponentImport TaskHelper taskHelper){
        this.exporter = exporter;
        this.taskHelper = taskHelper;
    }

    public String doExport(){
        // Define a set to store the keys of all of the projects that we wish to export
        Set projectKeys = new HashSet();

        // Add the project keys that we want to export to our projectKeys set
        projectKeys.add("DEMO");
        projectKeys.add("DEMO1");

        // Define a map to store all of the export options that we require
        Map<String, String> exportOptions = new HashMap<String, String>();

        // Add values to our exportOptions map
        exportOptions.put("filterCFMode", "filterUnusedCFExtended"); // Options: none, filterUnusedCFExtended, all
        exportOptions.put("jiraFilterExportMode", "none");
        // Options: none, global, projects, global-or-projects, shared, all
        exportOptions.put("jiraDashboardExportMode", "none");
        // Options: none, global, projects, global-or-projects, shared, all
        exportOptions.put("agileBoardsExportMode", "none"); // Options: none, projects, all

        // Try to generate the export safely throwing an exception if generating the export fails.
        try {
            // Call the asynchronous export method passing in the export options map and the project keys set as paramaters
            ConfigOpCallResult exportResult = exporter.export(exportOptions, projectKeys);

            // Check if the export completed successfully and if so generate the XML file
            // If the export failed notify the user
            // Possible return codes that can be checked = EXPORT_STARTED, NOT_LOGGED_IN, UNAUTHORIZED, UNLICENSED, NO_PROJECTS,

            //EXPORT_ALREADY_RUNNING
            if (!"EXPORT_STARTED".equals(exportResult.getReturnCode().toString())) {
                return "The export did not start successfully with a return code of " + exportResult.getReturnCode().toString();
                // If the export was successful write the XML out to a file and notify the user where the file is stored
            } else {
                // Define the path and export filename to be used below
                String exportFile = "/tmp/export.xml";
                // Get the task ID of of the export from the Config Op Call Result object
                Long taskId = exportResult.getTaskId();

                // Get the task descriptor object for the current task provided by the task helper class
                TaskDescriptorBean<?> taskDescriptor = taskHelper.getTaskState(taskId);

                // Wait until the export task is finished
                while (taskDescriptor.isFinished() == false) {
                    // Wait 0.5 seconds before getting a new instance of the taskDescriptor
                    Thread.sleep(500);
                    // Get a new instance of the task descriptor
                    taskDescriptor = taskHelper.getTaskState(taskId);
                }

                // Write out the xml file
                Path path = Paths.get(exportFile);
                byte[] strToBytes = ((ExportResult)taskHelper.getResult(taskDescriptor)).getExportedFile().toString().getBytes();
                // Write the generated xml out to a configuration export XML file.
                Files.write(path, strToBytes);

                //Return the location to the created export file
                return "Export file created at " + exportFile;
            }
            // Throw an exception if the XML export file cannot be generated
        } catch (IOException e) {
            return "An unexpected error occurred. Please check your atlassian-jira.log for more information" + "<br/>" + e;
        } catch (InterruptedException e) {
            return "An error occurred while the thread sleep" + "<br/>" + e;
        }
    }
}

Asynchronous Export Example Version 3.0.4 and Older

Asynchronous-export-example.java(v.3.0.4 or older)

package com.devoog.jira.plugin.actions;



import com.atlassian.jira.web.bean.TaskDescriptorBean;
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.awnaba.projectconfigurator.operationsapi.ConfigOpCallResult;
import com.awnaba.projectconfigurator.operationsapi.ExportResult;
import com.awnaba.projectconfigurator.operationsapi.ProjectConfigExporter;
import com.awnaba.projectconfigurator.operationsapi.TaskHelper;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Scanned
public class AsyncExportExample {

    private ProjectConfigExporter exporter;
    private TaskHelper taskHelper;

    public AsyncExportExample(@ComponentImport ProjectConfigExporter exporter, @ComponentImport TaskHelper taskHelper){
        this.exporter = exporter;
        this.taskHelper = taskHelper;
    }

    public String doExport(){
        // Define a set to store the keys of all of the projects that we wish to export
        Set projectKeys = new HashSet();

        // Add the project keys that we want to export to our projectKeys set
        projectKeys.add("DEMO");
        projectKeys.add("DEMO1");

        // Define a map to store all of the export options that we require
        Map<String, String> exportOptions = new HashMap<String, String>();

        // Add values to our exportOptions map
        exportOptions.put("filterCFMode", "filterUnusedCFExtended"); // Options: none, filterUnusedCFExtended, all
        exportOptions.put("jiraFilterExportMode", "none");
        // Options: none, global, projects, global-or-projects, shared, all
        exportOptions.put("jiraDashboardExportMode", "none");
        // Options: none, global, projects, global-or-projects, shared, all
        exportOptions.put("agileBoardsExportMode", "none"); // Options: none, projects, all

        // Try to generate the export safely throwing an exception if generating the export fails.
        try {
            // Call the asynchronous export method passing in the export options map and the project keys set as paramaters
            ConfigOpCallResult exportResult = exporter.export(exportOptions, projectKeys);

            // Check if the export completed successfully and if so generate the XML file
            // If the export failed notify the user
            // Possible return codes that can be checked = EXPORT_STARTED, NOT_LOGGED_IN, UNAUTHORIZED, UNLICENSED, NO_PROJECTS,

            //EXPORT_ALREADY_RUNNING
            if (!"EXPORT_STARTED".equals(exportResult.getReturnCode().toString())) {
                return "The export did not start successfully with a return code of " + exportResult.getReturnCode().toString();
                // If the export was successful write the XML out to a file and notify the user where the file is stored
            } else {
                // Define the path and export filename to be used below
                String exportFile = "/tmp/export.xml";
                // Get the task ID of of the export from the Config Op Call Result object
                Long taskId = exportResult.getTaskId();

                // Get the task descriptor object for the current task provided by the task helper class
                TaskDescriptorBean<?> taskDescriptor = taskHelper.getTaskState(taskId);

                // Wait until the export task is finished
                while (taskDescriptor.isFinished() == false) {
                    // Wait 0.5 seconds before getting a new instance of the taskDescriptor
                    Thread.sleep(500);
                    // Get a new instance of the task descriptor
                    taskDescriptor = taskHelper.getTaskState(taskId);
                }

                // Write out the xml file
                Path path = Paths.get(exportFile);
                byte[] strToBytes = ((ExportResult)taskHelper.getResult(taskDescriptor)).getExportedXML().toString().getBytes();
                // Write the generated xml out to a configuration export XML file.
                Files.write(path, strToBytes);

                //Return the location to the created export file
                return "Export file created at " + exportFile;
            }
            // Throw an exception if the XML export file cannot be generated
        } catch (IOException e) {
            return "An unexpected error occurred. Please check your atlassian-jira.log for more information" + "<br/>" + e;
        } catch (InterruptedException e) {
            return "An error occurred while the thread sleep" + "<br/>" + e;
        }
    }
}