net.andydvorak.intellij.lessc.fs.VirtualFileLocationChange.java Source code

Java tutorial

Introduction

Here is the source code for net.andydvorak.intellij.lessc.fs.VirtualFileLocationChange.java

Source

/*
 * Copyright 2012 Andrew C. Dvorak.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

package net.andydvorak.intellij.lessc.fs;

import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.*;
import net.andydvorak.intellij.lessc.state.CssDirectory;
import net.andydvorak.intellij.lessc.state.LessProfile;
import net.andydvorak.intellij.lessc.ui.configurable.VfsLocationChangeDialog;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Andrew C. Dvorak
 * @since 11/1/12
 */
public class VirtualFileLocationChange {
    @NotNull
    private final CssDirectory cssRootDir;
    @NotNull
    private final VirtualFile oldFile;
    @NotNull
    private final VirtualFile newParent;

    public VirtualFileLocationChange(@NotNull final CssDirectory cssRootDir, @NotNull final VirtualFile oldFile,
            @NotNull final VirtualFile newParent) {
        this.cssRootDir = cssRootDir;
        this.oldFile = oldFile;
        this.newParent = newParent;
    }

    public void copy() throws IOException {
        deleteExisting();
        final String name = oldFile.getName();
        oldFile.copy(this, newParent, name);
        refresh();
    }

    public void move() throws IOException {
        deleteExisting();
        oldFile.move(this, newParent);
        refresh();
    }

    public void delete() throws IOException {
        oldFile.delete(this);
        refresh();
    }

    private void deleteExisting() throws IOException {
        final File newFile = new File(newParent.getPath() + File.separator + oldFile.getName());
        if (newFile.exists()) {
            final VirtualFile newVirtualFile = getVirtualFile(newFile);
            if (newVirtualFile != null) {
                newVirtualFile.delete(this);
                refresh();
            }
        }
    }

    public void refresh() {
        refresh(cssRootDir);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        VirtualFileLocationChange that = (VirtualFileLocationChange) o;

        if (!ObjectUtils.equals(cssRootDir.getPath(), that.cssRootDir.getPath()))
            return false;
        if (!ObjectUtils.equals(newParent.getPath(), that.newParent.getPath()))
            return false;
        if (!ObjectUtils.equals(oldFile.getPath(), that.oldFile.getPath()))
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = StringUtils.defaultString(cssRootDir.getPath()).hashCode();
        result = 31 * result + StringUtils.defaultString(oldFile.getPath()).hashCode();
        result = 31 * result + StringUtils.defaultString(newParent.getPath()).hashCode();
        return result;
    }

    public static void refresh(@NotNull final Collection<CssDirectory> cssRootDirs) {
        for (CssDirectory cssRootDir : cssRootDirs)
            refresh(cssRootDir);
    }

    public static void refresh(@Nullable final CssDirectory cssRootDir) {
        if (cssRootDir == null)
            return;

        final VirtualFile virtualCssRootDir = getVirtualFile(cssRootDir, "");

        if (virtualCssRootDir != null) {
            virtualCssRootDir.refresh(true, true);
            VirtualFileManager.getInstance().refresh(true);
        }
    }

    public static int copyCssFiles(@NotNull final VirtualFileCopyEvent virtualFileCopyEvent,
            @Nullable final LessProfile lessProfile, @NotNull final VfsLocationChangeDialog vfsLocationChangeDialog)
            throws IOException {
        final Set<VirtualFileLocationChange> changes = getChanges(lessProfile, virtualFileCopyEvent);

        if (changes.isEmpty() || !vfsLocationChangeDialog.shouldCopyCssFile(virtualFileCopyEvent))
            return 0;

        for (VirtualFileLocationChange locationChange : changes) {
            locationChange.copy();
        }

        return changes.size();
    }

    public static int moveCssFiles(@NotNull final VirtualFileMoveEvent virtualFileMoveEvent,
            @Nullable final LessProfile lessProfile, @NotNull final VfsLocationChangeDialog vfsLocationChangeDialog)
            throws IOException {
        final Set<VirtualFileLocationChange> changes = getChanges(lessProfile, virtualFileMoveEvent);

        if (changes.isEmpty() || !vfsLocationChangeDialog.shouldMoveCssFile(virtualFileMoveEvent))
            return 0;

        for (VirtualFileLocationChange locationChange : changes) {
            locationChange.move();
        }

        return changes.size();
    }

    public static int deleteCssFiles(@NotNull final VirtualFileEvent virtualFileEvent,
            @Nullable final LessProfile lessProfile, @NotNull final VfsLocationChangeDialog vfsLocationChangeDialog)
            throws IOException {
        final Set<VirtualFileLocationChange> changes = getChanges(lessProfile, virtualFileEvent.getFile(),
                virtualFileEvent.getFile().getParent());

        if (changes.isEmpty() || !vfsLocationChangeDialog.shouldDeleteCssFile(virtualFileEvent))
            return 0;

        for (VirtualFileLocationChange locationChange : changes) {
            locationChange.delete();
        }

        return changes.size();
    }

    @NotNull
    public static Set<VirtualFileLocationChange> getChanges(@Nullable final LessProfile lessProfile,
            @NotNull final VirtualFileMoveEvent moveEvent) throws IOException {
        return getChanges(lessProfile, moveEvent.getFile(), moveEvent.getOldParent());
    }

    @NotNull
    public static Set<VirtualFileLocationChange> getChanges(@Nullable final LessProfile lessProfile,
            @NotNull final VirtualFileCopyEvent copyEvent) throws IOException {
        return getChanges(lessProfile, copyEvent.getFile(), copyEvent.getOriginalFile().getParent());
    }

    /**
     * NOTE: This method will create the parent directories for new CSS files if they don't already exist.
     * @param lessProfile
     * @param newVirtualLessFile
     * @param oldVirtualLessParent
     * @return
     * @throws IOException
     */
    @NotNull
    public static Set<VirtualFileLocationChange> getChanges(@Nullable final LessProfile lessProfile,
            @NotNull final VirtualFile newVirtualLessFile, @NotNull final VirtualFile oldVirtualLessParent)
            throws IOException {
        final Set<VirtualFileLocationChange> changes = new HashSet<VirtualFileLocationChange>();

        if (lessProfile == null)
            return changes;

        // TODO: Make sure new (and old?) directories are in the LESS profile dir
        final File lessRootDir = lessProfile.getLessDir();

        final File newLessFile = new File(newVirtualLessFile.getPath());
        final String newRelativeCssPath = toCssPath(FileUtil.getRelativePath(lessRootDir, newLessFile));

        if (newRelativeCssPath == null)
            return changes;

        final File oldLessFile = new File(oldVirtualLessParent.getPath() + File.separator + newLessFile.getName());
        final String oldRelativeCssPath = toCssPath(FileUtil.getRelativePath(lessRootDir, oldLessFile));

        if (oldRelativeCssPath == null)
            return changes;

        for (CssDirectory cssRootDir : lessProfile.getCssDirectories()) {
            final VirtualFile oldVirtualCssFile = getVirtualFile(cssRootDir, oldRelativeCssPath);

            if (oldVirtualCssFile == null)
                continue;

            final File newCssFile = getCssFile(cssRootDir, newRelativeCssPath);

            FileUtil.createParentDirs(newCssFile);

            final VirtualFile newVirtualCssFileParent = getVirtualFile(newCssFile.getParentFile());

            if (newVirtualCssFileParent == null)
                continue;

            changes.add(new VirtualFileLocationChange(cssRootDir, oldVirtualCssFile, newVirtualCssFileParent));
        }

        return changes;
    }

    @Nullable
    private static String toCssPath(final String lessPath) {
        return lessPath == null ? null : lessPath.replaceFirst("\\.less$", ".css");
    }

    @NotNull
    private static String getAbsolutePath(@NotNull final CssDirectory cssRootDir,
            @NotNull final String relativeCssPath) {
        return cssRootDir.getPath() + File.separator + relativeCssPath;
    }

    @NotNull
    private static File getCssFile(@NotNull final CssDirectory cssRootDir, @NotNull final String relativeCssPath) {
        return new File(getAbsolutePath(cssRootDir, relativeCssPath));
    }

    @Nullable
    private static VirtualFile getVirtualFile(@NotNull final CssDirectory cssRootDir,
            @NotNull final String relativeCssPath) {
        return getVirtualFile(getCssFile(cssRootDir, relativeCssPath));
    }

    @Nullable
    private static VirtualFile getVirtualFile(@NotNull final File file) {
        return LocalFileSystem.getInstance().findFileByIoFile(file);
    }
}