7_-_Creating_an_exporter

Allan Cunliffe

In order to load the DeNormaliser into Xena we need to create the appropriate entry in the Foolugin.java file. We will be modifying the getNormaliserInputMap and getNormaliserOutputMap methods that we created for the basic normaliser in step 4.

 @Override
        public Map<Type>> getNormaliserInputMap() {
                Map<Type>> inputMap = new HashMap<Type>>();

                // Normaliser
                FooNormaliser normaliser = new FooNormaliser();
                Set<Type> normaliserSet = new HashSet<Type>();
                normaliserSet.add(new FooFileType());
                inputMap.put(normaliser, normaliserSet);

                // Denormaliser
                XenaFooDeNormaliser denormaliser = new XenaFooDeNormaliser();
                Set<Type> denormaliserSet = new HashSet<Type>();
                denormaliserSet.add(new XenaFooFileType());
                inputMap.put(denormaliser, denormaliserSet);

                return inputMap;
        }

        @Override
        public Map<Type>> getNormaliserOutputMap() {
                Map<Type>> outputMap = new HashMap<Type>>();

                // Normaliser
                FooNormaliser normaliser = new FooNormaliser();
                Set<Type> normaliserSet = new HashSet<Type>();
                normaliserSet.add(new XenaFooFileType());
                outputMap.put(normaliser, normaliserSet);

                // Denormaliser
                XenaFooDeNormaliser denormaliser = new XenaFooDeNormaliser();
                Set<Type> denormaliserSet = new HashSet<Type>();
                denormaliserSet.add(new FooFileType());
                outputMap.put(denormaliser, denormaliserSet);

                return outputMap;
        }

Test the exporter

Now we need a way to test our Foo exporter. Because our exporter recreates our original foo file, we can programmatically check that the exported file is identical to the original file. We won't be able to do this for every plugin - for example the office plugin converts Microsoft Office files to ODF files, before being wrapped in XML produced by Xena. The exporter does not convert back to the Microsoft Office format but instead simply removes the XML wrapping to produce a native ODF file. There is thus no way to programmatically check that our office normaliser and exporter are working correctly.

The code to test our exporter is based on the NormaliseTester with extra code to perform the exporting and methods to compare the exported file with the original file. Here is the code:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Vector;

import au.gov.naa.digipres.xena.core.Xena;
import au.gov.naa.digipres.xena.kernel.XenaException;
import au.gov.naa.digipres.xena.kernel.XenaInputSource;
import au.gov.naa.digipres.xena.kernel.guesser.Guess;
import au.gov.naa.digipres.xena.kernel.normalise.ExportResult;
import au.gov.naa.digipres.xena.kernel.normalise.NormaliserResults;

public class ExporterTester {

        /**
         * @param args
         * @throws XenaException 
         * @throws IOException 
         */
        public static void main(String[] args) throws XenaException, IOException {
                Xena xena = new Xena();

                // our foo jar will already be on the class path, so load it by name...
                Vector<String> pluginList = new Vector<String>();
                pluginList.add("au.gov.naa.digipres.xena.demo.foo.FooPlugin");
                xena.loadPlugins(pluginList);

                // set the base path to be the current working directory
                xena.setBasePath(System.getProperty("user.dir"));
                System.out.println(System.getProperty("user.dir"));

                // create the new input source
                File inputFile = new File("../../../data/example_file.foo");
                XenaInputSource xis = new XenaInputSource(inputFile);
                // guess its type
                Guess fooGuess = xena.getBestGuess(xis);

                //print the guess...
                System.out.println("Here is the best guess returned by Xena: ");
                System.out.println(fooGuess.toString());
                System.out.println("-----------------------------------------");

                // normalise the file!
                NormaliserResults results = xena.normalise(xis);
                System.out.println("Here are the results of the normalisation:");
                System.out.println(results.getResultsDetails());
                System.out.println("-----------------------------------------");

                // Export the normalised file
                File outputFile = new File(results.getDestinationDirString(), results.getOutputFileName());
                XenaInputSource normalisedXIS = new XenaInputSource(outputFile);
                ExportResult exportResult = xena.export(normalisedXIS, new File(results.getDestinationDirString()), true);
                File exportedFile = new File(exportResult.getOutputDirectoryName(), exportResult.getOutputFileName());
                System.out.println("Here are the results of the export:");
                System.out.println(exportResult.toString());
                String compareString = compareFiles(inputFile, exportedFile) ? "identical" : "different";
                System.out.println("The original file is " + compareString + " to the exported file.");
                System.out.println("-----------------------------------------");
        }

        /**
         * Return true if and only if the files have exactly the same contents
         * @param file1
         * @param file2
         * @return
         * @throws IOException
         */
        private static boolean compareFiles(File file1, File file2) throws IOException {
                boolean filesIdentical = true;

                if (file1.length() == file2.length()) {
                        FileInputStream inputStream1 = new FileInputStream(file1);
                        FileInputStream inputStream2 = new FileInputStream(file2);

                        byte[] buffer1 = new byte[1024 * 10];
                        byte[] buffer2 = new byte[1024 * 10];

                        while (true) {
                                int bytesRead1 = inputStream1.read(buffer1);
                                int bytesRead2 = inputStream2.read(buffer2);

                                // The files must be the same length if we have reached this point, so something has gone wrong.
                                if (bytesRead1 != bytesRead2) {
                                        filesIdentical = false;
                                        break;
                                }

                                // We have reached the end of the files and have found no differences
                                if (bytesRead1

Here is the output when we run ExporterTester:

# java -cp foo.jar;../../../xena/xena.jar au.gov.naa.digipres.xena.demo.foo.test.ExporterTester
/home/dpuser/workspace/plugin-howto/05_exporter/foo_plugin/dist
Here is the best guess returned by Xena:
Guess... type: Foo
possible: Unknown
dataMatch:True
magicNumber: True
extensionMatch: True
mimeMatch: Unknown
certain: Unknown
priority: Default
-----------------------------------------
Here are the results of the normalisation:
Normalisation successful.
The input source name file:/home/dpuser/workspace/plugin-howto/05_exporter/foo_plugin/dist/../../../data/example_file.foo
normalised to: example_file.foo_Foo0001.xena
with normaliser: "Foo"
to the folder: /home/dpuser/workspace/plugin-howto/05_exporter/foo_plugin/dist
and the Xena id is: file:/../../../data/example_file.foo
-----------------------------------------
Here are the results of the export:
input file name: file:/home/dpuser/workspace/plugin-howto/05_exporter/foo_plugin/dist/example_file.foo_Foo0003.xena
success: true
output dir: /home/dpuser/workspace/plugin-howto/05_exporter/foo_plugin/dist
output file name: ../../../data/example_file.foo
The original file is identical to the exported file.
-----------------------------------------

This completes the work we will be doing on the Foo plugin. We will now move on to the OrgX plugin, which will handle naming our normalised files and the metadata they will contain.


Related

Wiki: Main_Page