|
28 | 28 | */
|
29 | 29 | public class SDCXMLParser {
|
30 | 30 |
|
31 |
| - private static final Logger logger = LoggerFactory.getLogger(SDCXMLParser.class); |
| 31 | + private static final Logger logger = LoggerFactory.getLogger(SDCXMLParser.class); |
32 | 32 |
|
33 |
| - private SDCXMLParser() { |
34 |
| - } |
| 33 | + private SDCXMLParser() { |
| 34 | + } |
35 | 35 |
|
36 |
| - public static SmartDerivativeContractDescriptor parse(String sdcxml) throws ParserConfigurationException, IOException, SAXException { |
| 36 | + public static SmartDerivativeContractDescriptor parse(String sdcxml) throws ParserConfigurationException, IOException, SAXException { |
37 | 37 |
|
38 |
| - Smartderivativecontract sdc = unmarshalXml(sdcxml, Smartderivativecontract.class); |
| 38 | + Smartderivativecontract sdc = unmarshalXml(sdcxml, Smartderivativecontract.class); |
39 | 39 |
|
40 |
| - LocalDateTime settlementDateInitial = LocalDateTime.parse(sdc.getSettlement().settlementDateInitial.trim()); |
| 40 | + LocalDateTime settlementDateInitial = LocalDateTime.parse(sdc.getSettlement().settlementDateInitial.trim()); |
41 | 41 |
|
42 |
| - String uniqueTradeIdentifier = sdc.getUniqueTradeIdentifier().trim(); |
43 |
| - String dltAddress = sdc.getDltAddress() == null ? "" : sdc.getDltAddress().trim(); |
44 |
| - String dltTradeId = sdc.getDltTradeId() == null ? "" : sdc.getDltTradeId().trim(); |
| 42 | + String uniqueTradeIdentifier = sdc.getUniqueTradeIdentifier().trim(); |
| 43 | + String dltAddress = sdc.getDltAddress() == null ? "" : sdc.getDltAddress().trim(); |
| 44 | + String dltTradeId = sdc.getDltTradeId() == null ? "" : sdc.getDltTradeId().trim(); |
45 | 45 |
|
46 | 46 | /*
|
47 | 47 | Market Data
|
48 | 48 | */
|
49 |
| - List<CalibrationDataItem.Spec> marketdataItems = new ArrayList<>(); |
50 |
| - for(Smartderivativecontract.Settlement.Marketdata.Marketdataitems.Item item : sdc.getSettlement().getMarketdata().getMarketdataitems().getItem()){ |
51 |
| - String symbol = item.getSymbol().get(0).trim(); |
52 |
| - String curve = item.getCurve().get(0).trim(); |
53 |
| - String type = item.getType().get(0).trim(); |
54 |
| - String tenor = item.getTenor().get(0).trim(); |
55 |
| - CalibrationDataItem.Spec spec = new CalibrationDataItem.Spec(symbol, curve, type, tenor); |
56 |
| - marketdataItems.add(spec); |
57 |
| - } |
58 |
| - |
59 |
| - /* |
60 |
| - * Counterparties |
61 |
| - */ |
62 |
| - List<SmartDerivativeContractDescriptor.Party> parties = new ArrayList<>(); |
63 |
| - Map<String, Double> marginAccountInitialByPartyID = new HashMap<>(); |
64 |
| - Map<String, Double> penaltyFeeInitialByPartyID = new HashMap<>(); |
65 |
| - |
66 |
| - for(Smartderivativecontract.Parties.Party p : sdc.getParties().getParty()){ |
67 |
| - SmartDerivativeContractDescriptor.Party party = new SmartDerivativeContractDescriptor.Party( |
68 |
| - p.getId().trim(), |
69 |
| - p.getName().trim(), |
70 |
| - null, |
71 |
| - p.getAddress().trim() |
72 |
| - ); |
73 |
| - parties.add(party); |
74 |
| - marginAccountInitialByPartyID.put(party.getId(), p.getMarginAccount().getValue()); |
75 |
| - penaltyFeeInitialByPartyID.put(party.getId(), p.getPenaltyFee().getValue()); |
76 |
| - } |
77 |
| - |
78 |
| - // Receiver party ID |
79 |
| - String receiverPartyID = sdc.getReceiverPartyID().trim(); |
80 |
| - |
81 |
| - // TODO The parser needs to check that the field receiverPartyID of the SDC matched the field <receiverPartyReference href="party2"/> in the FPML |
82 |
| - |
83 |
| - // TODO Support multiple underlyings |
84 |
| - |
85 |
| - Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(sdcxml.getBytes(StandardCharsets.UTF_8))); |
86 |
| - document.getDocumentElement().normalize(); |
87 |
| - |
88 |
| - Node underlying = document |
89 |
| - .getElementsByTagName("underlying") |
90 |
| - .item(0) |
91 |
| - .getFirstChild(); |
92 |
| - if (!underlying.getNodeName().equals("dataDocument")) { |
93 |
| - underlying = underlying.getNextSibling(); |
94 |
| - } |
95 |
| - Swap swap = (Swap) sdc.getUnderlyings().getUnderlying().getDataDocument().getTrade().get(0).getProduct().getValue(); |
96 |
| - String currency = swap.getSwapStream().get(0).getCalculationPeriodAmount().getCalculation().getNotionalSchedule().getNotionalStepSchedule().getCurrency().getValue().trim(); |
97 |
| - |
98 |
| - String marketDataProvider = sdc.getSettlement().getMarketdata().getProvider().trim(); |
99 |
| - |
100 |
| - return new SmartDerivativeContractDescriptor(dltTradeId, dltAddress, uniqueTradeIdentifier, settlementDateInitial, parties, marginAccountInitialByPartyID, penaltyFeeInitialByPartyID, receiverPartyID, underlying, marketdataItems, currency, marketDataProvider); |
101 |
| - } |
102 |
| - |
103 |
| - public static <T> T unmarshalXml(String xml, Class<T> t) { |
104 |
| - try { |
105 |
| - StringReader reader = new StringReader(xml); |
106 |
| - JAXBContext jaxbContext = JAXBContext.newInstance(t); |
107 |
| - Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); |
108 |
| - return (T) unmarshaller.unmarshal(reader); |
109 |
| - } catch (JAXBException e) { |
110 |
| - logger.error("unmarshalXml: jaxb error, ", e); |
111 |
| - throw new SDCException(ExceptionId.SDC_JAXB_ERROR, e.getMessage(), 400); |
112 |
| - } |
113 |
| - } |
114 |
| - |
115 |
| - public static <T> String marshalClassToXMLString(T t) { |
116 |
| - try { |
117 |
| - JAXBContext jaxbContextSettlement = JAXBContext.newInstance(t.getClass()); |
118 |
| - Marshaller jaxbMarshaller = jaxbContextSettlement.createMarshaller(); |
119 |
| - StringWriter writer = new StringWriter(); |
120 |
| - jaxbMarshaller.marshal(t, writer); |
121 |
| - return writer.toString(); |
122 |
| - } catch (JAXBException e) { |
123 |
| - logger.error("marshalClassToXMLString: jaxb error, ", e); |
124 |
| - throw new SDCException(ExceptionId.SDC_JAXB_ERROR, e.getMessage(), 400); |
125 |
| - } |
126 |
| - } |
| 49 | + List<CalibrationDataItem.Spec> marketdataItems = new ArrayList<>(); |
| 50 | + for (Smartderivativecontract.Settlement.Marketdata.Marketdataitems.Item item : sdc.getSettlement().getMarketdata().getMarketdataitems().getItem()) { |
| 51 | + String symbol = item.getSymbol().get(0).trim(); |
| 52 | + String curve = item.getCurve().get(0).trim(); |
| 53 | + String type = item.getType().get(0).trim(); |
| 54 | + String tenor = item.getTenor().get(0).trim(); |
| 55 | + CalibrationDataItem.Spec spec = new CalibrationDataItem.Spec(symbol, curve, type, tenor); |
| 56 | + marketdataItems.add(spec); |
| 57 | + } |
| 58 | + |
| 59 | + /* |
| 60 | + * Counterparties |
| 61 | + */ |
| 62 | + List<SmartDerivativeContractDescriptor.Party> parties = new ArrayList<>(); |
| 63 | + Map<String, Double> marginAccountInitialByPartyID = new HashMap<>(); |
| 64 | + Map<String, Double> penaltyFeeInitialByPartyID = new HashMap<>(); |
| 65 | + |
| 66 | + for (Smartderivativecontract.Parties.Party p : sdc.getParties().getParty()) { |
| 67 | + SmartDerivativeContractDescriptor.Party party = new SmartDerivativeContractDescriptor.Party( |
| 68 | + p.getId().trim(), |
| 69 | + p.getName().trim(), |
| 70 | + null, |
| 71 | + p.getAddress().trim() |
| 72 | + ); |
| 73 | + parties.add(party); |
| 74 | + marginAccountInitialByPartyID.put(party.getId(), p.getMarginAccount().getValue()); |
| 75 | + penaltyFeeInitialByPartyID.put(party.getId(), p.getPenaltyFee().getValue()); |
| 76 | + } |
| 77 | + |
| 78 | + // Receiver party ID |
| 79 | + String receiverPartyID = sdc.getReceiverPartyID().trim(); |
| 80 | + |
| 81 | + // TODO The parser needs to check that the field receiverPartyID of the SDC matched the field <receiverPartyReference href="party2"/> in the FPML |
| 82 | + |
| 83 | + // TODO Support multiple underlyings |
| 84 | + |
| 85 | + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(sdcxml.getBytes(StandardCharsets.UTF_8))); |
| 86 | + document.getDocumentElement().normalize(); |
| 87 | + |
| 88 | + Node underlying = document |
| 89 | + .getElementsByTagName("underlying") |
| 90 | + .item(0) |
| 91 | + .getFirstChild(); |
| 92 | + if (!underlying.getNodeName().contains("dataDocument")) { |
| 93 | + underlying = underlying.getNextSibling(); |
| 94 | + } |
| 95 | + Swap swap = (Swap) sdc.getUnderlyings().getUnderlying().getDataDocument().getTrade().get(0).getProduct().getValue(); |
| 96 | + String currency = swap.getSwapStream().get(0).getCalculationPeriodAmount().getCalculation().getNotionalSchedule().getNotionalStepSchedule().getCurrency().getValue().trim(); |
| 97 | + |
| 98 | + String marketDataProvider = sdc.getSettlement().getMarketdata().getProvider().trim(); |
| 99 | + |
| 100 | + return new SmartDerivativeContractDescriptor(dltTradeId, dltAddress, uniqueTradeIdentifier, settlementDateInitial, parties, marginAccountInitialByPartyID, penaltyFeeInitialByPartyID, receiverPartyID, underlying, marketdataItems, currency, marketDataProvider); |
| 101 | + } |
| 102 | + |
| 103 | + public static <T> T unmarshalXml(String xml, Class<T> t) { |
| 104 | + try { |
| 105 | + StringReader reader = new StringReader(xml); |
| 106 | + JAXBContext jaxbContext = JAXBContext.newInstance(t); |
| 107 | + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); |
| 108 | + return (T) unmarshaller.unmarshal(reader); |
| 109 | + } catch (JAXBException e) { |
| 110 | + logger.error("unmarshalXml: jaxb error, ", e); |
| 111 | + throw new SDCException(ExceptionId.SDC_JAXB_ERROR, e.getMessage(), 400); |
| 112 | + } |
| 113 | + } |
| 114 | + |
| 115 | + /** |
| 116 | + * Generic object-to-XML-string converter for all annotated classes |
| 117 | + * @param t object to be converted to an XML string |
| 118 | + * @return XML formatted String |
| 119 | + * @param <T> generic Type, which has the correct XML bind annotations |
| 120 | + */ |
| 121 | + public static <T> String marshalClassToXMLString(T t) { |
| 122 | + try { |
| 123 | + JAXBContext jaxbContextSettlement = JAXBContext.newInstance(t.getClass()); |
| 124 | + Marshaller jaxbMarshaller = jaxbContextSettlement.createMarshaller(); |
| 125 | + if (t instanceof Smartderivativecontract) |
| 126 | + jaxbMarshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "uri:sdc smartderivativecontract.xsd"); |
| 127 | + StringWriter writer = new StringWriter(); |
| 128 | + jaxbMarshaller.marshal(t, writer); |
| 129 | + return writer.toString(); |
| 130 | + } catch (JAXBException e) { |
| 131 | + logger.error("marshalClassToXMLString: jaxb error, ", e); |
| 132 | + throw new SDCException(ExceptionId.SDC_JAXB_ERROR, e.getMessage(), 400); |
| 133 | + } |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * this version of an SDC-object-to-XML-string conversion includes text replacements to get rid of XML namespace tags like "fpml:dataDocument" |
| 138 | + * @param smartderivativecontract SDC product data object which will be transformed into an XML string |
| 139 | + * @return formatted xml string |
| 140 | + */ |
| 141 | + public static String marshalSDCToXMLString(Smartderivativecontract smartderivativecontract) { |
| 142 | + //TODO took over an old implementation, please review |
| 143 | + return marshalClassToXMLString(smartderivativecontract) |
| 144 | + .replaceAll("<fpml:dataDocument fpmlVersion=\"5-9\">", "<dataDocument fpmlVersion=\"5-9\" xmlns=\"http://www.fpml.org/FpML-5/confirmation\">") |
| 145 | + .replaceAll("fpml:", ""); |
| 146 | + } |
127 | 147 | }
|
0 commit comments