@Override public void removeProject(ToBeBuilt toBeBuilt, IProject project, IProgressMonitor monitor) { storageMapper.collectNfarURIs(project, toBeBuilt.getToBeDeleted()); Iterator<Map.Entry<String, Set<URI>>> iterator = knownEntries.entrySet().iterator(); String keyPrefix = project.getName() + "|"; while (iterator.hasNext()) { String key = iterator.next().getKey(); if (key.startsWith(keyPrefix)) { iterator.remove(); } } }
@Override public boolean removeStorage(ToBeBuilt toBeBuilt, IStorage storage, IProgressMonitor monitor) { if (IN4JSArchive.NFAR_FILE_EXTENSION.equals(storage.getFullPath().getFileExtension()) && storage instanceof IFile) { IProject project = ((IFile) storage).getProject(); String key = project.getName() + "|" + storage.getFullPath().toPortableString(); Set<URI> cachedURIs = knownEntries.remove(key); if (cachedURIs != null) { toBeBuilt.getToBeDeleted().addAll(cachedURIs); } else { // cache not populated, use the index to find the URIs that shall be removed, e.g. // can happen after a restart of Eclipse Iterable<IResourceDescription> descriptions = builderState.getAllResourceDescriptions(); String expectedAuthority = "platform:/resource" + storage.getFullPath() + "!"; Set<URI> toBeDeleted = toBeBuilt.getToBeDeleted(); for (IResourceDescription description : descriptions) { URI knownURI = description.getURI(); if (knownURI.isArchive()) { String authority = knownURI.authority(); if (expectedAuthority.equals(authority)) { toBeDeleted.add(knownURI); } } } } return true; } return false; }
@Override protected ToBeBuilt getToBeBuilt(ToBeBuiltComputer computer, IProject project, IProgressMonitor monitor) { try { return computer.updateProject(project, monitor); } catch (OperationCanceledException | CoreException e) { final String name = project.getName(); LOGGER.error("Error occurred while calculating to be build data for '" + name + "' project.", e); throw Exceptions.sneakyThrow(e); } }
@Override protected void doClean(ToBeBuilt toBeBuilt, IProgressMonitor monitor) throws CoreException { try { updateProjectReferencesIfNecessary(); N4JSBuildTypeTracker.setBuildType(getProject(), BuildType.CLEAN); super.doClean(toBeBuilt, monitor); getProject().touch(monitor); } finally { N4JSBuildTypeTracker.clearBuildType(getProject()); } }
@Override protected void fullBuild(final IProgressMonitor monitor, final boolean isRecoveryBuild) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 2); IProject project = getProject(); ToBeBuilt toBeBuilt = isRecoveryBuild ? getToBeBuiltComputer().updateProjectNewResourcesOnly(project, progress.newChild(1)) : getToBeBuiltComputer().updateProject(project, progress.newChild(1)); doBuild(toBeBuilt, progress.newChild(1), isRecoveryBuild ? BuildType.RECOVERY : BuildType.FULL); }
@Override protected void clean(final IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 2); try { ToBeBuilt toBeBuilt = getToBeBuiltComputer().removeProject(getProject(), progress.newChild(1)); doClean(toBeBuilt, progress.newChild(1)); } finally { if (monitor != null) { monitor.done(); } } }
@Override public void updateProject(ToBeBuilt toBeBuilt, IProject project, IProgressMonitor monitor) throws CoreException { // nothing to do per project, storages are processed individually }
/** * Runs the operation in a blocking fashion. * * @param helper * the build helper to get the injected services. * @param project * the project to clean/build. * @param monitor * monitor for the operation. */ private void run(final ExternalLibraryBuilderHelper helper, IProject project, IProgressMonitor monitor) { checkArgument(project instanceof ExternalProject, "Expected external project: " + project); final SubMonitor subMonitor = SubMonitor.convert(monitor, 2); final ToBeBuiltComputer computer = helper.builtComputer; final IProgressMonitor computeMonitor = subMonitor.newChild(1, SUPPRESS_BEGINTASK); monitor.setTaskName("Collecting resource for '" + project.getName() + "'..."); final ToBeBuilt toBeBuilt = getToBeBuilt(computer, project, computeMonitor); if (toBeBuilt.getToBeDeleted().isEmpty() && toBeBuilt.getToBeUpdated().isEmpty()) { subMonitor.newChild(1, SUPPRESS_NONE).worked(1); return; } try { final IN4JSCore core = helper.core; final QueuedBuildData queuedBuildData = helper.queuedBuildData; final IBuilderState builderState = helper.builderState; final ExternalProject externalProject = (ExternalProject) project; final String path = externalProject.getExternalResource().getAbsolutePath(); final URI uri = URI.createFileURI(path); final IN4JSProject n4Project = core.findProject(uri).orNull(); ResourceSet resourceSet = null; try { resourceSet = core.createResourceSet(Optional.of(n4Project)); if (!resourceSet.getLoadOptions().isEmpty()) { resourceSet.getLoadOptions().clear(); } resourceSet.getLoadOptions().put(ResourceDescriptionsProvider.NAMED_BUILDER_SCOPE, Boolean.TRUE); if (resourceSet instanceof ResourceSetImpl) { ((ResourceSetImpl) resourceSet).setURIResourceMap(newHashMap()); } final BuildData buildData = new BuildData( project.getName(), resourceSet, toBeBuilt, queuedBuildData, true /* indexingOnly */); monitor.setTaskName("Building '" + project.getName() + "'..."); final IProgressMonitor buildMonitor = subMonitor.newChild(1, SUPPRESS_BEGINTASK); builderState.update(buildData, buildMonitor); } finally { if (null != resourceSet) { resourceSet.getResources().clear(); resourceSet.eAdapters().clear(); } } } catch (Exception e) { final String message = "Error occurred while " + toString().toLowerCase() + "ing external library " + project.getName() + "."; LOGGER.error(message, e); throw new RuntimeException(message, e); } }
/** * Like the super implementation, except the build is not triggered if * both toBeDeleted and toBeUpdated are empty. {@inheritDoc} */ @SuppressWarnings("nls") @Override protected void doBuild(final ToBeBuilt toBeBuilt, final IProgressMonitor monitor, final BuildType type) throws CoreException { if (toBeBuilt.getToBeDeleted().size() != 0 || toBeBuilt.getToBeUpdated().size() != 0) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Starting " + type.name() + " build:" + "\ndeleted(" + toBeBuilt.getToBeDeleted().size() + ")=" + toBeBuilt.getToBeDeleted().toString() + "\nupdated(" + toBeBuilt.getToBeUpdated().size() + ")=" + toBeBuilt.getToBeUpdated().toString()); } SubMonitor progress = SubMonitor.convert(monitor, 1 + 1 + 1); // build + participant + rebuild ResourceSet resourceSet = getResourceSetProvider().get(getProject()); resourceSet.getLoadOptions().put(ResourceDescriptionsProvider.NAMED_BUILDER_SCOPE, Boolean.TRUE); if (resourceSet instanceof ResourceSetImpl) { ((ResourceSetImpl) resourceSet).setURIResourceMap(Maps.<URI, Resource> newHashMap()); } BuildData buildData = new BuildData(getProject().getName(), resourceSet, toBeBuilt, queuedBuildData); ImmutableList<Delta> deltas = builderState.update(buildData, progress.newChild(1)); if (participant != null) { final BuildContext buildContext = new BuildContext(this, resourceSet, deltas, type); // remember the current workspace tree final ElementTree oldTree = ((Workspace) ResourcesPlugin.getWorkspace()).getElementTree(); oldTree.immutable(); participant.build(buildContext, progress.newChild(1)); if (buildContext.isRebuildRequired() && rebuilds++ <= 2) { final ElementTree newTree = ((Workspace) ResourcesPlugin.getWorkspace()).getElementTree(); newTree.immutable(); final ResourceDelta generatedDelta = ResourceDeltaFactory.computeDelta((Workspace) ResourcesPlugin.getWorkspace(), oldTree, newTree, getProject().getFullPath(), -1); // rebuild the generated delta ResourcesPlugin.getWorkspace().checkpoint(false); incrementalBuild(generatedDelta, progress.newChild(1)); } } else { progress.worked(2); } resourceSet.getResources().clear(); resourceSet.eAdapters().clear(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Build done."); } } else if (LOGGER.isDebugEnabled()) { LOGGER.debug("Ignoring empty " + type.name() + " build."); } }
@Override protected ToBeBuilt getToBeBuilt(ToBeBuiltComputer computer, IProject project, IProgressMonitor monitor) { return computer.removeProject(project, monitor); }
/** * Calculates the {@link ToBeBuilt} for the project. * * @param computer * the computer for the calculation. * @param project * the object of the operation. * @param monitor * the monitor for the process. * @return the calculated {@link ToBeBuilt} instance. */ abstract ToBeBuilt getToBeBuilt(ToBeBuiltComputer computer, IProject project, IProgressMonitor monitor);