001 package com.oxygenxml.validate.nvdl;
002
003 import org.xml.sax.Attributes;
004
005 /**
006 * Implementation of the Attributes interface that filters out some of the
007 * attributes of an actual Attributes implementation. We will keep only the
008 * attributes whose indexes are specified in a given set of indexes.
009 */
010 class FilteredAttributes implements Attributes {
011 /**
012 * The actual attributes, we will filter out some of them.
013 */
014 private final Attributes attributes;
015
016 /**
017 * The set of indexes of the attributes to used.
018 */
019 private final IntSet indexSet;
020
021 /**
022 * Maps indexes in the real attributes list to 1 based indexes in the
023 * filtered attributes list. For instance if we keep only the
024 * 1st and the 3rd attributes from 4 attributes then the
025 * reverse index map will have as values
026 * [0] --> 1
027 * [1] --> 0
028 * [2] --> 2
029 * [3] --> 0
030 *
031 */
032 private int[] reverseIndexMap;
033
034 /**
035 * Creates a filtered attributes instance.
036 * @param indexSet The set with indexes that we will keep.
037 * @param attributes The actual attributes.
038 */
039 public FilteredAttributes(IntSet indexSet, Attributes attributes) {
040 this.indexSet = indexSet;
041 this.attributes = attributes;
042 }
043
044 /**
045 * Gets the index in the filtered set for a given real index.
046 * If the reverseIndexMap is not computed it computes it,
047 * otherwise it just uses the previously computed map.
048 * @param k The index in the real attributes.
049 * @return The index in the filtered attributes.
050 */
051 private int reverseIndex(int k) {
052 if (reverseIndexMap == null) {
053 reverseIndexMap = new int[attributes.getLength()];
054 for (int i = 0, len = indexSet.size(); i < len; i++)
055 reverseIndexMap[indexSet.get(i)] = i + 1;
056 }
057 return reverseIndexMap[k] - 1;
058 }
059
060 /**
061 * The number of attributes, the same as the length of the list of indexes.
062 */
063 public int getLength() {
064 return indexSet.size();
065 }
066
067 /**
068 * Get the URI for the index-th attribute.
069 */
070 public String getURI(int index) {
071 if (index < 0 || index >= indexSet.size())
072 return null;
073 return attributes.getURI(indexSet.get(index));
074 }
075
076 /**
077 * Get the local name for the index-th attribute.
078 */
079 public String getLocalName(int index) {
080 if (index < 0 || index >= indexSet.size())
081 return null;
082 return attributes.getLocalName(indexSet.get(index));
083 }
084
085 /**
086 * Get the QName for the index-th attribute.
087 */
088 public String getQName(int index) {
089 if (index < 0 || index >= indexSet.size())
090 return null;
091 return attributes.getQName(indexSet.get(index));
092 }
093
094 /**
095 * Get the type for the index-th attribute.
096 */
097 public String getType(int index) {
098 if (index < 0 || index >= indexSet.size())
099 return null;
100 return attributes.getType(indexSet.get(index));
101 }
102
103 /**
104 * Get the value for the index-th attribute.
105 */
106 public String getValue(int index) {
107 if (index < 0 || index >= indexSet.size())
108 return null;
109 return attributes.getValue(indexSet.get(index));
110 }
111
112 public int getIndex(String uri, String localName) {
113 int n = attributes.getIndex(uri, localName);
114 if (n < 0)
115 return n;
116 return reverseIndex(n);
117 }
118
119 public int getIndex(String qName) {
120 int n = attributes.getIndex(qName);
121 if (n < 0)
122 return n;
123 return reverseIndex(n);
124 }
125
126 /**
127 * Get the real index, in the initial attributes list of a given attribute.
128 * If the attribute is filtered out then return -1.
129 * @param uri The attribute uri.
130 * @param localName The attribute local name.
131 * @return The real index if the attribute is present and not filtered out, otherwise -1.
132 */
133 private int getRealIndex(String uri, String localName) {
134 int index = attributes.getIndex(uri, localName);
135 if (index < 0 || reverseIndex(index) < 0)
136 return -1;
137 return index;
138 }
139
140 /**
141 * Get the real index, in the initial attributes list of a given attribute.
142 * If the attribute is filtered out then return -1.
143 * @param qName The attribute qualified name.
144 * @return The real index if the attribute is present and not filtered out, otherwise -1.
145 */
146 private int getRealIndex(String qName) {
147 int index = attributes.getIndex(qName);
148 if (index < 0 || reverseIndex(index) < 0)
149 return -1;
150 return index;
151 }
152
153 /**
154 * Get the type of the attribute.
155 * @param uri The attribute uri.
156 * @param localName The attribute local name.
157 */
158 public String getType(String uri, String localName) {
159 return attributes.getType(getRealIndex(uri, localName));
160 }
161
162 /**
163 * Get the value of the attribute.
164 * @param uri The attribute uri.
165 * @param localName The attribute local name.
166 */
167 public String getValue(String uri, String localName) {
168 return attributes.getValue(getRealIndex(uri, localName));
169 }
170
171 /**
172 * Get the type of the attribute.
173 * @param qName The attribute qualified name.
174 */
175 public String getType(String qName) {
176 return attributes.getType(getRealIndex(qName));
177 }
178
179 /**
180 * Get the value of the attribute.
181 * @param qName The attribute qualified name.
182 */
183 public String getValue(String qName) {
184 return attributes.getValue(getRealIndex(qName));
185 }
186 }