Skip to content
This repository has been archived by the owner on Jan 17, 2022. It is now read-only.

Commit

Permalink
Merge branches 'feature/cp-title-override' and 'master' of github.com…
Browse files Browse the repository at this point in the history
…:Financial-Times/methode-article-mapper into feature/cp-title-override
  • Loading branch information
radutudor committed May 2, 2017
2 parents 60e35c3 + 4a6b9d5 commit c8a0bb5
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package com.ft.methodearticlemapper.transformation;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;

import com.ft.bodyprocessing.BodyProcessingContext;
import com.ft.bodyprocessing.writer.BodyWriter;
import com.ft.bodyprocessing.xml.eventhandlers.BaseXMLEventHandler;
import com.ft.bodyprocessing.xml.eventhandlers.XMLEventHandler;
import com.google.common.base.Strings;

public class MethodeBrightcoveVideoXmlEventHandler extends BaseXMLEventHandler {
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import java.util.HashMap;
import java.util.Map;

public abstract class AbstractVideoXmlEventHandler extends BaseXMLEventHandler {

private static final String CONTENT_TAG = "content";
private static final String DATA_EMBEDDED = "data-embedded";
Expand All @@ -24,36 +21,27 @@ public class MethodeBrightcoveVideoXmlEventHandler extends BaseXMLEventHandler {
private static final String VIDEO_TYPE = "http://www.ft.com/ontology/content/MediaResource";

private final XMLEventHandler fallbackHandler;
private final String videoIdAttributeName;

public MethodeBrightcoveVideoXmlEventHandler(String videoIdAttributeName, XMLEventHandler fallbackHandler) {
public AbstractVideoXmlEventHandler(XMLEventHandler fallbackHandler) {
this.fallbackHandler = fallbackHandler;
this.videoIdAttributeName = videoIdAttributeName;
}

@Override
public void handleStartElementEvent(StartElement event, XMLEventReader xmlEventReader, BodyWriter eventWriter,
BodyProcessingContext bodyProcessingContext) throws XMLStreamException {
String videoId = extractVideoId(event);
if(Strings.isNullOrEmpty(videoId)){
if (Strings.isNullOrEmpty(videoId)) {
fallbackHandler.handleStartElementEvent(event, xmlEventReader, eventWriter, bodyProcessingContext);
return;
}
Map<String, String> attributesToAdd = new HashMap<>();
attributesToAdd.put(ID, UUID.nameUUIDFromBytes(videoId.getBytes()).toString());
attributesToAdd.put(ID, videoId);
attributesToAdd.put(DATA_EMBEDDED, Boolean.TRUE.toString());
attributesToAdd.put(TYPE, VIDEO_TYPE);
skipUntilMatchingEndTag(event.getName().toString(), xmlEventReader);
eventWriter.writeStartTag(CONTENT_TAG, attributesToAdd);
eventWriter.writeEndTag(CONTENT_TAG);
}

private String extractVideoId(StartElement event) {
Attribute attribute = event.getAttributeByName(QName.valueOf(videoIdAttributeName));
if(attribute == null){
return null;
}
return event.getAttributeByName(QName.valueOf(videoIdAttributeName)).getValue();
}

public abstract String extractVideoId(StartElement event);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ft.methodearticlemapper.transformation;

import com.ft.bodyprocessing.xml.eventhandlers.XMLEventHandler;
import com.google.common.base.Strings;

import javax.xml.namespace.QName;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ContentVideoXmlEventHandler extends AbstractVideoXmlEventHandler {

private static final String UUID_REGEX = "_([0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12})\\.xml";
private static final Pattern UUID_PATTERN = Pattern.compile(UUID_REGEX);

private String videoIdHolderAttribute;

public ContentVideoXmlEventHandler(String videoIdHolderAttribute, XMLEventHandler fallbackHandler) {
super(fallbackHandler);
this.videoIdHolderAttribute = videoIdHolderAttribute;
}

@Override
public String extractVideoId(StartElement event) {
Attribute attribute = event.getAttributeByName(QName.valueOf(videoIdHolderAttribute));
if (attribute == null) {
return null;
}
String videoIdHolder = event.getAttributeByName(QName.valueOf(videoIdHolderAttribute)).getValue();
return getVideoUuid(videoIdHolder);
}

private String getVideoUuid(String videoIdHolder) {
if (Strings.isNullOrEmpty(videoIdHolder)) {
return null;
}

Matcher matcher = UUID_PATTERN.matcher(videoIdHolder);
return matcher.find() ? matcher.group(1) : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public MethodeBodyTransformationXMLEventHandlerRegistry(final VideoMatcher video
registerStartAndEndElementEventHandler(new PromoBoxEventHandler(new PromoBoxXMLParser(new StAXTransformingBodyProcessor(this), inlineImageXmlEventHandler)), "promo-box");
registerStartAndEndElementEventHandler(new DataTableXMLEventHandler(new DataTableXMLParser(new StAXTransformingBodyProcessor(new StructuredMethodeSourcedBodyXMLEventHandlerRegistryInnerTable(this))), new StripElementAndContentsXMLEventHandler()), "table");

registerStartAndEndElementEventHandler(new MethodeBrightcoveVideoXmlEventHandler("videoid", new StripElementAndContentsXMLEventHandler()), "videoPlayer");
registerStartAndEndElementEventHandler(new MethodeVideoXmlEventHandler("videoid", new StripElementAndContentsXMLEventHandler()), "videoPlayer");
registerStartAndEndElementEventHandler(new ContentVideoXmlEventHandler("href", new StripElementAndContentsXMLEventHandler()), "content");
registerStartAndEndElementEventHandler(
new MethodeOtherVideoXmlEventHandler(
new InteractiveGraphicHandler(
Expand Down Expand Up @@ -59,7 +60,7 @@ public MethodeBodyTransformationXMLEventHandlerRegistry(final VideoMatcher video
);
// strip methode tags whose bodies we don't want
registerStartElementEventHandler(new StripElementAndContentsXMLEventHandler(),
"annotation", "byline", "content", "editor-choice", "headline", "inlineDwc", "interactive-chart",
"annotation", "byline", "editor-choice", "headline", "inlineDwc", "interactive-chart",
"lead-body", "lead-text", "ln", "photo", "photo-caption", "photo-group",
"plainHtml", "promo-headline", "promo-image", "promo-intro",
"promo-link", "promo-title", "promobox-body", "pull-quote", "pull-quote-header",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ft.methodearticlemapper.transformation;

import com.ft.bodyprocessing.xml.eventhandlers.XMLEventHandler;
import com.google.common.base.Strings;

import javax.xml.namespace.QName;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class MethodeVideoXmlEventHandler extends AbstractVideoXmlEventHandler {

private static final String UUID_REGEX = "[0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12}";
private static final Pattern UUID_PATTERN = Pattern.compile(UUID_REGEX);

private final String videoIdAttributeName;

public MethodeVideoXmlEventHandler(String videoIdAttributeName, XMLEventHandler fallbackHandler) {
super(fallbackHandler);
this.videoIdAttributeName = videoIdAttributeName;
}

@Override
public String extractVideoId(StartElement event) {
Attribute attribute = event.getAttributeByName(QName.valueOf(videoIdAttributeName));
if (attribute == null) {
return null;
}
String videoId = event.getAttributeByName(QName.valueOf(videoIdAttributeName)).getValue();
return Strings.isNullOrEmpty(videoId) ? null : getAsUUID(videoId);
}

private String getAsUUID(String videoId) {
Matcher matcher = UUID_PATTERN.matcher(videoId);
return matcher.matches() ? videoId : UUID.nameUUIDFromBytes(videoId.getBytes()).toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ public void setup() throws Exception {
rulesAndHandlers.put( "TRANSFORM TAG IF PROMO BOX WITH MASTER IMAGE", "PromoBoxEventHandler");
rulesAndHandlers.put( "RETAIN ELEMENT AND REMOVE FORMATTING ATTRIBUTES", "DataTableXMLEventHandler");
rulesAndHandlers.put( "TRANSFORM THE SCRIPT ELEMENT TO PODCAST", "PodcastXMLEventHandler");
rulesAndHandlers.put( "TRANSFORM THE TAG TO VIDEO", "MethodeBrightcoveVideoXmlEventHandler");
rulesAndHandlers.put( "TRANSFORM THE TAG TO VIDEO", "MethodeVideoXmlEventHandler");
rulesAndHandlers.put( "TRANSFORM THE NEXT TAG TO VIDEO", "MethodeVideoXmlEventHandler");
rulesAndHandlers.put( "TRANSFORM THE LINK TAG TO VIDEO", "ContentVideoXmlEventHandler");
rulesAndHandlers.put( "TRANSFORM INTERACTIVE GRAPHICS", "MethodeOtherVideoXmlEventHandler");
rulesAndHandlers.put( "TRANSFORM OTHER VIDEO TYPES", "MethodeOtherVideoXmlEventHandler");
rulesAndHandlers.put( "WRAP AND TRANSFORM A INLINE IMAGE", "WrappedHandlerXmlEventHandler");
Expand Down Expand Up @@ -370,7 +372,7 @@ private XMLEventHandler assertTagIsRegistered( String name, String rule ) {
String handler = rulesAndHandlers.get(rule);
StartElementEventImpl startElement = StartElementEventImpl.construct(null, new QName(name), null, null, null);
XMLEventHandler eventHandler = registry.getEventHandler(startElement);
assertThat("handler incorrect", eventHandler.getClass().getSimpleName(), equalTo(handler));
assertThat("handler incorrect", handler, equalTo(eventHandler.getClass().getSimpleName()));
return eventHandler;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ protected StartElement getCompactStartElement(String xmlString, String matchingS

}


private Attribute getAttribute(String name, String value) {
return new AttributeEventImpl(null, new QName(name), value, false);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.ft.methodearticlemapper.transformation;

import com.ft.bodyprocessing.BodyProcessingContext;
import com.ft.bodyprocessing.writer.BodyWriter;
import com.ft.bodyprocessing.xml.eventhandlers.XMLEventHandler;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.StartElement;
import java.util.HashMap;
import java.util.Map;

import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class ContentVideoXmlEventHandlerTest extends BaseXMLEventHandlerTest {

private ContentVideoXmlEventHandler eventHandler;
@Mock
private XMLEventHandler fallbackHandler;

@Mock
private XMLEventReader mockXmlEventReader;
@Mock
private BodyWriter mockBodyWriter;
@Mock
private BodyProcessingContext mockBodyProcessingContext;

private static final String VIDEO_LINK_ELEMENT = "content";
private static final String VIDEO_ID_HOLDER_ATTRIBUTE_NAME = "href";
private static final String VIDEO_UUID = "e21e5235-5f3f-4a53-bafd-73dbcd0552e0";
private static final String VIDEO_ID_HOLDER = "/FT/Content/Links/Videos/Video_upload-test.mp4_" + VIDEO_UUID
+ ".xml?uuid=dcc02264-2438-11e7-a24c-6bbb6ec0bc98&amp;xp=/doc/story/text/body&amp;lt=link\" id=\"U11603526769084aUD\"";
private static final String VIDEO_ID_HOLDER_NO_UUID = "/FT/Content/Links/Videos/Video_upload-test.mp4_123456789.xml?uuid=dcc02264-2438-11e7-a24c-6bbb6ec0bc98&amp;xp=/doc/story/text/body&amp;lt=link\" id=\"U11603526769084aUD\"";
private static final String DATA_EMBEDDED = "data-embedded";
private static final String VIDEO_TYPE = "http://www.ft.com/ontology/content/MediaResource";
private static final String CONTENT_TAG = "content";
private static final String ID = "id";
private static final String TYPE = "type";

@Before
public void setup() throws Exception {
eventHandler = new ContentVideoXmlEventHandler(VIDEO_ID_HOLDER_ATTRIBUTE_NAME, fallbackHandler);
}

@Test
public void shouldUseFallbackHandlerIfStartElementVideoIdHolderAttributeValueIsMissing() throws Exception {
StartElement startElement = getStartElement(VIDEO_LINK_ELEMENT);
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(fallbackHandler).handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
}

@Test
public void shouldUseFallbackHandlerIfStartElementVideoIdHolderAttributeValueIsEmpty() throws Exception {
StartElement startElement = getStartElementWithAttributes(
VIDEO_LINK_ELEMENT, buildOneAttributeMap(VIDEO_ID_HOLDER_ATTRIBUTE_NAME, ""));
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(fallbackHandler).handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
}

@Test
public void shouldWriteTransformedElementsToWriterWhenNextVideoUUID() throws Exception {
Map<String, String> transformedAttributes = new HashMap<>();
transformedAttributes.put(ID, VIDEO_UUID);
transformedAttributes.put(DATA_EMBEDDED, Boolean.TRUE.toString());
transformedAttributes.put(TYPE, VIDEO_TYPE);
StartElement startElement = getStartElementWithAttributes(
VIDEO_ID_HOLDER_ATTRIBUTE_NAME, buildOneAttributeMap(VIDEO_ID_HOLDER_ATTRIBUTE_NAME, VIDEO_ID_HOLDER));
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(mockBodyWriter).writeStartTag(CONTENT_TAG, transformedAttributes);
verify(mockBodyWriter).writeEndTag(CONTENT_TAG);
}

@Test
public void shouldUseFallbackHandlerIfStartElementVideoIdHolderAttributeValueIsNotUUID() throws Exception {
StartElement startElement = getStartElementWithAttributes(VIDEO_ID_HOLDER_ATTRIBUTE_NAME,
buildOneAttributeMap(VIDEO_ID_HOLDER_ATTRIBUTE_NAME, VIDEO_ID_HOLDER_NO_UUID));
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(fallbackHandler).handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
}

private Map<String, String> buildOneAttributeMap(String attributeName, String attributeValue) {
Map<String, String> attributes = new HashMap<>();
attributes.put(attributeName, attributeValue);
return attributes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,32 @@
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class MethodeBrightcoveVideoXmlEventHandlerTest extends BaseXMLEventHandlerTest {
public class MethodeVideoXmlEventHandlerTest extends BaseXMLEventHandlerTest {

private MethodeBrightcoveVideoXmlEventHandler eventHandler;
@Mock private XMLEventHandler fallbackHandler;
private MethodeVideoXmlEventHandler eventHandler;
@Mock
private XMLEventHandler fallbackHandler;

@Mock private XMLEventReader mockXmlEventReader;
@Mock private BodyWriter mockBodyWriter;
@Mock private BodyProcessingContext mockBodyProcessingContext;
@Mock
private XMLEventReader mockXmlEventReader;
@Mock
private BodyWriter mockBodyWriter;
@Mock
private BodyProcessingContext mockBodyProcessingContext;

private static final String VIDEO_PLAYER_ELEMENT = "videoPlayer";
private static final String VIDEO_ID_ATTRIBUTE_NAME = "videoID";
private static final String VIDEO_ID = "3920663836001";
private static final String VIDEO_UUID = "e21e5235-5f3f-4a53-bafd-73dbcd0552e0";
private static final String DATA_EMBEDDED = "data-embedded";
private static final String VIDEO_TYPE = "http://www.ft.com/ontology/content/MediaResource";
private static final String CONTENT_TAG = "content";
private static final String ID="id";
private static final String TYPE="type";
private static final String ID = "id";
private static final String TYPE = "type";

@Before
public void setup() throws Exception {
eventHandler = new MethodeBrightcoveVideoXmlEventHandler(VIDEO_ID_ATTRIBUTE_NAME, fallbackHandler);
public void setup() throws Exception {
eventHandler = new MethodeVideoXmlEventHandler(VIDEO_ID_ATTRIBUTE_NAME, fallbackHandler);
}

@Test
Expand All @@ -51,25 +56,41 @@ public void shouldUseFallbackHandlerIfStartElementVideoIdAttributeValuesAreNull(

@Test
public void shouldUseFallbackHandlerIfStartElementVideoIdAttributeValuesAreEmpty() throws Exception {
Map<String, String> attributes = new HashMap<>();
attributes.put("", "");
StartElement startElement = getStartElementWithAttributes(VIDEO_PLAYER_ELEMENT, attributes);
StartElement startElement = getStartElementWithAttributes(VIDEO_PLAYER_ELEMENT,
buildOneAttributeMap("", ""));
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(fallbackHandler).handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
}

@Test
public void shouldWriteTransformedElementsToWriter() throws Exception {
Map<String, String> videoPlayerAttributes = new HashMap<>();
videoPlayerAttributes.put(VIDEO_ID_ATTRIBUTE_NAME, VIDEO_ID);
public void shouldWriteTransformedElementsToWriterWhenBrightcoveId() throws Exception {
Map<String, String> transformedAttributes = new HashMap<>();
transformedAttributes.put(ID, UUID.nameUUIDFromBytes(VIDEO_ID.getBytes()).toString());
transformedAttributes.put(DATA_EMBEDDED, Boolean.TRUE.toString());
transformedAttributes.put(TYPE, VIDEO_TYPE);
StartElement startElement = getStartElementWithAttributes(VIDEO_PLAYER_ELEMENT, videoPlayerAttributes);
StartElement startElement = getStartElementWithAttributes(VIDEO_PLAYER_ELEMENT,
buildOneAttributeMap(VIDEO_ID_ATTRIBUTE_NAME, VIDEO_ID));
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(mockBodyWriter).writeStartTag(CONTENT_TAG, transformedAttributes);
verify(mockBodyWriter).writeEndTag(CONTENT_TAG);
}

@Test
public void shouldWriteTransformedElementsToWriterWhenNextVideoUUID() throws Exception {
Map<String, String> transformedAttributes = new HashMap<>();
transformedAttributes.put(ID, VIDEO_UUID);
transformedAttributes.put(DATA_EMBEDDED, Boolean.TRUE.toString());
transformedAttributes.put(TYPE, VIDEO_TYPE);
StartElement startElement = getStartElementWithAttributes(VIDEO_PLAYER_ELEMENT,
buildOneAttributeMap(VIDEO_ID_ATTRIBUTE_NAME, VIDEO_UUID));
eventHandler.handleStartElementEvent(startElement, mockXmlEventReader, mockBodyWriter, mockBodyProcessingContext);
verify(mockBodyWriter).writeStartTag(CONTENT_TAG, transformedAttributes);
verify(mockBodyWriter).writeEndTag(CONTENT_TAG);
}

private Map<String, String> buildOneAttributeMap(String attributeName, String attributeValue) {
Map<String, String> attributes = new HashMap<>();
attributes.put(attributeName, attributeValue);
return attributes;
}
}

0 comments on commit c8a0bb5

Please sign in to comment.