OSDN Git Service

* If automatic tagging is not used, value parameter of @ASN1Alternative for CHICE...
[bm-asn1/bm-asn1.git] / jp / bitmeister / asn1 / codec / xer / XerDecoder.java
1 /*
2  * Copyright 2011-2012 BitMeister Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package jp.bitmeister.asn1.codec.xer;
17
18 import static jp.bitmeister.asn1.codec.xer.XerConstants.BOOLEAN_FALSE;
19 import static jp.bitmeister.asn1.codec.xer.XerConstants.BOOLEAN_TRUE;
20 import static jp.bitmeister.asn1.codec.xer.XerConstants.REAL_MINUS_INFINITY;
21 import static jp.bitmeister.asn1.codec.xer.XerConstants.REAL_NAN;
22 import static jp.bitmeister.asn1.codec.xer.XerConstants.REAL_PLUS_INFINITY;
23
24 import java.io.InputStream;
25 import java.math.BigInteger;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import jp.bitmeister.asn1.codec.ASN1Decoder;
30 import jp.bitmeister.asn1.exception.ASN1DecodingException;
31 import jp.bitmeister.asn1.processor.ASN1Visitor;
32 import jp.bitmeister.asn1.type.ASN1Module;
33 import jp.bitmeister.asn1.type.ASN1ModuleManager;
34 import jp.bitmeister.asn1.type.ASN1Type;
35 import jp.bitmeister.asn1.type.CollectionType;
36 import jp.bitmeister.asn1.type.NamedTypeSpecification;
37 import jp.bitmeister.asn1.type.StringType;
38 import jp.bitmeister.asn1.type.StructuredType;
39 import jp.bitmeister.asn1.type.TimeType;
40 import jp.bitmeister.asn1.type.UnknownType;
41 import jp.bitmeister.asn1.type.builtin.ANY;
42 import jp.bitmeister.asn1.type.builtin.BIT_STRING;
43 import jp.bitmeister.asn1.type.builtin.BOOLEAN;
44 import jp.bitmeister.asn1.type.builtin.CHOICE;
45 import jp.bitmeister.asn1.type.builtin.ENUMERATED;
46 import jp.bitmeister.asn1.type.builtin.INTEGER;
47 import jp.bitmeister.asn1.type.builtin.NULL;
48 import jp.bitmeister.asn1.type.builtin.OBJECT_IDENTIFIER;
49 import jp.bitmeister.asn1.type.builtin.OCTET_STRING;
50 import jp.bitmeister.asn1.type.builtin.REAL;
51 import jp.bitmeister.asn1.type.builtin.RELATIVE_OID;
52 import jp.bitmeister.asn1.type.builtin.SEQUENCE;
53 import jp.bitmeister.asn1.type.builtin.SEQUENCE_OF;
54 import jp.bitmeister.asn1.type.builtin.SET;
55 import jp.bitmeister.asn1.type.builtin.SET_OF;
56 import jp.bitmeister.asn1.value.BinString;
57 import jp.bitmeister.asn1.value.HexString;
58
59 import org.xml.sax.Attributes;
60 import org.xml.sax.InputSource;
61 import org.xml.sax.SAXException;
62 import org.xml.sax.XMLReader;
63 import org.xml.sax.helpers.DefaultHandler;
64 import org.xml.sax.helpers.XMLReaderFactory;
65
66 /**
67  * XER (XML Encoding Rules) decoder.
68  * 
69  * <p>
70  * {@code XerDecoder} is an implementation of {@code ASN1Decoder}. It reads a
71  * number of bytes from an {@code InputStream} that is specified when a decoder
72  * is instantiated, and decodes them to an ASN.1 data using XML Encoding Rules
73  * (XER).
74  * </p>
75  * 
76  * @author WATANABE, Jun. <jwat at bitmeister.jp>
77  * 
78  * @see ASN1Decoder
79  * @see XerEncoder
80  */
81 public class XerDecoder implements ASN1Decoder,
82                 ASN1Visitor<XerDecoder.DataDecoder, SAXException> {
83
84         /**
85          * Abstract handler class used for decoding an XML element to an ASN.1 data.
86          * 
87          * @author WATANABE, Jun. <jwat at bitmeister.jp>
88          */
89         abstract class DataDecoder {
90
91                 /**
92                  * Callback method that is called when the data element started.
93                  */
94                 void startElement(String qName) throws SAXException {
95                 }
96
97                 /**
98                  * Callback method that is called when a child element started.
99                  * 
100                  * @param qName
101                  *            The element name.
102                  * @throws SAXException
103                  *             Thrown when an error occurred while the process.
104                  */
105                 void startChildElement(String qName) throws SAXException {
106                 }
107
108                 /**
109                  * Callback method that is called when a character sequence detected in
110                  * the XML element.
111                  * 
112                  * @param characters
113                  *            The character sequence.
114                  */
115                 void characters(String characters) {
116                 }
117
118                 /**
119                  * Callback method that is called when a child element ended.
120                  * 
121                  * @param qName
122                  *            The element name.
123                  * @throws SAXException
124                  *             Thrown when an error occurred while the process.
125                  */
126                 void endChildElement(String qName) {
127                 }
128
129                 /**
130                  * Callback method that is called when the data element ended.
131                  */
132                 void endElement() {
133                 }
134
135         }
136
137         /**
138          * Handler class for constructed data ({@code CollectionType} and
139          * {@code StructuredType}).
140          * 
141          * @author WATANABE, Jun. <jwat at bitmeister.jp>
142          */
143         private abstract class ConstructedDataDecoder extends DataDecoder {
144
145                 ElementDecoder decoder;
146
147                 /*
148                  * (non-Javadoc)
149                  * 
150                  * @see
151                  * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters(java
152                  * .lang.String)
153                  */
154                 @Override
155                 void characters(String characters) {
156                         if (decoder != null) {
157                                 decoder.characters(characters);
158                         }
159                 }
160
161         }
162
163         /**
164          * Abstract handler class used for decoding a sequence of XML elements to an
165          * ASN.1 type data.
166          * 
167          * @author WATANABE, Jun. <jwat at bitmeister.jp>
168          */
169         private abstract class ElementDecoder {
170
171                 DataDecoder decoder;
172
173                 /**
174                  * Instantiate an {@code ElementDecoder}.
175                  * 
176                  * @param decoder
177                  *            The {@code DataDecoder} used for decode the data.
178                  */
179                 ElementDecoder(DataDecoder decoder) {
180                         this.decoder = decoder;
181                 }
182
183                 /**
184                  * Callback method that is called when an XML element started.
185                  * 
186                  * @param qName
187                  *            The tag name of the element.
188                  * @throws SAXException
189                  *             Thrown when an error occurred while the process.
190                  */
191                 abstract void startElement(String qName) throws SAXException;
192
193                 /**
194                  * Callback method that is called when a character sequence detected in
195                  * an XML element.
196                  * 
197                  * @param characters
198                  *            The character sequence.
199                  */
200                 void characters(String characters) {
201                         decoder.characters(characters);
202                 }
203
204                 /**
205                  * Callback method that is called when an XML element ended.
206                  * 
207                  * @param qName
208                  *            The tag name of the element.
209                  * @return {@code true} when the element is enclosing element.
210                  */
211                 abstract boolean endElement(String qName);
212
213         }
214
215         /**
216          * Handler class used for decoding a sequence of data elements that enclosed
217          * by an element.
218          * 
219          * @author WATANABE, Jun. <jwat at bitmeister.jp>
220          */
221         private class NamedElementDecoder extends ElementDecoder {
222
223                 private String tagName;
224
225                 /**
226                  * Instantiate a {@code NamedElementDecoder}.
227                  * 
228                  * @param tagName
229                  *            The tag name of enclosing element.
230                  * @param decoder
231                  *            The {@code DataDecoder} used for decoding data elements.
232                  */
233                 NamedElementDecoder(String tagName, DataDecoder decoder) {
234                         super(decoder);
235                         this.tagName = tagName;
236                 }
237
238                 /*
239                  * (non-Javadoc)
240                  * 
241                  * @see
242                  * jp.bitmeister.asn1.codec.xer.XerDecoder.ElementDecoder#startElement
243                  * (java.lang.String)
244                  */
245                 public void startElement(String qName) throws SAXException {
246                         if (qName.equals(tagName)) {
247                                 decoder.startElement(qName);
248                         } else {
249                                 decoder.startChildElement(qName);
250                         }
251                 }
252
253                 /*
254                  * (non-Javadoc)
255                  * 
256                  * @see
257                  * jp.bitmeister.asn1.codec.xer.XerDecoder.ElementDecoder#endElement
258                  * (java.lang.String)
259                  */
260                 public boolean endElement(String qName) {
261                         if (qName.equals(tagName)) {
262                                 decoder.endElement();
263                                 return true;
264                         } else {
265                                 decoder.endChildElement(qName);
266                                 return false;
267                         }
268                 }
269
270         }
271
272         /**
273          * Handler class used for decoding an data element that is not enclosed by
274          * element.
275          * 
276          * @author WATANABE, Jun. <jwat at bitmeister.jp>
277          */
278         private class ValueListElementDecoder extends ElementDecoder {
279
280                 /**
281                  * Instantiate a {@code ValueListElementDecoder}.
282                  * 
283                  * @param decoder
284                  *            The {@code DataDecoder} used for decoding the data
285                  *            element.
286                  */
287                 ValueListElementDecoder(DataDecoder decoder) {
288                         super(decoder);
289                 }
290
291                 /*
292                  * (non-Javadoc)
293                  * 
294                  * @see
295                  * jp.bitmeister.asn1.codec.xer.XerDecoder.ElementDecoder#startElement
296                  * (java.lang.String)
297                  */
298                 public void startElement(String qName) throws SAXException {
299                         decoder.startElement(qName);
300                         decoder.startChildElement(qName);
301                 }
302
303                 /*
304                  * (non-Javadoc)
305                  * 
306                  * @see
307                  * jp.bitmeister.asn1.codec.xer.XerDecoder.ElementDecoder#endElement
308                  * (java.lang.String)
309                  */
310                 public boolean endElement(String qName) {
311                         decoder.endChildElement(qName);
312                         decoder.endElement();
313                         return true;
314                 }
315
316         }
317
318         /**
319          * Abstract handler class used for decosing an XML document to an ASN.1
320          * data.
321          * 
322          * @author WATANABE, Jun. <jwat at bitmeister.jp>
323          */
324         private abstract class XerHandler<T extends ASN1Type> extends
325                         DefaultHandler {
326
327                 T data;
328
329                 private ElementDecoder decoder;
330
331                 /**
332                  * Instantiates an ASN.1 data and sets it to this instance.
333                  * 
334                  * @param qName
335                  *            The tag name of the head element of the XML document.
336                  * @throws SAXException
337                  *             Thrown when an error occurred while the process.
338                  */
339                 abstract void initializeData(String qName) throws SAXException;
340
341                 /*
342                  * (non-Javadoc)
343                  * 
344                  * @see
345                  * org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
346                  * java.lang.String, java.lang.String, org.xml.sax.Attributes)
347                  */
348                 @Override
349                 public void startElement(String uri, String localName, String qName,
350                                 Attributes attributes) throws SAXException {
351                         if (data == null) {
352                                 initializeData(qName);
353                                 decoder = new NamedElementDecoder(qName,
354                                                 data.accept(XerDecoder.this));
355                         }
356                         decoder.startElement(qName);
357                 }
358
359                 /*
360                  * (non-Javadoc)
361                  * 
362                  * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
363                  */
364                 @Override
365                 public void characters(char[] ch, int start, int length) {
366                         char[] tmp = new char[length];
367                         System.arraycopy(ch, start, tmp, 0, length);
368                         decoder.characters(String.valueOf(tmp));
369                 }
370
371                 /*
372                  * (non-Javadoc)
373                  * 
374                  * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
375                  * java.lang.String, java.lang.String)
376                  */
377                 @Override
378                 public void endElement(String uri, String localName, String qName) {
379                         decoder.endElement(qName);
380                 }
381
382         }
383         
384         private Class<? extends ASN1Module> module;
385
386         private InputStream in;
387
388         private XMLReader reader;
389
390         /**
391          * Instantiates a {@code XerDecoder}.
392          * 
393          * @param in
394          *            The {@code InputStream} to be read.
395          */
396         public XerDecoder(InputStream in) {
397                 this.in = in;
398         }
399
400         /**
401          * Instantiates a {@code XerDecoder}.
402          * 
403          * @param in
404          *            The {@code InputStream} to be read.
405          */
406         public XerDecoder(Class<? extends ASN1Module> module, InputStream in) {
407                 this(in);
408                 this.module = module;
409         }
410         
411         /*
412          * (non-Javadoc)
413          * 
414          * @see jp.bitmeister.asn1.codec.ASN1Decoder#decode(java.lang.Class)
415          */
416         public <T extends ASN1Type> T decode(final Class<T> type)
417                         throws ASN1DecodingException {
418                 XerHandler<T> handler = new XerHandler<T>() {
419
420                         /*
421                          * (non-Javadoc)
422                          * 
423                          * @see
424                          * jp.bitmeister.asn1.codec.xer.XerDecoder.XerHandler#initializeData
425                          * (java.lang.String)
426                          */
427                         void initializeData(String qName) throws SAXException {
428                                 data = ASN1Type.instantiate(type);
429                                 if (module == null) {
430                                         module = data.specification().module();
431                                 }
432                                 if (!(data instanceof ANY)
433                                                 && !qName.equals(data.specification().xmlTypeName(module))) {
434                                         throw new SAXException("Unexpected xml tag name '" + qName
435                                                         + "'. '" + data.specification().xmlTypeName(module)
436                                                         + "' is expected.");
437                                 }
438                         }
439
440                 };
441                 parse(handler);
442                 return handler.data;
443         }
444
445         /*
446          * (non-Javadoc)
447          * 
448          * @see jp.bitmeister.asn1.codec.ASN1Decoder#decode()
449          */
450         public ASN1Type decode() throws ASN1DecodingException {
451                 XerHandler<ASN1Type> handler = new XerHandler<ASN1Type>() {
452
453                         /*
454                          * (non-Javadoc)
455                          * 
456                          * @see
457                          * jp.bitmeister.asn1.codec.xer.XerDecoder.XerHandler#initializeData
458                          * (java.lang.String)
459                          */
460                         void initializeData(String qName) throws SAXException {
461                                 data = ASN1ModuleManager.instantiate(module, qName);
462                                 if (data == null) {
463                                         throw new SAXException("Unknown data type '" + qName + "'.");
464                                 }
465                         }
466
467                 };
468                 parse(handler);
469                 return handler.data;
470         }
471
472         /**
473          * Decodes the source XML data read from the {@code InputStream} to the
474          * ASN.1 data.
475          * 
476          * @throws ASN1DecodingException
477          *             When an error occurred while the decoding process.
478          */
479         private void parse(XerHandler<?> handler) throws ASN1DecodingException {
480                 try {
481                         reader = XMLReaderFactory.createXMLReader();
482                         reader.setContentHandler(handler);
483                         reader.parse(new InputSource(in));
484                 } catch (Exception e) {
485                         ASN1DecodingException ex = new ASN1DecodingException();
486                         ex.setMessage("An exception thrown while decoding process.", e,
487                                         null, null, null);
488                         throw ex;
489                 }
490         }
491
492         /*
493          * (non-Javadoc)
494          * 
495          * @see
496          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
497          * .builtin.BOOLEAN)
498          */
499         public DataDecoder visit(final BOOLEAN data) {
500                 return new DataDecoder() {
501
502                         /*
503                          * (non-Javadoc)
504                          * 
505                          * @see
506                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
507                          * (java.lang.String)
508                          */
509                         @Override
510                         void startChildElement(String qName) {
511                                 if (qName.equals(BOOLEAN_TRUE)) {
512                                         data.set(true);
513                                 } else if (qName.equals(BOOLEAN_FALSE)) {
514                                         data.set(false);
515                                 }
516                         }
517
518                 };
519         }
520
521         /*
522          * (non-Javadoc)
523          * 
524          * @see
525          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
526          * .builtin.INTEGER)
527          */
528         public DataDecoder visit(final INTEGER data) {
529                 return new DataDecoder() {
530
531                         /*
532                          * (non-Javadoc)
533                          * 
534                          * @see
535                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
536                          * (java.lang.String)
537                          */
538                         @Override
539                         void startChildElement(String qName) {
540                                 data.set(qName);
541                         }
542
543                         /*
544                          * (non-Javadoc)
545                          * 
546                          * @see
547                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
548                          * (java.lang.String)
549                          */
550                         @Override
551                         public void characters(String characters) {
552                                 data.set(new BigInteger(characters));
553                         }
554
555                 };
556         }
557
558         /*
559          * (non-Javadoc)
560          * 
561          * @see
562          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
563          * .builtin.BIT_STRING)
564          */
565         public DataDecoder visit(final BIT_STRING data) {
566                 return new DataDecoder() {
567
568                         /*
569                          * (non-Javadoc)
570                          * 
571                          * @see
572                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
573                          * (java.lang.String)
574                          */
575                         @Override
576                         public void startChildElement(String qName) {
577                                 data.set(qName);
578                         }
579
580                         /*
581                          * (non-Javadoc)
582                          * 
583                          * @see
584                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
585                          * (java.lang.String)
586                          */
587                         @Override
588                         public void characters(String characters) {
589                                 data.set(new BinString(characters));
590                         }
591
592                 };
593         }
594
595         /*
596          * (non-Javadoc)
597          * 
598          * @see
599          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
600          * .builtin.OCTET_STRING)
601          */
602         public DataDecoder visit(final OCTET_STRING data) {
603                 return new DataDecoder() {
604
605                         /*
606                          * (non-Javadoc)
607                          * 
608                          * @see
609                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
610                          * (java.lang.String)
611                          */
612                         @Override
613                         public void characters(String characters) {
614                                 data.set(new HexString(characters));
615                         }
616
617                 };
618         }
619
620         /*
621          * (non-Javadoc)
622          * 
623          * @see
624          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
625          * .builtin.NULL)
626          */
627         public DataDecoder visit(NULL data) {
628                 return new DataDecoder() {
629                 };
630         }
631
632         /*
633          * (non-Javadoc)
634          * 
635          * @see
636          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
637          * .builtin.OBJECT_IDENTIFIER)
638          */
639         public DataDecoder visit(final OBJECT_IDENTIFIER data) {
640                 return new DataDecoder() {
641
642                         /*
643                          * (non-Javadoc)
644                          * 
645                          * @see
646                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
647                          * (java.lang.String)
648                          */
649                         @Override
650                         public void characters(String characters) {
651                                 List<Integer> oids = new ArrayList<Integer>();
652                                 for (String e : characters.split("\\.")) {
653                                         e.trim();
654                                         if (Character.isLetter(e.charAt(0))) {
655                                                 if (!e.endsWith(")")) {
656                                                         oids.add(OBJECT_IDENTIFIER.nameFormToInt(oids, e));
657                                                         continue;
658                                                 }
659                                                 e = e.substring(e.indexOf('(') + 1, e.indexOf(')'));
660                                         }
661                                         oids.add(Integer.parseInt(e));
662                                 }
663                                 data.set(oids);
664                         }
665
666                 };
667         }
668
669         /*
670          * (non-Javadoc)
671          * 
672          * @see
673          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
674          * .builtin.REAL)
675          */
676         public DataDecoder visit(final REAL data) {
677                 return new DataDecoder() {
678
679                         /*
680                          * (non-Javadoc)
681                          * 
682                          * @see
683                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
684                          * (java.lang.String)
685                          */
686                         @Override
687                         public void startChildElement(String qName) {
688                                 if (qName.equals(REAL_PLUS_INFINITY)) {
689                                         data.set(Double.POSITIVE_INFINITY);
690                                 } else if (qName.equals(REAL_MINUS_INFINITY)) {
691                                         data.set(Double.NEGATIVE_INFINITY);
692                                 } else if (qName.equals(REAL_NAN)) {
693                                         data.set(Double.NaN);
694                                 }
695                         }
696
697                         /*
698                          * (non-Javadoc)
699                          * 
700                          * @see
701                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
702                          * (java.lang.String)
703                          */
704                         @Override
705                         public void characters(String characters) {
706                                 data.set(Double.parseDouble(characters));
707                         }
708
709                 };
710         }
711
712         /*
713          * (non-Javadoc)
714          * 
715          * @see
716          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
717          * .builtin.ENUMERATED)
718          */
719         public DataDecoder visit(ENUMERATED data) {
720                 return visit((INTEGER) data);
721         }
722
723         /*
724          * (non-Javadoc)
725          * 
726          * @see
727          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
728          * .builtin.RELATIVE_OID)
729          */
730         public DataDecoder visit(RELATIVE_OID data) {
731                 return visit((OBJECT_IDENTIFIER) data);
732         }
733
734         /*
735          * (non-Javadoc)
736          * 
737          * @see
738          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
739          * .builtin.ANY)
740          */
741         public DataDecoder visit(final ANY data) {
742                 return new DataDecoder() {
743
744                         private DataDecoder decoder;
745
746                         @Override
747                         void startElement(String qName) throws SAXException {
748                                 data.set(ASN1ModuleManager.instantiate(module, qName));
749                                 decoder = data.value().accept(XerDecoder.this);
750                                 decoder.startElement(qName);
751                         }
752
753                         @Override
754                         void startChildElement(String qName) throws SAXException {
755                                 decoder.startChildElement(qName);
756                         }
757
758                         @Override
759                         void characters(String characters) {
760                                 decoder.characters(characters);
761                         }
762
763                         @Override
764                         void endChildElement(String qName) {
765                                 decoder.endChildElement(qName);
766                         }
767
768                         @Override
769                         void endElement() {
770                                 decoder.endElement();
771                         }
772
773                 };
774         }
775
776         /*
777          * (non-Javadoc)
778          * 
779          * @see
780          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
781          * .builtin.CHOICE)
782          */
783         public DataDecoder visit(CHOICE data) {
784                 return decoderForStructuredType(data);
785         }
786
787         /*
788          * (non-Javadoc)
789          * 
790          * @see
791          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
792          * .builtin.SEQUENCE_OF)
793          */
794         public DataDecoder visit(SEQUENCE_OF<? extends ASN1Type> data) {
795                 return decoderForCollectionType(data);
796         }
797
798         /*
799          * (non-Javadoc)
800          * 
801          * @see
802          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
803          * .builtin.SEQUENCE)
804          */
805         public DataDecoder visit(SEQUENCE data) {
806                 return decoderForStructuredType(data);
807         }
808
809         /*
810          * (non-Javadoc)
811          * 
812          * @see
813          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
814          * .builtin.SET_OF)
815          */
816         public DataDecoder visit(SET_OF<? extends ASN1Type> data) {
817                 return decoderForCollectionType(data);
818         }
819
820         /*
821          * (non-Javadoc)
822          * 
823          * @see
824          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
825          * .builtin.SET)
826          */
827         public DataDecoder visit(SET data) {
828                 return decoderForStructuredType(data);
829         }
830
831         /*
832          * (non-Javadoc)
833          * 
834          * @see
835          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
836          * .StringType)
837          */
838         public DataDecoder visit(final StringType data) {
839                 return new DataDecoder() {
840
841                         private StringBuilder builder = new StringBuilder();
842
843                         /*
844                          * (non-Javadoc)
845                          * 
846                          * @see
847                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
848                          * (java.lang.String)
849                          */
850                         @Override
851                         public void startChildElement(String qName) {
852                                 builder.append(XerStringEscapeUtil.unescapeCtrl(qName));
853                         }
854
855                         /*
856                          * (non-Javadoc)
857                          * 
858                          * @see
859                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#characters
860                          * (java.lang.String)
861                          */
862                         @Override
863                         public void characters(String characters) {
864                                 builder.append(characters);
865                         }
866
867                         /*
868                          * (non-Javadoc)
869                          * 
870                          * @see
871                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#endElement()
872                          */
873                         @Override
874                         void endElement() {
875                                 if (builder.length() > 0) {
876                                         data.set(builder.toString());
877                                 }
878                         }
879
880                 };
881         }
882
883         /*
884          * (non-Javadoc)
885          * 
886          * @see
887          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
888          * .TimeType)
889          */
890         public DataDecoder visit(TimeType data) {
891                 return visit((StringType) data);
892         }
893
894         /*
895          * (non-Javadoc)
896          * 
897          * @see
898          * jp.bitmeister.asn1.processor.ASN1Visitor#visit(jp.bitmeister.asn1.type
899          * .UnknownType)
900          */
901         public DataDecoder visit(UnknownType data) throws SAXException {
902                 throw new SAXException("UnkownType is not supported by XerDecoder.");
903         }
904
905         /**
906          * Returns handler for the {@code StructuredType}.
907          * 
908          * @param data
909          *            The {@code StructuredType} data.
910          * @return Handler for the data.
911          */
912         private DataDecoder decoderForStructuredType(final StructuredType data) {
913                 return new ConstructedDataDecoder() {
914
915                         private NamedTypeSpecification namedType;
916
917                         private ASN1Type element;
918
919                         /*
920                          * (non-Javadoc)
921                          * 
922                          * @see
923                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
924                          * (java.lang.String)
925                          */
926                         @Override
927                         void startChildElement(String qName) throws SAXException {
928                                 if (decoder == null) {
929                                         namedType = data.getElement(qName);
930                                         element = namedType.instantiate();
931                                         decoder = new NamedElementDecoder(qName,
932                                                         element.accept(XerDecoder.this));
933                                 }
934                                 decoder.startElement(qName);
935                         }
936
937                         /*
938                          * (non-Javadoc)
939                          * 
940                          * @see
941                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#endChildElement
942                          * (java.lang.String)
943                          */
944                         @Override
945                         void endChildElement(String qName) {
946                                 if (decoder.endElement(qName)) {
947                                         data.set(namedType, element);
948                                         decoder = null;
949                                 }
950                         }
951
952                 };
953         }
954
955         /**
956          * Returns handler for the {@code CollectionType}.
957          * 
958          * @param data
959          *            The {@code CollectionType} data.
960          * @return Handler for the data.
961          */
962         private <T extends ASN1Type> DataDecoder decoderForCollectionType(
963                         final CollectionType<T, ?> data) {
964                 return new ConstructedDataDecoder() {
965
966                         private T component;
967
968                         private boolean useXmlValueList = false;
969
970                         /*
971                          * (non-Javadoc)
972                          * 
973                          * @see
974                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startElement
975                          * ()
976                          */
977                         @Override
978                         void startElement(String qName) {
979                                 if (BOOLEAN.class.isAssignableFrom(data.componentType())
980                                                 || ENUMERATED.class.isAssignableFrom(data.componentType())
981                                                 || CHOICE.class.isAssignableFrom(data.componentType())) {
982                                         useXmlValueList = true;
983                                 }
984                         }
985
986                         /*
987                          * (non-Javadoc)
988                          * 
989                          * @see
990                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#startChildElement
991                          * (java.lang.String)
992                          */
993                         @Override
994                         void startChildElement(String qName) throws SAXException {
995                                 if (decoder == null) {
996                                         component = ASN1Type.instantiate(data.componentType());
997                                         if (useXmlValueList) {
998                                                 decoder = new ValueListElementDecoder(
999                                                                 component.accept(XerDecoder.this));
1000                                         } else {
1001                                                 decoder = new NamedElementDecoder(qName,
1002                                                                 component.accept(XerDecoder.this));
1003                                         }
1004                                 }
1005                                 decoder.startElement(qName);
1006                         }
1007
1008                         /*
1009                          * (non-Javadoc)
1010                          * 
1011                          * @see
1012                          * jp.bitmeister.asn1.codec.xer.XerDecoder.DataDecoder#endChildElement
1013                          * (java.lang.String)
1014                          */
1015                         @Override
1016                         void endChildElement(String qName) {
1017                                 if (decoder.endElement(qName)) {
1018                                         data.collection().add(component);
1019                                         decoder = null;
1020                                 }
1021                         }
1022
1023                 };
1024         }
1025
1026 }