View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
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"); //$NON-NLS-1$
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"); //$NON-NLS-1$
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 //$NON-NLS-1$
176 					+ "]: " + type + "."); //$NON-NLS-1$ //$NON-NLS-2$
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"); //$NON-NLS-1$
193 		NamespaceType nsType = EuromathConfig.getNamespace(namespaceUri);
194 		if (nsType == null)
195 			return Messages.getString("UNKNOWN_NAMESPACE", namespaceUri); //$NON-NLS-1$
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 }