@Override
 public boolean isAffected(
     Collection<Delta> deltas, IResourceDescription candidate, IResourceDescriptions context) {
   Set<URI> outgoingReferences = descriptionUtils.collectOutgoingReferences(candidate);
   if (!outgoingReferences.isEmpty()) {
     for (IResourceDescription.Delta delta : deltas)
       if (hasChanges(delta, candidate) && outgoingReferences.contains(delta.getUri()))
         return true;
   }
   // this is a tradeoff - we could either check whether a given delta uri is contained
   // in a reachable container and check for intersecting names afterwards, or we can do
   // the other way round
   // unfortunately there is no way to decide reliably which algorithm scales better
   // note that this method is called for each description so we have something like a
   // number of deltas x number of resources which is not really nice
   List<IContainer> containers = null;
   Collection<QualifiedName> importedNames = getImportedNames(candidate);
   for (IResourceDescription.Delta delta : deltas) {
     if (hasChanges(delta, candidate)) {
       // not a java resource - delta's resource should be contained in a visible container
       // as long as we did not delete the resource
       URI uri = delta.getUri();
       if ((uri.isPlatform() || uri.isArchive()) && delta.getNew() != null) {
         if (containers == null)
           containers = containerManager.getVisibleContainers(candidate, context);
         boolean descriptionIsContained = false;
         for (int i = 0; i < containers.size() && !descriptionIsContained; i++) {
           descriptionIsContained = containers.get(i).hasResourceDescription(uri);
         }
         if (!descriptionIsContained) return false;
       }
       if (isAffected(importedNames, delta.getNew())
           || isAffected(importedNames, delta.getOld())) {
         return true;
       }
     }
   }
   return false;
 }
 /** @since 2.7 */
 protected boolean doGenerate(
     IResourceDescription.Delta delta, IBuildContext context, IFileSystemAccess access) {
   if (delta.getNew() != null) {
     try {
       handleChangedContents(delta, context, access);
     } catch (OperationCanceledException e) {
       throw e;
     } catch (Exception e) {
       addMarkerAndLogError(delta.getUri(), e);
     }
     return true;
   }
   return false;
 }
  /** @since 2.7 */
  protected void doBuild(
      List<IResourceDescription.Delta> deltas,
      Map<String, OutputConfiguration> outputConfigurations,
      Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers,
      IBuildContext context,
      EclipseResourceFileSystemAccess2 access,
      IProgressMonitor progressMonitor)
      throws CoreException {
    final int numberOfDeltas = deltas.size();
    SubMonitor subMonitor =
        SubMonitor.convert(progressMonitor, numberOfDeltas / MONITOR_CHUNK_SIZE + 1);
    SubMonitor currentMonitor = null;
    int clusterIndex = 0;
    for (int i = 0; i < numberOfDeltas; i++) {
      IResourceDescription.Delta delta = deltas.get(i);

      if (subMonitor.isCanceled()) {
        throw new OperationCanceledException();
      }
      if (i % 10 == 0) {
        subMonitor.subTask(
            "Compiling chunk "
                + (i / MONITOR_CHUNK_SIZE + 1)
                + " of "
                + (numberOfDeltas / MONITOR_CHUNK_SIZE + 1));
        currentMonitor = subMonitor.newChild(1);
        access.setMonitor(currentMonitor);
      }
      if (logger.isDebugEnabled()) {
        logger.debug("Compiling " + delta.getUri() + " (" + i + " of " + numberOfDeltas + ")");
      }
      if (delta.getNew() != null
          && !clusteringPolicy.continueProcessing(
              context.getResourceSet(), delta.getUri(), clusterIndex)) {
        clearResourceSet(context.getResourceSet());
        clusterIndex = 0;
      }

      Set<IFile> derivedResources =
          getDerivedResources(delta, outputConfigurations, generatorMarkers);
      access.setPostProcessor(getPostProcessor(delta, context, derivedResources));

      if (doGenerate(delta, context, access)) {
        clusterIndex++;
        access.flushSourceTraces();
      }

      cleanDerivedResources(delta, derivedResources, context, access, currentMonitor);
    }
  }
Exemple #4
0
  public void build(final IBuildContext context, IProgressMonitor monitor) throws CoreException {
    if (!isEnabled(context)) {
      return;
    }

    final List<IResourceDescription.Delta> deltas = getRelevantDeltas(context);
    if (deltas.isEmpty()) {
      return;
    }

    final int numberOfDeltas = deltas.size();

    // monitor handling
    if (monitor.isCanceled()) throw new OperationCanceledException();
    SubMonitor subMonitor = SubMonitor.convert(monitor, numberOfDeltas + 3);

    EclipseResourceFileSystemAccess2 access = fileSystemAccessProvider.get();
    final IProject builtProject = context.getBuiltProject();
    access.setProject(builtProject);
    final Map<String, OutputConfiguration> outputConfigurations = getOutputConfigurations(context);
    refreshOutputFolders(context, outputConfigurations, subMonitor.newChild(1));
    access.setOutputConfigurations(outputConfigurations);
    if (context.getBuildType() == BuildType.CLEAN || context.getBuildType() == BuildType.RECOVERY) {
      SubMonitor cleanMonitor =
          SubMonitor.convert(subMonitor.newChild(1), outputConfigurations.size());
      for (OutputConfiguration config : outputConfigurations.values()) {
        cleanOutput(context, config, cleanMonitor.newChild(1));
      }
      if (context.getBuildType() == BuildType.CLEAN) return;
    }

    Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers = newHashMap();
    for (OutputConfiguration config : outputConfigurations.values()) {
      if (config.isCleanUpDerivedResources()) {
        final IFolder outputFolder = builtProject.getFolder(config.getOutputDirectory());
        final Iterable<IMarker> markers =
            derivedResourceMarkers.findDerivedResourceMarkers(
                outputFolder, generatorIdProvider.getGeneratorIdentifier());
        generatorMarkers.put(config, markers);
      }
    }

    for (int i = 0; i < numberOfDeltas; i++) {
      final IResourceDescription.Delta delta = deltas.get(i);

      // monitor handling
      if (subMonitor.isCanceled()) throw new OperationCanceledException();
      subMonitor.subTask(
          "Compiling " + delta.getUri().lastSegment() + " (" + i + " of " + numberOfDeltas + ")");
      access.setMonitor(subMonitor.newChild(1));

      final String uri = delta.getUri().toString();
      final Set<IFile> derivedResources = newLinkedHashSet();
      for (OutputConfiguration config : outputConfigurations.values()) {
        if (config.isCleanUpDerivedResources()) {
          Iterable<IMarker> markers = generatorMarkers.get(config);
          for (IMarker marker : markers) {
            String source = derivedResourceMarkers.getSource(marker);
            if (source != null && source.equals(uri))
              derivedResources.add((IFile) marker.getResource());
          }
        }
      }
      access.setPostProcessor(
          new EclipseResourceFileSystemAccess2.IFileCallback() {

            public boolean beforeFileDeletion(IFile file) {
              derivedResources.remove(file);
              context.needRebuild();
              return true;
            }

            public void afterFileUpdate(IFile file) {
              handleFileAccess(file);
            }

            public void afterFileCreation(IFile file) {
              handleFileAccess(file);
            }

            protected void handleFileAccess(IFile file) {
              try {
                derivedResources.remove(file);
                derivedResourceMarkers.installMarker(file, uri);
                context.needRebuild();
              } catch (CoreException e) {
                throw new RuntimeException(e);
              }
            }
          });
      if (delta.getNew() != null) {
        handleChangedContents(delta, context, access);
      }
      access.flushSourceTraces();
      SubMonitor deleteMonitor =
          SubMonitor.convert(subMonitor.newChild(1), derivedResources.size());
      for (IFile iFile : newLinkedHashSet(derivedResources)) {
        IMarker marker = derivedResourceMarkers.findDerivedResourceMarker(iFile, uri);
        if (marker != null) marker.delete();
        if (derivedResourceMarkers.findDerivedResourceMarkers(iFile).length == 0) {
          access.deleteFile(iFile, deleteMonitor);
          context.needRebuild();
        }
      }
    }
  }