Package org.intellij.grammar.actions

Source Code of org.intellij.grammar.actions.FileGeneratorUtil

/*
* Copyright 2011-2014 Gregory Shrago
*
* 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 org.intellij.grammar.actions;

import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.ProjectScope;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.grammar.generator.BnfConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;

import static com.intellij.util.ArrayUtil.getFirstElement;

/**
* @author gregsh
*/
public class FileGeneratorUtil {
  @NotNull
  public static VirtualFile getTargetDirectoryFor(@NotNull Project project,
                                                  @NotNull VirtualFile sourceFile,
                                                  @Nullable String targetFile,
                                                  @Nullable String targetPackage,
                                                  boolean returnRoot) {
    boolean hasPackage = StringUtil.isNotEmpty(targetPackage);
    ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
    ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(project);
    Collection<VirtualFile> files = targetFile == null ? Collections.<VirtualFile>emptyList() :
                                    FilenameIndex.getVirtualFilesByName(project, targetFile,
                                                                        ProjectScope.getAllScope(project));

    VirtualFile existingFile = null;
    for (VirtualFile file : files) {
      String existingFilePackage = fileIndex.getPackageNameByDirectory(file.getParent());
      if (!hasPackage || existingFilePackage == null || targetPackage.equals(existingFilePackage)) {
        existingFile = file;
        break;
      }
    }

    VirtualFile existingFileRoot =
      existingFile == null ? null :
      fileIndex.isInSourceContent(existingFile) ? fileIndex.getSourceRootForFile(existingFile) :
      fileIndex.isInContent(existingFile) ? fileIndex.getContentRootForFile(existingFile) : null;

    VirtualFile[] sourceRoots = rootManager.getContentSourceRoots();
    VirtualFile[] contentRoots = rootManager.getContentRoots();
    final VirtualFile virtualRoot = existingFileRoot != null ? existingFileRoot :
                                    hasPackage && fileIndex.isInSource(sourceFile) ? fileIndex.getSourceRootForFile(sourceFile) :
                                    fileIndex.isInContent(sourceFile) ? fileIndex.getContentRootForFile(sourceFile) :
                                    getFirstElement(hasPackage && sourceRoots.length > 0? sourceRoots : contentRoots);
    if (virtualRoot == null) {
      fail(project, sourceFile, "Unable to guess target source root");
      throw new ProcessCanceledException();
    }
    try {
      boolean newGenRoot = !fileIndex.isInSourceContent(virtualRoot);
      final String relativePath = (hasPackage && newGenRoot? "gen." + targetPackage :
                                  hasPackage ? targetPackage :
                                  newGenRoot ? "gen" : "").replace('.', '/');
      if (relativePath.isEmpty()) {
        return virtualRoot;
      }
      else {
        VirtualFile result = new WriteAction<VirtualFile>() {
          @Override
          protected void run(@NotNull Result<VirtualFile> result) throws Throwable {
            result.setResult(VfsUtil.createDirectoryIfMissing(virtualRoot, relativePath));
          }
        }.execute().throwException().getResultObject();
        LocalFileSystem.getInstance().refreshFiles(Collections.singleton(result));
        return returnRoot && newGenRoot? ObjectUtils.assertNotNull(virtualRoot.findChild("gen")) :
               returnRoot ? virtualRoot : result;
      }
    }
    catch (Exception ex) {
      fail(project, sourceFile, ex.getMessage());
      throw new ProcessCanceledException();
    }
  }

  static void fail(@NotNull Project project, @NotNull VirtualFile sourceFile, @NotNull String message) {
    Notifications.Bus.notify(new Notification(
      BnfConstants.GENERATION_GROUP,
      sourceFile.getName(), message,
      NotificationType.ERROR), project);
    throw new ProcessCanceledException();
  }
}
TOP

Related Classes of org.intellij.grammar.actions.FileGeneratorUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.