ch.cyberduck.core.local.Local.java Source code

Java tutorial

Introduction

Here is the source code for ch.cyberduck.core.local.Local.java

Source

package ch.cyberduck.core.local;

/*
 * Copyright (c) 2012 David Kocher. All rights reserved.
 * http://cyberduck.ch/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Bug fixes, suggestions and comments should be sent to:
 * dkocher@cyberduck.ch
 */

import ch.cyberduck.core.AbstractPath;
import ch.cyberduck.core.AttributedList;
import ch.cyberduck.core.Attributes;
import ch.cyberduck.core.PathFilter;
import ch.cyberduck.core.PathReference;
import ch.cyberduck.core.Permission;
import ch.cyberduck.core.Preferences;
import ch.cyberduck.core.io.RepeatableFileInputStream;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

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.util.Comparator;

import com.ibm.icu.text.Normalizer;

/**
 * @version $Id: Local.java 10851 2013-04-15 09:21:33Z dkocher $
 */
public abstract class Local extends AbstractPath {
    private static final Logger log = Logger.getLogger(Local.class);

    /**
     * Absolute path in local file system
     */
    private String path;

    /**
     * @param parent Parent directory
     * @param name   Filename
     */
    public Local(final Local parent, final String name) {
        this(parent.getAbsolute(), name);
    }

    /**
     * @param parent Parent directory
     * @param name   Filename
     */
    public Local(final String parent, final String name) {
        this.setPath(parent, name);
    }

    /**
     * @param path Absolute path
     */
    public Local(final String path) {
        this.setPath(path);
    }

    /**
     * @param path File reference
     */
    public Local(final File path) {
        try {
            this.setPath(path.getCanonicalPath());
        } catch (IOException e) {
            log.error(String.format("Error getting canonical path:%s", e.getMessage()));
            this.setPath(path.getAbsolutePath());
        }
    }

    @Override
    public Attributes attributes() {
        return new LocalAttributes(this.getAbsolute());
    }

    @Override
    public char getPathDelimiter() {
        return '/';
    }

    /**
     * Creates a new file and sets its resource fork to feature a custom progress icon
     */
    @Override
    public boolean touch() {
        try {
            final File file = new File(path);
            if (!file.getParentFile().mkdirs()) {
                log.debug(String.format("Create directory %s failed", path));
            }
            if (!file.createNewFile()) {
                log.warn(String.format("Create file %s failed", path));
                return false;
            }
            return true;
        } catch (IOException e) {
            log.error(String.format("Error creating new file %s", e.getMessage()));
            return false;
        }
    }

    @Override
    public void symlink(String target) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void mkdir() {
        if (!new File(path).mkdirs()) {
            log.debug(String.format("Create directory %s failed", path));
        }
    }

    /**
     * Delete the file
     */
    @Override
    public void delete() {
        if (!new File(path).delete()) {
            log.warn(String.format("Delete %s failed", path));
        }
    }

    /**
     * Delete file
     *
     * @param deferred On application quit
     */
    public void delete(boolean deferred) {
        if (deferred) {
            new File(path).deleteOnExit();
        } else {
            this.delete();
        }
    }

    /**
     * Move file to trash.
     */
    public void trash() {
        this.delete();
    }

    @Override
    public AttributedList<Local> list() {
        final AttributedList<Local> children = new AttributedList<Local>();
        final File[] files = new File(path).listFiles();
        if (null == files) {
            log.error(String.format("Error listing children at %s", path));
            return children;
        }
        for (File file : files) {
            children.add(LocalFactory.createLocal(file));
        }
        return children;
    }

    @Override
    public AttributedList<Local> children() {
        return this.children(null);
    }

    @Override
    public AttributedList<Local> children(final PathFilter<? extends AbstractPath> filter) {
        return this.children(null, filter);
    }

    @Override
    public AttributedList<Local> children(final Comparator<? extends AbstractPath> comparator,
            final PathFilter<? extends AbstractPath> filter) {
        return this.list().filter(comparator, filter);
    }

    @Override
    public String getAbsolute() {
        return new File(path).getAbsolutePath();
    }

    /**
     * @return A shortened path representation.
     */
    public String getAbbreviatedPath() {
        return this.getAbsolute();
    }

    @Override
    public AbstractPath getSymlinkTarget() {
        try {
            return LocalFactory.createLocal(this, new File(path).getCanonicalPath());
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return null;
    }

    /**
     * @return The last path component.
     */
    @Override
    public String getName() {
        return new File(path).getName();
    }

    public Local getVolume() {
        return LocalFactory.createLocal(new File(String.valueOf(this.getPathDelimiter())));
    }

    @Override
    public AbstractPath getParent() {
        return LocalFactory.createLocal(new File(path).getParentFile());
    }

    @Override
    public PathReference getReference() {
        return new PathReference<Local>() {
            @Override
            public Local unique() {
                return Local.this;
            }
        };
    }

    /**
     * @return True if the path exists on the file system.
     */
    @Override
    public boolean exists() {
        return new File(path).exists();
    }

    @Override
    protected void setPath(final String name) {
        String normalized = name;
        if (Preferences.instance().getBoolean("local.normalize.unicode")) {
            if (!Normalizer.isNormalized(normalized, Normalizer.NFC, Normalizer.UNICODE_3_2)) {
                // Canonical decomposition followed by canonical composition (default)
                normalized = Normalizer.normalize(name, Normalizer.NFC, Normalizer.UNICODE_3_2);
                if (log.isDebugEnabled()) {
                    log.debug("Normalized local path '" + name + "' to '" + normalized + "'");
                }
            }
        }
        path = normalized;
    }

    @Override
    public void writeUnixPermission(final Permission permission) {
        //
    }

    @Override
    public void writeTimestamp(final long created, final long modified, final long accessed) {
        if (modified < 0) {
            return;
        }
        if (!new File(path).setLastModified(modified)) {
            log.error(String.format("Write modification date failed for %s", path));
        }
    }

    @Override
    public void rename(final AbstractPath renamed) {
        if (!new File(path).renameTo(new File(renamed.getAbsolute()))) {
            log.error(String.format("Rename failed for %s", renamed.getAbsolute()));
        }
    }

    public void copy(final Local copy) {
        if (copy.equals(this)) {
            log.warn(String.format("%s and %s are identical. Not copied.", this.getName(), copy.getName()));
        } else {
            FileInputStream in = null;
            FileOutputStream out = null;
            try {
                in = new FileInputStream(new File(path));
                out = new FileOutputStream(copy.getAbsolute());
                IOUtils.copy(in, out);
            } catch (IOException e) {
                log.error(e.getMessage());
            } finally {
                IOUtils.closeQuietly(in);
                IOUtils.closeQuietly(out);
            }
        }
    }

    @Override
    public int hashCode() {
        return this.getAbsolute().hashCode();
    }

    /**
     * Compares the two files using their path with a string comparision ignoring case.
     * Implementations should override this depending on the case sensitivity of the file system.
     */
    @Override
    public boolean equals(Object o) {
        if (null == o) {
            return false;
        }
        if (o instanceof Local) {
            Local other = (Local) o;
            return this.getAbsolute().equalsIgnoreCase(other.getAbsolute());
        }
        return false;
    }

    @Override
    public String toString() {
        return this.getAbsolute();
    }

    @Override
    public String toURL() {
        try {
            return new File(path).toURI().toURL().toString();
        } catch (MalformedURLException e) {
            log.error(e.getMessage());
            return null;
        }
    }

    public InputStream getInputStream() throws FileNotFoundException {
        return new RepeatableFileInputStream(new File(path));
    }

    public OutputStream getOutputStream(final boolean append) throws FileNotFoundException {
        return new FileOutputStream(new File(path), append);
    }
}