/*
 * Copyright (c) 2017 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.wso2.carbon.transport.remotefilesystem.server.util;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * A Thread Pool factory for creating Thread Pools required for the File System transport
 */
public class ThreadPoolFactory {
    private ExecutorService executorService;

    public ThreadPoolFactory(int threadPoolSize) {
        if (threadPoolSize == 0) {
            executorService = Executors.newSingleThreadExecutor(new CustomThreadFactory());
        } else {
            executorService = Executors.newFixedThreadPool(threadPoolSize, new CustomThreadFactory());
        }
    }

    /**
     * Execute given runnable target.
     *
     * @param runnable RemoteFileSystemProcessor instance.
     */
    public void execute(Runnable runnable) {
        executorService.execute(runnable);
    }

    /**
     * Stop all the executing thread and shutdown the pool.
     */
    public void stop() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(500, TimeUnit.MILLISECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
    }

    /**
     * Custom thread factory class implementation.
     * This will allow us to provide a name for threads.
     * Edited original java.util.concurrent.DefaultThreadFactory implementation.
     */
    static class CustomThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        CustomThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
            namePrefix = "remote-file-" +
                    poolNumber.getAndIncrement() +
                    "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }
}

@@ -3105,17 +3105,19 @@
 aemon())
+ %7B
 %0A
-
         
@@ -3140,24 +3140,38 @@
 mon(false);%0A
+            %7D%0A
             
@@ -3214,16 +3214,18 @@
 RIORITY)
+ %7B
 %0A       
@@ -3270,16 +3270,30 @@
 ORITY);%0A
+            %7D%0A
         

Add CheckStyle suggestion