<commit_before>/*
 *   Copyright 2005 The Apache Software Foundation
 *
 *   Licensed 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.ldap.common.codec.search;

import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NamingException;

import org.apache.asn1.codec.DecoderException;
import org.apache.asn1.ber.grammar.IGrammar;
import org.apache.asn1.ber.grammar.AbstractGrammar;
import org.apache.asn1.ber.grammar.GrammarTransition;
import org.apache.asn1.ber.grammar.GrammarAction;
import org.apache.asn1.ber.IAsn1Container;
import org.apache.asn1.ber.tlv.UniversalTag;
import org.apache.asn1.ber.tlv.TLV;
import org.apache.asn1.ber.tlv.Value;
import org.apache.asn1.util.IntegerDecoderException;
import org.apache.asn1.util.IntegerDecoder;
import org.apache.asn1.util.BooleanDecoder;
import org.apache.asn1.util.BooleanDecoderException;
import org.apache.ldap.common.codec.LdapConstants;
import org.apache.ldap.common.codec.LdapMessage;
import org.apache.ldap.common.codec.LdapMessageContainer;
import org.apache.ldap.common.codec.LdapStatesEnum;
import org.apache.ldap.common.codec.util.LdapString;
import org.apache.ldap.common.codec.util.LdapStringEncodingException;
import org.apache.ldap.common.name.LdapDN;
import org.apache.ldap.common.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * This class implements the SearchRequest LDAP message. All the actions are declared in this
 * class. As it is a singleton, these declaration are only done once.
 * 
 * If an action is to be added or modified, this is where the work is to be done !
 * 
 * @author <a href="mailto:<EMAIL>">Apache Directory Project</a>
 */
public class SearchRequestGrammar extends AbstractGrammar implements IGrammar
{
    //~ Static fields/initializers -----------------------------------------------------------------

    /** The logger */
    private static final Logger log = LoggerFactory.getLogger( SearchRequestGrammar.class );

    /** The instance of grammar. SearchRequestGrammar is a singleton */
    private static IGrammar instance = new SearchRequestGrammar();

    //~ Constructors -------------------------------------------------------------------------------

    /**
     * Creates a new SearchRequestGrammar object.
     */
    private SearchRequestGrammar()
    {
        name       = SearchRequestGrammar.class.getName();
        statesEnum = LdapStatesEnum.getInstance();

        // Create the transitions table
        super.transitions = new GrammarTransition[LdapStatesEnum.LAST_SEARCH_REQUEST_STATE][256];

        //============================================================================================
        // SearchRequest Message
        //============================================================================================
        // LdapMessage   ::= ... SearchRequest ...
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { (Tag)
        //     ...
        // Nothing to do
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_TAG][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_TAG, LdapStatesEnum.SEARCH_REQUEST_VALUE, null );

        // LdapMessage   ::= ... SearchRequest ...
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { ... (Value)
        // Nothing to do.
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_VALUE][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_VALUE, LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_TAG,
                new GrammarAction( "Init SearchRequest" )
                {
                    public void action( IAsn1Container container ) 
                    {

                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer )
                            container;
                        LdapMessage      ldapMessage          =
                            ldapMessageContainer.getLdapMessage();

                        // Now, we can allocate the SearchRequest
                        // And we associate it to the ldapMessage Object
                        ldapMessage.setProtocolOP( new SearchRequest() );
                    }
                });

        // SearchRequest ::= [APPLICATION 3] SEQUENCE { 
        //    baseObject      LDAPDN, (Tag)
        //    ...
        // Nothing to do.
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_TAG][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_TAG, LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_VALUE,
                null);
        
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { 
        //    baseObject      LDAPDN, (Value)
        //    ...
        // We have a value for the base object, we will store it in the message
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_VALUE][UniversalTag.OCTET_STRING_TAG] =
            new GrammarTransition( LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_VALUE,
                LdapStatesEnum.SEARCH_REQUEST_SCOPE_TAG,
                new GrammarAction( "store base object value" )
                {
                    public void action( IAsn1Container container ) throws DecoderException
                    {

                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer )
                            container;

                        SearchRequest     searchRequest =
                            ldapMessageContainer.getLdapMessage().getSearchRequest();

                        TLV                  tlv = ldapMessageContainer.getCurrentTLV();

                        // We have to check that this is a correct DN
                        Name baseObject = LdapDN.EMPTY_LDAPDN;
                        
                        // We have to handle the special case of a 0 length base object,
                        // which means that the search is done from the default root.
                        if ( tlv.getLength().getLength() != 0 )
                        {
                            try
                            {
                                baseObject = new LdapDN( tlv.getValue().getData() );
                                baseObject = LdapDN.normalize( baseObject );
                            }
                            catch ( InvalidNameException ine )
                            {
                            	String msg = "The root DN " + baseObject.toString() + " is invalid"; 
                                log.error( msg + " : " + ine.getMessage());
                                throw new DecoderException( msg, ine );
                            }
                            catch ( NamingException ne )
                            {
                            	String msg = "The root DN " + baseObject.toString() + " cannot be modified";
                                log.error( msg + " : " + ne.getMessage() );
                                throw new DecoderException( msg, ne );
                            }
                        }
                        
                        searchRequest.setBaseObject(baseObject);

                        log.debug( "Searching with root DN : {}", baseObject );
                       
                        return;
                    }
                } );

        // SearchRequest ::= [APPLICATION 3] SEQUENCE {
        //    ...
        //    scope           ENUMERATED {
        //        baseObject              (0),
        //        singleLevel             (1),
        //        wholeSubtree            (2) }, (Tag)
        //    ...
        // Nothing to do.
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_SCOPE_TAG][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_SCOPE_TAG, LdapStatesEnum.SEARCH_REQUEST_SCOPE_VALUE,
                null);
        
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { 
        //    ...<commit_msg>Fixed the logs<commit_after>/*
 *   Copyright 2005 The Apache Software Foundation
 *
 *   Licensed 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.ldap.common.codec.search;

import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NamingException;

import org.apache.asn1.codec.DecoderException;
import org.apache.asn1.ber.grammar.IGrammar;
import org.apache.asn1.ber.grammar.AbstractGrammar;
import org.apache.asn1.ber.grammar.GrammarTransition;
import org.apache.asn1.ber.grammar.GrammarAction;
import org.apache.asn1.ber.IAsn1Container;
import org.apache.asn1.ber.tlv.UniversalTag;
import org.apache.asn1.ber.tlv.TLV;
import org.apache.asn1.ber.tlv.Value;
import org.apache.asn1.util.IntegerDecoderException;
import org.apache.asn1.util.IntegerDecoder;
import org.apache.asn1.util.BooleanDecoder;
import org.apache.asn1.util.BooleanDecoderException;
import org.apache.ldap.common.codec.LdapConstants;
import org.apache.ldap.common.codec.LdapMessage;
import org.apache.ldap.common.codec.LdapMessageContainer;
import org.apache.ldap.common.codec.LdapStatesEnum;
import org.apache.ldap.common.codec.util.LdapString;
import org.apache.ldap.common.codec.util.LdapStringEncodingException;
import org.apache.ldap.common.name.LdapDN;
import org.apache.ldap.common.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * This class implements the SearchRequest LDAP message. All the actions are declared in this
 * class. As it is a singleton, these declaration are only done once.
 * 
 * If an action is to be added or modified, this is where the work is to be done !
 * 
 * @author <a href="mailto:<EMAIL>">Apache Directory Project</a>
 */
public class SearchRequestGrammar extends AbstractGrammar implements IGrammar
{
    //~ Static fields/initializers -----------------------------------------------------------------

    /** The logger */
    private static final Logger log = LoggerFactory.getLogger( SearchRequestGrammar.class );

    /** The instance of grammar. SearchRequestGrammar is a singleton */
    private static IGrammar instance = new SearchRequestGrammar();

    //~ Constructors -------------------------------------------------------------------------------

    /**
     * Creates a new SearchRequestGrammar object.
     */
    private SearchRequestGrammar()
    {
        name       = SearchRequestGrammar.class.getName();
        statesEnum = LdapStatesEnum.getInstance();

        // Create the transitions table
        super.transitions = new GrammarTransition[LdapStatesEnum.LAST_SEARCH_REQUEST_STATE][256];

        //============================================================================================
        // SearchRequest Message
        //============================================================================================
        // LdapMessage   ::= ... SearchRequest ...
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { (Tag)
        //     ...
        // Nothing to do
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_TAG][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_TAG, LdapStatesEnum.SEARCH_REQUEST_VALUE, null );

        // LdapMessage   ::= ... SearchRequest ...
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { ... (Value)
        // Nothing to do.
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_VALUE][LdapConstants.SEARCH_REQUEST_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_VALUE, LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_TAG,
                new GrammarAction( "Init SearchRequest" )
                {
                    public void action( IAsn1Container container ) 
                    {

                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer )
                            container;
                        LdapMessage      ldapMessage          =
                            ldapMessageContainer.getLdapMessage();

                        // Now, we can allocate the SearchRequest
                        // And we associate it to the ldapMessage Object
                        ldapMessage.setProtocolOP( new SearchRequest() );
                    }
                });

        // SearchRequest ::= [APPLICATION 3] SEQUENCE { 
        //    baseObject      LDAPDN, (Tag)
        //    ...
        // Nothing to do.
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_TAG][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_TAG, LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_VALUE,
                null);
        
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { 
        //    baseObject      LDAPDN, (Value)
        //    ...
        // We have a value for the base object, we will store it in the message
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_VALUE][UniversalTag.OCTET_STRING_TAG] =
            new GrammarTransition( LdapStatesEnum.SEARCH_REQUEST_BASE_OBJECT_VALUE,
                LdapStatesEnum.SEARCH_REQUEST_SCOPE_TAG,
                new GrammarAction( "store base object value" )
                {
                    public void action( IAsn1Container container ) throws DecoderException
                    {

                        LdapMessageContainer ldapMessageContainer = ( LdapMessageContainer )
                            container;

                        SearchRequest     searchRequest =
                            ldapMessageContainer.getLdapMessage().getSearchRequest();

                        TLV                  tlv = ldapMessageContainer.getCurrentTLV();

                        // We have to check that this is a correct DN
                        Name baseObject = LdapDN.EMPTY_LDAPDN;
                        
                        // We have to handle the special case of a 0 length base object,
                        // which means that the search is done from the default root.
                        if ( tlv.getLength().getLength() != 0 )
                        {
                            try
                            {
                                baseObject = new LdapDN( tlv.getValue().getData() );
                                baseObject = LdapDN.normalize( baseObject );
                            }
                            catch ( InvalidNameException ine )
                            {
                            	String msg = "The root DN " + baseObject.toString() + " is invalid"; 
                                log.error( "{} : {}", msg, ine.getMessage());
                                throw new DecoderException( msg, ine );
                            }
                            catch ( NamingException ne )
                            {
                            	String msg = "The root DN " + baseObject.toString() + " cannot be modified";
                                log.error( "{} : {}", msg, ne.getMessage() );
                                throw new DecoderException( msg, ne );
                            }
                        }
                        
                        searchRequest.setBaseObject(baseObject);

                        log.debug( "Searching with root DN : {}", baseObject );
                       
                        return;
                    }
                } );

        // SearchRequest ::= [APPLICATION 3] SEQUENCE {
        //    ...
        //    scope           ENUMERATED {
        //        baseObject              (0),
        //        singleLevel             (1),
        //        wholeSubtree            (2) }, (Tag)
        //    ...
        // Nothing to do.
        super.transitions[LdapStatesEnum.SEARCH_REQUEST_SCOPE_TAG][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
                LdapStatesEnum.SEARCH_REQUEST_SCOPE_TAG, LdapStatesEnum.SEARCH_REQUEST_SCOPE_VALUE,
                null);
        
        // SearchRequest ::= [APPLICATION 3] SEQUENCE { 
        //    ...
{'fraction_non_alphanumeric': 0.11842181945334809, 'fraction_numerical': 0.004662276356431028, 'mean_word_length': 1.7139016289735884, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6724682', 'n_tokens_mistral': 4421, 'n_tokens_neox': 4268, 'n_words': 988}