OSDN Git Service

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