<commit_before>/*
 *  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.mitosis.syncrepl;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.apache.commons.io.FileUtils;
import org.apache.directory.server.core.DefaultDirectoryService;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.server.ldap.LdapService;
import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.directory.shared.ldap.filter.SearchScope;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.mina.util.AvailablePortFinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 *  A simple swing UI to start stop syncrepl consumer.
 *  This class avoids the costly operation of setting up config 
 *  and directory service between start/stop of consumer.
 *  
 * @author <a href="mailto:<EMAIL>">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class SyncreplRunnerUI implements ActionListener
{
    private SyncreplConfiguration config;
    
    private SyncreplConsumer agent = new SyncreplConsumer();
    
    private File workDir;
    
    private DirectoryService dirService;
    
    private static final Logger LOG = LoggerFactory.getLogger( SyncreplRunnerUI.class );
    
    // UI components
    private JButton btnStart;
    
    private JButton btnStop;
    
    private JButton btnCleanStart;
    
    public SyncreplRunnerUI()
    {
        config = new SyncreplConfiguration();
        config.setProviderHost( "localhost" );
        config.setPort( 389 );
        config.setBindDn( "cn=admin,dc=nodomain" );
        config.setCredentials( "secret" );
        config.setBaseDn( "dc=test,dc=nodomain" );
        config.setFilter( "(objectclass=*)" );
        config.setSearchScope( SearchScope.SUBTREE.getJndiScope() );
        config.setReplicaId( 1 );
        agent.setConfig( config );
        
        workDir = new File( System.getProperty( "java.io.tmpdir" ) + "/work" );
    }

    
    public void start()
    {
        if ( ! workDir.exists() )
        {
            workDir.mkdirs();
        }

        dirService = startEmbeddedServer( workDir );
        
        agent.init( dirService );
        agent.connect();
        agent.bind();
        agent.prepareSyncSearchRequest();
        agent.startSync();
    }

    public void stop()
    {
        try
        {
            agent.disconnet();
            dirService.shutdown();
        }
        catch( Exception e )
        {
            LOG.error( "Failed to stop", e );
        }
    }
    
    public void cleanStart()
    {
        try
        {
            if( workDir.exists() )
            {
                FileUtils.forceDelete( workDir );
            }
        }
        catch( Exception e )
        {
            LOG.error( "Failed to delete the work directory", e );
        }

        agent.deleteCookieFile();
        start();
    }
    
    
    private DirectoryService startEmbeddedServer( File workDir )
    {
        try
        {
            DefaultDirectoryService dirService = new DefaultDirectoryService();
            dirService.setShutdownHookEnabled( false );
            dirService.setWorkingDirectory( workDir );
            int consumerPort = AvailablePortFinder.getNextAvailable( 1024 );
            LdapService ldapService = new LdapService();
            ldapService.setTcpTransport( new TcpTransport( consumerPort ) );
            ldapService.setDirectoryService( dirService );

            LdapDN suffix = new LdapDN( config.getBaseDn() );
            JdbmPartition partition = new JdbmPartition();
            partition.setSuffix( suffix.getUpName() );
            partition.setId( "syncrepl" );
            partition.setSyncOnWrite( true );
            partition.init( dirService );

            dirService.addPartition( partition );

            dirService.startup();

            ldapService.addExtendedOperationHandler( new StartTlsHandler() );
            ldapService.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );

            ldapService.start();
            return dirService;
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        
        return null;
    }

    public void show()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        
        btnStart = new JButton( "Start" );
        btnStart.setMnemonic( 'S' );
        btnStart.addActionListener( this );
        
        
        btnCleanStart = new JButton( "Clean Start" );
        btnCleanStart.setMnemonic( 'R' );
        btnCleanStart.addActionListener( this );
        
        btnStop = new JButton( "Stop" );
        btnStop.setMnemonic( 'O' );
        btnStop.setEnabled( false );
        btnStop.addActionListener( this );
        
        JPanel panel = new JPanel();
        panel.add( btnStart );
        panel.add( btnStop );
        panel.add( btnCleanStart );
        
        frame.getContentPane().add( panel );
        frame.addWindowListener( new WindowAdapter()
        {
            @Override
            public void windowClosed( WindowEvent e )
            {
                stop();
            }
        });

        frame.pack();
        frame.setVisible( true );
    }


    public void actionPerformed( ActionEvent e )
    {
        Object src = e.getSource();
        
        if( src == btnStart )
        {
            btnStart.setEnabled( false );
            btnCleanStart.setEnabled( false );
            start();
            btnStop.setEnabled( true );
        }
        else if( src == btnStop )
        {
            btnStop.setEnabled( false );
            stop();
            btnStart.setEnabled( true );
            btnCleanStart.setEnabled( true );
        }
        else if( src == btnCleanStart )
        {
            btnCleanStart.setEnabled( false );
            btnStart.setEnabled( false );

            cleanStart();
            btnStop.setEnabled( true );
        }
    }


    public static void main( String[] args )<commit_msg>o fixed an issue with stopping embedded server o made the action methods to run in a separate thread<commit_after>/*
 *  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.mitosis.syncrepl;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import org.apache.commons.io.FileUtils;
import org.apache.directory.server.core.DefaultDirectoryService;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.server.ldap.LdapService;
import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
import org.apache.directory.shared.ldap.filter.SearchScope;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.mina.util.AvailablePortFinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 *  A simple swing UI to start stop syncrepl consumer.
 *  This class avoids the costly operation of setting up config 
 *  and directory service between start/stop of consumer.
 *  
 * @author <a href="mailto:<EMAIL>">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class SyncreplRunnerUI implements ActionListener
{
    private SyncreplConfiguration config;
    
    private SyncreplConsumer agent = new SyncreplConsumer();
    
    private File workDir;
    
    private DirectoryService dirService;
    
    private LdapService ldapService;
    
    private static final Logger LOG = LoggerFactory.getLogger( SyncreplRunnerUI.class );
    
    // UI components
    private JButton btnStart;
    
    private JButton btnStop;
    
    private JButton btnCleanStart;
    
    public SyncreplRunnerUI()
    {
        config = new SyncreplConfiguration();
        config.setProviderHost( "localhost" );
        config.setPort( 389 );
        config.setBindDn( "cn=admin,dc=nodomain" );
        config.setCredentials( "secret" );
        config.setBaseDn( "dc=test,dc=nodomain" );
        config.setFilter( "(objectclass=*)" );
        config.setSearchScope( SearchScope.SUBTREE.getJndiScope() );
        config.setReplicaId( 1 );
        agent.setConfig( config );
        
        workDir = new File( System.getProperty( "java.io.tmpdir" ) + "/work" );
    }

    
    public void start()
    {
        try
        {
            if ( ! workDir.exists() )
            {
                workDir.mkdirs();
            }
            
            dirService = startEmbeddedServer( workDir );
            
            agent.init( dirService );
            agent.connect();
            agent.bind();
            agent.prepareSyncSearchRequest();
            agent.startSync();
        }
        catch( Exception e )
        {
            LOG.error( "Failed to start the embedded server & syncrepl consumer", e );
            throw new RuntimeException( e );
        }
    }

    public void stop()
    {
        try
        {
            agent.disconnet();
            dirService.shutdown();
            ldapService.stop();
        }
        catch( Exception e )
        {
            LOG.error( "Failed to stop", e );
        }
    }
    
    public void cleanStart()
    {
        try
        {
            if( workDir.exists() )
            {
                FileUtils.forceDelete( workDir );
            }
        }
        catch( Exception e )
        {
            LOG.error( "Failed to delete the work directory", e );
        }

        agent.deleteCookieFile();
        start();
    }
    
    
    private DirectoryService startEmbeddedServer( File workDir )
    {
        try
        {
            DefaultDirectoryService dirService = new DefaultDirectoryService();
            dirService.setShutdownHookEnabled( false );
            dirService.setWorkingDirectory( workDir );
            int consumerPort = AvailablePortFinder.getNextAvailable( 1024 );
            ldapService = new LdapService();
            ldapService.setTcpTransport( new TcpTransport( consumerPort ) );
            ldapService.setDirectoryService( dirService );

            LdapDN suffix = new LdapDN( config.getBaseDn() );
            JdbmPartition partition = new JdbmPartition();
            partition.setSuffix( suffix.getUpName() );
            partition.setId( "syncrepl" );
            partition.setSyncOnWrite( true );
            partition.init( dirService );

            dirService.addPartition( partition );

            dirService.startup();

            ldapService.addExtendedOperationHandler( new StartTlsHandler() );
            ldapService.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );

            ldapService.start();
            return dirService;
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
        
        return null;
    }

    public void show()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setTitle( "Syncrepl consumer UI" );
        
        btnStart = new JButton( "Start" );
        btnStart.setMnemonic( 'S' );
        btnStart.addActionListener( this );
        
        
        btnCleanStart = new JButton( "Clean Start" );
        btnCleanStart.setMnemonic( 'R' );
        btnCleanStart.addActionListener( this );
        
        btnStop = new JButton( "Stop" );
        btnStop.setMnemonic( 'O' );
        btnStop.setEnabled( false );
        btnStop.addActionListener( this );
        
        JPanel panel = new JPanel();
        panel.add( btnStart );
        panel.add( btnStop );
        panel.add( btnCleanStart );
        
        frame.getContentPane().add( panel );
        frame.addWindowListener( new WindowAdapter()
        {
            @Override
            public void windowClosed( WindowEvent e )
            {
                stop();
            }
        });

        frame.pack();
        frame.setVisible( true );
    }


    public void actionPerformed( ActionEvent e )
    {
        Object src = e.getSource();
        
        if( src == btnStart )
        {
            btnStart.setEnabled( false );
            btnCleanStart.setEnabled( false );
            SwingUtilities.invokeLater( new Runnable()
            {
                public void run()
                {
                    start();
                }
            } );
            btnStop.setEnabled( true );
        }
        else if( src == btnStop )
        {
            btnStop.setEnabled( false );
            SwingUtilities.invokeLater( new Runnable()
            {
                public void run()
                {
                    stop();
                }
            } );

            btnStart.setEnabled( true );
            btnCleanStart.setEnabled( true );
        }
        else if( src == btnCleanStart )
        {
            btnCleanStart.setEnabled( false );
            btnStart.setEnabled( false );

            SwingUtilities.invokeLater( new Runnable()
            {
                public void run()
                {
                    cleanStart();
                }
            } );
            btnStop.setEnabled( true );
        }
    }


    public static void main( String[] args )
{'fraction_non_alphanumeric': 0.09251241563733605, 'fraction_numerical': 0.0017827581815866547, 'mean_word_length': 2.0310690852952527, '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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3319677', 'n_tokens_mistral': 4271, 'n_tokens_neox': 4186, 'n_words': 1017}