/*
* This file is part of LaTeXDraw.
* Copyright (c) 2005-2017 Arnaud BLOUIN
* LaTeXDraw is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later version.
* LaTeXDraw is distributed without any warranty; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
package net.sf.latexdraw.parsers.svg;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Defines an SVG named node map.
* @author Arnaud BLOUIN
*/
public class SVGNamedNodeMap implements NamedNodeMap, Cloneable {
/** The set of nodes. @since 0.1 */
protected List<SVGAttr> nnm;
/**
* The constructor by default.
* @since 0.1
*/
public SVGNamedNodeMap() {
super();
nnm = new ArrayList<>();
}
@Override
public int getLength() {
return nnm==null ? 0 : nnm.size();
}
@Override
public Node getNamedItem(final String name) {
if(nnm==null || name==null)
return null;
int i = 0;
final int size = getLength();
boolean found = false;
while(i<size && !found)
if(nnm.get(i).getName().equals(name))
found = true;
else
i++;
if(found)
return nnm.get(i);
return null;
}
@Override
public Node item(final int index) {
return nnm==null || index<0 || index>=getLength() ? null : nnm.get(index);
}
@Override
public Node removeNamedItem(final String name) {
if(name==null)
throw new DOMException(DOMException.NOT_FOUND_ERR, "name is null"); //$NON-NLS-1$
int i = 0;
final int size = getLength();
boolean found = false;
while(i<size && !found)
if(nnm.get(i).getName().equals(name))
found = true;
else
i++;
if(found)
return nnm.remove(i);
throw new DOMException(DOMException.NOT_FOUND_ERR, name);
}
@Override
public Node setNamedItem(final Node node) {
if(!(node instanceof SVGAttr))
return null;
final Node attr = getNamedItem(node.getNodeName());
if(attr==null)
nnm.add((SVGAttr)node);
else {
if(attr==node)
return null;
final int index = nnm.indexOf(attr);
nnm.remove(attr);
nnm.add(index, (SVGAttr)node);
}
return attr;
}
@Override
public Object clone() {
try {
final SVGNamedNodeMap clone = (SVGNamedNodeMap)super.clone();
//TODO: see if the ArrayList creation is useful.
clone.nnm = new ArrayList<>();
for(final SVGAttr attr : nnm)
clone.nnm.add((SVGAttr)attr.cloneNode(false));
return clone;
}
catch(final CloneNotSupportedException e) { return null; }
}
@Override
public String toString() {
final StringBuilder str = new StringBuilder().append('{');
for(final SVGAttr e : nnm)
str.append(e).append(',').append(' ');
return str.append('}').toString();
}
@Override
public Node getNamedItemNS(final String namespaceURI, final String localName)
{ throw new DOMException(DOMException.INVALID_ACCESS_ERR, SVGDocument.ACTION_NOT_IMPLEMENTED); }
@Override
public Node setNamedItemNS(final Node arg)
{ throw new DOMException(DOMException.INVALID_ACCESS_ERR, SVGDocument.ACTION_NOT_IMPLEMENTED); }
@Override
public Node removeNamedItemNS(final String namespaceURI, final String localName)
{ throw new DOMException(DOMException.INVALID_ACCESS_ERR, SVGDocument.ACTION_NOT_IMPLEMENTED); }
/**
* @return the attributes.
* @since 0.1
*/
public List<SVGAttr> getAttributes() {
return nnm;
}
@Override
public boolean equals(final Object obj) {
if(!(obj instanceof SVGNamedNodeMap))
return false;
final SVGNamedNodeMap map = (SVGNamedNodeMap)obj;
boolean ok = true;
int i;
final int size = getLength();
if(size!=map.getLength())
return false;
for(i=0; i<size && ok; i++)
ok = item(i).isEqualNode(map.item(i));
return ok;
}
@Override
public int hashCode() {
// Nothing to do.
return super.hashCode()^getLength();
}
}