Skip to content
This repository was archived by the owner on Mar 12, 2020. It is now read-only.

Commit cf4c367

Browse files
author
Eric Meyer
committed
Adds support for add-to-item for deltas and snapshots (the Discovery Engine does not support add-to-item for bulk or full changesets). The add-to-item configuration element supports the same attributes and child configuration elements as set-item.
1 parent 6545877 commit cf4c367

16 files changed

+1159
-24
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<schema xmlns="http://www.w3.org/2001/XMLSchema"
3+
targetNamespace="http://transparensee.com/schema/datatool-config-6"
4+
xmlns:tns="http://transparensee.com/schema/datatool-config-6"
5+
elementFormDefault="qualified"
6+
>
7+
8+
<element name="config" type="tns:ConfigType"/>
9+
10+
<complexType name="ConfigType">
11+
<sequence>
12+
<element name="accessControl" type="tns:AccessControlType" minOccurs="0" maxOccurs="1"/>
13+
<element name="dataSources" type="tns:DataSourcesType"/>
14+
<element name="profiles" type="tns:ProfilesType" minOccurs="0" maxOccurs="1"/>
15+
<element name="publishers" type="tns:PublishersType" minOccurs="0" maxOccurs="1"/>
16+
</sequence>
17+
</complexType>
18+
19+
<complexType name="AccessControlType">
20+
<annotation>
21+
<documentation xml:lang="en">
22+
Optional restrict feed access using basic HTTP authentication.
23+
Since datatool-config-3.
24+
By adding the element, you turn on basic HTTP authentication.
25+
Add child user elements.
26+
</documentation>
27+
</annotation>
28+
<sequence minOccurs="0">
29+
<element name="user">
30+
<complexType>
31+
<attribute name="name" type="string" use="required"/>
32+
<attribute name="password" type="string" use="required"/>
33+
</complexType>
34+
</element>
35+
</sequence>
36+
</complexType>
37+
38+
<complexType name="DataSourcesType">
39+
<sequence minOccurs="1" maxOccurs="unbounded">
40+
<choice>
41+
<element name="dataSource" type="tns:DataSourceType"/>
42+
<element name="driver" type="tns:DriverType"/>
43+
</choice>
44+
</sequence>
45+
</complexType>
46+
47+
<complexType name="DataSourceType">
48+
<sequence minOccurs="0" maxOccurs="unbounded">
49+
<any processContents="lax"/>
50+
</sequence>
51+
<attribute name="name" type="string" use="required"/>
52+
<attribute name="jar" type="string" use="optional"/>
53+
<attribute name="class" type="string" use="required"/>
54+
</complexType>
55+
56+
<complexType name="DriverType">
57+
<sequence>
58+
<element name="url"/>
59+
<element name="username" minOccurs="0"/>
60+
<element name="password" minOccurs="0"/>
61+
<element name="properties" minOccurs="0">
62+
<complexType>
63+
<sequence minOccurs="0" maxOccurs="unbounded">
64+
<any processContents="lax"/>
65+
</sequence>
66+
</complexType>
67+
</element>
68+
</sequence>
69+
<attribute name="name" type="string" use="required"/>
70+
<attribute name="jar" type="string" use="optional"/>
71+
<attribute name="class" type="string" use="required"/>
72+
</complexType>
73+
74+
<complexType name="ProfilesType">
75+
<sequence minOccurs="1" maxOccurs="unbounded">
76+
<element name="sqlProfile" type="tns:SqlProfileType"/>
77+
</sequence>
78+
</complexType>
79+
80+
<complexType name="PublishersType">
81+
<sequence minOccurs="0" maxOccurs="unbounded">
82+
<element name="sqlPublisher" type="tns:SqlPublisherType"/>
83+
</sequence>
84+
</complexType>
85+
86+
<complexType name="SqlProfileType">
87+
<sequence>
88+
<element name="createSql" type="string" minOccurs="0">
89+
<annotation>
90+
<documentation xml:lang="en">
91+
Optional SQL used to create a profile when one is not found.
92+
Since datatool-config-2.
93+
Bound parameters:
94+
:name -- profile name
95+
Outputs:
96+
none
97+
</documentation>
98+
</annotation>
99+
</element>
100+
<element name="retrieveSql" type="tns:retrieveSql"/>
101+
<element name="updateSql" type="string"/>
102+
</sequence>
103+
<attribute name="name" type="string" use="required"/>
104+
<attribute name="dataSource" type="string" use="required"/>
105+
</complexType>
106+
107+
<complexType name="retrieveSql" mixed="true">
108+
<attribute name="startColumn" use="required"/>
109+
<attribute name="endColumn" use="required"/>
110+
</complexType>
111+
112+
<complexType name="SqlPublisherType">
113+
<sequence>
114+
<choice minOccurs="0" maxOccurs="1">
115+
<element name="bulk" type="tns:BulkFullType"/>
116+
<element name="full" type="tns:BulkFullType"/>
117+
<element name="snapshot" type="tns:SnapshotOrDeltaType"/>
118+
</choice>
119+
<element name="delta" minOccurs="0" maxOccurs="1" type="tns:SnapshotOrDeltaType"/>
120+
</sequence>
121+
<attribute name="name" type="string" use="required"/>
122+
<attribute name="dataSource" type="string" use="required"/>
123+
<attribute name="profile" type="string" use="optional"/>
124+
</complexType>
125+
126+
<complexType name="BulkFullType">
127+
<sequence>
128+
<element name="set-item" minOccurs="0" maxOccurs="unbounded" type="tns:SetItemType"/>
129+
</sequence>
130+
</complexType>
131+
132+
<complexType name="SnapshotOrDeltaType">
133+
<sequence minOccurs="0" maxOccurs="unbounded">
134+
<choice minOccurs="0" maxOccurs="1">
135+
<element name="add-to-item" minOccurs="0" maxOccurs="unbounded" type="tns:SetItemType"/>
136+
<element name="set-item" minOccurs="0" maxOccurs="unbounded" type="tns:SetItemType"/>
137+
<element name="remove-item" minOccurs="0" maxOccurs="unbounded" type="tns:RemoveItemType"/>
138+
</choice>
139+
</sequence>
140+
</complexType>
141+
142+
<complexType name="SetItemType">
143+
<sequence>
144+
<element name="query" type="string"/>
145+
<element name="merge-columns" type="tns:MergeColumnsType" minOccurs="0" maxOccurs="unbounded"/>
146+
<element name="subquery" type="tns:SubQueryType" minOccurs="0" maxOccurs="unbounded"/>
147+
</sequence>
148+
<attribute name="idColumn" type="string" use="required"/>
149+
<attribute name="jsonColumnNames" type="string" use="optional"/>
150+
<attribute name="providerColumn" use="optional" type="string"/>
151+
<attribute name="kindColumn" use="optional" type="string"/>
152+
</complexType>
153+
154+
<complexType name="RemoveItemType">
155+
<sequence>
156+
<element name="query" type="string"/>
157+
</sequence>
158+
<attribute name="idColumn" type="string" use="required"/>
159+
<attribute name="providerColumn" use="optional" type="string"/>
160+
<attribute name="kindColumn" use="optional" type="string"/>
161+
</complexType>
162+
163+
<complexType name="SubQueryType">
164+
<simpleContent>
165+
<extension base="string">
166+
<attribute name="delimiter" type="string" use="optional" />
167+
<attribute name="property" type="string" use="optional"/>
168+
<attribute name="propertyPrefix" type="string" use="optional"/>
169+
<attribute name="discriminator" type="string" use="optional"/>
170+
<attribute name="type" type="tns:SubQueryTypeType" default="array" />
171+
</extension>
172+
</simpleContent>
173+
</complexType>
174+
175+
<simpleType name="SubQueryTypeType">
176+
<restriction base="string">
177+
<enumeration value="array"/>
178+
<enumeration value="delimited"/>
179+
</restriction>
180+
</simpleType>
181+
182+
<complexType name="MergeColumnsType">
183+
<attribute name="keyColumn" type="string" use="required"/>
184+
<attribute name="valueColumn" type="string" use="required"/>
185+
</complexType>
186+
187+
<simpleType name="ActionTypeType">
188+
<restriction base="string">
189+
<enumeration value="create"/>
190+
<enumeration value="delete"/>
191+
</restriction>
192+
</simpleType>
193+
194+
<simpleType name="FilterActionType">
195+
<restriction base="string">
196+
<enumeration value="delta"/>
197+
<enumeration value="snapshot"/>
198+
</restriction>
199+
</simpleType>
200+
</schema>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.t11e.discovery.datatool;
2+
3+
public enum ChangesetElement
4+
{
5+
SET_ITEM,
6+
ADD_TO_ITEM,
7+
REMOVE_ITEM
8+
}

src/main/java/com/t11e/discovery/datatool/ChangesetWriter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ void setItem(final String id, final String provider, final String kind, final Ma
1515
void addToItem(final String id, final Map<String, ? > properties)
1616
throws XMLStreamException;
1717

18+
void addToItem(final String id, final String provider, final String kind, final Map<String, ? > properties)
19+
throws XMLStreamException;
20+
1821
void removeFromItem(final String id, final Map<String, ? > properties)
1922
throws XMLStreamException;
2023

src/main/java/com/t11e/discovery/datatool/ConfigurationManager.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,19 +259,23 @@ private GenericApplicationContext createApplicationContext(final InputStream is)
259259
defineAndInstantiateSqlAction(filtered, applicationContext, action, action.valueOf("@type"),
260260
action.valueOf("@filter"), ns);
261261
}
262-
for (final Node action : (List<Node>) sqlPublisher.selectNodes("c:bulk/c:set-item|c:full/c:set-item".replace("c:", ns)))
262+
for (final Node action : (List<Node>) sqlPublisher.selectNodes(
263+
"c:bulk/c:set-item | c:full/c:set-item"
264+
.replace("c:", ns)))
263265
{
264-
defineAndInstantiateSqlActionFromSetItemOrRemoveItem(complete, applicationContext, action, ns);
266+
defineAndInstantiateSqlActionFromItemActionNode(complete, applicationContext, action, ns);
265267
}
266-
for (final Node action : (List<Node>) sqlPublisher.selectNodes("c:snapshot/c:set-item|c:snapshot/c:remove-item"
268+
for (final Node action : (List<Node>) sqlPublisher.selectNodes(
269+
"c:snapshot/c:set-item | c:snapshot/c:remove-item | c:delta/c:add-to-item"
267270
.replace("c:", ns)))
268271
{
269-
defineAndInstantiateSqlActionFromSetItemOrRemoveItem(complete, applicationContext, action, ns);
272+
defineAndInstantiateSqlActionFromItemActionNode(complete, applicationContext, action, ns);
270273
}
271-
for (final Node action : (List<Node>) sqlPublisher.selectNodes("c:delta/c:set-item|c:delta/c:remove-item".replace(
272-
"c:", ns)))
274+
for (final Node action : (List<Node>) sqlPublisher.selectNodes(
275+
"c:delta/c:set-item | c:delta/c:remove-item | c:delta/c:add-to-item"
276+
.replace("c:", ns)))
273277
{
274-
defineAndInstantiateSqlActionFromSetItemOrRemoveItem(incremental, applicationContext, action, ns);
278+
defineAndInstantiateSqlActionFromItemActionNode(incremental, applicationContext, action, ns);
275279
}
276280
BeanDefinition sqlChangesetExtractor;
277281
{
@@ -309,11 +313,23 @@ private GenericApplicationContext createApplicationContext(final InputStream is)
309313
return applicationContext;
310314
}
311315

312-
private void defineAndInstantiateSqlActionFromSetItemOrRemoveItem(final List<SqlAction> target,
316+
private void defineAndInstantiateSqlActionFromItemActionNode(final List<SqlAction> target,
313317
final GenericApplicationContext applicationContext, final Node action, final String ns)
314318
{
315319
final String filter = action.getParent().getName();
316-
final String type = "set-item".equals(action.getName()) ? "create" : "delete";
320+
final String type;
321+
if ("set-item".equals(action.getName()))
322+
{
323+
type = "create";
324+
}
325+
else if ("add-to-item".equals(action.getName()))
326+
{
327+
type = "add";
328+
}
329+
else
330+
{
331+
type = "delete";
332+
}
317333
defineAndInstantiateSqlAction(target, applicationContext, action, type, filter, ns);
318334
}
319335

@@ -452,7 +468,8 @@ private void parseConfiguration(
452468
"c2", "http://transparensee.com/schema/datatool-config-2",
453469
"c3", "http://transparensee.com/schema/datatool-config-3",
454470
"c4", "http://transparensee.com/schema/datatool-config-4",
455-
"c5", "http://transparensee.com/schema/datatool-config-5");
471+
"c5", "http://transparensee.com/schema/datatool-config-5",
472+
"c6", "http://transparensee.com/schema/datatool-config-6");
456473
final Map<String, String> namespacesByUri = MapUtils.invertMap(namespacesByPrefix);
457474
{
458475
final DocumentFactory factory = new DocumentFactory();

src/main/java/com/t11e/discovery/datatool/CreateActionRowCallbackHandler.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class CreateActionRowCallbackHandler
2929
{
3030
private static final Logger logger = Logger.getLogger(CreateActionRowCallbackHandler.class.getName());
3131
private final ChangesetWriter writer;
32+
private final ChangesetElement action;
3233
private final String providerColumn;
3334
private final String kindColumn;
3435
private final List<SubQuery> subqueries;
@@ -48,6 +49,7 @@ public class CreateActionRowCallbackHandler
4849
public CreateActionRowCallbackHandler(
4950
final NamedParameterJdbcOperations jdbcTemplate,
5051
final ChangesetWriter writer,
52+
final ChangesetElement action,
5153
final String idColumn,
5254
final String providerColumn,
5355
final String kindColumn,
@@ -59,6 +61,7 @@ public CreateActionRowCallbackHandler(
5961
{
6062
this.jdbcTemplate = jdbcTemplate;
6163
this.writer = writer;
64+
this.action = action;
6265
itemIdBuilder = new ItemIdBuilder(idColumn);
6366
this.providerColumn = providerColumn;
6467
this.kindColumn = kindColumn;
@@ -310,26 +313,55 @@ else if (values.size() > 1)
310313
try
311314
{
312315
properties.remove(itemIdBuilder.getIdColumn());
313-
if (providerColumn != null || kindColumn != null)
314-
{
315-
final Object provider = properties.remove(providerColumn);
316-
final Object kind = properties.remove(kindColumn);
317-
writer.setItem(id,
318-
provider instanceof String ? (String) provider : "",
319-
kind instanceof String ? (String) kind : "",
320-
properties);
321-
}
322-
else
323-
{
324-
writer.setItem(id, properties);
325-
}
316+
streamItem(id, properties);
326317
}
327318
catch (final XMLStreamException e)
328319
{
329320
throw new RuntimeException(e);
330321
}
331322
}
332323

324+
private void streamItem(final String id, final Map<String, Object> properties)
325+
throws XMLStreamException
326+
{
327+
if (providerColumn != null || kindColumn != null)
328+
{
329+
final Object provider = properties.remove(providerColumn);
330+
final Object kind = properties.remove(kindColumn);
331+
switch (action)
332+
{
333+
case SET_ITEM:
334+
writer.setItem(id,
335+
provider instanceof String ? (String) provider : "",
336+
kind instanceof String ? (String) kind : "",
337+
properties);
338+
break;
339+
case ADD_TO_ITEM:
340+
writer.addToItem(id,
341+
provider instanceof String ? (String) provider : "",
342+
kind instanceof String ? (String) kind : "",
343+
properties);
344+
break;
345+
default:
346+
throw new IllegalStateException("Cannot handle action of " + action);
347+
}
348+
}
349+
else
350+
{
351+
switch (action)
352+
{
353+
case SET_ITEM:
354+
writer.setItem(id, properties);
355+
break;
356+
case ADD_TO_ITEM:
357+
writer.addToItem(id, properties);
358+
break;
359+
default:
360+
throw new IllegalStateException("Cannot handle action of " + action);
361+
}
362+
}
363+
}
364+
333365
@Override
334366
public void flushItem()
335367
{

src/main/java/com/t11e/discovery/datatool/SqlChangesetExtractor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,13 @@ private void process(
108108
.addValue("end", end)
109109
.addValue("kind", kind);
110110
final CompletionAwareRowCallbackHandler callbackHandler;
111-
if ("create".equals(sqlAction.getAction()))
111+
if ("create".equals(sqlAction.getAction()) || "add".equals(sqlAction.getAction()))
112112
{
113113
callbackHandler =
114114
new CreateActionRowCallbackHandler(
115115
jdbcTemplate,
116116
writer,
117+
"create".equals(sqlAction.getAction()) ? ChangesetElement.SET_ITEM : ChangesetElement.ADD_TO_ITEM,
117118
sqlAction.getIdColumn(),
118119
sqlAction.getProviderColumn(),
119120
sqlAction.getKindColumn(),

0 commit comments

Comments
 (0)