Skip to content
Merged
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
129 changes: 129 additions & 0 deletions integration-tests/transforms/0120-change-file-encoding.hpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<pipeline>
<info>
<name>0120-change-file-encoding</name>
<name_sync_with_filename>Y</name_sync_with_filename>
<description/>
<extended_description/>
<pipeline_version/>
<pipeline_type>Normal</pipeline_type>
<parameters>
</parameters>
<capture_transform_performance>N</capture_transform_performance>
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
<created_user>-</created_user>
<created_date>2026/10/04 09:00:00.000</created_date>
<modified_user>-</modified_user>
<modified_date>2026/10/04 09:00:00.000</modified_date>
</info>
<notepads>
<notepad>
<note>Write a UTF-8 file in ISO-8859-1 to a folder that does not exist yet, with Create parent folder enabled.</note>
<xloc>128</xloc>
<yloc>16</yloc>
<width>400</width>
<heigth>27</heigth>
<fontname>Noto Sans</fontname>
<fontsize>11</fontsize>
<fontbold>N</fontbold>
<fontitalic>N</fontitalic>
<fontcolorred>14</fontcolorred>
<fontcolorgreen>58</fontcolorgreen>
<fontcolorblue>90</fontcolorblue>
<backgroundcolorred>201</backgroundcolorred>
<backgroundcolorgreen>232</backgroundcolorgreen>
<backgroundcolorblue>251</backgroundcolorblue>
<bordercolorred>14</bordercolorred>
<bordercolorgreen>58</bordercolorgreen>
<bordercolorblue>90</bordercolorblue>
</notepad>
</notepads>
<order>
<hop>
<from>get filenames</from>
<to>change file encoding</to>
<enabled>Y</enabled>
</hop>
</order>
<transform>
<name>get filenames</name>
<type>GetVariable</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<fields>
<field>
<length>-1</length>
<name>filename</name>
<precision>-1</precision>
<trim_type>none</trim_type>
<type>String</type>
<variable>${PROJECT_HOME}/files/change-file-encoding-utf8.txt</variable>
</field>
<field>
<length>-1</length>
<name>target_filename</name>
<precision>-1</precision>
<trim_type>none</trim_type>
<type>String</type>
<variable>${java.io.tmpdir}/0120-change-file-encoding/sub/change-file-encoding-iso.txt</variable>
</field>
</fields>
<attributes/>
<GUI>
<xloc>128</xloc>
<yloc>160</yloc>
</GUI>
</transform>
<transform>
<name>change file encoding</name>
<type>ChangeFileEncoding</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<addsourceresultfilenames>N</addsourceresultfilenames>
<addtargetresultfilenames>N</addtargetresultfilenames>
<filenamefield>filename</filenamefield>
<targetfilenamefield>target_filename</targetfilenamefield>
<targetencoding>ISO-8859-1</targetencoding>
<sourceencoding>UTF-8</sourceencoding>
<createparentfolder>Y</createparentfolder>
<attributes/>
<GUI>
<xloc>400</xloc>
<yloc>160</yloc>
</GUI>
</transform>
<transform_error_handling>
</transform_error_handling>
<attributes/>
</pipeline>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
café
naïve
résumé
165 changes: 165 additions & 0 deletions integration-tests/transforms/main-0120-change-file-encoding.hwf
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<workflow>
<name>main-0120-change-file-encoding</name>
<name_sync_with_filename>Y</name_sync_with_filename>
<description/>
<extended_description/>
<workflow_version/>
<created_user>-</created_user>
<created_date>2026/10/07 12:00:00.000</created_date>
<modified_user>-</modified_user>
<modified_date>2026/10/07 12:00:00.000</modified_date>
<parameters>
</parameters>
<actions>
<action>
<name>Start</name>
<description/>
<type>SPECIAL</type>
<attributes/>
<DayOfMonth>1</DayOfMonth>
<hour>12</hour>
<intervalMinutes>60</intervalMinutes>
<intervalSeconds>0</intervalSeconds>
<minutes>0</minutes>
<repeat>N</repeat>
<schedulerType>0</schedulerType>
<weekDay>1</weekDay>
<parallel>N</parallel>
<xloc>80</xloc>
<yloc>80</yloc>
<attributes_hac/>
</action>
<action>
<name>delete target folder</name>
<description/>
<type>DELETE_FOLDERS</type>
<attributes/>
<arg_from_previous>N</arg_from_previous>
<success_condition>success_if_no_errors</success_condition>
<limit_folders>10</limit_folders>
<fields>
<field>
<name>${java.io.tmpdir}/0120-change-file-encoding</name>
</field>
</fields>
<parallel>N</parallel>
<xloc>240</xloc>
<yloc>80</yloc>
<attributes_hac/>
</action>
<action>
<name>0120-change-file-encoding.hpl</name>
<description/>
<type>PIPELINE</type>
<attributes/>
<filename>${PROJECT_HOME}/0120-change-file-encoding.hpl</filename>
<params_from_previous>N</params_from_previous>
<exec_per_row>N</exec_per_row>
<set_logfile>N</set_logfile>
<logfile/>
<logext/>
<add_date>N</add_date>
<add_time>N</add_time>
<loglevel>Basic</loglevel>
<run_configuration>local</run_configuration>
<wait_until_finished>Y</wait_until_finished>
<create_parent_folder>N</create_parent_folder>
<parameters>
<pass_all_parameters>Y</pass_all_parameters>
</parameters>
<set_append_logfile>N</set_append_logfile>
<parallel>N</parallel>
<xloc>432</xloc>
<yloc>80</yloc>
<attributes_hac/>
</action>
<action>
<name>target file exists?</name>
<description/>
<type>FILE_EXISTS</type>
<attributes/>
<filename>${java.io.tmpdir}/0120-change-file-encoding/sub/change-file-encoding-iso.txt</filename>
<parallel>N</parallel>
<xloc>640</xloc>
<yloc>80</yloc>
<attributes_hac/>
</action>
<action>
<name>Abort</name>
<description/>
<type>ABORT</type>
<attributes/>
<message>Change file encoding did not write the target file into a new folder</message>
<parallel>N</parallel>
<xloc>640</xloc>
<yloc>224</yloc>
<attributes_hac/>
</action>
</actions>
<hops>
<hop>
<from>Start</from>
<to>delete target folder</to>
<enabled>Y</enabled>
<evaluation>Y</evaluation>
<unconditional>Y</unconditional>
</hop>
<hop>
<from>delete target folder</from>
<to>0120-change-file-encoding.hpl</to>
<enabled>Y</enabled>
<evaluation>Y</evaluation>
<unconditional>N</unconditional>
</hop>
<hop>
<from>0120-change-file-encoding.hpl</from>
<to>target file exists?</to>
<enabled>Y</enabled>
<evaluation>Y</evaluation>
<unconditional>N</unconditional>
</hop>
<hop>
<from>0120-change-file-encoding.hpl</from>
<to>Abort</to>
<enabled>Y</enabled>
<evaluation>N</evaluation>
<unconditional>N</unconditional>
</hop>
<hop>
<from>target file exists?</from>
<to>Abort</to>
<enabled>Y</enabled>
<evaluation>N</evaluation>
<unconditional>N</unconditional>
</hop>
<hop>
<from>delete target folder</from>
<to>Abort</to>
<enabled>Y</enabled>
<evaluation>N</evaluation>
<unconditional>N</unconditional>
</hop>
</hops>
<notepads>
</notepads>
<attributes/>
</workflow>
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileType;
import org.apache.hop.core.ResultFile;
import org.apache.hop.core.exception.HopException;
Expand Down Expand Up @@ -153,21 +152,22 @@ public boolean processRow() throws HopException {
PKG, "ChangeFileEncoding.Error.SourceFileNotAFile", sourceFilename));
}

// create directory only if not exists
if (!data.sourceFile.getParent().exists()) {
data.targetFile = HopVfs.getFileObject(targetFilename, variables);

// create the folder of the target file only if it does not exist
FileObject targetFolder = data.targetFile.getParent();
if (!targetFolder.exists()) {
if (meta.isCreateParentFolder()) {
data.sourceFile.getParent().createFolder();
targetFolder.createFolder();
} else {
throw new HopException(
BaseMessages.getString(
PKG,
"ChangeFileEncoding.Error.ParentFolderNotExist",
data.sourceFile.getParent().toString()));
PKG, "ChangeFileEncoding.Error.ParentFolderNotExist", targetFolder.toString()));
}
}

// Change file encoding
changeEncoding(sourceFilename, targetFilename);
changeEncoding(targetFilename);

putRow(data.inputRowMeta, outputRow); // copy row to output rowset(s)

Expand Down Expand Up @@ -209,7 +209,7 @@ public boolean processRow() throws HopException {
return true;
}

private void changeEncoding(String sourceFilename, String targetFilename) throws HopException {
private void changeEncoding(String targetFilename) throws HopException {

BufferedWriter buffWriter = null;
BufferedReader buffReader = null;
Expand All @@ -218,13 +218,14 @@ private void changeEncoding(String sourceFilename, String targetFilename) throws
buffWriter =
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(targetFilename, false), data.targetEncoding));
HopVfs.getOutputStream(data.targetFile, false), data.targetEncoding));
if (Utils.isEmpty(data.sourceEncoding)) {
buffReader = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFilename)));
buffReader =
new BufferedReader(new InputStreamReader(HopVfs.getInputStream(data.sourceFile)));
} else {
buffReader =
new BufferedReader(
new InputStreamReader(new FileInputStream(sourceFilename), data.sourceEncoding));
new InputStreamReader(HopVfs.getInputStream(data.sourceFile), data.sourceEncoding));
}

char[] cBuf = new char[8192];
Expand Down Expand Up @@ -258,7 +259,7 @@ private void changeEncoding(String sourceFilename, String targetFilename) throws
ResultFile resultFile =
new ResultFile(
ResultFile.FILE_TYPE_GENERAL,
HopVfs.getFileObject(targetFilename, variables),
data.targetFile,
getPipelineMeta().getName(),
getTransformName());
resultFile.setComment(
Expand Down Expand Up @@ -300,6 +301,13 @@ public void dispose() {
// ignore
}
}
if (data.targetFile != null) {
try {
data.targetFile.close();
} catch (Exception e) {
// ignore
}
}
super.dispose();
}
}
Loading
Loading