<commit_before>/*
 * Cacheonix Systems licenses this file to You under the LGPL 2.1
 * (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.cacheonix.org/products/cacheonix/license-lgpl-2.1.htm
 *
 * 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.cacheonix.impl.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.cacheonix.cache.ConfigurationException;
import org.cacheonix.impl.util.exception.ExceptionUtils;
import org.cacheonix.impl.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import static org.cacheonix.impl.util.IOUtils.closeHard;

/**
 * Configuration reader.
 * <p/>
 *
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
public final class ConfigurationReader {

   /**
    * Logger.
    *
    * @noinspection UNUSED_SYMBOL, UnusedDeclaration
    */
   private static final Logger LOG = Logger.getLogger(ConfigurationReader.class); // NOPMD


   private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";

   private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";

   private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";


   /**
    * Reads configuration defined by the <code>configurationPath</code>. The configuration is first considered as a
    * fully-qualified URL, a fully-qualified file path, a relative file path or a resource in the class path.
    *
    * @param configurationPath path to Cacheonix configuration. Can be a URL,  file path or a resource in the
    *                          classpath.
    * @return Cacheonix configuration.
    * @throws IOException if an I/O error occurs while reading the configuration.
    * @noinspection MethodReturnOfConcreteClass, IOResourceOpenedButNotSafelyClosed
    */
   public CacheonixConfiguration readConfiguration(final String configurationPath) throws IOException {

      InputStream is = null;
      try {

         // Try to get it from the URL
         is = openAsURL(configurationPath);

         // Try to get it from a file
         if (is == null) {

            is = openAsFile(configurationPath);
         }

         // Try to get it from the classpath
         if (is == null) {

            is = openAsResource(configurationPath);
         }

         if (is == null) {

            throw new ConfigurationException("Configuration could not be found: " + configurationPath);
         }

         // Read
         return readConfiguration(is);
      } finally {
         closeHard(is);
      }
   }


   public CacheonixConfiguration readConfiguration(final InputStream is) throws IOException {

      final CacheonixConfiguration cacheonixConfiguration = new CacheonixConfiguration();
      final Document document = parseConfiguration(is);
      final Node cacheonix = document.getElementsByTagName("cacheonix").item(0);
      cacheonixConfiguration.read(cacheonix);
      return cacheonixConfiguration;
   }


   private InputStream openAsResource(final String configurationPath) {

      return getClass().getClassLoader().getResourceAsStream(configurationPath);
   }


   private static InputStream openAsFile(final String configurationName) throws FileNotFoundException {

      final File file = new File(configurationName);
      if (file.exists()) {
         return new FileInputStream(configurationName);
      }
      return null;
   }


   private static InputStream openAsURL(final String configurationName) {

      try {

         final URL url = new URL(configurationName);
         return url.openStream();
      } catch (final IOException ignored) { // NOPMD
         // Expected
      }
      return null;
   }


   private Document parseConfiguration(final InputStream is) throws IOException {

      final String xsd = getClass().getClassLoader().getResource("META-INF/cacheonix-config-2.0.xsd").toString();<commit_msg>Fixed a potential null reference by explicitly checking for the presence of Cacheonix XSD in the classpath. (cherry picked from commit 15511d4)<commit_after>/*
 * Cacheonix Systems licenses this file to You under the LGPL 2.1
 * (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.cacheonix.org/products/cacheonix/license-lgpl-2.1.htm
 *
 * 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.cacheonix.impl.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.cacheonix.cache.ConfigurationException;
import org.cacheonix.impl.util.exception.ExceptionUtils;
import org.cacheonix.impl.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import static org.cacheonix.impl.util.IOUtils.closeHard;

/**
 * Configuration reader.
 * <p/>
 *
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 */
public final class ConfigurationReader {

   /**
    * Logger.
    *
    * @noinspection UNUSED_SYMBOL, UnusedDeclaration
    */
   private static final Logger LOG = Logger.getLogger(ConfigurationReader.class); // NOPMD


   private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";

   private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";

   private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";

   private static final String META_INF_CACHEONIX_CONFIG_2_0_XSD = "META-INF/cacheonix-config-2.0.xsd";


   /**
    * Reads configuration defined by the <code>configurationPath</code>. The configuration is first considered as a
    * fully-qualified URL, a fully-qualified file path, a relative file path or a resource in the class path.
    *
    * @param configurationPath path to Cacheonix configuration. Can be a URL,  file path or a resource in the
    *                          classpath.
    * @return Cacheonix configuration.
    * @throws IOException if an I/O error occurs while reading the configuration.
    * @noinspection MethodReturnOfConcreteClass, IOResourceOpenedButNotSafelyClosed
    */
   public CacheonixConfiguration readConfiguration(final String configurationPath) throws IOException {

      InputStream is = null;
      try {

         // Try to get it from the URL
         is = openAsURL(configurationPath);

         // Try to get it from a file
         if (is == null) {

            is = openAsFile(configurationPath);
         }

         // Try to get it from the classpath
         if (is == null) {

            is = openAsResource(configurationPath);
         }

         if (is == null) {

            throw new ConfigurationException("Configuration could not be found: " + configurationPath);
         }

         // Read
         return readConfiguration(is);
      } finally {
         closeHard(is);
      }
   }


   public CacheonixConfiguration readConfiguration(final InputStream is) throws IOException {

      final CacheonixConfiguration cacheonixConfiguration = new CacheonixConfiguration();
      final Document document = parseConfiguration(is);
      final Node cacheonix = document.getElementsByTagName("cacheonix").item(0);
      cacheonixConfiguration.read(cacheonix);
      return cacheonixConfiguration;
   }


   private InputStream openAsResource(final String configurationPath) {

      return getClass().getClassLoader().getResourceAsStream(configurationPath);
   }


   private static InputStream openAsFile(final String configurationName) throws FileNotFoundException {

      final File file = new File(configurationName);
      if (file.exists()) {
         return new FileInputStream(configurationName);
      }
      return null;
   }


   private static InputStream openAsURL(final String configurationName) {

      try {

         final URL url = new URL(configurationName);
         return url.openStream();
      } catch (final IOException ignored) { // NOPMD
         // Expected
      }
      return null;
   }


   private Document parseConfiguration(final InputStream is) throws IOException {

      final URL resource = getClass().getClassLoader().getResource(META_INF_CACHEONIX_CONFIG_2_0_XSD);
      if (resource == null) {
         throw new IOException("Couldn't find packaged " + META_INF_CACHEONIX_CONFIG_2_0_XSD + " in the classpath");
      }

      final String xsd = resource.toString();
{'fraction_non_alphanumeric': 0.0856873822975518, 'fraction_numerical': 0.004394224733207784, 'mean_word_length': 3.240905057675244, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 12}, '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': '1688652', 'n_tokens_mistral': 2636, 'n_tokens_neox': 2541, 'n_words': 772}