All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.core.internal.watson.ElementTreeWriter Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *     Lars Vogel  - Bug 473427
 *     Mickael Istria (Red Hat Inc.) - Bug 488937
 *******************************************************************************/
package org.eclipse.core.internal.watson;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.internal.dtree.DataTreeWriter;
import org.eclipse.core.internal.dtree.DeltaDataTree;
import org.eclipse.core.internal.dtree.IDataFlattener;
import org.eclipse.core.internal.resources.SaveManager;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;

/** ElementTreeWriter flattens an ElementTree
 * onto a data output stream.
 *
 * 

This writer generates the most up-to-date format * of a saved element tree (cf. readers, which must usually also * deal with backward compatibility issues). The flattened * representation always includes a format version number. * *

The writer has an IElementInfoFactory, * which it consults for writing element infos. * *

Element tree writers are thread-safe; several * threads may share a single writer. * */ public class ElementTreeWriter { /** * The current format version number. */ public static final int CURRENT_FORMAT = 1; /** * Constant representing infinite depth */ public static final int D_INFINITE = DataTreeWriter.D_INFINITE; /** * For writing DeltaDataTrees */ protected DataTreeWriter dataTreeWriter; /** * Constructs a new element tree writer that works for * the given element info flattener. */ public ElementTreeWriter(final IElementInfoFlattener flattener) { /* wrap the IElementInfoFlattener in an IDataFlattener */ IDataFlattener f = new IDataFlattener() { @Override public void writeData(IPath path, Object data, DataOutput output) throws IOException { // never write the root node of an ElementTree //because it contains the parent backpointer. if (!IPath.ROOT.equals(path)) { flattener.writeElement(path, data, output); } } @Override public Object readData(IPath path, DataInput input) { return null; } }; dataTreeWriter = new DataTreeWriter(f); } /** * Writes indexes of sorted trees to output stream. * * @return sorted array of trees. * @throws IOException if sorting can not be done. * @see SaveManager#sortTrees */ protected ElementTree[] writeSortedTrees(ElementTree[] trees, DataOutput output) throws IOException { ElementTree[] sorted = SaveManager.sortTrees(trees); if (sorted == null) { throw new IOException("Unable to save workspace - Trees in ambiguous order (Bug 352867)"); //$NON-NLS-1$ } // compute indexes from sorted elements: int numTrees = trees.length; Map> indicesByTree = new HashMap<>(); for (int i = 0; i < numTrees; i++) { indicesByTree.computeIfAbsent(trees[i], k -> new ArrayDeque<>()).push(i); } /* write the order array */ for (int i = 0; i < numTrees; i++) { Integer order = indicesByTree.get(sorted[i]).pop(); writeNumber(order, output); } return sorted; } /** * Writes the delta describing the changes that have to be made * to newerTree to obtain olderTree. * * @param path The path of the subtree to write. All nodes on the path above * the subtree are represented as empty nodes. * @param depth The depth of the subtree to write. A depth of zero writes a * single node, and a depth of D_INFINITE writes the whole subtree. * @param output The stream to write the subtree to. */ public void writeDelta(ElementTree olderTree, ElementTree newerTree, IPath path, int depth, final DataOutput output, IElementComparator comparator) throws IOException { /* write the version number */ writeNumber(CURRENT_FORMAT, output); /** * Note that in current ElementTree usage, the newest * tree is the complete tree, and older trees are just * deltas on the new tree. */ DeltaDataTree completeTree = newerTree.getDataTree(); DeltaDataTree derivedTree = olderTree.getDataTree(); DeltaDataTree deltaToWrite = completeTree.forwardDeltaWith(derivedTree, comparator); Assert.isTrue(deltaToWrite.isImmutable()); dataTreeWriter.writeTree(deltaToWrite, path, depth, output); } /** * Writes an array of ElementTrees to the given output stream. * @param trees A chain of ElementTrees, where on tree in the list is * complete, and all other trees are deltas on the previous tree in the list. * @param path The path of the subtree to write. All nodes on the path above * the subtree are represented as empty nodes. * @param depth The depth of the subtree to write. A depth of zero writes a * single node, and a depth of D_INFINITE writes the whole subtree. * @param output The stream to write the subtree to. */ public void writeDeltaChain(ElementTree[] trees, IPath path, int depth, DataOutput output, IElementComparator comparator) throws IOException { /* Write the format version number */ writeNumber(CURRENT_FORMAT, output); /* Write the number of trees */ int treeCount = trees.length; writeNumber(treeCount, output); if (treeCount <= 0) { return; } /** * Sort the trees in ancestral order, * which writes the tree order to the output */ ElementTree[] sortedTrees = writeSortedTrees(trees, output); /* Write the complete tree */ writeTree(sortedTrees[0], path, depth, output); /* Write the deltas for each of the remaining trees */ for (int i = 1; i < treeCount; i++) { writeDelta(sortedTrees[i], sortedTrees[i - 1], path, depth, output, comparator); } } /** * Writes an integer in a compact format biased towards * small non-negative numbers. Numbers between * 0 and 254 inclusive occupy 1 byte; other numbers occupy 5 bytes. */ protected void writeNumber(int number, DataOutput output) throws IOException { if (number >= 0 && number < 0xff) { output.writeByte(number); } else { output.writeByte(0xff); output.writeInt(number); } } /** * Writes all or some of an element tree to an output stream. * This always writes the most current version of the element tree * file format, whereas the reader supports multiple versions. * * @param tree The tree to write * @param path The path of the subtree to write. All nodes on the path above * the subtree are represented as empty nodes. * @param depth The depth of the subtree to write. A depth of zero writes a * single node, and a depth of D_INFINITE writes the whole subtree. * @param output The stream to write the subtree to. */ public void writeTree(ElementTree tree, IPath path, int depth, final DataOutput output) throws IOException { /* Write the format version number. */ writeNumber(CURRENT_FORMAT, output); /* This actually just copies the root node, which is what we want */ DeltaDataTree subtree = new DeltaDataTree(tree.getDataTree().copyCompleteSubtree(IPath.ROOT)); dataTreeWriter.writeTree(subtree, path, depth, output); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy