Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/apache/directory-studio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Roubert <fredrik@roubert.name>2022-05-16 08:07:31 +0300
committerGitHub <noreply@github.com>2022-05-16 08:07:31 +0300
commit5251dfb5f83d42f89e0dcbdb65ed14ed5c6ee115 (patch)
tree5aa5a31ba29e17acf7a8f7d11aa5684e9fa01cfb
parente3d8183d1b13f450ea9a9e4eda21973220111cb5 (diff)
DIRSTUDIO-1296: Decode RFC 4517 Postal Address syntax upon export (#32)
-rw-r--r--plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java8
-rw-r--r--plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java10
-rw-r--r--plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java14
-rw-r--r--plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java27
-rw-r--r--plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java54
-rw-r--r--tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java42
6 files changed, 154 insertions, 1 deletions
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java
index 7d4382ae4..e6195ba77 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportCsvRunnable.java
@@ -30,7 +30,9 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.jobs.StudioConnectionRunnableWithProgress;
@@ -41,6 +43,7 @@ import org.apache.directory.studio.ldapbrowser.core.model.AttributeDescription;
import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
import org.apache.directory.studio.ldapbrowser.core.utils.JNDIUtils;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
import org.apache.directory.studio.ldifparser.LdifUtils;
import org.apache.directory.studio.ldifparser.model.LdifEnumeration;
import org.apache.directory.studio.ldifparser.model.container.LdifContainer;
@@ -288,6 +291,11 @@ public class ExportCsvRunnable implements StudioConnectionRunnableWithProgress
if ( attributeMap.containsKey( oidString ) )
{
String value = attributeMap.get( oidString );
+ AttributeType type = browserConnection.getSchema().getAttributeTypeDescription( attributeName );
+ if ( SchemaConstants.POSTAL_ADDRESS_SYNTAX.equals( type.getSyntaxOid() ) )
+ {
+ value = Utils.decodePostalAddress( value, lineSeparator );
+ }
appendValue( quoteCharacter, sb, value );
}
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java
index 191eab35a..abbed1d05 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportOdfRunnable.java
@@ -26,7 +26,9 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.jobs.StudioConnectionRunnableWithProgress;
@@ -36,6 +38,7 @@ import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
import org.apache.directory.studio.ldapbrowser.core.utils.JNDIUtils;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
import org.apache.directory.studio.ldifparser.model.LdifEnumeration;
import org.apache.directory.studio.ldifparser.model.container.LdifContainer;
import org.apache.directory.studio.ldifparser.model.container.LdifContentRecord;
@@ -290,6 +293,13 @@ public class ExportOdfRunnable implements StudioConnectionRunnableWithProgress
short cellNum = headerRowAttributeNameMap.get( attributeName ).shortValue();
Cell cell = row.getCellByIndex( cellNum );
cell.setValueType( ValueType.STRING.name() );
+ AttributeType type = browserConnection.getSchema().getAttributeTypeDescription( attributeName );
+ if ( SchemaConstants.POSTAL_ADDRESS_SYNTAX.equals( type.getSyntaxOid() ) )
+ {
+ // https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#__RefHeading__1017970_715980110
+ value = Utils.decodePostalAddress( value, "\n" ); //$NON-NLS-1$
+ cell.setTextWrapped( true );
+ }
cell.setStringValue( value );
}
}
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java
index cde55db3a..203002223 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/jobs/ExportXlsRunnable.java
@@ -27,7 +27,9 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.jobs.StudioConnectionRunnableWithProgress;
@@ -37,6 +39,7 @@ import org.apache.directory.studio.ldapbrowser.core.BrowserCorePlugin;
import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
import org.apache.directory.studio.ldapbrowser.core.utils.JNDIUtils;
+import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
import org.apache.directory.studio.ldifparser.model.LdifEnumeration;
import org.apache.directory.studio.ldifparser.model.container.LdifContainer;
import org.apache.directory.studio.ldifparser.model.container.LdifContentRecord;
@@ -45,6 +48,7 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
import org.eclipse.core.runtime.Preferences;
@@ -280,6 +284,9 @@ public class ExportXlsRunnable implements StudioConnectionRunnableWithProgress
Map<String, String> attributeMap = ExportCsvRunnable.getAttributeMap( null, record, valueDelimiter, "UTF-16", //$NON-NLS-1$
binaryEncoding );
+ CellStyle wrapStyle = sheet.getWorkbook().createCellStyle();
+ wrapStyle.setWrapText( true );
+
// output attributes
HSSFRow row = sheet.createRow( sheet.getLastRowNum() + 1 );
if ( exportDn )
@@ -303,6 +310,13 @@ public class ExportXlsRunnable implements StudioConnectionRunnableWithProgress
{
int cellNum = headerRowAttributeNameMap.get( attributeName ).shortValue();
HSSFCell cell = createStringCell( row, cellNum );
+ AttributeType type = browserConnection.getSchema().getAttributeTypeDescription( attributeName );
+ if ( SchemaConstants.POSTAL_ADDRESS_SYNTAX.equals( type.getSyntaxOid() ) )
+ {
+ // https://poi.apache.org/components/spreadsheet/quick-guide.html#NewLinesInCells
+ value = Utils.decodePostalAddress( value, "\n" ); //$NON-NLS-1$
+ cell.setCellStyle( wrapStyle );
+ }
cell.setCellValue( value );
}
}
diff --git a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
index 2cc7bad60..bb20a39cd 100644
--- a/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
+++ b/plugins/ldapbrowser.core/src/main/java/org/apache/directory/studio/ldapbrowser/core/utils/Utils.java
@@ -657,4 +657,31 @@ public class Utils
return LdifAttrValLine.create( attribute.getDescription(), value.getStringValue() );
}
}
+
+
+ /**
+ * Decodes the RFC 4517 Postal Address syntax.
+ *
+ * <pre>
+ * PostalAddress = line *( DOLLAR line )
+ * line = 1*line-char
+ * line-char = %x00-23
+ * / (%x5C "24") ; escaped "$"
+ * / %x25-5B
+ * / (%x5C "5C") ; escaped "\"
+ * / %x5D-7F
+ * / UTFMB
+ * </pre>
+ *
+ * @param input the encoded string
+ * @param separator the separator to output between address lines
+ * @return the decoded string
+ */
+ public static String decodePostalAddress( String input, String separator )
+ {
+ return input.replace( "$", separator ) //$NON-NLS-1$
+ .replace( "\\24", "$" ) //$NON-NLS-1$ //$NON-NLS-2$
+ .replace( "\\5C", "\\" ) //$NON-NLS-1$ //$NON-NLS-2$
+ .replace( "\\5c", "\\" ); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
diff --git a/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java b/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java
new file mode 100644
index 000000000..d7c76ca57
--- /dev/null
+++ b/plugins/ldapbrowser.core/src/test/java/org/apache/directory/studio/ldapbrowser/core/utils/UtilsTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.directory.studio.ldapbrowser.core.utils;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import org.junit.jupiter.api.Test;
+
+
+public class UtilsTest
+{
+ @Test
+ public void testPostalAddressTrivial()
+ {
+ assertEquals( "abc", Utils.decodePostalAddress( "abc", "!" ) );
+ }
+
+
+ @Test
+ public void testPostalAddressEscaped()
+ {
+ assertEquals( "!", Utils.decodePostalAddress( "$", "!" ) );
+ assertEquals( "$", Utils.decodePostalAddress( "\\24", "!" ) );
+ assertEquals( "\\", Utils.decodePostalAddress( "\\5C", "!" ) );
+ assertEquals( "\\", Utils.decodePostalAddress( "\\5c", "!" ) );
+ }
+
+
+ @Test
+ public void testPostalAddressRfcExamples()
+ {
+ assertEquals( "1234 Main St.\nAnytown, CA 12345\nUSA",
+ Utils.decodePostalAddress( "1234 Main St.$Anytown, CA 12345$USA", "\n" ) );
+ assertEquals( "$1,000,000 Sweepstakes\nPO Box 1000000\nAnytown, CA 12345\nUSA",
+ Utils.decodePostalAddress( "\\241,000,000 Sweepstakes$PO Box 1000000$Anytown, CA 12345$USA", "\n" ) );
+ }
+}
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java
index fcf5291d2..0ff46aa15 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/ImportExportTest.java
@@ -625,7 +625,9 @@ public class ImportExportTest extends AbstractTestBase
store.setDefault( BrowserCoreConstants.PREFERENCE_FORMAT_CSV_ENCODING, "UTF-8" );
URL url = Platform.getInstanceLocation().getURL();
- final String file = url.getFile() + "ImportExportTest" + server.getType().name() + ".csv";
+ final String file = url.getFile()
+ + "ImportExportShouldPrefixFormulaWithApostropheTest"
+ + server.getType().name() + ".csv";
browserViewBot.selectEntry( path( GERMAN_UMLAUT_DN ) );
@@ -647,6 +649,44 @@ public class ImportExportTest extends AbstractTestBase
/**
+ * Export to CSV and checks that RFC 4517 Postal Address syntax is decoded.
+ */
+ @ParameterizedTest
+ @LdapServersSource
+ public void testExportCsvShouldDecodePostalAddress( TestLdapServer server ) throws Exception
+ {
+ connectionsViewBot.createTestConnection( server );
+ // set CSV encoding explicit to UTF-8, otherwise platform default encoding would be used
+ Preferences store = BrowserCorePlugin.getDefault().getPluginPreferences();
+ store.setDefault( BrowserCoreConstants.PREFERENCE_FORMAT_CSV_ENCODING, "UTF-8" );
+
+ URL url = Platform.getInstanceLocation().getURL();
+ final String file = url.getFile()
+ + "ImportExportShouldDecodePostalAddressTest"
+ + server.getType().name() + ".csv";
+
+ browserViewBot.selectEntry( path( USER1_DN ) );
+
+ // export CSV
+ ExportWizardBot wizardBot = browserViewBot.openExportCsvWizard();
+ assertTrue( wizardBot.isVisible() );
+ wizardBot.setReturningAttributes( "postalAddress" );
+ wizardBot.clickNextButton();
+ wizardBot.typeFile( file );
+ wizardBot.clickFinishButton();
+ wizardBot.waitTillExportFinished( file, 100 );
+
+ List<String> lines = FileUtils.readLines( new File( file ), StandardCharsets.UTF_8 );
+ // verify that the first line is header
+ assertEquals( "dn,postalAddress", lines.get( 0 ) );
+ // verify that the postal address is broken into several lines
+ assertEquals( "\"uid=user.1,ou=users,dc=example,dc=org\",\"Aaccf Amar", lines.get( 1 ) );
+ assertEquals( "27919 Broadway Street", lines.get( 2 ) );
+ assertEquals( "Tallahassee, DE 67698\"", lines.get( 3 ) );
+ }
+
+
+ /**
* Test for DIRSTUDIO-1160.
*
* Attributes silently dropped and not imported when import LDIF and provider is Apache Directory LDAP API.