Export.java

package com.zeroinllc.xellerate.utils;

import java.util.*;
import java.io.*;
import Thor.API.Exceptions.tcAPIException;
import Thor.API.Operations.tcExportOperationsIntf;
import Thor.API.tcUtilityFactory;
import com.thortech.xl.util.config.ConfigurationClient;

/**
 * Exports Xellerate objects to file. Each object will be exported to its own
 * XML file.
 * 
 * Usage: [username] [password] [inputfile]
 * 
 * Works with Oracle Xellerate IDM 9.0
 * 
 * The objects to be exported are listed in an input file in this format:
 * [category1]=[object-names1] 
 * [category2]=[object-names2]
 * 
 * Categories are: EntityAdapter, Process, Organization, DataObjectDef,
 * TaskAdapter, Resource Form, ITResource, UserGroup, Resource, ITResourceDef,
 * Rule, Process Form, ErrorCode, UserDefinedFields, Lookup, EmailDef,
 * ScheduleTask, PrepopAdapter
 * 
 * Example input file: 
 * # Exports the AD task adapters 
 * TaskAdapter = adpAD* 
 * #Exports the AD prepop adapters 
 * PrepopAdapter = adpAD*
 * 
 * Wild cards ('*') in object names are accepted.
 * 
 * Exporting each object to its own file allows versioning and diff tools to
 * function properly.
 * 
 * (Actually diff tools will not work correctly because the XML is not indented.
 * Run an xml indenting tool to indent the files. Example tidy usage: tidy -xml
 * -indent -modify *.xml)
 * 
 * @author Vinh-An Trinh (vinhant@zerointech.com)
 */
public class Export
{

    public static void showHelp(tcExportOperationsIntf intf)
            throws tcAPIException
    {
        System.out.println("xelsysadm xelsysadm inputfile");

        java.util.Collection cat = intf.retrieveCategories();
        System.out.println("Categories: " + cat);
    }

    /*
     * arg[0] : username arg[1] : password (eg xelsysadm) arg[2] : input file
     */
    public static void main(String args[])
    {

        try
        {
            Properties jndi = ConfigurationClient.getComplexSettingByPath(
                    "Discovery.CoreServer").getAllSettings();
            tcUtilityFactory tcutilityfactory = new tcUtilityFactory(jndi,
                    args[0], args[1]);

            tcExportOperationsIntf intf = (tcExportOperationsIntf) tcutilityfactory
                    .getUtility("Thor.API.Operations.tcExportOperationsIntf");

            if (args.length < 3)
            {
                showHelp(intf);
                return;
            }
            String filenameIn = args[2];
            boolean verbose = true;

            BufferedReader in = new BufferedReader(new FileReader(filenameIn));
            String line = null;
            while (null != (line = in.readLine()))
            {
                if (line.startsWith("#") || line.trim().length() == 0) continue;

                int idx = line.indexOf('=');
                if (idx < 0)
                {
                    System.out.println("Skipped line : " + line);
                }
                String cat = line.substring(0, idx).trim();
                String name = line.substring(idx + 1).trim();

                if (verbose) System.out.println("Searching for " + cat + " "
                        + name);

                java.util.Collection coll = intf.findObjects(cat, name);

                if (verbose) System.out.println("Found: " + coll);

                // Export one file per object found
                int i = 0;
                Iterator it = coll.iterator();
                while (it.hasNext())
                {
                    Object item = it.next();

                    // Parse category and object name
                    int idxBegin = item.toString().indexOf("[");
                    int idxEnd = item.toString().indexOf("]", idxBegin);
                    String itemName = removeNonAlphaNum(item.toString()
                            .substring(0, idxBegin - 1));
                    String itemCategory = removeNonAlphaNum(item.toString()
                            .substring(idxBegin + 1, idxEnd));
                    String filename = itemCategory + "-" + itemName;

                    Vector tmpVector = new Vector();
                    tmpVector.add(item);
                    String xml = intf.getExportXML(tmpVector, filename);
                    if (verbose) System.out.println(filename);
                    writeFile(filename + ".xml", xml.getBytes());
                    i++;
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            System.exit(0);
        }
    }

    /**
     * Store the contents of a String in a file.
     */
    static public void writeFile(String name, byte[] contents)
    {
        String path = getFilePath(name);
        FileOutputStream fos = null;
        try
        {
            fos = new FileOutputStream(path);
            fos.write(contents);
        }
        catch (java.io.FileNotFoundException ex)
        {
            ex.printStackTrace();
        }
        catch (java.io.IOException ex)
        {
            ex.printStackTrace();
        }
        finally
        {
            try
            {
                if (fos != null) fos.close();
            }
            catch (java.io.IOException e)
            {
            }
        }
    }

    /**
     * Build an absolute path name for a file. Typically used when you want to
     * write an output file to the "current working directory".
     * 
     * If the name is already an absolute path we use it, otherwise we use the
     * system property "user.dir" as the root directory and add the name.
     */
    public static String getFilePath(String name)
    {

        String path = null;

        if (name.charAt(0) == '/' || name.indexOf(":") != -1)
        {
            // its an absolute path, just return it
            path = name;
        }
        else
        {
            // try relative to user.dir
            String root = System.getProperty("user.dir");
            if (root != null)
            {
                path = root + "/" + name;
            }
            else
            {
                // no obvious way to position it, have to leave
                // it in the process' current working directory
                path = name;
            }
        }

        return path;
    }

    public static String removeNonAlphaNum(String username)
    {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < username.length(); i++)
        {
            char c = username.charAt(i);
            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                    || (c >= '0' && c <= '9'))
            {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}