<commit_before> /**********************************************************************
 **                                                                   **
 **               This code belongs to the KETTLE project.            **
 **                                                                   **
 ** Kettle, from version 2.2 on, is released into the public domain   **
 ** under the Lesser GNU Public License (LGPL).                       **
 **                                                                   **
 ** For more details, please read the document LICENSE.txt, included  **
 ** in this project                                                   **
 **                                                                   **
 ** http://www.kettle.be                                              **
 ** <EMAIL>                                                    **
 **                                                                   **
 **********************************************************************/
 

package org.pentaho.di.trans.steps.ldapinput;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.row.RowDataUtil;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStep;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;

/**
 * Read LDAP Host, convert them to rows and writes these to one or more output streams.
 * 
 * @author Samatar
 * @since 21-09-2007
 */
public class LDAPInput extends BaseStep implements StepInterface
{
	private LDAPInputMeta meta;
	private LDAPInputData data;

	
	public LDAPInput(StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta, Trans trans)
	{
		super(stepMeta, stepDataInterface, copyNr, transMeta, trans);
	}
	
	public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
	{
    	
		String basedn=environmentSubstitute(meta.getBaseDn());
		String hostname=environmentSubstitute(meta.getHost());
		String username=environmentSubstitute(meta.getUserName());
		String password=environmentSubstitute(meta.getPassword());
        //Set the filter string.  The more exact of the search string
		String filter=environmentSubstitute(meta.getFilterString());
		//Set the Search base.This is the place where the search will
		String searchbase=environmentSubstitute(meta.getSearchBase());
	
		
		NamingEnumeration<SearchResult> results=null;
		DirContext ctx = null;
		data.rownr=0;
		linesInput=0;
		
	    String [] attrReturned = new String [meta.getInputFields().length];
	    Object[] outputRowData = null;
        
        if (first)
        {
            first = false;
            // Create the output row meta-data
            data.outputRowMeta = new RowMeta();
            meta.getFields(data.outputRowMeta, getStepname(), null, null, this); // get the metadata populated
            
            
            // Create convert meta-data objects that will contain Date & Number formatters
            //
            data.convertRowMeta = data.outputRowMeta.clone();
            for (int i=0;i<data.convertRowMeta.size();i++) data.convertRowMeta.getValueMeta(i).setType(ValueMetaInterface.TYPE_STRING);

            
            
            // For String to <type> conversions, we allocate a conversion meta data row as well...
			//
			data.convertRowMeta = data.outputRowMeta.clone();
			for (int i=0;i<data.convertRowMeta.size();i++) {
				data.convertRowMeta.getValueMeta(i).setType(ValueMetaInterface.TYPE_STRING);           
            
			}
			
		   // Get user selection attributes
		   for (int i=0;i<meta.getInputFields().length;i++)
		   {
		    	attrReturned[i]=meta.getInputFields()[i].getAttribute();
			
		   }
        }
	
		try 
		{	

			// Try to connect to LDAP server
             ctx = connectServerLdap(hostname,username, password,basedn);

		     
		     if (ctx==null)
		     {
		    	 log.logError("Connection", "ERROR");
		     }
		     
		     log.logBasic("Connection", "Connected to server [{0}]",hostname);
		     if (log.isDetailed()) log.logDetailed("Class", "Class name [{0}]",ctx.getClass().getName());
		     // Get the schema tree root
		     DirContext schema = ctx.getSchema("");
		     
		     if (log.isDetailed()) log.logDetailed("Schema tree root", ""+schema.list(""));
		     
 
		     SearchControls controls = new SearchControls();
		     controls.setCountLimit(meta.getRowLimit());
		     //controls.setTimeLimit(0);
		    
		     // Limit returned attributes to user selection
		     controls.setReturningAttributes(attrReturned);
		
	         controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	         
	         results = ctx.search(searchbase,filter.replace("\n\r", "").replace("\n", ""), controls);
	        
	         // Get value for attributes

	         Attribute attr=null; 
	         String attrvalue=null;
	       
		       while (((meta.getRowLimit()>0 &&  data.rownr<meta.getRowLimit()) || meta.getRowLimit()==0)  && (results.hasMore()))  
				{
		    	    
	                SearchResult searchResult = (SearchResult) results.next();
	                Attributes attributes = searchResult.getAttributes();      
	                
					// Create new row				
					outputRowData = buildEmptyRow();
							
					// Execute for each Input field...
					for (int i=0;i<meta.getInputFields().length;i++)
					{
						// Get attribute value
		            	attr = attributes.get(meta.getInputFields()[i].getAttribute()); 
		                if (attr!=null) attrvalue=(String) attr.get();
		               
						// DO Trimming!
						switch (meta.getInputFields()[i].getTrimType())
						{
						case LDAPInputField.TYPE_TRIM_LEFT:
							attrvalue = Const.ltrim(attrvalue);
							break;
						case LDAPInputField.TYPE_TRIM_RIGHT:
							attrvalue = Const.rtrim(attrvalue);
							break;
						case LDAPInputField.TYPE_TRIM_BOTH:
							attrvalue = Const.trim(attrvalue);
							break;
						default:
							break;
						}
							      
						
						// DO CONVERSIONS...
						//
						ValueMetaInterface targetValueMeta = data.outputRowMeta.getValueMeta(i);
						ValueMetaInterface sourceValueMeta = data.convertRowMeta.getValueMeta(i);
						outputRowData[i] = targetValueMeta.convertData(sourceValueMeta, attrvalue);
						
						// Do we need to repeat this field if it is null?<commit_msg>code clean<commit_after> /**********************************************************************
 **                                                                   **
 **               This code belongs to the KETTLE project.            **
 **                                                                   **
 ** Kettle, from version 2.2 on, is released into the public domain   **
 ** under the Lesser GNU Public License (LGPL).                       **
 **                                                                   **
 ** For more details, please read the document LICENSE.txt, included  **
 ** in this project                                                   **
 **                                                                   **
 ** http://www.kettle.be                                              **
 ** <EMAIL>                                                    **
 **                                                                   **
 **********************************************************************/
 

package org.pentaho.di.trans.steps.ldapinput;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.row.RowDataUtil;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStep;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;

/**
 * Read LDAP Host, convert them to rows and writes these to one or more output streams.
 * 
 * @author Samatar
 * @since 21-09-2007
 */
public class LDAPInput extends BaseStep implements StepInterface
{
	private LDAPInputMeta meta;
	private LDAPInputData data;

	
	public LDAPInput(StepMeta stepMeta, StepDataInterface stepDataInterface, int copyNr, TransMeta transMeta, Trans trans)
	{
		super(stepMeta, stepDataInterface, copyNr, transMeta, trans);
	}
	
	public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
	{
    	
		String basedn=environmentSubstitute(meta.getBaseDn());
		String hostname=environmentSubstitute(meta.getHost());
		String username=environmentSubstitute(meta.getUserName());
		String password=environmentSubstitute(meta.getPassword());
        //Set the filter string.  The more exact of the search string
		String filter=environmentSubstitute(meta.getFilterString());
		//Set the Search base.This is the place where the search will
		String searchbase=environmentSubstitute(meta.getSearchBase());
	
		
		NamingEnumeration<SearchResult> results=null;
		DirContext ctx = null;
		data.rownr=0;
		linesInput=0;
		
	    String [] attrReturned = new String [meta.getInputFields().length];
	    Object[] outputRowData = null;
        
        if (first)
        {
            first = false;
            // Create the output row meta-data
            data.outputRowMeta = new RowMeta();
            meta.getFields(data.outputRowMeta, getStepname(), null, null, this); // get the metadata populated
            
            
            // Create convert meta-data objects that will contain Date & Number formatters
            //
            data.convertRowMeta = data.outputRowMeta.clone();
            for (int i=0;i<data.convertRowMeta.size();i++) data.convertRowMeta.getValueMeta(i).setType(ValueMetaInterface.TYPE_STRING);

            
            
            // For String to <type> conversions, we allocate a conversion meta data row as well...
			//
			data.convertRowMeta = data.outputRowMeta.clone();
			for (int i=0;i<data.convertRowMeta.size();i++) {
				data.convertRowMeta.getValueMeta(i).setType(ValueMetaInterface.TYPE_STRING);           
            
			}
			
		   // Get user selection attributes
		   for (int i=0;i<meta.getInputFields().length;i++)
		   {
		    	attrReturned[i]=environmentSubstitute(meta.getInputFields()[i].getAttribute());
			
		   }
        }
	
		try 
		{	

			// Try to connect to LDAP server
             ctx = connectServerLdap(hostname,username, password,basedn);

		     
		     if (ctx==null)
		     {
		    	 log.logError("Connection", "ERROR");
		     }
		     
		     log.logBasic("Connection", "Connected to server [{0}]",hostname);
		     if (log.isDetailed()) log.logDetailed("Class", "Class name [{0}]",ctx.getClass().getName());
		     // Get the schema tree root
		     DirContext schema = ctx.getSchema("");
		     
		     if (log.isDetailed()) log.logDetailed("Schema tree root", ""+schema.list(""));
		     
 
		     SearchControls controls = new SearchControls();
		     controls.setCountLimit(meta.getRowLimit());
		     //controls.setTimeLimit(0);
		    
		     // Limit returned attributes to user selection
		     controls.setReturningAttributes(attrReturned);
		
	         controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	         
	         results = ctx.search(searchbase,filter.replace("\n\r", "").replace("\n", ""), controls);
	        
	         // Get value for attributes

	         Attribute attr=null; 
	         String attrvalue=null;
	       
		       while (((meta.getRowLimit()>0 &&  data.rownr<meta.getRowLimit()) || meta.getRowLimit()==0)  && (results.hasMore()))  
				{
		    	    
	                SearchResult searchResult = (SearchResult) results.next();
	                Attributes attributes = searchResult.getAttributes();      
	                
					// Create new row				
					outputRowData = buildEmptyRow();
							
					// Execute for each Input field...
					for (int i=0;i<meta.getInputFields().length;i++)
					{
						// Get attribute value
		            	attr = attributes.get(environmentSubstitute(meta.getInputFields()[i].getAttribute())); 
		                if (attr!=null) attrvalue=(String) attr.get();
		               
						// DO Trimming!
						switch (meta.getInputFields()[i].getTrimType())
						{
						case LDAPInputField.TYPE_TRIM_LEFT:
							attrvalue = Const.ltrim(attrvalue);
							break;
						case LDAPInputField.TYPE_TRIM_RIGHT:
							attrvalue = Const.rtrim(attrvalue);
							break;
						case LDAPInputField.TYPE_TRIM_BOTH:
							attrvalue = Const.trim(attrvalue);
							break;
						default:
							break;
						}
							      
						
						// DO CONVERSIONS...
						//
						ValueMetaInterface targetValueMeta = data.outputRowMeta.getValueMeta(i);
						ValueMetaInterface sourceValueMeta = data.convertRowMeta.getValueMeta(i);
						outputRowData[i] = targetValueMeta.convertData(sourceValueMeta, attrvalue);
						
						// Do we need to repeat this field if it is null?
{'fraction_non_alphanumeric': 0.12446442368476505, 'fraction_numerical': 0.0029500597035892395, 'mean_word_length': 2.203870387038704, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3746355', 'n_tokens_mistral': 4328, 'n_tokens_neox': 3673, 'n_words': 802}