1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor.widgets.namelist;
13 import javax.xml.namespace.QName;
14 import org.apache.commons.lang.StringUtils;
15 import sk.baka.xml.schematic.rules.BaseRule;
16 import sk.uniba.euromath.config.EuromathConfig;
17 import sk.uniba.euromath.config.bind.NamespaceType;
18 import sk.uniba.euromath.editor.lang.Messages;
19 /***
20 * Represents the displayable name list. There is one difference between 'DOM'
21 * and 'Real' namespace: When the list represents elements then they are equal.
22 * However, a local attribute (with <code>null</code> DOM namespace) has a
23 * 'real' namespace equal to its owner namespace.
24 * @param <R> the rule type. Can be instance of <code>AttributeRule</code> or
25 * <code>NewElementRule</code> only.
26 * @author Martin Vysny
27 */
28 public abstract class DisplayableNameList<R extends BaseRule> {
29 /***
30 * The namespace of all local names.
31 */
32 public final String localNamespaceUri;
33 /***
34 * True if this object represents rules for element, false otherwise.
35 */
36 public final boolean isElement;
37 /***
38 * The name of the namespace of all local names, as defined in a config
39 * file.
40 */
41 public final String localNamespaceName;
42 /***
43 * Basic constructor.
44 * @param localNamespaceUri the namespace of the local elements/attributes.
45 * @param isElement true if this object will represent elements or
46 * attributes. There is a difference: elements from non-null namespace will
47 * have a prefix, attributes from non-null (local) namespace will have a
48 * prefix only if this namespace is different than a namespace of the owner
49 * element.
50 */
51 protected DisplayableNameList(String localNamespaceUri, boolean isElement) {
52 super();
53 this.localNamespaceUri = localNamespaceUri;
54 this.isElement = isElement;
55 localNamespaceName = getNamespaceDescription(localNamespaceUri);
56 }
57 /***
58 * Returns array of a displayable representation of names.
59 * @return array of a displayable representation of names.
60 */
61 public abstract String[] getStrings();
62 /***
63 * Determines the type of the item.
64 * @param i index of the name, as in <code>getStrings()</code> array.
65 * @return item type.
66 */
67 public abstract DisplayableNameItemTypeEnum getType(int i);
68 /***
69 * Determines if item can have a rule. Item can have a rule when it has
70 * valid index and it is local or foreign qname.
71 * @param i index
72 * @return <code>true</code> if the item can have rule.
73 */
74 public final boolean hasRule(int i) {
75 if ((i < 0) || (i >= getLength()))
76 return false;
77 DisplayableNameItemTypeEnum type = getType(i);
78 return ((type == DisplayableNameItemTypeEnum.ITEM_LOCAL) || (type == DisplayableNameItemTypeEnum.ITEM_FOREIGN));
79 }
80 /***
81 * Returns the local name.
82 * @param i index of the name, as in <code>getStrings()</code> array.
83 * @return a local name, that can be used to query the name list.
84 * @throws IndexOutOfBoundsException if the index is out of bounds or does
85 * not denote a local name.
86 */
87 public abstract String getLocal(int i);
88 /***
89 * Returns the foreign name.
90 * @param i index of the name, as in <code>getStrings()</code> array.
91 * @return a foreign name, that can be used to query the name list.
92 * @throws IndexOutOfBoundsException if the index is out of bounds or does
93 * not denote a foreign qname.
94 */
95 public abstract QName getForeign(int i);
96 /***
97 * Returns the namespace item.
98 * @param i index of the name, as in <code>getStrings()</code> array.
99 * @return a namespace denoting foreign qnames that doesn't have schema
100 * loaded or doesn't have schema at all.
101 * @throws IndexOutOfBoundsException if the index is out of bounds or does
102 * not denote a namespace.
103 */
104 public abstract String getNamespace(int i);
105 /***
106 * Returns the DOM namespace of the name.
107 * @param i index of the name, as in <code>getStrings()</code> array.
108 * @return the namespace of the name.
109 */
110 public final String getDomNamespaceUri(int i) {
111 switch (getType(i)) {
112 case ITEM_LOCAL:
113 return isElement ? localNamespaceUri : null;
114 case ITEM_FOREIGN:
115 return getForeign(i).getNamespaceURI();
116 case ITEM_NAMESPACE:
117 return getNamespace(i);
118 }
119 throw new IllegalArgumentException("i does not denote valid item");
120 }
121 /***
122 * Returns the 'real' namespace of the name.
123 * @param i index of the name, as in <code>getStrings()</code> array.
124 * @return the namespace of the name.
125 */
126 public final String getRealNamespaceUri(int i) {
127 switch (getType(i)) {
128 case ITEM_LOCAL:
129 return localNamespaceUri;
130 case ITEM_FOREIGN:
131 return getForeign(i).getNamespaceURI();
132 case ITEM_NAMESPACE:
133 return getNamespace(i);
134 }
135 throw new IllegalArgumentException("i does not denote valid item");
136 }
137 /***
138 * Returns the name of the namespace, as defined in the config file.
139 * @param i index of the name, as in <code>getStrings()</code> array.
140 * @return the name of the namespace, or <code>namespaceUri</code> if no
141 * name is defined.
142 */
143 public final String getRealNamespaceDescription(int i) {
144 DisplayableNameItemTypeEnum type = getType(i);
145 if (type == DisplayableNameItemTypeEnum.ITEM_LOCAL)
146 return localNamespaceName;
147 String ns = (type == DisplayableNameItemTypeEnum.ITEM_FOREIGN) ? getForeign(
148 i).getNamespaceURI()
149 : getNamespace(i);
150 return getNamespaceDescription(ns);
151 }
152 /***
153 * Returns the rule for the name as returned by the <code>NameList</code>
154 * class. Only local and foreign items can have a rule.
155 * @param i index of the name, as in <code>getStrings()</code> array.
156 * @return the rule.
157 * @throws IndexOutOfBoundsException if the index is out of bounds
158 * @throws IllegalArgumentException if i does not denote local nor foreign
159 * items.
160 */
161 public abstract R getRule(int i);
162 /***
163 * Returns the qname for the name.
164 * @param i index of the name, as in <code>getStrings()</code> array.
165 * @param prefix the prefix for the qname.
166 * @return the rule.
167 * @throws IndexOutOfBoundsException if the index is out of bounds
168 * @throws IllegalArgumentException if i does not denote local nor foreign
169 * items.
170 */
171 public final QName getDomQName(final int i, final String prefix) {
172 final DisplayableNameItemTypeEnum type = getType(i);
173 if ((type != DisplayableNameItemTypeEnum.ITEM_LOCAL)
174 && (type != DisplayableNameItemTypeEnum.ITEM_FOREIGN))
175 throw new IllegalArgumentException("Invalid item type at [" + i
176 + "]: " + type + ".");
177 if (type == DisplayableNameItemTypeEnum.ITEM_LOCAL)
178 return new QName(isElement ? localNamespaceUri : null, getLocal(i),
179 prefix);
180 final QName foreign = getForeign(i);
181 return new QName(foreign.getNamespaceURI(), foreign.getLocalPart(),
182 prefix);
183 }
184 /***
185 * Returns the name of the namespace, as defined in the config file.
186 * @param namespaceUri the namespace to query.
187 * @return the name of the namespace, or <code>namespaceUri</code> if no
188 * name is defined.
189 */
190 public static final String getNamespaceDescription(String namespaceUri) {
191 if (StringUtils.isEmpty(namespaceUri))
192 return Messages.getString("NULL_NAMESPACE");
193 NamespaceType nsType = EuromathConfig.getNamespace(namespaceUri);
194 if (nsType == null)
195 return Messages.getString("UNKNOWN_NAMESPACE", namespaceUri);
196 return nsType.getDesc();
197 }
198 /***
199 * Returns number of items in the list.
200 * @return number of items.
201 */
202 public final int getLength() {
203 return getStrings().length;
204 }
205 /***
206 * Returns <code>true</code> if this list is empty.
207 * @return <code>true</code> if length is zero.
208 */
209 public final boolean isEmpty() {
210 return getLength() == 0;
211 }
212 }