package at.gv.util.client.ur_V5; import java.math.BigInteger; import java.net.URL; import java.util.ArrayList; import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Resource; import javax.net.ssl.SSLContext; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import javax.xml.ws.BindingProvider; import javax.xml.ws.WebServiceContext; import javax.xml.ws.WebServiceException; import javax.xml.ws.handler.Handler; import org.apache.commons.lang.RandomStringUtils; import org.apache.cxf.configuration.jsse.TLSClientParameters; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gv.util.xsd.ur_V5.xmlsw.ExtraResultCriteria; import at.gv.util.xsd.ur_V5.xmlsw.ResultCriteriaType; import at.gv.util.xsd.ur_V5.xmlsw.ResultRecord; import at.gv.util.xsd.ur_V5.xmlsw.SearchByExampleType; import at.gv.util.xsd.ur_V5.xmlsw.SearchCriteriaType; import at.gv.util.xsd.ur_V5.xmlsw.SearchResponseType; import at.gv.util.LaxHostNameVerifier; import at.gv.util.LoggingHandler; import at.gv.util.MiscUtil; import at.gv.util.client.szr.SZRSOAPHandler; import at.gv.util.config.EgovUtilConfiguration; import at.gv.util.ex.EgovUtilException; import at.gv.util.wsdl.ur_V5.URSuche; import at.gv.util.wsdl.ur_V5.URSucheService; import at.gv.util.wsdl.ur_V5.XmlSwFault; import at.gv.util.xsd.szr.pvp.PvpTokenType; import at.gv.util.xsd.ur_V5.pd.IdentificationType; import at.gv.util.xsd.ur_V5.pd.NichtNatuerlichePersonTyp; import at.gv.util.xsd.ur_V5.pd.PersonenDatenTyp; import at.gv.util.xsd.ur_V5.pd.PersonenDatenTyp.Zusatzdaten; import at.gv.util.xsd.ur_V5.pd.PersonenDatenZusatzdatenTyp; import at.gv.util.xsd.ur_V5.pd.ZusatzdatenPersonenTyp; import at.gv.util.xsd.ur_V5.search.BestandszeitraumVollzug; import at.gv.util.xsd.ur_V5.search.FktRegelTypVollzug; import at.gv.util.xsd.ur_V5.search.FunktionVollzug; import at.gv.util.xsd.ur_V5.search.SucheUnternehmenNachBpkRequest; import at.gv.util.xsd.ur_V5.search.SucheUnternehmenNachIdRequest; import at.gv.util.xsd.ur_V5.search.SucheUnternehmenRequest; import at.gv.util.xsd.ur_V5.search.SucheUnternehmensdaten; import at.gv.util.xsd.ur_V5.simpletypes.EvbStatusTyp; public class URClient { @Resource WebServiceContext wsContext; private EgovUtilConfiguration config = null; private Logger log = LoggerFactory.getLogger(URClient.class); private boolean logEnabled = true; private boolean evbCheck = true; private URSuche urSuche = null; private final static String version = "V5.0"; private List allowedKeys = null; private HashSet allowedERsBKeys = null; public URClient(EgovUtilConfiguration config, List allowedKeys, HashSet ersbkeys, boolean evbCheck, boolean logEnabled) throws EgovUtilException { MiscUtil.assertNotNull(config, "config"); this.config = config; this.allowedKeys = allowedKeys; this.logEnabled = logEnabled; this.evbCheck = evbCheck; this.allowedERsBKeys = ersbkeys; initialize(); } public List searchByRegisterNumberFullInfo(String number, String type, int maxResults) throws Exception { SucheUnternehmenNachIdRequest request = new SucheUnternehmenNachIdRequest(); if (type.equals("ERJ")) request.setErj(number); else if (type.equals("FBN")) request.setFbn(number); else if (type.equals("KUR")) request.setKur(number); else if (type.equals("SEK")) request.setSek(number); else if (type.equals("ZVR")) request.setZvr(number); else throw new Exception("Wrong RegisterNumber Type"); request.setMitHistorie(true); SearchCriteriaType sct = new SearchCriteriaType(); sct.setSucheUnternehmenNachIdRequest(request); List results = searchByExample(sct, -1); return getURSearchResult(results); } public List searchByBpk(String vzbpk) throws URClientException { SucheUnternehmenNachBpkRequest request = new SucheUnternehmenNachBpkRequest(); request.setVersion(version); request.setBpkWTUREncoded(vzbpk); request.setNurAktive(true); SearchCriteriaType sct = new SearchCriteriaType(); sct.setSucheUnternehmenNachBpkRequest(request); List results = searchByExample(sct, -1); return getURSearchResult(results); } public List searchByRegisterNumber(String number, String type, int maxResults) throws URClientException { SucheUnternehmenRequest request = new SucheUnternehmenRequest(); request.setVersion(version); SucheUnternehmensdaten sud = new SucheUnternehmensdaten(); sud.setId(number); sud.setIdArt(type); request.setUnternehmensdaten(sud); SearchCriteriaType sct = new SearchCriteriaType(); sct.setSucheUnternehmenRequest(request); List results = searchByExample(sct, maxResults); return getNichtNatuerlichePersonen(results); } public List searchByName(String name, String plz, int maxResults) throws URClientException { SucheUnternehmenRequest request = new SucheUnternehmenRequest(); request.setVersion(version); SucheUnternehmensdaten sud = new SucheUnternehmensdaten(); sud.setUntName(name); if (MiscUtil.isNotEmpty(plz)) { sud.setPlz(plz); } request.setUnternehmensdaten(sud); SearchCriteriaType sct = new SearchCriteriaType(); sct.setSucheUnternehmenRequest(request); List results = searchByExample(sct, maxResults); return getNichtNatuerlichePersonen(results); } private List getURSearchResult(List records) throws URClientException { if (records == null || records.size() == 0) { return new ArrayList(); } List result = new ArrayList(); log.debug("UR SOAP response with " + records.size() + "records"); for (ResultRecord rr : records) { PersonenDatenTyp pdt = rr.getPersonenDaten(); NichtNatuerlichePersonTyp nnpt = pdt.getNichtNatuerlichePerson(); Zusatzdaten zsd = pdt.getZusatzdaten(); //check validity era boolean check_valera = isInValidityEra(zsd); //check allowed keys boolean check_allowedkeys = hasAllowedKeys(nnpt.getIdentification()); //ERsB function codes List ersbcode = hasAllowedEVBCode(zsd); //check EVB boolean check_EVB = isEVB(zsd); if (check_valera && check_allowedkeys && (check_EVB || !ersbcode.isEmpty())) { result.add(new URSearchResult(nnpt, ersbcode, check_EVB)); } else { log.debug("No validity for " + nnpt.getRest().get(0).getValue() + "(Validity era=" + String.valueOf(check_valera) + " Allowed Keys="+ String.valueOf(check_allowedkeys) + " EVB check=" + String.valueOf(check_EVB) +")"); } } return result; } private List getNichtNatuerlichePersonen(List records) throws URClientException { if (records == null || records.size() == 0) { return new ArrayList(); } List result = new ArrayList(); log.debug("UR SOAP response with " + records.size() + "records"); for (ResultRecord rr : records) { PersonenDatenTyp pdt = rr.getPersonenDaten(); NichtNatuerlichePersonTyp nnpt = pdt.getNichtNatuerlichePerson(); Zusatzdaten zsd = pdt.getZusatzdaten(); //check validity era boolean check_valera = isInValidityEra(zsd); //check allowed keys boolean check_allowedkeys = hasAllowedKeys(nnpt.getIdentification()); //check EVB boolean check_EVB = isEVB(zsd); if (check_valera && check_allowedkeys && check_EVB) { result.add(nnpt); } else { log.debug("No validity for " + nnpt.getRest().get(0).getValue() + "(Validity era=" + String.valueOf(check_valera) + " Allowed Keys="+ String.valueOf(check_allowedkeys) + " EVB check=" + String.valueOf(check_EVB) +")"); } } return result; } private List hasAllowedEVBCode(Zusatzdaten zsd) { Set set = new HashSet(); if ((this.allowedERsBKeys == null || this.allowedERsBKeys.size() == 0)) { return new ArrayList(); } else { GregorianCalendar now = new GregorianCalendar(); XMLGregorianCalendar xmldate; try { xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(now); if(zsd != null) { List pd = zsd.getPersonenDaten(); for (PersonenDatenZusatzdatenTyp pdzd : pd) { ZusatzdatenPersonenTyp zusatzdaten = pdzd.getZusatzdaten(); if (zusatzdaten != null) { List function = zusatzdaten.getFunktion(); for (FunktionVollzug funct : function) { if (this.allowedERsBKeys.contains(String.valueOf(funct.getFktName()))) { List functRegel = funct.getFktRegel(); for (FktRegelTypVollzug el : functRegel) { if ( el.getFktRegelVon() == null && el.getFktRegelBis() == null) set.add(String.valueOf(funct.getFktName())); else if ( el.getFktRegelVon() != null && el.getFktRegelBis() == null && el.getFktRegelVon().compare(xmldate) == DatatypeConstants.LESSER ) set.add(String.valueOf(funct.getFktName())); else if ( el.getFktRegelVon() == null && el.getFktRegelBis() != null && el.getFktRegelBis().compare(xmldate) == DatatypeConstants.GREATER ) set.add(String.valueOf(funct.getFktName())); else if ( el.getFktRegelVon() != null && el.getFktRegelBis() != null && (el.getFktRegelVon().compare(xmldate) == DatatypeConstants.LESSER && el.getFktRegelBis().compare(xmldate) == DatatypeConstants.GREATER) ) set.add(String.valueOf(funct.getFktName())); } } } } } } } catch (DatatypeConfigurationException e) { log.warn("Internal error during date conversion", e); } return new ArrayList(set); } } //check if corporation is in validity era //TODO: check correctness of TRUE if no validity era is defined!!! private boolean isInValidityEra(Zusatzdaten zsd) throws URClientException { if(zsd != null) { List validityera = zsd.getBestandszeitraum(); for ( BestandszeitraumVollzug valera_el : validityera) { try { GregorianCalendar now = new GregorianCalendar(); XMLGregorianCalendar xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(now); if ( !(valera_el.getBestandVon().compare(xmldate) == DatatypeConstants.LESSER && valera_el.getBestandBis().compare(xmldate) == DatatypeConstants.GREATER) ) { log.debug("Corporation is not within the validity period"); return false; } } catch (DatatypeConfigurationException e) { log.warn("Internal error during date conversion", e); } } } return true; } // check if person is einzelvertretungsbefugt private boolean isEVB(Zusatzdaten zsd) { if (!this.evbCheck) { return true; } else { if(zsd != null) { List pd = zsd.getPersonenDaten(); for (PersonenDatenZusatzdatenTyp pdzd : pd) { if (pdzd.getZusatzdaten() != null) { EvbStatusTyp evbstatus = pdzd.getZusatzdaten().getEvbStatus(); if (evbstatus!=null && evbstatus.equals(EvbStatusTyp.J)) { return true; } } } } } return false; } //check allowedKeys private boolean hasAllowedKeys(List list) throws URClientException { if ((this.allowedKeys == null || this.allowedKeys.size() == 0)) { return true; } else { for (IdentificationType idt : list) { if (this.allowedKeys.contains(idt.getType())) { return true; } } } return false; } // search by example public List searchByExample(SearchCriteriaType sct, int maxResults) throws URClientException { SearchByExampleType body = new SearchByExampleType(); body.setSearchRequestId(createURSearchId()); ResultCriteriaType rc = new ResultCriteriaType(); log.debug("UR SOAP request with Id " + body.getSearchRequestId()); // set only value of max results if > 0 if (maxResults > 0) { rc.setMaxRecords(BigInteger.valueOf(maxResults)); } // set ExtraResultCriterias ExtraResultCriteria ec = new ExtraResultCriteria(); ec.setErsbAttribute(true); rc.setExtraResultCriteria(ec); body.setResultCriteria(rc); body.setSearchCriteria(sct); //request UR service SearchResponseType srt = null; try { srt = this.urSuche.searchByExample(body); } catch (javax.xml.ws.soap.SOAPFaultException e) { //request secondary service switchTOSecondarySystem(e); try { srt = this.urSuche.searchByExample(body); } catch (XmlSwFault e1) { if (e1.getFaultInfo() != null) { throw new URClientException(e1.getFaultInfo().getHelp(), e1.getFaultInfo().getCode().intValue()); } else { throw new URClientException(e1.getMessage(), -1, e1); } } } catch (WebServiceException e) { //request secondary service switchTOSecondarySystem(e); try { srt = this.urSuche.searchByExample(body); } catch (XmlSwFault e1) { if (e1.getFaultInfo() != null) { throw new URClientException(e1.getFaultInfo().getHelp(), e1.getFaultInfo().getCode().intValue()); } else { throw new URClientException(e1.getMessage(), -1, e1); } } } catch (XmlSwFault e) { if (e.getFaultInfo() != null) { throw new URClientException(e.getFaultInfo().getHelp(), e.getFaultInfo().getCode().intValue()); } else { throw new URClientException(e.getMessage(), -1, e); } } // check number of records found // int numFound = 0; // if (srt.getResultInfo() != null) { // numFound = srt.getResultInfo().getReturnedRecords().intValue(); // } // check whether we have an error message if (srt.getMessage() != null) { if (srt.getMessage().getCode().intValue() != 2040) { // 2040 = no records found throw new URClientException(srt.getMessage().getReason().get(0), srt.getMessage().getCode().intValue()); } } if (srt.getResultRecords() == null || srt.getResultRecords().getResultRecord() == null) { return new ArrayList(); } return srt.getResultRecords().getResultRecord(); } private void switchTOSecondarySystem(Exception e) throws URClientException { log.warn("Request primary UR service failed with error \"" + e.getMessage() +"\". " + "Switch to secondary UR service."); String urURL = config.getURSecondaryProductionEnvironmentURL(); try { setURServiceURL(urURL); } catch (EgovUtilException e1) { log.error("Switch to secodary UR service FAILED!", e1); throw new URClientException(e1.getMessage(), 0); } } private void setURServiceURL(String urURL) throws EgovUtilException { // set UR Service URL log.trace("UR connection URL: " + urURL); BindingProvider bindingProvider = (BindingProvider) urSuche; Map requestContext = bindingProvider.getRequestContext(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, urURL); //set HTTP Client Timeout (Default Timeout 60sec) Client client = ClientProxy.getClient(urSuche); HTTPConduit http = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); //set HTTP Client Timeout (Default Timeout 60sec) httpClientPolicy.setConnectionTimeout(15000); httpClientPolicy.setAllowChunking(false); httpClientPolicy.setReceiveTimeout(32000); http.setClient(httpClientPolicy); //check for ssl if (urURL.toLowerCase().startsWith("https")) { log.trace("Using ssl for SZR client request."); SSLContext sslContext = this.config.getURsslConfiguration().getSSLContext(false); if (sslContext == null) { throw new EgovUtilException("SSL context from configuration is empty. Please configure an SSL context in the configuration first."); } TLSClientParameters tlsParams = new TLSClientParameters(); tlsParams.setSSLSocketFactory(sslContext.getSocketFactory()); // check for lax hostname if (this.config.getURsslConfiguration().useLaxHostNameVerifier()) { log.trace("LaxHostnameVerifier enabled. This setting is not recommended to use."); tlsParams.setHostnameVerifier(new LaxHostNameVerifier()); } http.setTlsClientParameters(tlsParams ); } } @SuppressWarnings({ "rawtypes", "unchecked" }) private void initialize() throws EgovUtilException { URL url = URClient.class.getResource("/wsdl/ur_V5/URSucheService.wsdl"); URSucheService urService = null; urService = new URSucheService(url, new QName("urn:at:statistik:ur:ws", "URSucheService")); urSuche = urService.getURSucheService(); BindingProvider bindingProvider = (BindingProvider) urSuche; //set service URLs String urURL = null; if (config.isURTestEnvironment()) { log.trace("Initializing UR test configuration."); urURL = config.getURTestEnvironmentURL(); } else { log.trace("Initializing UR productive configuration."); urURL = config.getURProductionEnvironmentURL(); } setURServiceURL(urURL); log.trace("Adding JAX-WS request/response trace handler."); List handlerList = bindingProvider.getBinding().getHandlerChain(); if (handlerList == null) { handlerList = new ArrayList(); } LoggingHandler loggingHandler = new LoggingHandler(); if (this.logEnabled) { handlerList.add(loggingHandler); } log.trace("Adding WS-Security Header handler."); PvpTokenType pvpToken = config.getURPVPToken(); SZRSOAPHandler szrSOAPHandler = new SZRSOAPHandler(); szrSOAPHandler.configure(pvpToken); handlerList.add(szrSOAPHandler); bindingProvider.getBinding().setHandlerChain(handlerList); } private String createURSearchId() { return RandomStringUtils.randomAlphanumeric(8) + "-" + RandomStringUtils.randomAlphanumeric(4) + "-" + RandomStringUtils.randomAlphanumeric(4) + "-" + RandomStringUtils.randomAlphanumeric(12); } public class URSearchResult { private NichtNatuerlichePersonTyp result; private List ersbcode; private boolean evb; public URSearchResult() { this.result = null; this.ersbcode = null; this.evb = false; } public URSearchResult(NichtNatuerlichePersonTyp result, List ersb_code, boolean isevb) { this.result = result; this.ersbcode = ersb_code; this.evb = isevb; } public NichtNatuerlichePersonTyp getResult() { return result; } public List getErsbcode() { return ersbcode; } public boolean isEVB() { return evb; } } }