Copyright (c) 2000, 2015 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Francis Lynch (Wind River) - [305718] Allow reading snapshot into renamed project James Blackburn (Broadcom Corp.) - ongoing development Lars Vogel - Bug 473427
/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Francis Lynch (Wind River) - [305718] Allow reading snapshot into renamed project * James Blackburn (Broadcom Corp.) - ongoing development * Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427 *******************************************************************************/
package org.eclipse.core.internal.resources; import java.io.*; import java.util.*; import org.eclipse.core.internal.events.BuilderPersistentInfo; import org.eclipse.core.internal.utils.Messages; import org.eclipse.core.internal.utils.Policy; import org.eclipse.core.internal.watson.ElementTree; import org.eclipse.core.internal.watson.ElementTreeReader; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.runtime.*;
Reads version 1 of the workspace tree file format.
/** * Reads version 1 of the workspace tree file format. */
public class WorkspaceTreeReader_1 extends WorkspaceTreeReader { protected Workspace workspace; public WorkspaceTreeReader_1(Workspace workspace) { this.workspace = workspace; } protected int getVersion() { return ICoreConstants.WORKSPACE_TREE_VERSION_1; } protected void linkBuildersToTrees(List<BuilderPersistentInfo> buildersToBeLinked, ElementTree[] trees, int index, IProgressMonitor monitor) { monitor = Policy.monitorFor(monitor); try { ArrayList<BuilderPersistentInfo> infos = null; String projectName = null; for (int i = 0; i < buildersToBeLinked.size(); i++) { BuilderPersistentInfo info = buildersToBeLinked.get(i); if (!info.getProjectName().equals(projectName)) { if (infos != null) { // if it is not the first iteration IProject project = workspace.getRoot().getProject(projectName); workspace.getBuildManager().setBuildersPersistentInfo(project, infos); } projectName = info.getProjectName(); infos = new ArrayList<>(5); } info.setLastBuildTree(trees[index++]); infos.add(info); } if (infos != null) { IProject project = workspace.getRoot().getProject(projectName); workspace.getBuildManager().setBuildersPersistentInfo(project, infos); } } finally { monitor.done(); } } protected void linkPluginsSavedStateToTrees(List<SavedState> states, ElementTree[] trees, IProgressMonitor monitor) { monitor = Policy.monitorFor(monitor); try { for (int i = 0; i < states.size(); i++) { SavedState state = states.get(i); // If the tree is too old (depends on the policy), the plug-in should not // get it back as a delta. It is expensive to maintain this information too long. final SaveManager saveManager = workspace.getSaveManager(); if (!saveManager.isOldPluginTree(state.pluginId)) { state.oldTree = trees[i]; } else { //clear information for this plugin from master table saveManager.clearDeltaExpiration(state.pluginId); } } } finally { monitor.done(); } } protected BuilderPersistentInfo readBuilderInfo(IProject project, DataInputStream input, int index) throws IOException { //read the project name String projectName = input.readUTF(); //use the name of the project handle if available if (project != null) projectName = project.getName(); String builderName = input.readUTF(); return new BuilderPersistentInfo(projectName, builderName, index); } protected void readBuildersPersistentInfo(IProject project, DataInputStream input, List<BuilderPersistentInfo> builders, IProgressMonitor monitor) throws IOException { monitor = Policy.monitorFor(monitor); try { int builderCount = input.readInt(); for (int i = 0; i < builderCount; i++) builders.add(readBuilderInfo(project, input, i)); } finally { monitor.done(); } } protected void readPluginsSavedStates(DataInputStream input, HashMap<String, SavedState> savedStates, List<SavedState> plugins, IProgressMonitor monitor) throws IOException, CoreException { monitor = Policy.monitorFor(monitor); try { int stateCount = input.readInt(); for (int i = 0; i < stateCount; i++) { String pluginId = input.readUTF(); SavedState state = new SavedState(workspace, pluginId, null, null); savedStates.put(pluginId, state); plugins.add(state); } } finally { monitor.done(); } } @Override public ElementTree readSnapshotTree(DataInputStream input, ElementTree complete, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); String message; try { message = Messages.resources_readingSnap; monitor.beginTask(message, Policy.totalWork); ElementTreeReader reader = new ElementTreeReader(workspace.getSaveManager()); while (input.available() > 0) { readWorkspaceFields(input, Policy.subMonitorFor(monitor, Policy.totalWork / 2)); complete = reader.readDelta(complete, input); try { // make sure each snapshot is read by the correct reader int version = input.readInt(); if (version != getVersion()) return WorkspaceTreeReader.getReader(workspace, version).readSnapshotTree(input, complete, monitor); } catch (EOFException e) { break; } } return complete; } catch (IOException e) { message = Messages.resources_readWorkspaceSnap; throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, null, message, e); } finally { monitor.done(); } } @Override public void readTree(DataInputStream input, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); String message; try { message = Messages.resources_reading; monitor.beginTask(message, Policy.totalWork); readWorkspaceFields(input, Policy.subMonitorFor(monitor, Policy.opWork * 20 / 100)); HashMap<String, SavedState> savedStates = new HashMap<>(20); List<SavedState> pluginsToBeLinked = new ArrayList<>(20); readPluginsSavedStates(input, savedStates, pluginsToBeLinked, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100)); workspace.getSaveManager().setPluginsSavedState(savedStates); List<BuilderPersistentInfo> buildersToBeLinked = new ArrayList<>(20); readBuildersPersistentInfo(null, input, buildersToBeLinked, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100)); ElementTree[] trees = readTrees(Path.ROOT, input, Policy.subMonitorFor(monitor, Policy.opWork * 40 / 100)); linkPluginsSavedStateToTrees(pluginsToBeLinked, trees, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100)); linkBuildersToTrees(buildersToBeLinked, trees, pluginsToBeLinked.size(), Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100)); } catch (IOException e) { message = Messages.resources_readWorkspaceTree; throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, null, message, e); } finally { monitor.done(); } } @Override public void readTree(IProject project, DataInputStream input, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); String message; try { message = Messages.resources_reading; monitor.beginTask(message, 10); /* read the number of builders */ int numBuilders = input.readInt(); /* read in the list of builder names */ String[] builderNames = new String[numBuilders]; for (int i = 0; i < numBuilders; i++) { String builderName = input.readUTF(); builderNames[i] = builderName; } monitor.worked(1); /* read and link the trees */ ElementTree[] trees = readTrees(project.getFullPath(), input, Policy.subMonitorFor(monitor, 8)); /* map builder names to trees */ if (numBuilders > 0) { ArrayList<BuilderPersistentInfo> infos = new ArrayList<>(trees.length * 2 + 1); for (int i = 0; i < numBuilders; i++) { BuilderPersistentInfo info = new BuilderPersistentInfo(project.getName(), builderNames[i], -1); info.setLastBuildTree(trees[i]); infos.add(info); } workspace.getBuildManager().setBuildersPersistentInfo(project, infos); } monitor.worked(1); } catch (IOException e) { message = Messages.resources_readProjectTree; throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, null, message, e); } finally { monitor.done(); } }
Read trees from disk and link them to the workspace tree.
/** * Read trees from disk and link them to the workspace tree. */
protected ElementTree[] readTrees(IPath root, DataInputStream input, IProgressMonitor monitor) throws IOException { monitor = Policy.monitorFor(monitor); try { String message = Messages.resources_reading; monitor.beginTask(message, 4); ElementTreeReader treeReader = new ElementTreeReader(workspace.getSaveManager()); String newProjectName = ""; //$NON-NLS-1$ if (renameProjectNode) { //have the existing project name (path to import into) take precedence over what we read newProjectName = root.segment(0); } ElementTree[] trees = treeReader.readDeltaChain(input, newProjectName); monitor.worked(3); if (root.isRoot()) { //Don't need to link because we're reading the whole workspace. //The last tree in the chain is the complete tree. ElementTree newTree = trees[trees.length - 1]; newTree.setTreeData(workspace.tree.getTreeData()); workspace.tree = newTree; } else { //splice the restored tree into the current set of trees workspace.linkTrees(root, trees); } monitor.worked(1); return trees; } finally { monitor.done(); } } protected void readWorkspaceFields(DataInputStream input, IProgressMonitor monitor) throws IOException, CoreException { monitor = Policy.monitorFor(monitor); try { // read the node id workspace.nextNodeId = input.readLong(); // read the modification stamp (no longer used) input.readLong(); // read the next marker id workspace.nextMarkerId = input.readLong(); // read the synchronizer's registered sync partners ((Synchronizer) workspace.getSynchronizer()).readPartners(input); } finally { monitor.done(); } } }