1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23package com.sun.org.apache.xml.internal.security.c14n.helper; 24 25import com.sun.org.apache.xml.internal.security.utils.Constants; 26import org.w3c.dom.Attr; 27import java.io.Serializable; 28import java.util.Comparator; 29 30/** 31 * Compares two attributes based on the C14n specification. 32 * 33 * <UL> 34 * <LI>Namespace nodes have a lesser document order position than attribute 35 * nodes. 36 * <LI> An element's namespace nodes are sorted lexicographically by 37 * local name (the default namespace node, if one exists, has no 38 * local name and is therefore lexicographically least). 39 * <LI> An element's attribute nodes are sorted lexicographically with 40 * namespace URI as the primary key and local name as the secondary 41 * key (an empty namespace URI is lexicographically least). 42 * </UL> 43 * 44 * @author Christian Geuer-Pollmann 45 */ 46public class AttrCompare implements Comparator<Attr>, Serializable { 47 48 private static final long serialVersionUID = -7113259629930576230L; 49 private static final int ATTR0_BEFORE_ATTR1 = -1; 50 private static final int ATTR1_BEFORE_ATTR0 = 1; 51 private static final String XMLNS = Constants.NamespaceSpecNS; 52 53 /** 54 * Compares two attributes based on the C14n specification. 55 * 56 * <UL> 57 * <LI>Namespace nodes have a lesser document order position than 58 * attribute nodes. 59 * <LI> An element's namespace nodes are sorted lexicographically by 60 * local name (the default namespace node, if one exists, has no 61 * local name and is therefore lexicographically least). 62 * <LI> An element's attribute nodes are sorted lexicographically with 63 * namespace URI as the primary key and local name as the secondary 64 * key (an empty namespace URI is lexicographically least). 65 * </UL> 66 * 67 * @param attr0 68 * @param attr1 69 * @return returns a negative integer, zero, or a positive integer as 70 * obj0 is less than, equal to, or greater than obj1 71 * 72 */ 73 public int compare(Attr attr0, Attr attr1) { 74 String namespaceURI0 = attr0.getNamespaceURI(); 75 String namespaceURI1 = attr1.getNamespaceURI(); 76 77 boolean isNamespaceAttr0 = XMLNS.equals(namespaceURI0); 78 boolean isNamespaceAttr1 = XMLNS.equals(namespaceURI1); 79 80 if (isNamespaceAttr0) { 81 if (isNamespaceAttr1) { 82 // both are namespaces 83 String localname0 = attr0.getLocalName(); 84 String localname1 = attr1.getLocalName(); 85 86 if ("xmlns".equals(localname0)) { 87 localname0 = ""; 88 } 89 90 if ("xmlns".equals(localname1)) { 91 localname1 = ""; 92 } 93 94 return localname0.compareTo(localname1); 95 } 96 // attr0 is a namespace, attr1 is not 97 return ATTR0_BEFORE_ATTR1; 98 } else if (isNamespaceAttr1) { 99 // attr1 is a namespace, attr0 is not 100 return ATTR1_BEFORE_ATTR0; 101 } 102 103 // none is a namespace 104 if (namespaceURI0 == null) { 105 if (namespaceURI1 == null) { 106 String name0 = attr0.getName(); 107 String name1 = attr1.getName(); 108 return name0.compareTo(name1); 109 } 110 return ATTR0_BEFORE_ATTR1; 111 } else if (namespaceURI1 == null) { 112 return ATTR1_BEFORE_ATTR0; 113 } 114 115 int a = namespaceURI0.compareTo(namespaceURI1); 116 if (a != 0) { 117 return a; 118 } 119 120 return (attr0.getLocalName()).compareTo(attr1.getLocalName()); 121 } 122} 123