Skip to content

Commit eefe8d8

Browse files
committed
[KNOWAGE-9894] [KNOWAGE-9768] dynamic widget title
1 parent 9c76d6c commit eefe8d8

7 files changed

Lines changed: 239 additions & 16 deletions

File tree

knowage-core/src/main/java/it/eng/knowage/dashboardexport/DashboardExportResource.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public class DashboardExportResource {
6262
private static final String IS_MULTI_SHEET = "isMultiSheet";
6363
private static final String EXPORT_FILE_NAME = "exportFileName";
6464
private static final String DASHBOARD_VARIABLES = "dashboardVariables";
65+
private static final String DRIVER_DESCRIPTION_SUFFIX = "_description";
6566

6667
@Context
6768
protected HttpServletRequest request;
@@ -213,6 +214,7 @@ private static String replaceDriverPlaceholders(String widgetName, JSONArray dri
213214
String driverName = driver.optString("urlName");
214215
if (!StringUtils.isBlank(driverName)) {
215216
widgetName = widgetName.replace("$P{" + driverName + "}", getDriverValue(driver));
217+
widgetName = widgetName.replace("$P{" + driverName + DRIVER_DESCRIPTION_SUFFIX + "}", getDriverDescription(driver));
216218
}
217219
}
218220
return widgetName;
@@ -237,6 +239,27 @@ private static String getDriverValue(JSONObject driver) throws JSONException {
237239
return driverValue;
238240
}
239241

242+
private static String getDriverDescription(JSONObject driver) throws JSONException {
243+
String driverDescription = driver.optString("description");
244+
if (!StringUtils.isBlank(driverDescription)) {
245+
return driverDescription;
246+
}
247+
248+
JSONArray parameterValue = driver.optJSONArray("parameterValue");
249+
if (parameterValue != null) {
250+
driverDescription = joinDriverDescriptions(parameterValue);
251+
}
252+
253+
if (StringUtils.isBlank(driverDescription)) {
254+
Object rawValue = driver.opt("value");
255+
if (rawValue instanceof JSONArray) {
256+
driverDescription = joinDriverDescriptions((JSONArray) rawValue);
257+
}
258+
}
259+
260+
return driverDescription;
261+
}
262+
240263
private static String joinDriverValues(JSONArray driverValues) throws JSONException {
241264
List<String> resolvedValues = new ArrayList<>();
242265
for (int i = 0; i < driverValues.length(); i++) {
@@ -258,6 +281,27 @@ private static String joinDriverValues(JSONArray driverValues) throws JSONExcept
258281
return String.join(", ", resolvedValues);
259282
}
260283

284+
private static String joinDriverDescriptions(JSONArray driverValues) throws JSONException {
285+
List<String> resolvedDescriptions = new ArrayList<>();
286+
for (int i = 0; i < driverValues.length(); i++) {
287+
Object currentValue = driverValues.get(i);
288+
if (currentValue instanceof JSONObject) {
289+
JSONObject currentValueAsJsonObject = (JSONObject) currentValue;
290+
String nestedDescription = currentValueAsJsonObject.optString("description");
291+
if (StringUtils.isBlank(nestedDescription)) {
292+
nestedDescription = currentValueAsJsonObject.optString("value");
293+
}
294+
if (!StringUtils.isBlank(nestedDescription)) {
295+
resolvedDescriptions.add(nestedDescription);
296+
}
297+
} else if (currentValue != null && currentValue != JSONObject.NULL) {
298+
resolvedDescriptions.add(String.valueOf(currentValue));
299+
}
300+
}
301+
302+
return String.join(", ", resolvedDescriptions);
303+
}
304+
261305
private static String replaceVariablePlaceholders(String widgetName, JSONArray variables) throws JSONException {
262306
if (variables == null) {
263307
return widgetName;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package it.eng.knowage.dashboardexport;
2+
3+
import org.json.JSONArray;
4+
import org.json.JSONObject;
5+
import org.junit.Test;
6+
7+
import java.lang.reflect.Method;
8+
9+
import static org.junit.Assert.assertEquals;
10+
11+
public class DashboardExportResourceTest {
12+
13+
@Test
14+
public void shouldResolveDescriptionPlaceholderFromDashboardDrivers() throws Exception {
15+
JSONArray drivers = new JSONArray()
16+
.put(new JSONObject()
17+
.put("urlName", "country")
18+
.put("value", "IT")
19+
.put("description", "Italy"));
20+
21+
String resolved = invokeResolveDashboardExportFileName("dashboard-$P{country_description}", "dashboard", drivers, new JSONArray());
22+
23+
assertEquals("dashboard-Italy", resolved);
24+
}
25+
26+
@Test
27+
public void shouldResolveDescriptionPlaceholderFromPdfStructuredParameters() throws Exception {
28+
JSONArray parameters = new JSONArray()
29+
.put(new JSONObject()
30+
.put("urlName", "country")
31+
.put("value", new JSONArray().put(new JSONObject().put("value", "IT").put("description", "Italy"))));
32+
33+
String resolved = invokeResolveDashboardExportFileName("dashboard-$P{country_description}", "dashboard", parameters, new JSONArray());
34+
35+
assertEquals("dashboard-Italy", resolved);
36+
}
37+
38+
private String invokeResolveDashboardExportFileName(String exportFileNameTemplate, String defaultFileName, JSONArray drivers, JSONArray variables) throws Exception {
39+
Method resolveMethod = DashboardExportResource.class.getDeclaredMethod("resolveDashboardExportFileName", String.class, String.class, JSONArray.class, JSONArray.class);
40+
resolveMethod.setAccessible(true);
41+
return (String) resolveMethod.invoke(null, exportFileNameTemplate, defaultFileName, drivers, variables);
42+
}
43+
}

knowage-export/src/main/java/it/eng/knowage/engine/api/export/dashboard/JSONObjectUtils.java

Lines changed: 102 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@
77
import org.json.JSONException;
88
import org.json.JSONObject;
99

10+
import java.util.regex.Matcher;
11+
import java.util.regex.Pattern;
12+
1013
public class JSONObjectUtils {
1114
private static final Logger LOGGER = LogManager.getLogger(JSONObjectUtils.class);
15+
private static final String DRIVER_DESCRIPTION_SUFFIX = "_description";
16+
private static final Pattern PARAMETER_PLACEHOLDER_PATTERN = Pattern.compile("\\$P\\{([^}]+)}");
17+
private static final Pattern VARIABLE_PLACEHOLDER_PATTERN = Pattern.compile("\\$V\\{([^}]+)}");
1218

1319

1420
public JSONObject getVisualizationFromSettings(JSONObject settings) {
@@ -55,21 +61,104 @@ private static String getWidgetGenericName(JSONObject widget) {
5561
}
5662

5763
public String replacePlaceholderIfPresent(String widgetName, JSONObject drivers) {
58-
if (widgetName.contains("$P{")) {
59-
String placeholder = widgetName.substring(widgetName.indexOf("$P{") + 3, widgetName.indexOf("}"));
60-
if (drivers.has(placeholder)) {
61-
try {
62-
JSONArray valuesArray = drivers.getJSONArray(placeholder);
63-
if (valuesArray.length() > 0) {
64-
JSONObject value = valuesArray.getJSONObject(0);
65-
widgetName = widgetName.replace("$P{" + placeholder + "}", value.getString("value"));
66-
}
67-
} catch (JSONException e) {
68-
throw new SpagoBIRuntimeException("Unable to replace placeholder in widget name", e);
69-
}
64+
return replacePlaceholderIfPresent(widgetName, drivers, null);
65+
}
66+
67+
public String replacePlaceholderIfPresent(String widgetName, JSONObject drivers, JSONArray variables) {
68+
if (widgetName == null || drivers == null || !widgetName.contains("$P{")) {
69+
return replaceVariablePlaceholdersIfPresent(widgetName, variables);
70+
}
71+
72+
Matcher placeholderMatcher = PARAMETER_PLACEHOLDER_PATTERN.matcher(widgetName);
73+
StringBuffer resolvedWidgetName = new StringBuffer();
74+
while (placeholderMatcher.find()) {
75+
String placeholder = placeholderMatcher.group(1);
76+
String replacement = resolveDriverPlaceholderValue(drivers, placeholder);
77+
if (replacement == null) {
78+
placeholderMatcher.appendReplacement(resolvedWidgetName, Matcher.quoteReplacement(placeholderMatcher.group(0)));
79+
} else {
80+
placeholderMatcher.appendReplacement(resolvedWidgetName, Matcher.quoteReplacement(replacement));
7081
}
7182
}
72-
return widgetName;
83+
placeholderMatcher.appendTail(resolvedWidgetName);
84+
return replaceVariablePlaceholdersIfPresent(resolvedWidgetName.toString(), variables);
85+
}
86+
87+
private String resolveDriverPlaceholderValue(JSONObject drivers, String placeholder) {
88+
String driverKey = placeholder;
89+
boolean useDescription = false;
90+
if (placeholder.endsWith(DRIVER_DESCRIPTION_SUFFIX)) {
91+
driverKey = placeholder.substring(0, placeholder.length() - DRIVER_DESCRIPTION_SUFFIX.length());
92+
useDescription = true;
93+
}
94+
95+
if (!drivers.has(driverKey)) {
96+
return null;
97+
}
98+
99+
try {
100+
JSONArray valuesArray = drivers.getJSONArray(driverKey);
101+
if (valuesArray.length() == 0) {
102+
return null;
103+
}
104+
105+
JSONObject value = valuesArray.getJSONObject(0);
106+
String resolvedValue = useDescription ? value.optString("description") : value.optString("value");
107+
if (resolvedValue.isEmpty() && useDescription) {
108+
resolvedValue = value.optString("value");
109+
}
110+
return resolvedValue.isEmpty() ? null : resolvedValue;
111+
} catch (JSONException e) {
112+
throw new SpagoBIRuntimeException("Unable to replace placeholder in widget name", e);
113+
}
73114
}
74115

116+
private String replaceVariablePlaceholdersIfPresent(String widgetName, JSONArray variables) {
117+
if (widgetName == null || variables == null || !widgetName.contains("$V{")) {
118+
return widgetName;
119+
}
120+
121+
Matcher placeholderMatcher = VARIABLE_PLACEHOLDER_PATTERN.matcher(widgetName);
122+
StringBuffer resolvedWidgetName = new StringBuffer();
123+
while (placeholderMatcher.find()) {
124+
String placeholder = placeholderMatcher.group(1);
125+
String replacement = resolveVariablePlaceholderValue(variables, placeholder);
126+
if (replacement == null) {
127+
placeholderMatcher.appendReplacement(resolvedWidgetName, Matcher.quoteReplacement(placeholderMatcher.group(0)));
128+
} else {
129+
placeholderMatcher.appendReplacement(resolvedWidgetName, Matcher.quoteReplacement(replacement));
130+
}
131+
}
132+
placeholderMatcher.appendTail(resolvedWidgetName);
133+
return resolvedWidgetName.toString();
134+
}
135+
136+
private String resolveVariablePlaceholderValue(JSONArray variables, String placeholder) {
137+
for (int i = 0; i < variables.length(); i++) {
138+
JSONObject variable = variables.optJSONObject(i);
139+
if (variable == null) {
140+
continue;
141+
}
142+
143+
String variableName = variable.optString("name");
144+
if (variableName.equals(placeholder)) {
145+
String variableValue = variable.optString("value");
146+
return variableValue.isEmpty() ? null : variableValue;
147+
}
148+
149+
String pivotSeparator = ".";
150+
if (placeholder.startsWith(variableName + pivotSeparator)) {
151+
JSONObject pivotedValues = variable.optJSONObject("pivotedValues");
152+
if (pivotedValues == null) {
153+
continue;
154+
}
155+
156+
String variableKey = placeholder.substring(variableName.length() + pivotSeparator.length());
157+
String variableValue = pivotedValues.optString(variableKey);
158+
return variableValue.isEmpty() ? null : variableValue;
159+
}
160+
}
161+
162+
return null;
163+
}
75164
}

knowage-export/src/main/java/it/eng/knowage/engine/api/export/dashboard/excel/exporters/DashboardPivotExporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public Workbook exportPivot() {
6969
JSONArray columns = fields.getJSONArray("columns");
7070
JSONArray rows = fields.getJSONArray("rows");
7171
int trackedPathFieldCount = columns.length() + rows.length();
72-
String widgetName = getJsonObjectUtils().replacePlaceholderIfPresent(getJsonObjectUtils().getDashboardWidgetName(widget), drivers);
72+
String widgetName = getJsonObjectUtils().replacePlaceholderIfPresent(getJsonObjectUtils().getDashboardWidgetName(widget), drivers, widget.optJSONArray("variables"));
7373

7474
int offset = 0;
7575
int fetchSize = Integer.parseInt(SingletonConfig.getInstance().getConfigValue("SPAGOBI.API.DATASET.MAX_ROWS_NUMBER"));

knowage-export/src/main/java/it/eng/knowage/engine/api/export/dashboard/excel/exporters/DashboardTableExporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public int export() {
2525
try {
2626
JSONObject settings = widget.getJSONObject("settings");
2727
String dashboardSheetName = documentName != null ? documentName : "Dashboard";
28-
String widgetName = getJsonObjectUtils().replacePlaceholderIfPresent(getJsonObjectUtils().getDashboardWidgetName(widget), drivers);
28+
String widgetName = getJsonObjectUtils().replacePlaceholderIfPresent(getJsonObjectUtils().getDashboardWidgetName(widget), drivers, widget.optJSONArray("variables"));
2929
Sheet sheet = excelExporter.createUniqueSafeSheet(wb, widgetName, dashboardSheetName);
3030
int offset = 0;
3131
int fetchSize = Integer.parseInt(SingletonConfig.getInstance().getConfigValue("SPAGOBI.API.DATASET.MAX_ROWS_NUMBER"));

knowage-export/src/main/java/it/eng/knowage/engine/api/export/dashboard/excel/exporters/GenericDashboardWidgetExporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public int export() {
6464
try {
6565
JSONObject settings = widget.getJSONObject("settings");
6666
JSONObject dataStore = getDataStoreforDashboardSingleWidget(widget, selections, drivers, parameters);
67-
String widgetName = getJsonObjectUtils().replacePlaceholderIfPresent(getJsonObjectUtils().getDashboardWidgetName(widget), drivers);
67+
String widgetName = getJsonObjectUtils().replacePlaceholderIfPresent(getJsonObjectUtils().getDashboardWidgetName(widget), drivers, widget.optJSONArray("variables"));
6868
if (dataStore != null) {
6969
String dashboardSheetName = documentName != null ? documentName : "Dashboard";
7070
Sheet sheet = excelExporter.createUniqueSafeSheet(wb, widgetName, dashboardSheetName);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package it.eng.knowage.engine.api.export.dashboard;
2+
3+
import org.json.JSONArray;
4+
import org.json.JSONException;
5+
import org.json.JSONObject;
6+
import org.junit.Test;
7+
8+
import static org.junit.Assert.assertEquals;
9+
10+
public class JSONObjectUtilsTest {
11+
12+
private final JSONObjectUtils jsonObjectUtils = new JSONObjectUtils();
13+
14+
@Test
15+
public void shouldReplaceDriverDescriptionPlaceholderWhenVariablePlaceholderIsPresentBeforeIt() throws JSONException {
16+
JSONObject drivers = new JSONObject()
17+
.put("country", new JSONArray().put(new JSONObject().put("value", "IT").put("description", "Italy")));
18+
JSONArray variables = new JSONArray()
19+
.put(new JSONObject().put("name", "Year").put("value", "2024"));
20+
21+
String resolvedWidgetName = jsonObjectUtils.replacePlaceholderIfPresent("$V{Year} $P{country_description}", drivers, variables);
22+
23+
assertEquals("2024 Italy", resolvedWidgetName);
24+
}
25+
26+
@Test
27+
public void shouldReplaceBothDriverValueAndDescriptionPlaceholders() throws JSONException {
28+
JSONObject drivers = new JSONObject()
29+
.put("country", new JSONArray().put(new JSONObject().put("value", "IT").put("description", "Italy")));
30+
31+
String resolvedWidgetName = jsonObjectUtils.replacePlaceholderIfPresent("$P{country} - $P{country_description}", drivers);
32+
33+
assertEquals("IT - Italy", resolvedWidgetName);
34+
}
35+
36+
@Test
37+
public void shouldReplacePivotedVariablePlaceholder() throws JSONException {
38+
JSONArray variables = new JSONArray()
39+
.put(new JSONObject()
40+
.put("name", "DatasetSummary")
41+
.put("pivotedValues", new JSONObject().put("Revenue", "1250")));
42+
43+
String resolvedWidgetName = jsonObjectUtils.replacePlaceholderIfPresent("$V{DatasetSummary.Revenue}", new JSONObject(), variables);
44+
45+
assertEquals("1250", resolvedWidgetName);
46+
}
47+
}

0 commit comments

Comments
 (0)