de.mprengemann.intellij.plugin.androidicons.images.RefactoringTask.java Source code

Java tutorial

Introduction

Here is the source code for de.mprengemann.intellij.plugin.androidicons.images.RefactoringTask.java

Source

/*
 * Copyright 2015 Marc Prengemann
 *
 * 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 de.mprengemann.intellij.plugin.androidicons.images;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.ui.UIUtil;
import de.mprengemann.intellij.plugin.androidicons.model.ImageInformation;
import de.mprengemann.intellij.plugin.androidicons.util.ExportNameUtils;
import de.mprengemann.intellij.plugin.androidicons.util.ImageUtils;
import de.mprengemann.intellij.plugin.androidicons.util.RunnableUtils;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class RefactoringTask extends Task.Backgroundable {

    private static final String TAG = RefactoringTask.class.getSimpleName();
    private static final Logger LOGGER = Logger.getInstance(TAG);
    private Project project;
    private List<ImageInformation> imageInformationList = new ArrayList<ImageInformation>();
    private int selection;
    private ProgressIndicator progressIndicator;

    public RefactoringTask(Project project) {
        super(project, "Importing Images...", true);
        this.project = project;
    }

    private void refactor() throws IOException, ProcessCanceledException {
        progressIndicator.checkCanceled();
        progressIndicator.setIndeterminate(false);
        for (int i = 0; i < imageInformationList.size(); i++) {
            ImageInformation information = imageInformationList.get(i);
            progressIndicator.setText2(information.getExportName());
            progressIndicator.checkCanceled();
            if (information.isVector()) {
                copyTempImage(information);
            } else {
                exportTempImage(information);
            }
            progressIndicator.setFraction((float) (i + 1) / (float) imageInformationList.size());
        }

        progressIndicator.setIndeterminate(true);
        progressIndicator.setText2("Finishing");
        UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
            public void run() {
                try {
                    move(project, imageInformationList);
                    LocalFileSystem.getInstance().refresh(true);
                } catch (IOException e) {
                    LOGGER.error(e);
                }
            }
        });
    }

    public void addImage(ImageInformation imageInformation) {
        if (imageInformation == null) {
            return;
        }
        imageInformationList.add(imageInformation);
    }

    protected void onPreExecute() {
    }

    @Override
    public void run(@NotNull final ProgressIndicator progressIndicator) {
        if (imageInformationList.isEmpty()) {
            return;
        }
        this.progressIndicator = progressIndicator;
        onPreExecute();
        ApplicationManager.getApplication().runReadAction(new Runnable() {
            @Override
            public void run() {
                try {
                    refactor();
                } catch (ProcessCanceledException e) {
                    FileUtils.deleteQuietly(ImageInformation.getTempDir());
                } catch (Exception e) {
                    LOGGER.error(e);
                }
            }
        });
    }

    protected void onPostExecute() {
    }

    private boolean checkFileExist(@Nullable PsiDirectory targetDirectory, int[] choice, PsiFile file, String name,
            String title) {
        if (targetDirectory == null) {
            return false;
        }
        final PsiFile existing = targetDirectory.findFile(name);
        if (existing == null || existing.equals(file)) {
            return false;
        }
        int selection;
        if (choice == null || choice[0] == -1) {
            final String message = String.format("File '%s' already exists in directory '%s'", name,
                    targetDirectory.getVirtualFile().getPath());
            String[] options = choice == null ? new String[] { "Overwrite", "Skip" }
                    : new String[] { "Overwrite", "Skip", "Overwrite for all", "Skip for all" };
            selection = Messages.showDialog(message, title, options, 0, Messages.getQuestionIcon());
            if (selection == 2 || selection == 3) {
                this.selection = selection;
            }
        } else {
            selection = choice[0];
        }

        if (choice != null && selection > 1) {
            choice[0] = selection % 2;
            selection = choice[0];
        }

        if (selection == 0 && file != existing) {
            existing.delete();
        } else {
            return true;
        }

        return false;
    }

    private void copy(Project project, String description, List<File> sources, List<File> targets)
            throws IOException {
        final PsiManager instance = PsiManager.getInstance(project);
        final List<PsiFile> files = new ArrayList<PsiFile>();
        final List<PsiDirectory> dirs = new ArrayList<PsiDirectory>();
        final List<String> names = new ArrayList<String>();

        for (File source : sources) {
            LocalFileSystem.getInstance().findFileByIoFile(source);
            final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(source);
            if (vFile != null) {
                PsiFile item = instance.findFile(vFile);
                if (item != null) {
                    files.add(item);
                }
            }
        }

        for (File target : targets) {
            VirtualFile targetDir = LocalFileSystem.getInstance()
                    .refreshAndFindFileByIoFile(target.getParentFile());
            if (targetDir == null) {
                FileUtils.forceMkdir(target.getParentFile());
                targetDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(target.getParentFile());
            }
            if (targetDir != null) {
                final PsiDirectory dir = instance.findDirectory(targetDir);
                if (dir != null) {
                    dirs.add(dir);
                    names.add(target.getName());
                }
            }
        }

        if (files.size() == dirs.size() && !files.isEmpty()) {
            selection = -1;
            RunnableUtils.runWriteCommand(project, new Runnable() {
                @Override
                public void run() {
                    PsiFile file;
                    PsiDirectory dir;
                    String name;
                    for (int i = 0; i < files.size(); i++) {
                        file = files.get(i);
                        dir = dirs.get(i);
                        name = names.get(i);
                        if (checkFileExist(dir, new int[] { selection }, file, name, "Copy")) {
                            continue;
                        }
                        dir.copyFileFrom(name, file);
                    }
                }
            }, description);
            return;
        }

        throw new FileNotFoundException(sources.toString());
    }

    private void move(Project project, List<ImageInformation> scalingInformationList) throws IOException {
        List<File> tempFiles = new ArrayList<File>();
        List<File> targets = new ArrayList<File>();

        for (ImageInformation information : scalingInformationList) {
            tempFiles.add(information.getTempImage());
            targets.add(information.getTargetFile());
        }

        final String description = ExportNameUtils.getExportDescription(scalingInformationList);
        copy(project, description, tempFiles, targets);
        RunnableUtils.runWriteCommand(project, new Runnable() {
            @Override
            public void run() {
                FileUtils.deleteQuietly(ImageInformation.getTempDir());
                onPostExecute();
            }
        }, description);
    }

    private void exportTempImage(final ImageInformation information) {
        try {
            BufferedImage resizeImageJpg;
            if (information.isNinePatch()) {
                resizeImageJpg = ImageUtils.resizeNinePatchImage(information);
            } else {
                resizeImageJpg = ImageUtils.resizeNormalImage(information);
            }
            ImageUtils.saveImageTempFile(resizeImageJpg, information);
        } catch (Exception e) {
            LOGGER.error(e);
        }
    }

    private void copyTempImage(ImageInformation information) {
        try {
            File exportFile = information.getTempImage();
            if (exportFile != null) {
                if (!exportFile.getParentFile().exists()) {
                    FileUtils.forceMkdir(exportFile.getParentFile());
                }
                FileUtils.copyFile(information.getImageFile(), information.getTempImage());
            } else {
                throw new IOException("Couldn't find .idea path.");
            }
        } catch (Exception e) {
            LOGGER.error(e);
        }
    }
}