Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.List;

import com.evolveum.midpoint.gui.impl.component.data.provider.StreamingCsvDataExporter;
import com.evolveum.midpoint.model.api.authentication.CompiledGuiProfile;

import org.apache.wicket.extensions.markup.html.repeater.data.table.export.AbstractDataExporter;
import org.apache.wicket.extensions.markup.html.repeater.data.table.export.IExportableColumn;
Expand Down Expand Up @@ -48,7 +49,8 @@ protected IModel<String> getConfirmationMessage(final Long exportSizeLimit) {

@Override
protected AbstractDataExporter getDataExporter() {
return new StreamingCsvDataExporter(component.getPageBase()) {
String encoding = resolveExportEncoding();
return new StreamingCsvDataExporter(component.getPageBase(), encoding) {
@Serial private static final long serialVersionUID = 1L;

@Override
Expand Down Expand Up @@ -82,4 +84,17 @@ protected <T> IModel<T> wrapModel(IModel<T> model) {
}
};
}

private String resolveExportEncoding() {
try {
CompiledGuiProfile profile = WebComponentUtil.getPageBase(component).getCompiledGuiProfile();
if (profile.getDefaultExportSettings() != null
&& profile.getDefaultExportSettings().getEncoding() != null) {
return profile.getDefaultExportSettings().getEncoding();
}
} catch (Exception ex) {
LOGGER.warn("Unable to get export encoding setting, falling back to utf-8", ex);
}
return "utf-8";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,43 @@ public class StreamingCsvDataExporter extends CSVDataExporter {
private static final String DOT_CLASS = StreamingCsvDataExporter.class.getName() + ".";
private static final String OPERATION_EXPORT_DATA = DOT_CLASS + "exportData";

private static final String UTF_8_BOM_ENCODING = "utf-8-bom";
private static final byte[] UTF8_BOM = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };

private final PageBase pageBase;
private final String configuredEncoding;

public StreamingCsvDataExporter(PageBase pageBase) {
public StreamingCsvDataExporter(PageBase pageBase, String encoding) {
this.pageBase = pageBase;
this.configuredEncoding = encoding;
setCharacterSet(resolveEffectiveCharset(encoding));
}

public StreamingCsvDataExporter(PageBase pageBase) {
this(pageBase, null);
}

private static String resolveEffectiveCharset(String encoding) {
if (encoding == null || UTF_8_BOM_ENCODING.equalsIgnoreCase(encoding)) {
return "utf-8";
}
return encoding;
}

private boolean isUtf8Bom() {
return UTF_8_BOM_ENCODING.equalsIgnoreCase(configuredEncoding);
}

@Override
public <T> void exportData(IDataProvider<T> dataProvider,
List<IExportableColumn<T, ?>> columns, OutputStream outputStream)
throws IOException {

if (isUtf8Bom()) {
outputStream.write(UTF8_BOM);
outputStream.flush();
}

if (!(dataProvider instanceof IterativeExportSupport)
|| !((IterativeExportSupport<?>) dataProvider).supportsIterativeExport()) {
// Fall back to standard export if provider doesn't support iterative export
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3871,6 +3871,21 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="encoding" type="xsd:string" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Character encoding for exported CSV files.
Default is "utf-8". Use "utf-8-bom" to prepend a UTF-8 BOM
(byte order mark) to the exported file, which helps applications
like Microsoft Excel on non-UTF-8 locale systems correctly
recognize the file as UTF-8.
</xsd:documentation>
<xsd:appinfo>
<a:displayName>GuiExportSettingsType.encoding</a:displayName>
<a:since>4.10.4</a:since>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<!-- TODO: later: default data language, sync/async, whether to show detail dialog or just run the export, etc. -->
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
Expand Down