blob: 3bfaafc6a77cbf2e553e67e5ba91850b82fab07f [file] [log] [blame]
/*
* 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.jobs;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.text.translate.CharSequenceTranslator;
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;
import org.apache.directory.studio.ldapbrowser.core.BrowserCoreConstants;
import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
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;
import org.apache.poi.hssf.usermodel.HSSFCell;
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;
/**
* Runnable to export directory content to an XLS file.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class ExportXlsRunnable implements StudioConnectionRunnableWithProgress
{
/** The maximum count limit */
public static final int MAX_COUNT_LIMIT = 65000;
/** The postal address decoder. */
private static CharSequenceTranslator DECODER = Utils.createPostalAddressDecoder( "\n" ); //$NON-NLS-1$;
/** The filename of the XLS file. */
private String exportXlsFilename;
/** The browser connection. */
private IBrowserConnection browserConnection;
/** The search parameter. */
private SearchParameter searchParameter;
/** The export dn flag. */
private boolean exportDn;
/**
* Creates a new instance of ExportXlsRunnable.
*
* @param exportLdifFilename the export ldif filename
* @param browserConnection the browser connection
* @param searchParameter the search parameter
* @param exportDn true to export the Dn
*/
public ExportXlsRunnable( String exportLdifFilename, IBrowserConnection browserConnection,
SearchParameter searchParameter, boolean exportDn )
{
this.exportXlsFilename = exportLdifFilename;
this.browserConnection = browserConnection;
this.searchParameter = searchParameter;
this.exportDn = exportDn;
}
/**
* {@inheritDoc}
*/
public Connection[] getConnections()
{
return new Connection[]
{ browserConnection.getConnection() };
}
/**
* {@inheritDoc}
*/
public String getName()
{
return BrowserCoreMessages.jobs__export_xls_name;
}
/**
* {@inheritDoc}
*/
public Object[] getLockedObjects()
{
return new Object[]
{ browserConnection.getUrl() + "_" + DigestUtils.shaHex( exportXlsFilename ) }; //$NON-NLS-1$
}
/**
* {@inheritDoc}
*/
public String getErrorMessage()
{
return BrowserCoreMessages.jobs__export_xls_error;
}
/**
* {@inheritDoc}
*/
public void run( StudioProgressMonitor monitor )
{
monitor.beginTask( BrowserCoreMessages.jobs__export_xls_task, 2 );
monitor.reportProgress( " " ); //$NON-NLS-1$
monitor.worked( 1 );
Preferences coreStore = BrowserCorePlugin.getDefault().getPluginPreferences();
String valueDelimiter = coreStore.getString( BrowserCoreConstants.PREFERENCE_FORMAT_XLS_VALUEDELIMITER );
int binaryEncoding = coreStore.getInt( BrowserCoreConstants.PREFERENCE_FORMAT_XLS_BINARYENCODING );
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet( "Export" ); //$NON-NLS-1$
// header
HSSFRow headerRow = sheet.createRow( 0 );
LinkedHashMap<String, Integer> attributeNameMap = new LinkedHashMap<String, Integer>();
if ( this.exportDn )
{
int cellNum = 0;
attributeNameMap.put( "dn", cellNum ); //$NON-NLS-1$
createStringCell( headerRow, cellNum ).setCellValue( "dn" ); //$NON-NLS-1$
}
// max export
if ( searchParameter.getCountLimit() < 1 || searchParameter.getCountLimit() > MAX_COUNT_LIMIT )
{
searchParameter.setCountLimit( MAX_COUNT_LIMIT );
}
// export
try
{
int count = 0;
exportToXls( browserConnection, searchParameter, sheet, headerRow, count, monitor, attributeNameMap,
valueDelimiter, binaryEncoding, this.exportDn );
}
catch ( Exception e )
{
monitor.reportError( e );
}
// column width
for ( int i = 0; i <= sheet.getLastRowNum(); i++ )
{
HSSFRow row = sheet.getRow( i );
for ( short j = 0; row != null && j <= row.getLastCellNum(); j++ )
{
HSSFCell cell = row.getCell( j );
if ( cell != null && cell.getCellType() == HSSFCell.CELL_TYPE_STRING )
{
String value = cell.getStringCellValue();
if ( ( short ) ( value.length() * 256 * 1.1 ) > sheet.getColumnWidth( j ) )
{
sheet.setColumnWidth( j, ( short ) ( value.length() * 256 * 1.1 ) );
}
}
}
}
try
{
FileOutputStream fileOut = new FileOutputStream( exportXlsFilename );
wb.write( fileOut );
fileOut.close();
}
catch ( Exception e )
{
monitor.reportError( e );
}
}
/**
* Exports to XLS.
*
* @param browserConnection the browser connection
* @param searchParameter the search parameter
* @param sheet the sheet
* @param headerRow the header row
* @param count the count
* @param monitor the monitor
* @param attributeNameMap the attribute name map
* @param valueDelimiter the value delimiter
* @param binaryEncoding the binary encoding
* @param exportDn the export dn
*
* @throws IOException Signals that an I/O exception has occurred.
*/
private static void exportToXls( IBrowserConnection browserConnection, SearchParameter searchParameter,
HSSFSheet sheet, HSSFRow headerRow, int count, StudioProgressMonitor monitor,
LinkedHashMap<String, Integer> attributeNameMap, String valueDelimiter, int binaryEncoding, boolean exportDn )
throws IOException
{
try
{
LdifEnumeration enumeration = ExportLdifRunnable.search( browserConnection, searchParameter, monitor );
while ( !monitor.isCanceled() && !monitor.errorsReported() && enumeration.hasNext() )
{
LdifContainer container = enumeration.next();
if ( container instanceof LdifContentRecord )
{
LdifContentRecord record = ( LdifContentRecord ) container;
recordToHSSFRow( browserConnection, record, sheet, headerRow, attributeNameMap, valueDelimiter,
binaryEncoding, exportDn );
count++;
monitor.reportProgress( BrowserCoreMessages.bind( BrowserCoreMessages.jobs__export_progress,
new String[]
{ Integer.toString( count ) } ) );
}
}
}
catch ( LdapException ne )
{
int ldapStatusCode = JNDIUtils.getLdapStatusCode( ne );
if ( ldapStatusCode == 3 || ldapStatusCode == 4 || ldapStatusCode == 11 )
{
// nothing
}
else
{
monitor.reportError( ne );
}
}
}
/**
* Transforms an LDIF record to an HSSF row.
*
* @param browserConnection the browser connection
* @param record the record
* @param sheet the sheet
* @param headerRow the header row
* @param headerRowAttributeNameMap the header row attribute name map
* @param valueDelimiter the value delimiter
* @param binaryEncoding the binary encoding
* @param exportDn the export dn
*/
private static void recordToHSSFRow( IBrowserConnection browserConnection, LdifContentRecord record,
HSSFSheet sheet, HSSFRow headerRow, Map<String, Integer> headerRowAttributeNameMap, String valueDelimiter,
int binaryEncoding, boolean exportDn )
{
// group multi-valued attributes
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 )
{
HSSFCell cell = createStringCell(row, 0 );
cell.setCellValue( record.getDnLine().getValueAsString() );
}
for ( String attributeName : attributeMap.keySet() )
{
String value = attributeMap.get( attributeName );
if ( !headerRowAttributeNameMap.containsKey( attributeName ) )
{
int cellNum = headerRowAttributeNameMap.size();
headerRowAttributeNameMap.put( attributeName, new Integer( cellNum ) );
HSSFCell cell = createStringCell( headerRow, cellNum );
cell.setCellValue( attributeName );
}
if ( headerRowAttributeNameMap.containsKey( attributeName ) )
{
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 = DECODER.translate( value );
cell.setCellStyle( wrapStyle );
}
cell.setCellValue( value );
}
}
}
private static HSSFCell createStringCell( HSSFRow row, int cellNum )
{
HSSFCell cell = row.createCell( cellNum );
cell.setCellType( Cell.CELL_TYPE_STRING );
return cell;
}
}