Skip to content

Commit 4a13a12

Browse files
AGNT-378 Support Enhanced tags in MessageML (#393)
1 parent 8dc8971 commit 4a13a12

23 files changed

+1062
-4
lines changed

src/main/java/org/symphonyoss/symphony/messageml/MessageMLParser.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import freemarker.template.TemplateExceptionHandler;
1515
import org.apache.commons.io.input.ReaderInputStream;
1616
import org.apache.commons.lang3.StringUtils;
17+
import org.apache.commons.lang3.tuple.ImmutablePair;
1718
import org.apache.commons.lang3.tuple.Pair;
1819
import org.symphonyoss.symphony.messageml.bi.BiContext;
1920
import org.symphonyoss.symphony.messageml.bi.BiFields;
@@ -39,6 +40,7 @@
3940
import org.symphonyoss.symphony.messageml.elements.ExpandableCard;
4041
import org.symphonyoss.symphony.messageml.elements.ExpandableCardBody;
4142
import org.symphonyoss.symphony.messageml.elements.ExpandableCardHeader;
43+
import org.symphonyoss.symphony.messageml.elements.Tag;
4244
import org.symphonyoss.symphony.messageml.elements.Form;
4345
import org.symphonyoss.symphony.messageml.elements.FormElement;
4446
import org.symphonyoss.symphony.messageml.elements.FormatEnum;
@@ -83,6 +85,9 @@
8385
import org.symphonyoss.symphony.messageml.util.IDataProvider;
8486
import org.symphonyoss.symphony.messageml.util.NoOpEntityResolver;
8587
import org.symphonyoss.symphony.messageml.util.NullErrorHandler;
88+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.InstrumentKind;
89+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.InstrumentResolution;
90+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.ResolutionResults;
8691
import org.w3c.dom.Document;
8792
import org.w3c.dom.Node;
8893
import org.w3c.dom.NodeList;
@@ -102,6 +107,7 @@
102107
import java.util.Optional;
103108
import java.util.Set;
104109
import java.util.stream.Collectors;
110+
import java.util.stream.IntStream;
105111

106112
import javax.xml.parsers.DocumentBuilder;
107113
import javax.xml.parsers.DocumentBuilderFactory;
@@ -366,8 +372,8 @@ private MessageML parseMessageML(String messageML, String version) throws Invali
366372

367373
MessageML result = new MessageML(messageFormat, version);
368374
result.buildAll(this, docElement);
375+
result.enhanceFinancialTags(result, dataProvider);
369376
result.validate();
370-
371377
return result;
372378
}
373379

@@ -629,6 +635,9 @@ public Element createElement(org.w3c.dom.Element element, Element parent) throws
629635
case Superscript.MESSAGEML_TAG:
630636
return new Superscript(parent);
631637

638+
case Tag.MESSAGEML_TAG:
639+
return new Tag(parent, ++index);
640+
632641
default:
633642
throw new InvalidInputException("Invalid MessageML content at element \"" + tag + "\"");
634643
}

src/main/java/org/symphonyoss/symphony/messageml/elements/Element.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,28 @@ public Integer countChildrenOfType(Class<? extends Element> type) {
436436
return count;
437437
}
438438

439+
/**
440+
* This method applies a breadth-first traversal of a tree of elements getting list of
441+
* elements found which
442+
* belong to the class type passed as input
443+
*/
444+
public List<Element> getChildrenOfType(Class<? extends Element> type) {
445+
List<Element> elements = new ArrayList<>();
446+
Stack<Element> stack = new Stack<>();
447+
Element current = this;
448+
stack.push(current);
449+
while (!stack.isEmpty()) {
450+
current = stack.pop();
451+
if (current.getClass() == type) {
452+
elements.add(current);
453+
}
454+
for (Element child : current.getChildren()) {
455+
stack.push(child);
456+
}
457+
}
458+
return elements;
459+
}
460+
439461
/**
440462
* Return the EntityJSON representation of the node.
441463
*/

src/main/java/org/symphonyoss/symphony/messageml/elements/MessageML.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,24 @@
2626

2727
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
2828
import com.fasterxml.jackson.databind.node.ObjectNode;
29+
import org.apache.commons.lang3.tuple.ImmutablePair;
30+
import org.apache.commons.lang3.tuple.Pair;
2931
import org.commonmark.node.Document;
3032
import org.symphonyoss.symphony.messageml.MessageMLContext;
3133
import org.symphonyoss.symphony.messageml.MessageMLParser;
3234
import org.symphonyoss.symphony.messageml.exceptions.InvalidInputException;
35+
import org.symphonyoss.symphony.messageml.util.IDataProvider;
3336
import org.symphonyoss.symphony.messageml.util.XmlPrintStream;
37+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.InstrumentKind;
38+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.InstrumentResolution;
39+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.MarketSector;
40+
import org.symphonyoss.symphony.messageml.util.instrument.resolver.ResolutionResults;
3441
import org.w3c.dom.Node;
3542

43+
import java.util.Collections;
3644
import java.util.List;
45+
import java.util.stream.Collectors;
46+
import java.util.stream.IntStream;
3747

3848

3949
/**
@@ -182,4 +192,61 @@ private void validateTargetIdForUIActions() throws InvalidInputException {
182192
uiAction.setAttribute(TARGET_ID, dialog.getPresentationMlIdAttribute());
183193
}
184194
}
195+
196+
public void enhanceFinancialTags(MessageML result, IDataProvider dataProvider)
197+
throws InvalidInputException {
198+
199+
List<Tag> elements = result.getChildrenOfType(Tag.class)
200+
.stream()
201+
.map(element -> Tag.class.cast(element))
202+
.collect(Collectors.toList());
203+
if (elements != null && !elements.isEmpty()) {processFinancialTags(elements, dataProvider);}
204+
}
205+
206+
private void processFinancialTags(List<Tag> elements, IDataProvider dataProvider)
207+
throws InvalidInputException {
208+
List<Pair<InstrumentResolution, Tag>> instrumentResolutionMap =
209+
IntStream.range(0, elements.size())
210+
.mapToObj(index -> buildInstrumentResolutionRequest(elements.get(index), index))
211+
.collect(Collectors.toList());
212+
// Build resolver api request
213+
List<InstrumentResolution> criteria =
214+
instrumentResolutionMap.stream().map(Pair::getLeft).collect(Collectors.toList());
215+
ResolutionResults results = dataProvider.getFinTagPresentation(criteria);
216+
// update financial tag element data
217+
instrumentResolutionMap.forEach(entry -> {
218+
String resolutionId = entry.getLeft().getResolutionId();
219+
if (results != null && results.getInstruments() != null && results.getInstruments()
220+
.containsKey(resolutionId)) {
221+
entry.getRight()
222+
.setInstrument(
223+
results.getInstruments().get(resolutionId).getInstrument());
224+
}
225+
}
226+
);
227+
for (Tag element : elements) {element.validateFallBackTicker();}
228+
}
229+
230+
private Pair<InstrumentResolution, Tag> buildInstrumentResolutionRequest(Tag tag,
231+
Integer order) {
232+
InstrumentResolution resolution = new InstrumentResolution();
233+
resolution.setResolutionId(order.toString());
234+
resolution.setBbgCompTicker(tag.getTagAttributes().getBbgcompticker());
235+
resolution.setFigi(tag.getTagAttributes().getFigi());
236+
resolution.setFigiTicker(tag.getTagAttributes().getFigiTicker());
237+
resolution.setUniqueId(tag.getTagAttributes().getUniqueId());
238+
resolution.setIsin(tag.getTagAttributes().getIsin());
239+
resolution.setUsCode(tag.getTagAttributes().getUscode());
240+
resolution.setFullBbgCompTicker(tag.getTagAttributes().getFullBbgCompTicker());
241+
resolution.setLocalCode(tag.getTagAttributes().getLocalcode());
242+
resolution.setOperationalMic(tag.getTagAttributes().getOperationalMic());
243+
resolution.setInstrumentClass(
244+
InstrumentKind.fromValue(tag.getTagAttributes().getInstrumentclass()));
245+
resolution.setCountryCode(tag.getTagAttributes().getCountrycode());
246+
resolution.setReturnMainListing(tag.getTagAttributes().getReturnMainListing());
247+
resolution.setBbgMarketSector(
248+
MarketSector.fromValue(tag.getTagAttributes().getBbgmarketsector()));
249+
return new ImmutablePair<>(resolution, tag);
250+
}
251+
185252
}

0 commit comments

Comments
 (0)