Skip to content
Permalink
Browse files

Adds support for provider and kind to Discovery Data Tool. The config…

…uration elements can now take optional attributes providerColumn and kindColumn. If either of these are specified, then the resulting changeset set-item and remove-item elements will not have an id attribute, and instead will have locator, provider and kind attributes. The providerColumn and kindColumn are not included in the resulting set-item properties, since that would be redundant.
  • Loading branch information...
Eric Meyer
Eric Meyer committed Sep 28, 2011
1 parent d5c4f82 commit dfc26bef5316a3646618bdbeff0b10a5d1092322
@@ -146,13 +146,17 @@
</sequence>
<attribute name="idColumn" type="string" use="required"/>
<attribute name="jsonColumnNames" type="string" use="optional"/>
<attribute name="providerColumn" use="optional" type="string"/>
<attribute name="kindColumn" use="optional" type="string"/>
</complexType>

<complexType name="RemoveItemType">
<sequence>
<element name="query" type="string"/>
</sequence>
<attribute name="idColumn" type="string" use="required"/>
<attribute name="providerColumn" use="optional" type="string"/>
<attribute name="kindColumn" use="optional" type="string"/>
</complexType>

<complexType name="SubQueryType">
@@ -9,6 +9,9 @@
void setItem(final String id, final Map<String, ? > properties)
throws XMLStreamException;

void setItem(final String id, final String provider, final String kind, final Map<String, ? > properties)
throws XMLStreamException;

void addToItem(final String id, final Map<String, ? > properties)
throws XMLStreamException;

@@ -23,4 +26,7 @@ void addItem(final String id)

void removeItem(final String id)
throws XMLStreamException;

void removeItem(final String id, final String provider, final String kind)
throws XMLStreamException;
}
@@ -347,6 +347,8 @@ private void fillActionBeanDefinition(final BeanDefinitionBuilder builder, final
final String ns)
{
builder.addPropertyValue("idColumn", parentElementToQuery.valueOf("@idColumn"));
addAttributeValueIfNotNull(builder, parentElementToQuery, "providerColumn");
addAttributeValueIfNotNull(builder, parentElementToQuery, "kindColumn");
builder.addPropertyValue("jsonColumnNames", parentElementToQuery.valueOf("@jsonColumnNames"));
builder
.addPropertyValue("query",
@@ -393,6 +395,17 @@ private void fillActionBeanDefinition(final BeanDefinitionBuilder builder, final
}
}

private void addAttributeValueIfNotNull(final BeanDefinitionBuilder builder, final Node node, final String attribute)
{

final Node attrNode = node.selectSingleNode("@" + attribute);
if (attrNode != null)
{
final String attrValue = attrNode.getText();
builder.addPropertyValue(attribute, attrValue);
}
}

@SuppressWarnings("unchecked")
private void applyAccessControl(final InputStream is)
{
@@ -29,6 +29,8 @@
{
private static final Logger logger = Logger.getLogger(CreateActionRowCallbackHandler.class.getName());
private final ChangesetWriter writer;
private final String providerColumn;
private final String kindColumn;
private final List<SubQuery> subqueries;
private final NamedParameterJdbcOperations jdbcTemplate;
private final ResultSetConvertor resultSetConvertor;
@@ -47,6 +49,8 @@ public CreateActionRowCallbackHandler(
final NamedParameterJdbcOperations jdbcTemplate,
final ChangesetWriter writer,
final String idColumn,
final String providerColumn,
final String kindColumn,
final boolean lowerCaseColumnNames,
final Set<String> jsonColumns,
final List<MergeColumns> mergeColumns,
@@ -56,6 +60,8 @@ public CreateActionRowCallbackHandler(
this.jdbcTemplate = jdbcTemplate;
this.writer = writer;
itemIdBuilder = new ItemIdBuilder(idColumn);
this.providerColumn = providerColumn;
this.kindColumn = kindColumn;
this.mergeColumns = mergeColumns != null ? mergeColumns : Collections.<MergeColumns> emptyList();
mergeContiguous = !this.mergeColumns.isEmpty();
this.shouldRecordTimings = shouldRecordTimings;
@@ -305,7 +311,19 @@ else if (values.size() > 1)
try
{
properties.remove(itemIdBuilder.getIdColumn());
writer.setItem(id, properties);
if (providerColumn != null || kindColumn != null)
{
final Object provider = properties.remove(providerColumn);
final Object kind = properties.remove(kindColumn);
writer.setItem(id,
provider instanceof String ? (String) provider : "",
kind instanceof String ? (String) kind : "",
properties);
}
else
{
writer.setItem(id, properties);
}
}
catch (final XMLStreamException e)
{
@@ -5,17 +5,25 @@

import javax.xml.stream.XMLStreamException;

import org.apache.commons.lang.StringUtils;

public class DeleteActionRowCallbackHandler
implements CompletionAwareRowCallbackHandler
{
private final ChangesetWriter writer;
private final ItemIdBuilder itemIdBuilder;
private final String providerColumn;
private final String kindColumn;

public DeleteActionRowCallbackHandler(
final ChangesetWriter writer,
final String idColumn)
final String idColumn,
final String providerColumn,
final String kindColumn)
{
this.writer = writer;
this.providerColumn = providerColumn;
this.kindColumn = kindColumn;
itemIdBuilder = new ItemIdBuilder(idColumn);
}

@@ -26,7 +34,16 @@ public void processRow(final ResultSet rs)
final String id = itemIdBuilder.getId(rs);
try
{
writer.removeItem(id);
if (providerColumn != null || kindColumn != null)
{
final String provider = StringUtils.trimToEmpty(rs.getString(providerColumn));
final String kind = StringUtils.trimToEmpty(rs.getString(kindColumn));
writer.removeItem(id, provider, kind);
}
else
{
writer.removeItem(id);
}
}
catch (final XMLStreamException e)
{
@@ -19,6 +19,8 @@
private List<SubQuery> subqueries;
private List<MergeColumns> mergeColumns;
private String idColumn;
private String providerColumn;
private String kindColumn;
private Set<String> jsonColumnNames = Collections.emptySet();
private boolean useLowerCaseColumnNames = true;

@@ -104,6 +106,26 @@ public void setUseLowerCaseColumnNames(final boolean useLowerCaseColumnNames)
this.useLowerCaseColumnNames = useLowerCaseColumnNames;
}

public String getProviderColumn()
{
return providerColumn;
}

public void setProviderColumn(final String providerColumn)
{
this.providerColumn = providerColumn;
}

public String getKindColumn()
{
return kindColumn;
}

public void setKindColumn(final String kindColumn)
{
this.kindColumn = kindColumn;
}

public void setMergeColumns(final List<MergeColumns> mergeColumns)
{
this.mergeColumns = mergeColumns;
@@ -115,6 +115,8 @@ private void process(
jdbcTemplate,
writer,
sqlAction.getIdColumn(),
sqlAction.getProviderColumn(),
sqlAction.getKindColumn(),
sqlAction.isUseLowerCaseColumnNames(),
sqlAction.getJsonColumnNames(),
sqlAction.getMergeColumns(),
@@ -126,7 +128,9 @@ else if ("delete".equals(sqlAction.getAction()))
callbackHandler =
new DeleteActionRowCallbackHandler(
writer,
sqlAction.getIdColumn());
sqlAction.getIdColumn(),
sqlAction.getProviderColumn(),
sqlAction.getKindColumn());
}
else
{
@@ -32,6 +32,21 @@ public void setItem(
writer.writeCharacters("\n");
}

@Override
public void setItem(final String id, final String provider, final String kind, final Map<String, ? > properties)
throws XMLStreamException
{
writer.writeStartElement("set-item");
writer.writeAttribute("locator", id);
writer.writeAttribute("provider", provider);
writer.writeAttribute("kind", kind);
writer.writeStartElement("properties");
writeValue(id, properties, false);
writer.writeEndElement();
writer.writeEndElement();
writer.writeCharacters("\n");
}

@Override
public void addToItem(
final String id,
@@ -96,6 +111,18 @@ public void removeItem(
writer.writeCharacters("\n");
}

@Override
public void removeItem(final String id, final String provider, final String kind)
throws XMLStreamException
{
writer.writeStartElement("remove-item");
writer.writeAttribute("locator", id);
writer.writeAttribute("provider", provider);
writer.writeAttribute("kind", kind);
writer.writeEndElement();
writer.writeCharacters("\n");
}

void writeValue(
final String id,
final Object object,
@@ -112,6 +112,22 @@ protected Document parseXmlResponse(final MockHttpServletResponse response)
protected Document assertChangeset(final String publisher, final String profile, final String expectedType,
final Collection<String> expectedSetItemIds, final Collection<String> expectedRemoveItemIds,
final boolean forceSnapshot)
{
final Document doc = assertChangeset(publisher, profile, expectedType, forceSnapshot);
final String asXml = doc.asXML();
Assert.assertEquals(asXml, expectedSetItemIds.size(), doc.selectNodes("/changeset/set-item").size());
Assert.assertEquals(asXml,
new HashSet<String>(expectedSetItemIds),
new HashSet<String>(nodesAsStrings(doc, "/changeset/set-item/@id")));
Assert.assertEquals(asXml, expectedRemoveItemIds.size(), doc.selectNodes("/changeset/remove-item").size());
Assert.assertEquals(asXml,
new HashSet<String>(expectedRemoveItemIds),
new HashSet<String>(nodesAsStrings(doc, "/changeset/remove-item/@id")));
return doc;
}

protected Document assertChangeset(final String publisher, final String profile, final String expectedType,
final boolean forceSnapshot)
{
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
@@ -140,15 +156,6 @@ protected Document assertChangeset(final String publisher, final String profile,
{
throw new RuntimeException(e);
}
final String asXml = doc.asXML();
Assert.assertEquals(asXml, expectedSetItemIds.size(), doc.selectNodes("/changeset/set-item").size());
Assert.assertEquals(asXml,
new HashSet<String>(expectedSetItemIds),
new HashSet<String>(nodesAsStrings(doc, "/changeset/set-item/@id")));
Assert.assertEquals(asXml, expectedRemoveItemIds.size(), doc.selectNodes("/changeset/remove-item").size());
Assert.assertEquals(asXml,
new HashSet<String>(expectedRemoveItemIds),
new HashSet<String>(nodesAsStrings(doc, "/changeset/remove-item/@id")));
return doc;
}

@@ -0,0 +1,103 @@
package com.t11e.discovery.datatool;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.InputStream;

import org.dom4j.Document;
import org.dom4j.Node;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class FeedProviderTest
extends EndToEndTestBase
{

@Override
protected InputStream getConfigurationXml()
{
return getClass().getResourceAsStream("FeedProviderTest.xml");
}

@Before
public void setup()
{
executeSqlScripts("FeedProviderTestCreate.sql");
}

@After
public void teardown()
{
executeSqlScripts("FeedProviderTestDrop.sql");
}

@Test
public void simple()
{
final Document doc = assertChangeset("test-simple", "", "snapshot", false);
final String asXml = doc.asXML();
assertEquals(asXml, 4, doc.selectNodes("/changeset/set-item").size());
assertEquals(asXml, 0, doc.selectNodes("/changeset/set-item[@id]").size());
assertEquals(asXml, 4, doc.selectNodes("/changeset/set-item[@locator and @provider and @kind]").size());
{
final Node node = doc.selectSingleNode("/changeset/set-item[@locator='1' and @provider='' and @kind='']");
assertNotNull(node);
assertEquals("val1", node.selectSingleNode("./properties/struct/entry[@name='value']/string/text()").getText());
assertNoIdProviderOrKindProperties(node);
}
{
final Node node = doc.selectSingleNode("/changeset/set-item[@locator='2' and @provider='p1' and @kind='k1']");
assertNotNull(node);
assertEquals("val2", node.selectSingleNode("./properties/struct/entry[@name='value']/string/text()").getText());
assertNoIdProviderOrKindProperties(node);
}
{
final Node node = doc.selectSingleNode("/changeset/set-item[@locator='3' and @provider='p2' and @kind='k2']");
assertNotNull(node);
assertEquals("val3", node.selectSingleNode("./properties/struct/entry[@name='value']/string/text()").getText());
assertNoIdProviderOrKindProperties(node);
}
{
final Node node = doc.selectSingleNode("/changeset/set-item[@locator='4' and @provider='' and @kind='']");
assertNotNull(node);
assertEquals("val4", node.selectSingleNode("./properties/struct/entry[@name='value']/string/text()").getText());
assertNoIdProviderOrKindProperties(node);
}
assertEquals(asXml, 2, doc.selectNodes("/changeset/remove-item").size());
assertEquals(asXml, 0, doc.selectNodes("/changeset/remove-item[@id]").size());
assertEquals(asXml, 2, doc.selectNodes("/changeset/remove-item[@locator and @provider and @kind]").size());
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@locator='5' and @provider='p1' and @kind='k1']"));
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@locator='6' and @provider='' and @kind='']"));
}

private void assertNoIdProviderOrKindProperties(final Node node)
{
assertEquals(0,
node.selectNodes("./properties/struct/entry[@name='id' or @name='kind' or @name='provider']").size());
}

@Test
public void muliProvider()
{
final Document doc = assertChangeset("test-multi", "", "snapshot", false);
final String asXml = doc.asXML();
assertEquals(asXml, 12, doc.selectNodes("/changeset/set-item").size());
assertEquals(asXml, 4, doc.selectNodes("/changeset/set-item[@id]").size());
assertEquals(asXml, 8, doc.selectNodes("/changeset/set-item[@locator and @provider and @kind]").size());
assertEquals(0,
doc.selectNodes("//properties/struct/entry[@name='id' or @name='kind' or @name='provider']").size());

assertEquals(asXml, 6, doc.selectNodes("/changeset/remove-item").size());
assertEquals(asXml, 2, doc.selectNodes("/changeset/remove-item[@id]").size());
assertEquals(asXml, 4, doc.selectNodes("/changeset/remove-item[@locator and @provider and @kind]").size());
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@locator='5' and @provider='p1' and @kind='k1']"));
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@locator='6' and @provider='' and @kind='']"));
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@locator='5' and @provider='calcp' and @kind='calck']"));
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@locator='6' and @provider='calcp' and @kind='calck']"));
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@id='5']"));
assertNotNull(doc.selectSingleNode("/changeset/remove-item[@id='6']"));

}
}

0 comments on commit dfc26be

Please sign in to comment.
You can’t perform that action at this time.