<commit_before>/**
 * Copyright (c) 2014-2016 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.smarthome.core.service;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Base class for OSGI services that access to file system by Java WatchService. <br />
 * See the WatchService <a href=
 * "http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html"
 * >java docs</a> for more details
 *
 * @author <NAME>
 *
 */
public abstract class AbstractWatchService {

    /**
     * Default logger for ESH Watch Services
     */
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * The WatchService
     */
    protected WatchService watchService;

    /**
     * The queue reader
     */
    protected AbstractWatchQueueReader watchQueueReader;

    /**
     * Method to call on service activation
     */
    public void activate() {
        initializeWatchService();
    }

    /**
     * Method to call on service deactivation
     */
    public void deactivate() {
        stopWatchService();
    }

    protected void initializeWatchService() {
        if (watchService != null) {
            try {
                watchService.close();
            } catch (IOException e) {
                logger.warn("Cannot deactivate folder watcher", e);
            }
        }

        String pathToWatch = getSourcePath();
        if (StringUtils.isNotBlank(pathToWatch)) {
            Path toWatch = Paths.get(pathToWatch);
            try {
                if (watchSubDirectories()) {
                    watchService = FileSystems.getDefault().newWatchService();

                    Files.walkFileTree(toWatch, new SimpleFileVisitor<Path>() {
                        @Override
                        public FileVisitResult preVisitDirectory(Path subDir, BasicFileAttributes attrs)
                                throws IOException {
                            registerDirectory(subDir);
                            return FileVisitResult.CONTINUE;
                        }
                    });
                } else {
                    watchService = toWatch.getFileSystem().newWatchService();
                    registerDirectory(toWatch);
                }

                AbstractWatchQueueReader reader = buildWatchQueueReader(watchService, toWatch);

                Thread qr = new Thread(reader, "Dir Watcher");<commit_msg>Added follow symlink option to abstract watch service. (#2036)<commit_after>/**
 * Copyright (c) 2014-2016 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipse.smarthome.core.service;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Base class for OSGI services that access to file system by Java WatchService. <br />
 * See the WatchService <a href=
 * "http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html"
 * >java docs</a> for more details
 *
 * @author <NAME>
 *
 */
public abstract class AbstractWatchService {

    /**
     * Default logger for ESH Watch Services
     */
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * The WatchService
     */
    protected WatchService watchService;

    /**
     * The queue reader
     */
    protected AbstractWatchQueueReader watchQueueReader;

    /**
     * Method to call on service activation
     */
    public void activate() {
        initializeWatchService();
    }

    /**
     * Method to call on service deactivation
     */
    public void deactivate() {
        stopWatchService();
    }

    protected void initializeWatchService() {
        if (watchService != null) {
            try {
                watchService.close();
            } catch (IOException e) {
                logger.warn("Cannot deactivate folder watcher", e);
            }
        }

        String pathToWatch = getSourcePath();
        if (StringUtils.isNotBlank(pathToWatch)) {
            Path toWatch = Paths.get(pathToWatch);
            try {
                if (watchSubDirectories()) {
                    watchService = FileSystems.getDefault().newWatchService();

                    // walk through all folders and follow symlinks
                    Files.walkFileTree(toWatch, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, 
                    		new SimpleFileVisitor<Path>() {
                        @Override
                        public FileVisitResult preVisitDirectory(Path subDir, BasicFileAttributes attrs)
                                throws IOException {
                            registerDirectory(subDir);
                            return FileVisitResult.CONTINUE;
                        }
                    });
                } else {
                    watchService = toWatch.getFileSystem().newWatchService();
                    registerDirectory(toWatch);
                }

                AbstractWatchQueueReader reader = buildWatchQueueReader(watchService, toWatch);

                Thread qr = new Thread(reader, "Dir Watcher");
{'fraction_non_alphanumeric': 0.09199048374306107, 'fraction_numerical': 0.005392545598731166, 'mean_word_length': 2.164074259909684, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, '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': '5901315', 'n_tokens_mistral': 1663, 'n_tokens_neox': 1569, 'n_words': 412}