net.sf.saxon.tree.linked.AttributeMapWithIdentity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Saxon-HE Show documentation
Show all versions of Saxon-HE Show documentation
The XSLT and XQuery Processor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018-2022 Saxonica Limited
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package net.sf.saxon.tree.linked;
import net.sf.saxon.om.*;
import net.sf.saxon.transpile.CSharpInjectMembers;
import net.sf.saxon.tree.iter.AxisIterator;
import net.sf.saxon.tree.iter.NodeListIterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
* An implementation of AttributeMap suitable for representing attributes on a mutable tree.
* Unlike an ordinary AttributeMap, each AttributeInfo has a persistent index value, which
* remains unchanged when attributes are added or removed or renamed. New attributes are allocated
* an index value greater than any previously-allocated index value.
*
* However, an {@code AttributeMapWithIdentity}, like any other {@code AttributeMap},
* is an immutable object.
*/
@CSharpInjectMembers(code={
" public System.Collections.Generic.IEnumerator GetEnumerator() {"
+ " foreach (Saxon.Hej.om.AttributeInfo att in attributes) {"
+ " if (att is not Saxon.Hej.om.AttributeInfo.Deleted) {"
+ " yield return att;"
+ " }"
+ " }"
+ " }"
+ ""
+ " System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {"
+ " return GetEnumerator();"
+ " }"
})
public class AttributeMapWithIdentity implements AttributeMap {
private final List attributes;
AttributeMapWithIdentity(List attributes) {
this.attributes = attributes;
}
/**
* Return the number of attributes in the map.
*
* @return The number of attributes in the map.
*/
@Override
public int size() {
int count = 0;
for (AttributeInfo att : attributes) {
if (!(att instanceof AttributeInfo.Deleted)) {
count++;
}
}
return count;
}
public AxisIterator iterateAttributes(ElementImpl owner) {
List list = new ArrayList<>(attributes.size());
for (int i=0; i newList = new ArrayList<>(attributes);
if (index >= 0 && index < attributes.size()) {
newList.set(index, info);
} else if (index == attributes.size()) {
newList.add(info);
}
return new AttributeMapWithIdentity(newList);
}
public AttributeMapWithIdentity add(AttributeInfo info) {
List newList = new ArrayList<>(attributes);
newList.add(info);
return new AttributeMapWithIdentity(newList);
}
/**
* Remove an existing attribute, to create a new AttributeMap
*
* @param index the index of the attribute to be removed (if it exists)
* @return a new attribute map in which the specified attribute is marked as deleted.
*/
public AttributeMapWithIdentity remove(int index) {
List newList = new ArrayList<>(attributes);
if (index >= 0 && index < attributes.size()) {
AttributeInfo.Deleted del = new AttributeInfo.Deleted(attributes.get(index));
newList.set(index, del);
}
return new AttributeMapWithIdentity(newList);
}
@Override
public AttributeInfo getByFingerprint(int fingerprint, NamePool namePool) {
for (AttributeInfo info : attributes) {
NodeName name = info.getNodeName();
if (name.obtainFingerprint(namePool) == fingerprint) {
return info;
}
}
return null;
}
@Override
public Iterator iterator() {
return attributes.stream().filter(info -> !(info instanceof AttributeInfo.Deleted)).iterator();
}
@Override
public ArrayList asList() {
List list = attributes.stream().filter(
info -> !(info instanceof AttributeInfo.Deleted)).collect(Collectors.toList());
return list instanceof ArrayList ? (ArrayList)list : new ArrayList<>(list);
}
@Override
public AttributeInfo itemAt(int index) {
return attributes.get(index);
}
}