All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.asprise.ocr.sample.util.prefs.FileSystemPreferences Maven / Gradle / Ivy

Go to download

A Java OCR SDK Library API allows you to perform OCR and bar code recognition on images (JPEG, PNG, TIFF, PDF, etc.) and output as plain text, xml with full coordinate, searchable PDF or editable RTF.

There is a newer version: 15.3.0.3
Show newest version
/**********************************************************************************************
 *
 * Asprise OCR Java API
 * Copyright (C) 1998-2015. Asprise Inc. 
 *
 * This file is licensed under the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation.
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * You should have received a copy of the GNU Affero General Public License.  If not, please
 * visit .
 *
 **********************************************************************************************/
package com.asprise.ocr.sample.util.prefs;

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.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;
import java.util.prefs.InvalidPreferencesFormatException;
import java.util.prefs.Preferences;



class FileSystemPreferences extends AbstractPreferences {
    
    private static final int SYNC_INTERVAL = Math.max(1,
            Integer.parseInt(
                    AccessController.doPrivileged(
                            new sun.security.action.GetPropertyAction(
                                    "java.util.prefs.syncInterval", "30"))));

    

    private static Logger _logger;
    private static Logger getLogger() {
        if(_logger == null) {
            _logger = Logger.getLogger("asprise.FileSystemPreferences");
            _logger.setLevel(Level.SEVERE);
        }
        return _logger;
    }

    
    private static File systemRootDir;


    private static boolean isSystemRootWritable;

    
    private static File userRootDir;


    private static boolean isUserRootWritable;

    
    static Preferences userRoot = null;

    static synchronized Preferences getUserRoot() {
        if (userRoot == null) {
            setupUserRoot();
            userRoot = new FileSystemPreferences(true);
        }
        return userRoot;
    }

    private static void setupUserRoot() {
        AccessController.doPrivileged(new PrivilegedAction() {
            public Void run() {
                userRootDir =
                        new File(System.getProperty("java.util.prefs.userRoot",
                                System.getProperty("user.home")), ".java/.userPrefs");

                if (!userRootDir.exists()) {
                    if (userRootDir.mkdirs()) {
                        try {
                            chmod(userRootDir.getCanonicalPath(), USER_RWX);
                        } catch (IOException e) {
                            getLogger().warning("Could not change permissions" +
                                    " on userRoot directory. ");
                        }
                        getLogger().info("Created user preferences directory.");
                    }
                    else
                        getLogger().warning("Couldn't create user preferences" +
                                " directory. User preferences are unusable.");
                }
                isUserRootWritable = userRootDir.canWrite();
                String USER_NAME = System.getProperty("user.name");
                userLockFile = new File (userRootDir,".user.lock." + USER_NAME);
                userRootModFile = new File (userRootDir,
                        ".userRootModFile." + USER_NAME);
                if (!userRootModFile.exists())
                    try {

                        userRootModFile.createNewFile();

                        int result = chmod(userRootModFile.getCanonicalPath(),
                                USER_READ_WRITE);
                        if (result !=0)
                            getLogger().warning("Problem creating userRoot " +
                                    "mod file. Chmod failed on " +
                                    userRootModFile.getCanonicalPath() +
                                    " Unix error code " + result);
                    } catch (IOException e) {
                        getLogger().warning(e.toString());
                    }
                userRootModTime = userRootModFile.lastModified();
                return null;
            }
        });
    }


    
    static Preferences systemRoot;

    static synchronized Preferences getSystemRoot() {
        if (systemRoot == null) {
            setupSystemRoot();
            systemRoot = new FileSystemPreferences(false);
        }
        return systemRoot;
    }

    private static void setupSystemRoot() {
        AccessController.doPrivileged(new PrivilegedAction() {
            public Void run() {
                String systemPrefsDirName =
                        System.getProperty("java.util.prefs.systemRoot","/etc/.java");
                systemRootDir =
                        new File(systemPrefsDirName, ".systemPrefs");

                if (!systemRootDir.exists()) {

                    systemRootDir =
                            new File(System.getProperty("java.home"),
                                    ".systemPrefs");
                    if (!systemRootDir.exists()) {
                        if (systemRootDir.mkdirs()) {
                            getLogger().info(
                                    "Created system preferences directory "
                                            + "in java.home.");
                            try {
                                chmod(systemRootDir.getCanonicalPath(),
                                        USER_RWX_ALL_RX);
                            } catch (IOException e) {
                            }
                        } else {
                            getLogger().warning("Could not create "
                                    + "system preferences directory. System "
                                    + "preferences are unusable.");
                        }
                    }
                }
                isSystemRootWritable = systemRootDir.canWrite();
                systemLockFile = new File(systemRootDir, ".system.lock");
                systemRootModFile =
                        new File (systemRootDir,".systemRootModFile");
                if (!systemRootModFile.exists() && isSystemRootWritable)
                    try {

                        systemRootModFile.createNewFile();
                        int result = chmod(systemRootModFile.getCanonicalPath(),
                                USER_RW_ALL_READ);
                        if (result !=0)
                            getLogger().warning("Chmod failed on " +
                                    systemRootModFile.getCanonicalPath() +
                                    " Unix error code " + result);
                    } catch (IOException e) { getLogger().warning(e.toString());
                    }
                systemRootModTime = systemRootModFile.lastModified();
                return null;
            }
        });
    }


    
    private static final int USER_READ_WRITE = 0600;

    private static final int USER_RW_ALL_READ = 0644;


    private static final int USER_RWX_ALL_RX = 0755;

    private static final int USER_RWX = 0700;

    
    static File userLockFile;



    
    static File systemLockFile;

    

    private static int userRootLockHandle = 0;

    

    private static int systemRootLockHandle = 0;

    
    private final File dir;

    
    private final File prefsFile;

    
    private final File tmpFile;

    
    private static  File userRootModFile;

    
    private static boolean isUserRootModified = false;

    
    private static long userRootModTime;



    private static File systemRootModFile;

    private static boolean isSystemRootModified = false;

    
    private static long systemRootModTime;

    
    private Map prefsCache = null;

    
    private long lastSyncTime = 0;

    
    private static final int EAGAIN = 11;

    
    private static final int EACCES = 13;


    private static final int LOCK_HANDLE = 0;
    private static final int ERROR_CODE = 1;

    
    final List changeLog = new ArrayList();

    
    private abstract class Change {

        abstract void replay();
    };

    
    private class Put extends Change {
        String key, value;

        Put(String key, String value) {
            this.key = key;
            this.value = value;
        }

        void replay() {
            prefsCache.put(key, value);
        }
    }

    
    private class Remove extends Change {
        String key;

        Remove(String key) {
            this.key = key;
        }

        void replay() {
            prefsCache.remove(key);
        }
    }

    
    private class NodeCreate extends Change {

        void replay() {
        }
    }

    
    NodeCreate nodeCreate = null;

    
    private void replayChanges() {
        for (int i = 0, n = changeLog.size(); i() {
            public Void run() {
                Runtime.getRuntime().addShutdownHook(new Thread() {
                    public void run() {
                        syncTimer.cancel();
                        syncWorld();
                    }
                });
                return null;
            }
        });
    }

    private static void syncWorld() {

        Preferences userRt;
        Preferences systemRt;
        synchronized(FileSystemPreferences.class) {
            userRt   = userRoot;
            systemRt = systemRoot;
        }

        try {
            if (userRt != null)
                userRt.flush();
        } catch(BackingStoreException e) {
            getLogger().warning("Couldn't flush user prefs: " + e);
        }

        try {
            if (systemRt != null)
                systemRt.flush();
        } catch(BackingStoreException e) {
            getLogger().warning("Couldn't flush system prefs: " + e);
        }
    }

    private final boolean isUserNode;

    
    private FileSystemPreferences(boolean user) {
        super(null, "");
        isUserNode = user;
        dir = (user ? userRootDir: systemRootDir);
        prefsFile = new File(dir, "prefs.xml");
        tmpFile   = new File(dir, "prefs.tmp");
    }

    
    private FileSystemPreferences(FileSystemPreferences parent, String name) {
        super(parent, name);
        isUserNode = parent.isUserNode;
        dir  = new File(parent.dir, dirName(name));
        prefsFile = new File(dir, "prefs.xml");
        tmpFile  = new File(dir, "prefs.tmp");
        AccessController.doPrivileged(new PrivilegedAction() {
            public Void run() {
                newNode = !dir.exists();
                return null;
            }
        });
        if (newNode) {

            prefsCache = new TreeMap();
            nodeCreate = new NodeCreate();
            changeLog.add(nodeCreate);
        }
    }

    public boolean isUserNode() {
        return isUserNode;
    }

    protected void putSpi(String key, String value) {
        initCacheIfNecessary();
        changeLog.add(new Put(key, value));
        prefsCache.put(key, value);
    }

    protected String getSpi(String key) {
        initCacheIfNecessary();
        return prefsCache.get(key);
    }

    protected void removeSpi(String key) {
        initCacheIfNecessary();
        changeLog.add(new Remove(key));
        prefsCache.remove(key);
    }

    
    private void initCacheIfNecessary() {
        if (prefsCache != null)
            return;

        try {
            loadCache();
        } catch(Exception e) {

            prefsCache = new TreeMap();
        }
    }

    
    private void loadCache() throws BackingStoreException {
        try {
            AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Void run() throws BackingStoreException {
                            Map m = new TreeMap();
                            long newLastSyncTime = 0;
                            try {
                                newLastSyncTime = prefsFile.lastModified();

                                    FileInputStream fis = new FileInputStream(prefsFile);
                                    XmlSupport.importMap(fis, m);

                            } catch(Exception e) {
                                if (e instanceof InvalidPreferencesFormatException) {
                                    getLogger().warning("Invalid preferences format in "
                                            +  prefsFile.getPath());

                                   renameFile(prefsFile, new File(prefsFile.getParentFile(), "IncorrectFormatPrefs.xml"));
                                    m = new TreeMap();
                                } else if (e instanceof FileNotFoundException) {

                                } else {
                                    throw new BackingStoreException(e);
                                }
                            }

                            prefsCache = m;
                            lastSyncTime = newLastSyncTime;
                            return null;
                        }
                    });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }

    
    private void writeBackCache() throws BackingStoreException {
        try {
            AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Void run() throws BackingStoreException {
                            try {
                                if (!dir.exists() && !dir.mkdirs())
                                    throw new BackingStoreException(dir +
                                            " create failed.");

                                    FileOutputStream fos = new FileOutputStream(tmpFile);
                                    XmlSupport.exportMap(fos, prefsCache);

                                if (!renameFile(tmpFile, prefsFile))
                                    throw new BackingStoreException("Can't rename " +
                                            tmpFile + " to " + prefsFile);
                            } catch(Exception e) {
                                if (e instanceof BackingStoreException)
                                    throw (BackingStoreException)e;
                                throw new BackingStoreException(e);
                            }
                            return null;
                        }
                    });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }

    protected String[] keysSpi() {
        initCacheIfNecessary();
        return prefsCache.keySet().toArray(new String[prefsCache.size()]);
    }

    protected String[] childrenNamesSpi() {
        return AccessController.doPrivileged(
                new PrivilegedAction() {
                    public String[] run() {
                        List result = new ArrayList();
                        File[] dirContents = dir.listFiles();
                        if (dirContents != null) {
                            for (int i = 0; i < dirContents.length; i++)
                                if (dirContents[i].isDirectory())
                                    result.add(nodeName(dirContents[i].getName()));
                        }
                        return result.toArray(EMPTY_STRING_ARRAY);
                    }
                });
    }

    private static final String[] EMPTY_STRING_ARRAY = new String[0];

    protected AbstractPreferences childSpi(String name) {
        return new FileSystemPreferences(this, name);
    }

    public void removeNode() throws BackingStoreException {
        synchronized (isUserNode()? userLockFile: systemLockFile) {

            if (!lockFile(false))
                throw(new BackingStoreException("Couldn't get file lock."));
            try {
                super.removeNode();
            } finally {
                unlockFile();
            }
        }
    }

    
    protected void removeNodeSpi() throws BackingStoreException {
        try {
            AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Void run() throws BackingStoreException {
                            if (changeLog.contains(nodeCreate)) {
                                changeLog.remove(nodeCreate);
                                nodeCreate = null;
                                return null;
                            }
                            if (!dir.exists())
                                return null;
                            prefsFile.delete();
                            tmpFile.delete();

                            File[] junk = dir.listFiles();
                            if (junk.length != 0) {
                                getLogger().warning(
                                        "Found extraneous files when removing node: "
                                                + Arrays.asList(junk));
                                for (int i=0; i() {
                                public Long run() {
                                    long nmt;
                                    if (isUserNode()) {
                                        nmt = userRootModFile.lastModified();
                                        isUserRootModified = userRootModTime == nmt;
                                    } else {
                                        nmt = systemRootModFile.lastModified();
                                        isSystemRootModified = systemRootModTime == nmt;
                                    }
                                    return new Long(nmt);
                                }
                            });
            try {
                super.sync();
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Void run() {
                        if (isUserNode()) {
                            userRootModTime = newModTime.longValue() + 1000;
                            userRootModFile.setLastModified(userRootModTime);
                        } else {
                            systemRootModTime = newModTime.longValue() + 1000;
                            systemRootModFile.setLastModified(systemRootModTime);
                        }
                        return null;
                    }
                });
            } finally {
                unlockFile();
            }
        }
    }

    protected void syncSpi() throws BackingStoreException {
        try {
            AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Void run() throws BackingStoreException {
                            syncSpiPrivileged();
                            return null;
                        }
                    });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }
    private void syncSpiPrivileged() throws BackingStoreException {
        if (isRemoved())
            throw new IllegalStateException("Node has been removed");
        if (prefsCache == null)
            return;  
        long lastModifiedTime;
        if ((isUserNode() ? isUserRootModified : isSystemRootModified)) {
            lastModifiedTime = prefsFile.lastModified();
            if (lastModifiedTime  != lastSyncTime) {

                loadCache();
                replayChanges();
                lastSyncTime = lastModifiedTime;
            }
        } else if (lastSyncTime != 0 && !dir.exists()) {

            prefsCache = new TreeMap();
            replayChanges();
        }
        if (!changeLog.isEmpty()) {
            writeBackCache();  
            lastModifiedTime = prefsFile.lastModified();

            if (lastSyncTime <= lastModifiedTime) {
                lastSyncTime = lastModifiedTime + 1000;
                prefsFile.setLastModified(lastSyncTime);
            }
            changeLog.clear();
        }
    }

    public void flush() throws BackingStoreException {
        if (isRemoved())
            return;
        sync();
    }

    protected void flushSpi() throws BackingStoreException {

    }

    
    private static boolean isDirChar(char ch) {
        return ch > 0x1f && ch < 0x7f && ch != '/' && ch != '.' && ch != '_';
    }

    
    private static String dirName(String nodeName) {

        StringBuilder sb = new StringBuilder(nodeName);
        for(int i = 0; i < sb.length(); i++) {
            char c = sb.charAt(i);
            if( (c >= 0 && c <= 9)
                    || (c >= 'a' && c <= 'z')
                    || (c >= 'A' && c <= 'Z')
                || (c == '-' || c == '_' )
                    ) {

            } else {
                sb.setCharAt(i, '_');
            }
        }
        return sb.toString(); 
    }

    
    private static byte[] byteArray(String s) {
        int len = s.length();
        byte[] result = new byte[2*len];
        for (int i=0, j=0; i>8);
            result[j++] = (byte) c;
        }
        return result;
    }

    
    private static String nodeName(String dirName) {
        if (dirName.charAt(0) != '_')
            return dirName;
        byte a[] = Base64.altBase64ToByteArray(dirName.substring(1));
        StringBuffer result = new StringBuffer(a.length/2);
        for (int i = 0; i < a.length; ) {
            int highByte = a[i++] & 0xff;
            int lowByte =  a[i++] & 0xff;
            result.append((char) ((highByte << 8) | lowByte));
        }
        return result.toString();
    }

    
    private boolean lockFile(boolean shared) throws SecurityException{
        boolean usernode = isUserNode();
        int[] result;
        int errorCode = 0;
        File lockFile = (usernode ? userLockFile : systemLockFile);
        long sleepTime = INIT_SLEEP_TIME;
        for (int i = 0; i < MAX_ATTEMPTS; i++) {
            try {
                int perm = (usernode? USER_READ_WRITE: USER_RW_ALL_READ);
                result = lockFile0(lockFile.getCanonicalPath(), perm, shared);

                errorCode = result[ERROR_CODE];
                if (result[LOCK_HANDLE] != 0) {
                    if (usernode) {
                        userRootLockHandle = result[LOCK_HANDLE];
                    } else {
                        systemRootLockHandle = result[LOCK_HANDLE];
                    }
                    return true;
                }
            } catch(IOException e) {

            }

            try {
                Thread.sleep(sleepTime);
            } catch(InterruptedException e) {
                checkLockFile0ErrorCode(errorCode);
                return false;
            }
            sleepTime *= 2;
        }
        checkLockFile0ErrorCode(errorCode);
        return false;
    }

    
    private void checkLockFile0ErrorCode (int errorCode)
            throws SecurityException {
        if (errorCode == EACCES)
            throw new SecurityException("Could not lock " +
                    (isUserNode()? "User prefs." : "System prefs.") +
                    " Lock file access denied.");
        if (errorCode != EAGAIN)
            getLogger().warning("Could not lock " +
                    (isUserNode()? "User prefs. " : "System prefs.") +
                    " Unix error code " + errorCode + ".");
    }

    
    private static int[] lockFile0(String fileName, int permission, boolean shared) {
        return new int[] {1, 0};
    }

    
    private  static int unlockFile0(int lockHandle) {
        return 0;
    }

    

    private static int chmod(String fileName, int permission) {
        return 0;
    }

    
    private static int INIT_SLEEP_TIME = 50;

    
    private static int MAX_ATTEMPTS = 5;

    
    private void unlockFile() {
        int result;
        boolean usernode = isUserNode();
        File lockFile = (usernode ? userLockFile : systemLockFile);
        int lockHandle = ( usernode ? userRootLockHandle:systemRootLockHandle);
        if (lockHandle == 0) {
            getLogger().warning("Unlock: zero lockHandle for " +
                    (usernode ? "user":"system") + " preferences.)");
            return;
        }
        result = unlockFile0(lockHandle);
        if (result != 0) {
            getLogger().warning("Could not drop file-lock on " +
                    (isUserNode() ? "user" : "system") + " preferences." +
                    " Unix error code " + result + ".");
            if (result == EACCES)
                throw new SecurityException("Could not unlock" +
                        (isUserNode()? "User prefs." : "System prefs.") +
                        " Lock file access denied.");
        }
        if (isUserNode()) {
            userRootLockHandle = 0;
        } else {
            systemRootLockHandle = 0;
        }
    }

    @Override
    public boolean isRemoved() {
        return super.isRemoved();
    }

    public Object getLock() {
        return lock;
    }

    static boolean renameFile(File source, File target) {
        if(System.getProperty("os.name").toLowerCase().contains("windows")) {
            if(copyFile(source, target)) {
                source.delete();
                return true;
            } else {
                return false;
            }
        } else {
            return source.renameTo(target); 
        }
    }

    static boolean copyFile(File source, File target) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = new FileInputStream(source);
            if(inputStream == null) {
                return false;
            }
            outputStream = new FileOutputStream(target);
            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            while (len != -1) {
                outputStream.write(buffer, 0, len);
                len = inputStream.read(buffer);
            }
            return true;
        } catch (Throwable t) {
            return false;
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {

                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {

                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy