org.openhealthtools.openxds.repository.Utility.java Source code

Java tutorial

Introduction

Here is the source code for org.openhealthtools.openxds.repository.Utility.java

Source

/*
 * ====================================================================
 *
 * This code is subject to the freebxml License, Version 1.1
 *
 * Copyright (c) 2001 - 2003 freebxml.org.  All rights reserved.
 *
 * $Header: /cvsroot/ebxmlrr/omar/src/java/org/freebxml/omar/common/Utility.java,v 1.40 2007/05/18 18:58:59 psterk Exp $
 * ====================================================================
 */
package org.openhealthtools.openxds.repository;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.UUID;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;

import org.openhealthtools.openxds.repository.api.XdsRepositoryItem;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Class Declaration.
 * @see
 * @author Farrukh S. Najmi
 * @author Adrian Chong
 * @version   1.2, 05/02/00
 */
public class Utility {
    private static final Log log = LogFactory.getLog(Utility.class);

    public static final int MAX_REGISTRY_ID_LENGTH = 256;
    private static HashMap tableNameMap = new HashMap();
    public static final String FILE_SEPARATOR = System.getProperty("file.separator");
    /*
     * See http://www.digit-life.com/articles/ntfs/
     */
    public static final int MAX_FILE_LENGTH = 255;
    /**
     *         128-bit buffer for use with secRand
     */
    private final byte[] secRandBuf16 = new byte[16];

    /**
     * 64-bit buffer for use with secRand
     */
    private final byte[] secRandBuf8 = new byte[8];
    /**
     * random number generator for UUID generation
     */
    private final SecureRandom secRand = new SecureRandom();
    static {
        tableNameMap.put("user", "user_");
        tableNameMap.put("name", "name_");
        tableNameMap.put("classificationscheme", "ClassScheme");
        tableNameMap.put("concept", "ClassificationNode");
    }

    private static HashMap columnNameMap = new HashMap();

    static {
        columnNameMap.put("number", "number_");
        columnNameMap.put("name", "name_");
        columnNameMap.put("user", "user_");
        columnNameMap.put("timestamp", "timestamp_");
    }

    /**
     * @link
     * @shapeType PatternLink
     * @pattern Singleton
     * @supplierRole Singleton factory
     */

    /* # private Utility _utility; */
    private static Utility instance = null;

    /**
     * Class Constructor.
     *
     *
     * @see
     */
    protected Utility() {
    }

    /**
     * Converts an InputStream to a String.
     *
     * @param is the InputStream content to convert to String
     */
    public String unmarshalInputStreamToString(InputStream is) throws IOException {

        int buflen = 1024;
        byte[] bytes = new byte[buflen + 1];

        BufferedInputStream bis = new BufferedInputStream(is);

        int bytesRead = 0;

        StringBuffer strBuf = new StringBuffer();
        while ((bytesRead = bis.read(bytes, 0, buflen)) != -1) {
            strBuf.append(new String(bytes, 0, bytesRead, "utf-8"));
        }

        return strBuf.toString();
    }

    /**
     * Create a temporary file with the specified content.
     *
     * @param content contents of the created RepositoryItem
     * @param deleteOnExit deletes the temporary file upon exiting the VM if true.
     *
     * @return the File instance representing the temporary file
     */
    public static File createTempFile(String content, boolean deleteOnExit) throws IOException {
        // Write to temp file
        byte[] bytes = content.getBytes("utf-8");
        File temp = createTempFile(bytes, "omar", ".txt", deleteOnExit);

        return temp;
    }

    public static File createTempFile(byte[] bytes, String prefix, String extension, boolean deleteOnExit)
            throws IOException {
        File temp = File.createTempFile(prefix, extension);

        // Delete temp file when program exits.
        if (deleteOnExit) {
            temp.deleteOnExit();
        }

        // Write to temp file
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(temp));
        out.write(bytes, 0, bytes.length);
        out.close();

        return temp;
    }

    /**
     * Create a RepositoryItem containing provided content.
     *
     * @param id the id of the created ExtrinsicObject created for the RepositoryItem
     * @param content contents of the created RepositoryItem
     *
     * @return a <code>RepositoryItem</code> value
     * @throws IOException encountered during IO operations
     */
    public XdsRepositoryItem createRepositoryItem(String id, String content) throws IOException {
        File file = createTempFile(content, true);

        DataHandler dh = new DataHandler(new FileDataSource(file));
        XdsRepositoryItem ri = new XdsRepositoryItemImpl(id, dh);
        return ri;
    }

    /**
     * Create a valid registry id.
     */
    public String createId() {
        String id = "urn:uuid:" + getNewUUID();
        return id;
    }

    /**
     * Strip urn:uuid: part from start of registry
     * object id.  If id is null or doesn't start with
     * urn:uuid: then the id is returned without modification.
     */
    public String stripId(String id) {
        if (id != null) {
            if (id.startsWith("urn:uuid:")) {
                id = id.substring(9).trim();
            } else {
                // id is urn
                id = id.replaceAll(":", "_");
            }
        }

        return id;
    }

    /**
     * Validates URIs according to Registry specs.
     *
     * From Registry specs: "If the URI is a URL then a registry MUST validate the
     * URL to be resolvable at the time of submission before accepting an
     * ExternalLink submission to the registry."
     *
     * Any non-Http URLs and other types of URIs will not be checked. If the http
     * response code is smaller than 200 or bigger than 299, the http URL is
     * considered invalid.
     */
    public boolean isValidURI(String uRI) {
        if (uRI == null) {
            return false;
        }

        try {
            java.net.URI _uri = new java.net.URI(uRI);
        } catch (java.net.URISyntaxException e) {
            // Not an URI. return false
            return false;
        }

        // Quoting Doug: "URLs are resolvable URIs"!
        // Try to resolve the URLs here, if it is URL
        try {
            java.net.URL uRL = new java.net.URL(uRI);
            if (uRI.startsWith("http:")) {
                java.net.HttpURLConnection httpUrlConn = (java.net.HttpURLConnection) uRL.openConnection();
                int responseCode = httpUrlConn.getResponseCode();

                if ((responseCode < 200) || (responseCode > 299)) {
                    return false;
                } else {
                    return true;
                }
            } else {
                URLConnection conn = uRL.openConnection();
            }
        } catch (java.net.MalformedURLException e) {
            // Not an URL, will not try to resolve. Valid URI
        } catch (IOException e) {
            return false;
        }

        return true;
    }

    public static String fixIdentifier(String inputId) {
        String outputId = inputId.replace(':', '_');
        outputId = outputId.replace('.', '_');
        outputId = outputId.replace('$', '_');
        return outputId;
    }

    /**
     * Fixes an input URN to comply with URN syntax by replacing invalid chars with '_'
     */
    public static String fixURN(String inputId) {
        String outputId = inputId.replace(FILE_SEPARATOR.charAt(0), ':');
        if (!(outputId.startsWith("urn:"))) {
            outputId = "urn:" + outputId;
        }
        outputId = outputId.replaceAll("[^a-zA-Z_0-9:_]", "_");
        return outputId;
    }

    /*
     * Gets the path suitable for the path component of a URL based upon the specified URI.
     */
    public static String getURLPathFromURI(String uri) throws URISyntaxException {
        String path = null;

        try {
            URL url = new URL(uri);
            path = url.getPath();
        } catch (MalformedURLException e) {
            //Not a URL. Convert to URN
            String urn = fixURN(uri);
            path = getURLPathFromURN(urn);
        }

        return path;
    }

    public static String getURLPathFromURN(String urn) throws URISyntaxException {
        String path = null;

        URI uri = new java.net.URI(urn);
        path = urn.replaceAll("[:]", "/");
        return path;
    }

    public static ZipOutputStream createZipOutputStream(String baseDir, String[] relativeFilePaths, OutputStream os)
            throws FileNotFoundException, IOException {
        if (baseDir.startsWith("file:/")) {
            baseDir = baseDir.substring(5);
        }
        ZipOutputStream zipoutputstream = new ZipOutputStream(os);

        zipoutputstream.setMethod(ZipOutputStream.STORED);

        for (int i = 0; i < relativeFilePaths.length; i++) {
            File file = new File(baseDir + FILE_SEPARATOR + relativeFilePaths[i]);

            byte[] buffer = new byte[1000];

            int n;

            FileInputStream fis;

            // Calculate the CRC-32 value.  This isn't strictly necessary
            //   for deflated entries, but it doesn't hurt.

            CRC32 crc32 = new CRC32();

            fis = new FileInputStream(file);

            while ((n = fis.read(buffer)) > -1) {
                crc32.update(buffer, 0, n);
            }

            fis.close();

            // Create a zip entry.

            ZipEntry zipEntry = new ZipEntry(relativeFilePaths[i]);

            zipEntry.setSize(file.length());
            zipEntry.setTime(file.lastModified());
            zipEntry.setCrc(crc32.getValue());

            // Add the zip entry and associated data.

            zipoutputstream.putNextEntry(zipEntry);

            fis = new FileInputStream(file);

            while ((n = fis.read(buffer)) > -1) {
                zipoutputstream.write(buffer, 0, n);
            }

            fis.close();

            zipoutputstream.closeEntry();
        }

        return zipoutputstream;
    }

    /**
     *
     * Extracts Zip file contents relative to baseDir
     * @return An ArrayList containing the File instances for each unzipped file
     */
    public static ArrayList unZip(String baseDir, InputStream is) throws IOException {
        ArrayList files = new ArrayList();
        ZipInputStream zis = new ZipInputStream(is);

        while (true) {
            // Get the next zip entry.  Break out of the loop if there are
            //   no more.
            ZipEntry zipEntry = zis.getNextEntry();
            if (zipEntry == null)
                break;

            String entryName = zipEntry.getName();
            if (FILE_SEPARATOR.equalsIgnoreCase("\\")) {
                // Convert '/' to Windows file separator
                entryName = entryName.replaceAll("/", "\\\\");
            }
            String fileName = baseDir + FILE_SEPARATOR + entryName;
            //Make sure that directory exists.
            String dirName = fileName.substring(0, fileName.lastIndexOf(FILE_SEPARATOR));
            File dir = new File(dirName);
            dir.mkdirs();

            //Entry could be a directory
            if (!(zipEntry.isDirectory())) {
                //Entry is a file not a directory.
                //Write out the content of of entry to file 
                File file = new File(fileName);
                files.add(file);
                FileOutputStream fos = new FileOutputStream(file);

                // Read data from the zip entry.  The read() method will return
                //   -1 when there is no more data to read.
                byte[] buffer = new byte[1000];

                int n;

                while ((n = zis.read(buffer)) > -1) {
                    // In real life, you'd probably write the data to a file.
                    fos.write(buffer, 0, n);
                }
                zis.closeEntry();
                fos.close();
            } else {
                zis.closeEntry();
            }
        }

        zis.close();

        return files;
    }

    /* public String mapTableName(RegistryObjectType ro) {
    Class clazz = ro.getClass();
    String className = clazz.getName();
    className = className.substring(className.lastIndexOf(".") + 1);
        
    if (className.endsWith("Impl")) {
        className = className.substring(0, className.length() - 4);
    }
        
    return mapTableName(className);
     }*/

    public String mapTableName(String name) {
        String newName = (String) tableNameMap.get(name.toLowerCase().trim());

        if (newName == null) {
            newName = name;
        }

        return newName;
    }

    public String mapColumnName(String name) {
        String newName = (String) columnNameMap.get(name.toLowerCase().trim());

        if (newName == null) {
            newName = name;
        }

        return newName;
    }

    public String getClassNameNoPackage(Object obj) {

        Class clazz = obj.getClass();

        return getClassNameNoPackage(clazz);
    }

    public String getClassNameNoPackage(Class clazz) {
        String className = clazz.getName();

        //Make sure className is not package qualified
        int index = className.lastIndexOf('.');
        if (index >= 0) {
            className = className.substring(index + 1, className.length());
        }

        return className;
    }

    public static boolean containsWhiteSpacesOnly(String str) {
        boolean whiteSpaceOnly = false;
        String[] strArr = str.split("[^\\s]");
        if ((str == null) || (str.length() == 0) || ((str.split("[^\\s]")).length <= 1)) {
            whiteSpaceOnly = true;
        }

        return whiteSpaceOnly;
    }

    public static String absolutize(String name) {
        // absolutize all the system IDs in the input,
        // so that we can map system IDs to DOM trees.
        try {
            URL baseURL = new File(".").getCanonicalFile().toURL();
            return new URL(baseURL, name).toExternalForm();
        } catch (IOException e) {
            ; // ignore
        }
        return name;
    }

    public static String getFileOrURLName(String fileOrURL) {
        try {
            try {
                return escapeSpace(new URL(fileOrURL).toExternalForm());
            } catch (MalformedURLException e) {
                return new File(fileOrURL).getCanonicalFile().toURL().toExternalForm();
            }
        } catch (Exception e) {
            // try it as an URL
            return fileOrURL;
        }
    }

    private static String escapeSpace(String url) {
        // URLEncoder didn't work.
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < url.length(); i++) {
            // TODO: not sure if this is the only character that needs to be escaped.
            if (url.charAt(i) == ' ')
                buf.append("%20");
            else
                buf.append(url.charAt(i));
        }
        return buf.toString();
    }

    /**
     * Method Declaration.
     *
     *
     * @return
     *
     * @see
     */
    public synchronized static Utility getInstance() {
        if (instance == null) {
            instance = new Utility();
        }

        return instance;
    }

    /**
     * This method is used to retrieve a QName prefix
     *
     * @arg qName
     *  A String containing the QName from which to retrieve the prefix.
     * @return
     *  A String containing the prefix
     */
    public static String getPrefix(String qName) {
        int i = qName.indexOf(':');
        if (i == -1) {
            return null;
        }
        return qName.substring(0, i);
    }

    /**
     * This method is used to retrieve the local part of a QName
     *
     * @arg qName
     *  A String containing the QName from which to retrieve the local part.
     * @return
     *  A String containing the local part
     */
    public static String getLocalPart(String qName) {
        int i = qName.lastIndexOf(':');
        if (i == -1) {
            return qName;
        }
        return qName.substring(i + 1);
    }

    /**
     * Replaces a JDK 1.5 Pattern.quote method to allow use with JDK 1.4
     *
     * Returns a literal pattern <code>String</code> for the specified
     * <code>String</code>.
     *
     * <p>This method produces a <code>String</code> that can be used to
     * create a <code>Pattern</code> that would match the string
     * <code>s</code> as if it were a literal pattern.</p> Metacharacters
     * or escape sequences in the input sequence will be given no special
     * meaning.
     *
     * @param  s The string to be literalized
     * @return  A literal string replacement
     * @since 1.5
     */
    public static String quote(String s) {
        int slashEIndex = s.indexOf("\\E");
        if (slashEIndex == -1)
            return "\\Q" + s + "\\E";

        StringBuffer sb = new StringBuffer(s.length() * 2);
        sb.append("\\Q");
        slashEIndex = 0;
        int current = 0;
        while ((slashEIndex = s.indexOf("\\E", current)) != -1) {
            sb.append(s.substring(current, slashEIndex));
            current = slashEIndex + 2;
            sb.append("\\E\\\\E\\Q");
        }
        sb.append(s.substring(current, s.length()));
        sb.append("\\E");
        return sb.toString();
    }

    /**
     * This method takes a fileName and verifies that it is a valid filename
     * @param fileName
     * A String that contains the file name to validate
     * @return
     * A String that contains a validated file name
     */
    public static String makeValidFileName(String fileName) {
        // First check to see if fileName is > MAX_FILE_LENGTH
        // If it is, truncate.
        String validFileName = new String(fileName);
        int fileNameLength = validFileName.length();
        if (fileNameLength > MAX_FILE_LENGTH) {
            validFileName = validFileName.substring(0, MAX_FILE_LENGTH - 1);
        }
        // Replace illegal characters with a '-'
        validFileName = validFileName.replaceAll("[:*?\"<>]", "-");
        return validFileName;
    }

    public UUID getNewUUID() {
        secRand.nextBytes(secRandBuf16);
        secRandBuf16[6] &= 0x0f;
        secRandBuf16[6] |= 0x40; /* version 4 */
        secRandBuf16[8] &= 0x3f;
        secRandBuf16[8] |= 0x80; /* IETF variant */
        secRandBuf16[10] |= 0x80; /* multicast bit */

        long mostSig = 0;

        for (int i = 0; i < 8; i++) {
            mostSig = (mostSig << 8) | (secRandBuf16[i] & 0xff);
        }

        long leastSig = 0;

        for (int i = 8; i < 16; i++) {
            leastSig = (leastSig << 8) | (secRandBuf16[i] & 0xff);
        }

        return new UUID(mostSig, leastSig);
    }

}