OSDN Git Service

Merge release/v3.120.2
[mikutoga/TogaGem.git] / src / main / java / jp / sfjp / mikutoga / xml / DomNsUtils.java
1 /*
2  * XML DOM utilities with namespace
3  *
4  * License : The MIT License
5  * Copyright(c) 2011 MikuToga Partners
6  */
7
8 package jp.sfjp.mikutoga.xml;
9
10 import java.text.MessageFormat;
11 import java.util.Iterator;
12 import org.w3c.dom.DOMException;
13 import org.w3c.dom.Element;
14 import org.w3c.dom.Node;
15
16 /**
17  * DOMユーティリティ(名前空間対応)。
18  * <p>各種名前空間引数にnullが渡された場合、全ての名前空間にマッチする。
19  * <p>各種ローカル名引数にnullが渡された場合、全てのローカル名にマッチする。
20  * <p>ノードの持つ名前空間がnullの場合、全ての名前空間引数にマッチする。
21  */
22 public final class DomNsUtils {
23
24     private static final String ERRMSG_NOELEM =
25             "Elem:[{0}] was not found in Elem:[{1}]";
26     private static final String ERRMSG_NOATTR =
27             "Attr:[{0}] was not found in Elem:[{1}]";
28     private static final String ERRMSG_INVATTR =
29             "Invalid attribute form Attr[{0}] Value[{1}]";
30
31
32     /**
33      * 隠しコンストラクタ。
34      */
35     private DomNsUtils(){
36         assert false;
37         throw new AssertionError();
38     }
39
40
41     /**
42      * 名前空間とローカル名が一致するノードか判定する。
43      * @param node ノード
44      * @param nsuri 名前空間URI
45      * @param localName ローカル名。
46      * @return ノードの名前空間およびローカル名が一致したらtrue
47      */
48     public static boolean hasNsLocalNameNode(Node node,
49                                                 String nsuri,
50                                                 String localName ){
51         String nodeLocalName = node.getLocalName();
52         String nodeNsUri     = node.getNamespaceURI();
53
54         if(localName != null){
55             if( ! localName.equals(nodeLocalName) ) return false;
56         }
57
58         if(nsuri != null && nodeNsUri != null){
59             if( ! nsuri.equals(nodeNsUri) ) return false;
60         }
61
62         return true;
63     }
64
65     /**
66      * 名前空間とローカル名が一致する要素か判定する。
67      * @param node ノード
68      * @param nsuri 名前空間URI
69      * @param localName ローカル名。
70      * @return 名前空間およびローカル名が一致する要素であればtrue
71      */
72     public static boolean hasNsLocalNameElem(Node node,
73                                              String nsuri,
74                                              String localName ){
75         if(node.getNodeType() != Node.ELEMENT_NODE) return false;
76         if( ! hasNsLocalNameNode(node, nsuri, localName) ) return false;
77         return true;
78     }
79
80     /**
81      * 親要素が指定された名前の子要素を持つか判定する。
82      * @param parent 親要素
83      * @param nsuri 名前空間URI
84      * @param localName ローカル名
85      * @return 指定名の子要素が存在すればtrue
86      */
87     public static boolean hasChild(Element parent,
88                                     String nsuri,
89                                     String localName ){
90         for(Node node = parent.getFirstChild();
91             node != null;
92             node = node.getNextSibling() ){
93
94             if(hasNsLocalNameElem(node, nsuri, localName)){
95                 return true;
96             }
97         }
98
99         return false;
100     }
101
102     /**
103      * 指定された名前空間とローカル名に合致する最初の直下子要素を返す。
104      * @param parent 親要素
105      * @param nsuri 名前空間URI
106      * @param localName ローカル名
107      * @return 最初の直下子要素。見つからなければnull。
108      */
109     public static Element pickFirstChild(Node parent,
110                                          String nsuri,
111                                          String localName ){
112         Node node = parent.getFirstChild();
113         while(node != null){
114             if(hasNsLocalNameElem(node, nsuri, localName)){
115                 break;
116             }
117             node = node.getNextSibling();
118         }
119         return (Element) node;
120     }
121
122     /**
123      * 指定された名前空間とローカル名に合致する最初の直下子要素を返す。
124      * <p>見つからなければ例外を投げる。
125      * @param parent 親要素
126      * @param nsuri 名前空間URI
127      * @param localName ローカル名
128      * @return 最初の直下子要素。
129      * @throws TogaXmlException 1つも見つからなかった
130      */
131     public static Element getFirstChild(Element parent,
132                                         String nsuri,
133                                         String localName )
134             throws TogaXmlException{
135         Element elem = pickFirstChild(parent, nsuri, localName);
136
137         if(elem == null){
138             String message = MessageFormat.format(ERRMSG_NOELEM,
139                                                   localName,
140                                                   parent.getLocalName() );
141             throw new TogaXmlException(message);
142         }
143
144         return elem;
145     }
146
147     /**
148      * 指定された名前の子要素のforeachを返す。
149      * @param parent 親要素
150      * @param nsuri 名前空間URI
151      * @param localName 子要素名
152      * @return 子要素のforeach
153      */
154     public static Iterable<Element> getEachChild(final Element parent,
155                                                  final String nsuri,
156                                                  final String localName ){
157         Iterable<Element> result = new Iterable<Element>(){
158             @Override
159             public Iterator<Element> iterator(){
160                 return new SiblingElemIterator(parent, nsuri, localName);
161             }
162         };
163         return result;
164     }
165
166     /**
167      * 要素に属性が存在するか判定する。
168      * @param elem 要素
169      * @param nsuri 名前空間URI
170      * @param localName ローカル名
171      * @return 存在するならtrue
172      */
173     public static boolean hasAttrNS(Element elem,
174                                     String nsuri,
175                                     String localName ){
176         return elem.hasAttributeNS(nsuri, localName);
177     }
178
179     /**
180      * 要素からxsd:string型属性値を読み取る。
181      * @param elem 要素
182      * @param nsuri 名前空間URI
183      * @param localName 属性名
184      * @return 文字列
185      * @throws TogaXmlException 属性値が見つからなかった。
186      */
187     public static String getStringAttrNS(Element elem,
188                                          String nsuri,
189                                          String localName )
190             throws TogaXmlException{
191         if( ! hasAttrNS(elem, nsuri, localName) ){
192             String message = MessageFormat.format(ERRMSG_NOATTR,
193                                                   localName,
194                                                   elem.getLocalName() );
195             throw new TogaXmlException(message);
196         }
197
198         String result;
199         try{
200             result = elem.getAttributeNS(nsuri, localName);
201         }catch(DOMException e){
202             assert false;
203             throw new AssertionError(e);
204         }
205
206         return result;
207     }
208
209     /**
210      * 要素からxsd:boolean型属性値を読み取る。
211      * @param elem 要素
212      * @param nsuri 名前空間URI
213      * @param localName 属性名
214      * @return 真ならtrue
215      * @throws TogaXmlException 属性値が見つからなかった。
216      */
217     public static boolean getBooleanAttrNS(Element elem,
218                                            String nsuri,
219                                            String localName )
220             throws TogaXmlException{
221         String value = getStringAttrNS(elem, nsuri, localName);
222
223         boolean result;
224         try{
225             result = DatatypeIo.parseBoolean(value);
226         }catch(IllegalArgumentException e){
227             String message = MessageFormat.format(ERRMSG_INVATTR,
228                                                   localName,
229                                                   value );
230             throw new TogaXmlException(message, e);
231         }
232
233         return result;
234     }
235
236     /**
237      * 要素からxsd:integer型属性値を読み取る。
238      * @param elem 要素
239      * @param nsuri 名前空間URI
240      * @param localName 属性名
241      * @return int値
242      * @throws TogaXmlException 属性値が見つからなかった。
243      */
244     public static int getIntegerAttrNS(Element elem,
245                                        String nsuri,
246                                        String localName )
247             throws TogaXmlException{
248         String value = getStringAttrNS(elem, nsuri, localName);
249
250         int result;
251         try{
252             result = DatatypeIo.parseInt(value);
253         }catch(NumberFormatException e){
254             String message = MessageFormat.format(ERRMSG_INVATTR,
255                                                   localName,
256                                                   value );
257             throw new TogaXmlException(message, e);
258         }
259
260         return result;
261     }
262
263     /**
264      * 要素からxsd:float型属性値を読み取る。
265      * @param elem 要素
266      * @param nsuri 名前空間URI
267      * @param localName 属性名
268      * @return float値
269      * @throws TogaXmlException 属性値が見つからなかった。
270      */
271     public static float getFloatAttrNS(Element elem,
272                                        String nsuri,
273                                        String localName )
274             throws TogaXmlException{
275         String value = getStringAttrNS(elem, nsuri, localName);
276
277         float result;
278         try{
279             result = DatatypeIo.parseFloat(value);
280         }catch(NumberFormatException e){
281             String message = MessageFormat.format(ERRMSG_INVATTR,
282                                                   localName,
283                                                   value );
284             throw new TogaXmlException(message, e);
285         }
286
287         return result;
288     }
289
290 }