O dispositivo de parsing está implementado simplesmente como um par de interfaces: os dispositivos efetivos deverão implementar a interface EnvelopeParser. Em vista da complexidade da árvore de objetos, imaginamos delegar a responsabilidade de efetuar o parsing de cada um deles por helpers que implementem a interface genérica ParsingHelper. A pobreza do design é devida também às radicais diferenças entre as duas implementações planejadas: CMS e XMLDSig, que têm em comum somente a semântica dos diversos componentes de cada envelope. A próxima seção ilustra o graphos de chamada do parser implementado.
Um exemplo de utilização pode ser visto a seguir. Observe-se que a implementação CMSParser capta todas as exceções disparadas por seus componentes, incluindo o BouncyCastle e as relança como uma ParserException ou uma de suas especializações. Desse modo, é aconselhável a obtenção sempre da causa da exceção com getCause().
public class TestCMSParser { public static void listSignedFile(String file) { TestCMSParser testCase = new TestCMSParser(); testCase.registerComponents(); FileInputStream in; try { in = new FileInputStream(file); try { ContentInfo envelope = testCase.parseEnvelope(in); testCase.doSomething(envelope); } finally { in.close(); } } catch (RuntimeException e) { System.out.println("Parse error:"); e.printStackTrace(); e.getCause().printStackTrace(); } catch (IOException e) { System.out.println("I/O error:"); e.printStackTrace(); } } public static void createNewSignedFile(String file) { TestCMSParser testCase = new TestCMSParser(); testCase.registerComponents(); FileInputStream in; try { in = new FileInputStream(file); try { ContentInfo envelope = testCase.parseEnvelope(in); FileOutputStream out = new FileOutputStream(file + ".p7s"); try { testCase.buildEnvelope(envelope, out); } finally { out.close(); } } finally { in.close(); } } catch (RuntimeException e) { System.out.println("Parse error:"); e.printStackTrace(); e.getCause().printStackTrace(); } catch (IOException e) { System.out.println("I/O error:"); e.printStackTrace(); } } public void buildEnvelope(ContentInfo envelope, OutputStream out) { EnvelopeParser parser = AbstractParser.getInstance(); parser.buildEnvelope(envelope, out); } public void registerComponents() { AbstractParser.register("CMS", new CMSParser()); AbstractParser.setDefaultImplementation("CMS"); } public ContentInfo parseEnvelope(InputStream in) { EnvelopeParser parser = AbstractParser.getInstance(); return parser.parseEnvelope(in); } public void doSomething(ContentInfo envelope) { System.out.println("Envelope content type: " + envelope.getContentType()); SignedData signedData = (SignedData) envelope.getContent(); System.out.println("Version: " + signedData.getVersion()); System.out.println("Encapsulated content info type: " + signedData.getEncapContentInfo().getContentType()); Iteratorcerts = signedData.getCertificates().iterator(); System.out.println("Included certificates:"); while (certs.hasNext()) System.out.println("Subject: " + certs.next().getSubjectX500Principal().getName()); Iterator crls = signedData.getCrls().iterator(); System.out.println("Included CRLs:"); while (crls.hasNext()) System.out.println("Issuer: " + crls.next().getIssuerX500Principal().getName()); Iterator signers = signedData.getSignerInfos().iterator(); System.out.println("Document signers:"); while (signers.hasNext()) { SignerInfo signer = signers.next(); System.out.println("Version: " + signer.getVersion()); System.out.println("Signer identifier: " + signer.getSid().toString()); System.out.println("Digest algorithm: " + signer.getDigestAlgorithm().getAlgorithm()); System.out.println("Signature algorithm: " + signer.getSignatureAlgorithm().getAlgorithm()); System.out.println("Signed attributes:"); Iterator attributes = signer.getSignedAttrs().iterator(); while (attributes.hasNext()) System.out.println("OID: " + attributes.next().getAttrType()); System.out.println("Unsigned attributes: "); attributes = signer.getUnsignedAttrs().iterator(); while (attributes.hasNext()) System.out.println("OID: " + attributes.next().getAttrType()); } } }