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
/******************************************************************************* * 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 <Lars.Vogel@vogella.com> - Bug 473427 * Mickael Istria (Red Hat Inc.) - Bug 488937 *******************************************************************************/
package org.eclipse.core.internal.resources; import java.io.DataOutputStream; import java.io.IOException; import java.util.*; import org.eclipse.core.internal.watson.IPathRequestor; // public class MarkerWriter { protected MarkerManager manager; // version numbers public static final int MARKERS_SAVE_VERSION = 3; public static final int MARKERS_SNAP_VERSION = 2; // type constants public static final byte INDEX = 1; public static final byte QNAME = 2; // marker attribute types public static final byte ATTRIBUTE_NULL = 0; public static final byte ATTRIBUTE_BOOLEAN = 1; public static final byte ATTRIBUTE_INTEGER = 2; public static final byte ATTRIBUTE_STRING = 3; public MarkerWriter(MarkerManager manager) { super(); this.manager = manager; }
Returns an Object array of length 2. The first element is an Integer which is the number of persistent markers found. The second element is an array of boolean values, with a value of true meaning that the marker at that index is to be persisted.
/** * Returns an Object array of length 2. The first element is an Integer which is the number * of persistent markers found. The second element is an array of boolean values, with a * value of true meaning that the marker at that index is to be persisted. */
private Object[] filterMarkers(IMarkerSetElement[] markers) { Object[] result = new Object[2]; boolean[] isPersistent = new boolean[markers.length]; int count = 0; for (int i = 0; i < markers.length; i++) { MarkerInfo info = (MarkerInfo) markers[i]; if (manager.isPersistent(info)) { isPersistent[i] = true; count++; } } result[0] = count; result[1] = isPersistent; return result; }
 
SAVE_FILE -> VERSION_ID RESOURCE+
VERSION_ID -> int
RESOURCE -> RESOURCE_PATH MARKERS_SIZE MARKER+
RESOURCE_PATH -> String
MARKERS_SIZE -> int
MARKER -> MARKER_ID TYPE ATTRIBUTES_SIZE ATTRIBUTE* CREATION_TIME
MARKER_ID -> long
TYPE -> INDEX | QNAME
INDEX -> byte int
QNAME -> byte String
ATTRIBUTES_SIZE -> short
ATTRIBUTE -> ATTRIBUTE_KEY ATTRIBUTE_VALUE
ATTRIBUTE_KEY -> String
ATTRIBUTE_VALUE -> INTEGER_VALUE | BOOLEAN_VALUE | STRING_VALUE | NULL_VALUE
INTEGER_VALUE -> byte int
BOOLEAN_VALUE -> byte boolean
STRING_VALUE -> byte String
NULL_VALUE -> byte
CREATION_TIME -> long
/** * <pre> {@code * SAVE_FILE -> VERSION_ID RESOURCE+ * VERSION_ID -> int * RESOURCE -> RESOURCE_PATH MARKERS_SIZE MARKER+ * RESOURCE_PATH -> String * MARKERS_SIZE -> int * MARKER -> MARKER_ID TYPE ATTRIBUTES_SIZE ATTRIBUTE* CREATION_TIME * MARKER_ID -> long * TYPE -> INDEX | QNAME * INDEX -> byte int * QNAME -> byte String * ATTRIBUTES_SIZE -> short * ATTRIBUTE -> ATTRIBUTE_KEY ATTRIBUTE_VALUE * ATTRIBUTE_KEY -> String * ATTRIBUTE_VALUE -> INTEGER_VALUE | BOOLEAN_VALUE | STRING_VALUE | NULL_VALUE * INTEGER_VALUE -> byte int * BOOLEAN_VALUE -> byte boolean * STRING_VALUE -> byte String * NULL_VALUE -> byte * CREATION_TIME -> long * }</pre> */
public void save(ResourceInfo info, IPathRequestor requestor, DataOutputStream output, List<String> writtenTypes) throws IOException { // phantom resources don't have markers if (info.isSet(ICoreConstants.M_PHANTOM)) return; MarkerSet markers = info.getMarkers(false); if (markers == null) return; IMarkerSetElement[] elements = markers.elements(); // filter out the markers...determine if there are any persistent ones Object[] result = filterMarkers(elements); int count = ((Integer) result[0]).intValue(); if (count == 0) return; // if this is the first set of markers that we have written, then // write the version id for the file. if (output.size() == 0) output.writeInt(MARKERS_SAVE_VERSION); boolean[] isPersistent = (boolean[]) result[1]; output.writeUTF(requestor.requestPath().toString()); output.writeInt(count); for (int i = 0; i < elements.length; i++) if (isPersistent[i]) write((MarkerInfo) elements[i], output, writtenTypes); }
Snapshot the markers for the specified resource to the given output stream.
 
SNAP_FILE -> [VERSION_ID RESOURCE]*
VERSION_ID -> int (used for backwards compatibiliy)
RESOURCE -> RESOURCE_PATH MARKER_SIZE MARKER+
RESOURCE_PATH -> String
MARKER_SIZE -> int
MARKER -> MARKER_ID TYPE ATTRIBUTES_SIZE ATTRIBUTE* CREATION_TIME
MARKER_ID -> long
TYPE -> INDEX | QNAME
INDEX -> byte int
QNAME -> byte String
ATTRIBUTES_SIZE -> short
ATTRIBUTE -> ATTRIBUTE_KEY ATTRIBUTE_VALUE
ATTRIBUTE_KEY -> String
ATTRIBUTE_VALUE -> BOOLEAN_VALUE | INTEGER_VALUE | STRING_VALUE | NULL_VALUE
BOOLEAN_VALUE -> byte boolean
INTEGER_VALUE -> byte int
STRING_VALUE -> byte String
NULL_VALUE -> byte
CREATION_TIME -> long
/** * Snapshot the markers for the specified resource to the given output stream. * * <pre> {@code * SNAP_FILE -> [VERSION_ID RESOURCE]* * VERSION_ID -> int (used for backwards compatibiliy) * RESOURCE -> RESOURCE_PATH MARKER_SIZE MARKER+ * RESOURCE_PATH -> String * MARKER_SIZE -> int * MARKER -> MARKER_ID TYPE ATTRIBUTES_SIZE ATTRIBUTE* CREATION_TIME * MARKER_ID -> long * TYPE -> INDEX | QNAME * INDEX -> byte int * QNAME -> byte String * ATTRIBUTES_SIZE -> short * ATTRIBUTE -> ATTRIBUTE_KEY ATTRIBUTE_VALUE * ATTRIBUTE_KEY -> String * ATTRIBUTE_VALUE -> BOOLEAN_VALUE | INTEGER_VALUE | STRING_VALUE | NULL_VALUE * BOOLEAN_VALUE -> byte boolean * INTEGER_VALUE -> byte int * STRING_VALUE -> byte String * NULL_VALUE -> byte * CREATION_TIME -> long * }</pre> */
public void snap(ResourceInfo info, IPathRequestor requestor, DataOutputStream output) throws IOException { // phantom resources don't have markers if (info.isSet(ICoreConstants.M_PHANTOM)) return; if (!info.isSet(ICoreConstants.M_MARKERS_SNAP_DIRTY)) return; MarkerSet markers = info.getMarkers(false); if (markers == null) return; IMarkerSetElement[] elements = markers.elements(); // filter out the markers...determine if there are any persistent ones Object[] result = filterMarkers(elements); int count = ((Integer) result[0]).intValue(); // write the version id for the snapshot. output.writeInt(MARKERS_SNAP_VERSION); boolean[] isPersistent = (boolean[]) result[1]; output.writeUTF(requestor.requestPath().toString()); // always write out the count...even if its zero. this will help // use pick up marker deletions from our snapshot. output.writeInt(count); List<String> writtenTypes = new ArrayList<>(); for (int i = 0; i < elements.length; i++) if (isPersistent[i]) write((MarkerInfo) elements[i], output, writtenTypes); info.clear(ICoreConstants.M_MARKERS_SNAP_DIRTY); } /* * Write out the given marker attributes to the given output stream. */ private void write(Map<String, Object> attributes, DataOutputStream output) throws IOException { output.writeShort(attributes.size()); for (Map.Entry<String, Object> e : attributes.entrySet()) { String key = e.getKey(); output.writeUTF(key); Object value = e.getValue(); if (value instanceof Integer) { output.writeByte(ATTRIBUTE_INTEGER); output.writeInt(((Integer) value).intValue()); continue; } if (value instanceof Boolean) { output.writeByte(ATTRIBUTE_BOOLEAN); output.writeBoolean(((Boolean) value).booleanValue()); continue; } if (value instanceof String) { output.writeByte(ATTRIBUTE_STRING); output.writeUTF((String) value); continue; } // otherwise we came across an attribute of an unknown type // so just write out null since we don't know how to marshal it. output.writeByte(ATTRIBUTE_NULL); } } private void write(MarkerInfo info, DataOutputStream output, List<String> writtenTypes) throws IOException { output.writeLong(info.getId()); // if we have already written the type once, then write an integer // constant to represent it instead to remove duplication String type = info.getType(); int index = writtenTypes.indexOf(type); if (index == -1) { output.writeByte(QNAME); output.writeUTF(type); writtenTypes.add(type); } else { output.writeByte(INDEX); output.writeInt(index); } // write out the size of the attribute table and // then each attribute. if (info.getAttributes(false) == null) { output.writeShort(0); } else write(info.getAttributes(false), output); // write out the creation time output.writeLong(info.getCreationTime()); } }