OSDN Git Service

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