OSDN Git Service

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