Пример #1
0
  /**
   * Returns the {@link ResourceFile} matching the given name, {@link ResourceType} and
   * configuration.
   *
   * <p>This only works with files generating one resource named after the file (for instance,
   * layouts, bitmap based drawable, xml, anims).
   *
   * @param name the resource name or file name
   * @param type the folder type search for
   * @param config the folder configuration to match for
   * @return the matching file or <code>null</code> if no match was found.
   */
  @Nullable
  public ResourceFile getMatchingFile(
      @NonNull String name, @NonNull ResourceType type, @NonNull FolderConfiguration config) {
    ensureInitialized();

    String resourceName = name;
    int dot = resourceName.indexOf('.');
    if (dot != -1) {
      resourceName = resourceName.substring(0, dot);
    }

    Map<String, ResourceItem> items = mResourceMap.get(type);
    if (items != null) {
      ResourceItem item = items.get(resourceName);
      if (item != null) {
        List<ResourceFile> files = item.getSourceFileList();
        if (files != null) {
          if (files.size() > 1) {
            ResourceValue value = item.getResourceValue(type, config, isFrameworkRepository());
            if (value != null) {
              String v = value.getValue();
              if (v != null) {
                ResourceUrl url = ResourceUrl.parse(v);
                if (url != null) {
                  return getMatchingFile(url.name, url.type, config);
                } else {
                  // Looks like the resource value is pointing to a file
                  // It's most likely one of the source files for this
                  // resource item, so check those first
                  for (ResourceFile f : files) {
                    if (v.equals(f.getFile().getOsLocation())) {
                      // Found the file
                      return f;
                    }
                  }

                  // No; look up the resource file from the full path
                  File file = new File(v);
                  if (file.exists()) {
                    ResourceFile f = findResourceFile(file);
                    if (f != null) {
                      return f;
                    }
                  }
                }
              }
            }
          } else if (files.size() == 1) {
            // Single file: see if it matches
            ResourceFile matchingFile = files.get(0);
            if (matchingFile.getFolder().getConfiguration().isMatchFor(config)) {
              return matchingFile;
            }
          }
        }
      }
    }

    return null;
  }
  /**
   * Removes a file that already exists in the out res folder. This has to be a non value file.
   *
   * @param resourceFile the source file that created the file to remove.
   * @return true if success.
   */
  private boolean removeOutFile(ResourceFile resourceFile) {
    if (resourceFile.getType() == ResourceFile.FileType.MULTI) {
      throw new IllegalArgumentException("SourceFile cannot be a FileType.MULTI");
    }

    File file = resourceFile.getFile();
    String fileName = file.getName();
    String folderName = file.getParentFile().getName();

    return removeOutFile(folderName, fileName);
  }
  @Override
  protected void postWriteAction() throws ConsumerException {

    // now write the values files.
    for (String key : mValuesResMap.keySet()) {
      // the key is the qualifier.

      // check if we have to write the file due to deleted values.
      // also remove it from that list anyway (to detect empty qualifiers later).
      boolean mustWriteFile = mQualifierWithDeletedValues.remove(key);

      // get the list of items to write
      List<ResourceItem> items = mValuesResMap.get(key);

      // now check if we really have to write it
      if (!mustWriteFile) {
        for (ResourceItem item : items) {
          if (item.isTouched()) {
            mustWriteFile = true;
            break;
          }
        }
      }

      if (mustWriteFile) {
        String folderName =
            key.isEmpty()
                ? ResourceFolderType.VALUES.getName()
                : ResourceFolderType.VALUES.getName() + RES_QUALIFIER_SEP + key;

        try {
          File valuesFolder = new File(getRootFolder(), folderName);
          createDir(valuesFolder);
          File outFile = new File(valuesFolder, FN_VALUES_XML);

          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          factory.setNamespaceAware(true);
          factory.setValidating(false);
          factory.setIgnoringComments(true);
          DocumentBuilder builder;

          builder = factory.newDocumentBuilder();
          Document document = builder.newDocument();

          Node rootNode = document.createElement(TAG_RESOURCES);
          document.appendChild(rootNode);

          Collections.sort(items);

          ResourceFile currentFile = null;
          for (ResourceItem item : items) {
            ResourceFile source = item.getSource();
            if (source != currentFile) {
              currentFile = source;
              rootNode.appendChild(document.createTextNode("\n"));
              File file = source.getFile();
              rootNode.appendChild(document.createComment(createPathComment(file)));
              rootNode.appendChild(document.createTextNode("\n"));
            }
            Node adoptedNode = NodeUtils.adoptNode(document, item.getValue());
            rootNode.appendChild(adoptedNode);
          }

          String content;
          try {
            content = XmlPrettyPrinter.prettyPrint(document, true);
          } catch (Throwable t) {
            content = XmlUtils.toXml(document, false);
          }

          Files.write(content, outFile, Charsets.UTF_8);
        } catch (Throwable t) {
          throw new ConsumerException(t);
        }
      }
    }

    // now remove empty values files.
    for (String key : mQualifierWithDeletedValues) {
      String folderName =
          key != null && !key.isEmpty()
              ? ResourceFolderType.VALUES.getName() + RES_QUALIFIER_SEP + key
              : ResourceFolderType.VALUES.getName();

      removeOutFile(folderName, FN_VALUES_XML);
    }
  }
Пример #4
0
  private MPSCompilationResult compile(Set<SModule> modules, JavaCompilerOptions compilerOptions) {
    boolean hasAnythingToCompile = false;
    List<IMessage> messages = new ArrayList<IMessage>();

    for (SModule m : modules) {
      if (isExcluded(m)) continue;

      hasAnythingToCompile = true;
    }

    if (!hasAnythingToCompile) {
      return new MPSCompilationResult(0, 0, false, Collections.<SModule>emptySet());
    }

    JavaCompiler compiler = new JavaCompiler();
    boolean hasJavaToCompile = false;
    boolean hasFilesToCopyOrDelete = false;

    myTracer.push("preparing to compile", false);
    Set<SModule> modulesWithRemovals = new HashSet<SModule>();
    for (SModule m : modules) {
      if (areClassesUpToDate(m)) continue;

      if (!getJavaFacet(m).isCompileInMps()) {
        String text =
            "Module which compiled in IDEA depends on module which has to be compiled in MPS:"
                + m.getModuleName();
        messages.add(createMessage(MessageKind.WARNING, text, m));
        myHandler.handle(createMessage(MessageKind.INFORMATION, text, m));
        continue;
      }

      ModuleSources sources = getModuleSources(m);
      hasFilesToCopyOrDelete |= !sources.isResourcesUpToDate();
      hasJavaToCompile |= !sources.isJavaUpToDate();

      for (File f : sources.getFilesToDelete()) {
        //noinspection ResultOfMethodCallIgnored
        f.delete();
        modulesWithRemovals.add(m);
      }

      for (JavaFile f : sources.getFilesToCompile()) {
        compiler.addSource(f.getClassName(), f.getContents());
        myContainingModules.put(f.getClassName(), m);
      }
    }
    myTracer.pop();

    if (!hasJavaToCompile && !hasFilesToCopyOrDelete) {
      return new MPSCompilationResult(0, 0, false, Collections.<SModule>emptySet(), messages);
    }

    myTracer.push("invalidating classpath", false);
    for (SModule module : modulesWithRemovals) {
      invalidateCompiledClasses(module);
    }
    myTracer.pop();

    Set<SModule> changedModules = new HashSet<SModule>();
    MyCompilationResultAdapter listener = null;
    if (hasJavaToCompile) {
      myTracer.push("compiling java", false);
      IClassPathItem classPathItems = computeDependenciesClassPath(modules);
      listener = new MyCompilationResultAdapter(modules, classPathItems, messages);
      compiler.addCompilationResultListener(listener);
      myTracer.push("eclipse compiler", true);

      if (compilerOptions == null) {
        compiler.compile(classPathItems);
      } else {
        compiler.compile(classPathItems, compilerOptions);
      }
      myTracer.pop();
      changedModules.addAll(listener.myChangedModules);
      compiler.removeCompilationResultListener(listener);
      myTracer.pop();
    }

    myTracer.push("copying resources", false);
    for (SModule module : modules) {
      ModuleSources sources = getModuleSources(module);
      IFile classesGen = getJavaFacet(module).getClassesGen();
      if (classesGen == null) {
        continue;
      }
      for (ResourceFile toCopy : sources.getResourcesToCopy()) {
        String fqName = toCopy.getPath();

        fqName = fqName.substring(0, fqName.length() - toCopy.getFile().getName().length());
        String path = fqName.replace('/', File.separatorChar) + toCopy.getFile().getName();

        if (new File(toCopy.getFile().getAbsolutePath()).exists()) {
          FileUtil.copyFile(
              new File(toCopy.getFile().getAbsolutePath()),
              new File(classesGen.getDescendant(path).getPath()));
        }
      }
    }
    myTracer.pop();

    myTracer.push("updating classpath", false);
    for (SModule module : changedModules) {
      invalidateCompiledClasses(module);
    }
    myTracer.pop();

    for (SModule module : modulesWithRemovals) {
      if (!changedModules.contains(module)) {
        myHandler.handle(
            createMessage(
                MessageKind.WARNING,
                "Module with removals not in changed modules: " + module,
                module));
      }
    }

    // todo: check possibility of this statements
    if (hasJavaToCompile && changedModules.isEmpty()) {
      myHandler.handle(
          createMessage(
              MessageKind.ERROR, "has java to compile but changed modules is empty", null));
    }
    if (!hasJavaToCompile && !changedModules.isEmpty()) {
      myHandler.handle(
          createMessage(
              MessageKind.ERROR, "has not java to compile but changed modules is not empty", null));
    }

    return new MPSCompilationResult(
        listener == null ? 0 : listener.getErrorCount(), 0, false, changedModules, messages);
  }