code: /**
   * This file is part of Eclipse Steady.
   *
   * 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.
   *
   * SPDX-License-Identifier: Apache-2.0
   * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors
   */
  package org.eclipse.steady;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.ServiceLoader;
  import java.util.Set;
  
  import org.apache.logging.log4j.Logger;
  import org.eclipse.steady.shared.util.FileUtil;
  
  /**
   * Creates instances of {@link FileAnalyzer}.
   */
  public class FileAnalyzerFactory {
  
    private static final Logger log =
        org.apache.logging.log4j.LogManager.getLogger(FileAnalyzerFactory.class);
  
    private static String[] supportedFileExtensions = null;
  
    /**
     * Loops over all {@link FileAnalyzer}s and returns an array of all supported file extensions.
     *
     * @return an array of {@link java.lang.String} objects.
     */
    public static synchronized String[] getSupportedFileExtensions() {
      if (supportedFileExtensions == null) {
        final Set<String> exts = new HashSet<String>();
        final ServiceLoader<FileAnalyzer> loader = ServiceLoader.load(FileAnalyzer.class);
        for (FileAnalyzer l : loader) {
          final String[] ana_exts = l.getSupportedFileExtensions();
          for (String ana_ext : ana_exts) {
            if (exts.contains(ana_ext))
              log.warn("File extension [" + ana_ext + "] supported multiple times");
            else exts.add(ana_ext);
          }
        }
        supportedFileExtensions = new String[exts.size()];
        new ArrayList<String>(exts).toArray(supportedFileExtensions);
      }
      return supportedFileExtensions.clone();
    }
  
    /**
     * <p>isSupportedFileExtension.</p>
     *
     * @param _ext a {@link java.lang.String} object.
     * @return a boolean.
     */
    public static boolean isSupportedFileExtension(String _ext) {
      return Arrays.asList(getSupportedFileExtensions()).contains(_ext);
    }
  
    /**
     * Creates instances of {@link FileAnalyzer} depending on the file.
     *
     * @param _file a {@link java.io.File} object.
     * @return a {@link org.eclipse.steady.FileAnalyzer} object.
     * @throws java.lang.IllegalArgumentException if any.
     */
    public static final FileAnalyzer buildFileAnalyzer(File _file) throws IllegalArgumentException {
      return FileAnalyzerFactory.buildFileAnalyzer(_file, null);
    }
  
    /**
     * Creates instances of {@link FileAnalyzer} depending on the file.
     *
     * @param _file a {@link java.io.File} object.
     * @param _exts an array of {@link java.lang.String} objects.
     * @return a {@link org.eclipse.steady.FileAnalyzer} object.
     * @throws java.lang.IllegalArgumentException if any.
     */
    public static final FileAnalyzer buildFileAnalyzer(File _file, String[] _exts)
        throws IllegalArgumentException {
      FileAnalyzer fa = null;
  
      // Check implementations of FileAnalyzer service
      if (FileUtil.isAccessibleDirectory(_file) || FileUtil.isAccessibleFile(_file.toPath())) {
        final ServiceLoader<FileAnalyzer> loader = ServiceLoader.load(FileAnalyzer.class);
        for (FileAnalyzer l : loader) {
          if (l.canAnalyze(_file)) {
            try {
              fa = l;
  
              // This is to limit the search of the DirAnalyzer to given extensions
              if (_exts != null && fa instanceof DirAnalyzer)
                ((DirAnalyzer) fa).setExtensionFilter(_exts);
  
              fa.analyze(_file);
            } catch (FileAnalysisException e) {
              log.error(
                  "Error when creating file analyzer for ["
                      + _file.toString()
                      + "]: "
                      + e.getMessage(),
                  e);
            }
          }
  
          if (fa != null) break;
        }
      }
      // Not accessible
      else
        throw new IllegalArgumentException(
            "File [" + _file.toString() + "] not found or not readable");
  
      if (fa == null) log.warn("No analyzer found for file  [" + _file.toString() + "]");
  
      return fa;
    }
  }
  