ee.sk.digidoc.tsl.TslParser Maven / Gradle / Ivy
/*
* TslParser.java
* ETSI TS 102 231 V3.1.1. TSL xml format parser
* AUTHOR: Veiko Sinivee, Sunset Software OÜ
*==================================================
* Copyright (C) AS Sertifitseerimiskeskus
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* GNU Lesser General Public Licence is available at
* http://www.gnu.org/copyleft/lesser.html
*==================================================
*/
package ee.sk.digidoc.tsl;
import ee.sk.digidoc.*;
import ee.sk.digidoc.factory.SAXDigiDocException;
import ee.sk.utils.ConvertUtils;
import java.io.InputStream;
import java.io.IOException;
import java.util.Stack;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import java.security.cert.X509Certificate;
import org.apache.log4j.Logger;
/**
* ETSI TS 102 231 V3.1.1. TSL xml format parser
* @author Veiko Sinivee
* @version 1.0
*/
public class TslParser extends DefaultHandler
{
/** log4j logger */
private static Logger m_logger = Logger.getLogger(TslParser.class);
private Stack m_tags;
private TrustServiceStatusList m_tsl;
private StringBuffer m_sbCollectItem;
private SchemeInformation m_si;
private TrustServiceProvider m_tsp;
private MultiLangString m_mls;
private PostalAddress m_adr;
private TSPService m_tsps;
private Quality m_qual;
/**
* Reads in a TSL file
* @param is opened stream with TSL data
* The user must open and close it.
* @return TSL
*/
public TrustServiceStatusList readTSL(InputStream is)
throws DigiDocException
{
// Use an instance of ourselves as the SAX event handler
TslParser handler = this;
// Use the default (non-validating) parser
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(is, handler);
} catch (SAXDigiDocException ex) {
throw ex.getDigiDocException();
} catch (Exception ex) {
DigiDocException.handleException(ex, DigiDocException.ERR_PARSE_XML);
}
if (m_tsl == null)
throw new DigiDocException(DigiDocException.ERR_DIGIDOC_FORMAT,
"This document is not in TSL format", null);
return m_tsl;
}
/**
* Start Document handler
*/
public void startDocument() throws SAXException {
m_tags = new Stack();
m_tsl = null;
m_sbCollectItem = null;
m_si = null;
m_tsp = null;
m_mls = null;
m_adr = null;
m_tsps = null;
m_qual = null;
}
/**
* End Document handler
*/
public void endDocument() throws SAXException {
}
private String getAttrValue(Attributes attrs, String key)
{
for(int i = 0; i < attrs.getLength(); i++) {
String key2 = attrs.getQName(i);
if(m_logger.isDebugEnabled())
m_logger.debug("Attr: " + key2 + " value: " + attrs.getValue(i));
//System.out.println("Attr: " + key2 + " value: " + attrs.getValue(i));
if(key2.indexOf(key) != -1)
return attrs.getValue(i);
}
return null;
}
private boolean findTagOnStack(String tag)
{
java.util.Enumeration eTags = m_tags.elements();
while(eTags.hasMoreElements()) {
String t2 = (String)eTags.nextElement();
if(t2.equals(tag))
return true;
}
return false;
}
/**
* Start Element handler
* @param namespaceURI namespace URI
* @param lName local name
* @param qName qualified name
* @param attrs attributes
*/
public void startElement(String namespaceURI, String lName, String qName, Attributes attrs)
throws SAXDigiDocException
{
//if(m_logger.isDebugEnabled())
// m_logger.debug("Start Element: " + qName + " lname: " + lName + " uri: " + namespaceURI);
String tag = qName;
if(tag.indexOf(':') != -1) {
tag = qName.substring(qName.indexOf(':') + 1);
}
m_tags.push(tag);
m_sbCollectItem = new StringBuffer();
//
if(tag.equals("TrustServiceStatusList"))
m_tsl = new TrustServiceStatusList();
//
if(tag.equals("SchemeInformation")) {
m_si = new SchemeInformation();
if(m_tsl != null)
m_tsl.setSchemeInformation(m_si);
}
//
if(tag.equals("PostalAddress")) {
m_adr = new PostalAddress();
if(m_si != null && findTagOnStack("SchemeOperatorAddress"))
m_si.addPostalAddress(m_adr);
if(m_tsp != null && m_tsp.getTSPInformation() != null && findTagOnStack("TSPAddress"))
m_tsp.getTSPInformation().addPostalAddress(m_adr);
}
//
if(tag.equals("URI")) {
m_mls = new MultiLangString();
m_mls.setLang(getAttrValue(attrs, "lang"));
if(m_si != null && findTagOnStack("SchemeOperatorAddress"))
m_si.addElectronicAddress(m_mls);
if(m_si != null && findTagOnStack("SchemeTypeCommunityRules"))
m_si.addSchemeTypeCommunityRule(m_mls);
if(m_si != null && findTagOnStack("DistributionPoints"))
m_si.addDistributionPoint(m_mls);
if(m_si != null && findTagOnStack("SchemeInformationURI"))
m_si.addSchemeInformationURI(m_mls);
if(m_tsp != null && m_tsp.getTSPInformation() != null && findTagOnStack("TSPAddress"))
m_tsp.getTSPInformation().addElectronicAddress(m_mls);
if(m_tsp != null && m_tsp.getTSPInformation() != null && findTagOnStack("TSPInformationURI"))
m_tsp.getTSPInformation().addInformationURI(m_mls);
if(m_tsps != null && findTagOnStack("TSPServiceDefinitionURI"))
m_tsps.addServiceDefinitionURI(m_mls);
}
//
if(tag.equals("TSLLegalNotice")) {
m_mls = new MultiLangString();
m_mls.setLang(getAttrValue(attrs, "lang"));
if(m_si != null)
m_si.addPolicyOrLegalNotice(m_mls);
}
//
if(tag.equals("Name")) {
m_mls = new MultiLangString();
m_mls.setLang(getAttrValue(attrs, "lang"));
if(m_si != null && findTagOnStack("SchemeOperatorName"))
m_si.addOperatorName(m_mls);
if(m_si != null && findTagOnStack("SchemeName"))
m_si.addSchemeName(m_mls);
if(m_tsp != null && m_tsp.getTSPInformation() != null && findTagOnStack("TSPName"))
m_tsp.getTSPInformation().addName(m_mls);
if(m_tsp != null && m_tsp.getTSPInformation() != null && findTagOnStack("TSPTradeName"))
m_tsp.getTSPInformation().addTradeName(m_mls);
if(m_tsps != null)
m_tsps.addName(m_mls);
}
//
if(tag.equals("TrustServiceProvider")) {
m_tsp = new TrustServiceProvider();
if(m_tsl != null)
m_tsl.addTrustServiceProvider(m_tsp);
}
//
if(tag.equals("TSPInformation")) {
if(m_tsp != null)
m_tsp.setTSPInformation(new TSPInformation());
}
//
if(tag.equals("TSPService")) {
m_tsps = new TSPService();
if(m_tsp != null)
m_tsp.addTSPService(m_tsps);
}
//
if(tag.equals("QualityElement")) {
m_qual = new Quality();
if(m_tsps != null)
m_tsps.addQuality(m_qual);
}
}
/**
* End Element handler
* @param namespaceURI namespace URI
* @param lName local name
* @param qName qualified name
*/
public void endElement(String namespaceURI, String sName, String qName)
throws SAXException
{
//if(m_logger.isDebugEnabled())
// m_logger.debug("End Element: " + qName);
// remove last tag from stack
String tag = qName;
String nsPref = null;
if(tag.indexOf(':') != -1) {
tag = qName.substring(qName.indexOf(':') + 1);
nsPref = qName.substring(0, qName.indexOf(':'));
}
String currTag = (String) m_tags.pop();
//
if(tag.equals("SchemeInformation"))
m_si = null;
//
if(tag.equals("TSLVersionIdentifier")) {
if(m_si != null)
m_si.setVersionIdentifier(Integer.parseInt(m_sbCollectItem.toString()));
}
//
if(tag.equals("TSLSequenceNumber")) {
if(m_si != null)
m_si.setSequenceNumber(Integer.parseInt(m_sbCollectItem.toString()));
}
//
if(tag.equals("TSLType")) {
if(m_si != null)
m_si.setType(m_sbCollectItem.toString());
}
//
if(tag.equals("Name")) {
if(m_mls != null)
m_mls.setValue(m_sbCollectItem.toString());
m_mls = null;
}
//
if(tag.equals("PostalAddress")) {
m_adr = null;
}
//
if(tag.equals("StreetAddress")) {
if(m_adr != null)
m_adr.setStreetAddress(m_sbCollectItem.toString());
}
//
if(tag.equals("Locality")) {
if(m_adr != null)
m_adr.setLocality(m_sbCollectItem.toString());
}
//
if(tag.equals("PostalCode")) {
if(m_adr != null)
m_adr.setPostalCode(m_sbCollectItem.toString());
}
//
if(tag.equals("CountryName")) {
if(m_adr != null)
m_adr.setCountryName(m_sbCollectItem.toString());
}
//
if(tag.equals("URI")) {
if(m_mls != null)
m_mls.setValue(m_sbCollectItem.toString());
m_mls = null;
}
//
if(tag.equals("TSLLegalNotice")) {
if(m_mls != null)
m_mls.setValue(m_sbCollectItem.toString());
m_mls = null;
}
//
if(tag.equals("StatusDeterminationApproach")) {
if(m_si != null)
m_si.setStatusDeterminationApproach(m_sbCollectItem.toString());
}
//
if(tag.equals("SchemeTerritory")) {
if(m_si != null)
m_si.setSchemeTerritory(m_sbCollectItem.toString());
}
//
if(tag.equals("HistoricalInformationPeriod")) {
if(m_si != null)
m_si.setHistoricalInformationPeriod(Integer.parseInt(m_sbCollectItem.toString()));
}
//
if(tag.equals("ListIssueDateTime")) {
if(m_si != null)
m_si.setListIssueDate(ConvertUtils.str2date(m_sbCollectItem.toString()));
}
//
if(tag.equals("dateTime")) {
if(m_si != null && findTagOnStack("NextUpdate"))
m_si.addNextUpdate(ConvertUtils.str2date(m_sbCollectItem.toString()));
}
//
if(tag.equals("ServiceTypeIdentifier")) {
if(m_tsps != null)
m_tsps.setType(m_sbCollectItem.toString());
}
//
if(tag.equals("X509Certificate")) {
try {
if(m_tsps != null && findTagOnStack("ServiceDigitalIdentity")) {
X509Certificate cert = SignedDoc.readCertificate(Base64Util.decode(m_sbCollectItem.toString()));
if(cert != null) {
m_tsps.addCertificate(cert);
String sDn = ConvertUtils.convX509Name(cert.getIssuerX500Principal());
String sCn = ConvertUtils.getCommonName(sDn);
if(m_logger.isDebugEnabled())
m_logger.debug("DN: " + sDn + " CN: " + sCn);
m_tsps.setCaCn(sCn);
}
}
} catch(DigiDocException ex) {
SAXDigiDocException.handleException(ex);
}
}
//
if(tag.equals("X509SubjectName")) {
if(m_tsps != null && findTagOnStack("ServiceDigitalIdentity"))
m_tsps.addSubjectName(new MultiLangString(null, m_sbCollectItem.toString()));
if(m_tsps != null && findTagOnStack("DigitalId")) {
m_tsps.addSubjectName(new MultiLangString(null, m_sbCollectItem.toString()));
String cn = ConvertUtils.getCommonName(m_sbCollectItem.toString());
if(cn != null && cn.trim().length() > 0)
m_tsps.setCn(cn);
}
}
//
if(tag.equals("ServiceStatus")) {
if(m_tsps != null)
m_tsps.setStatus(m_sbCollectItem.toString());
}
//
if(tag.equals("StatusStartingTime")) {
if(m_tsps != null)
m_tsps.setStatusStartingTime(ConvertUtils.str2date(m_sbCollectItem.toString()));
}
//
if(tag.equals("QualityName")) {
if(m_qual != null)
m_qual.setName(m_sbCollectItem.toString());
}
//
if(tag.equals("QualityValue")) {
if(m_qual != null)
m_qual.setValue(Integer.parseInt(m_sbCollectItem.toString()));
}
//
if(tag.equals("ServiceSupplyPoint")) {
if(m_tsp != null)
m_tsps.addServiceAccessPoint(m_sbCollectItem.toString());
}
//
if(tag.equals("QualityElement"))
m_qual = null;
//
if(tag.equals("TSPService"))
m_tsps = null;
//
if(tag.equals("TrustServiceProvider"))
m_tsp = null;
m_sbCollectItem = null;
}
/**
* SAX characters event handler
* @param buf received bytes array
* @param offset offset to the array
* @param len length of data
*/
public void characters(char buf[], int offset, int len)
throws SAXException
{
String s = new String(buf, offset, len);
if(s != null && m_sbCollectItem != null)
m_sbCollectItem.append(s);
}
}