<commit_before>package org.radargun.config;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;


import org.radargun.utils.Utils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Base class for generators of schemas.
 *
 * @author <NAME> &lt;<EMAIL>&gt;
 */
public abstract class SchemaGenerator {

   protected static final String NS_XS = "http://www.w3.org/2001/XMLSchema";
   protected static final String XS_ELEMENT = "element";
   protected static final String XS_COMPLEX_TYPE = "complexType";
   protected static final String XS_NAME = "name";
   protected static final String THIS_PREFIX = "this:";

   protected static final String XS_ANY = "any";
   protected static final String XS_RESTRICTION = "restriction";
   protected static final String XS_PATTERN = "pattern";
   protected static final String XS_ENUMERATION = "enumeration";
   protected static final String XS_SIMPLE_TYPE = "simpleType";
   protected static final String XS_SEQUENCE = "sequence";
   protected static final String XS_UNION = "union";
   protected static final String XS_MIN_OCCURS = "minOccurs";
   protected static final String XS_MAX_OCCURS = "maxOccurs";
   protected static final String XS_ATTRIBUTE = "attribute";
   protected static final String XS_TYPE = "type";
   protected static final String XS_USE = "use";
   protected static final String XS_REQUIRED = "required";
   protected static final String XS_STRING = "string";
   protected static final XmlType STRING_TYPE = new XmlType(null, XS_STRING);
   protected static final String XS_INTEGER = "integer";
   protected static final String XS_LONG = "long";
   protected static final String XS_FLOAT = "float";
   protected static final String XS_DOUBLE = "double";
   protected static final String XS_BOOLEAN = "boolean";
   protected static final String XS_COMPLEX_CONTENT = "complexContent";
   protected static final String XS_SIMPLE_CONTENT = "simpleContent";
   protected static final String XS_EXTENSION = "extension";
   protected static final String XS_BASE = "base";
   protected static final String XS_VALUE = "value";
   protected static final String XS_ABSTRACT = "abstract";
   protected static final String XS_CHOICE = "choice";
   protected static final String XS_ANNOTATION = "annotation";
   protected static final String XS_DOCUMENTATION = "documentation";
   protected static final String XS_NAMESPACE = "namespace";
   protected static final String XS_OTHER_NAMESPACE = "##other";
   protected static final String XS_ANY_NAMESPACE = "##any";
   protected static final String XS_INCLUDE = "include";
   protected static final String XS_IMPORT = "import";
   protected static final String XS_SCHEMA_LOCATION = "schemaLocation";

   protected final String namespaceRoot;
   protected final String namespace;
   protected final String omitPrefix;
   private final Map<String, String> importedNamespaces = new HashMap<>();
   private int nsCounter = 0;

   protected Document doc;
   protected Element schema;

   protected XmlType intType;
   protected Map<String, XmlType> generatedTypes = new HashMap<>();

   public SchemaGenerator(String namespaceRoot, String namespace, String omitPrefix) {
      this.namespaceRoot = namespaceRoot;
      this.namespace = namespace;
      this.omitPrefix = omitPrefix;
   }

   /**
    * For reusing the generator within another document
    * @param doc
    * @param schema
    */
   void setDocSchema(Document doc, Element schema) {
      this.doc = doc;
      this.schema = schema;
   }

   protected XmlType generateClass(Class<?> clazz) {
      String typeName = class2xmlId(clazz);
      XmlType fullName = generatedTypes.get(typeName);
      if (fullName != null) {
         return fullName;
      }
      XmlType superType = null;
      if (clazz.getSuperclass() != Object.class) {
         superType = generateClass(clazz.getSuperclass());
      }
      NamespaceHelper.Coords coords = NamespaceHelper.getCoords(namespaceRoot, clazz, omitPrefix);
      if (coords == null || coords.namespace.equals(this.namespace)) {
         String source = Utils.getCodePath(clazz);
         if (source == null) source = "unknown source";
         int lastSlash = source.lastIndexOf('/');
         if (lastSlash > 0) source = source.substring(lastSlash + 1);
         schema.appendChild(doc.createComment("From " + source));

         Element typeElement = createComplexType(typeName, superType == null ? null : superType.toString(), true,
            Modifier.isAbstract(clazz.getModifiers()), findDocumentation(clazz));
         Element propertiesSequence = createSequence(typeElement);
         for (Map.Entry<String, Path> property : PropertyHelper.getDeclaredProperties(clazz, true, true)) {
            generateProperty(typeElement, propertiesSequence, property.getKey(), property.getValue(), true);
         }
         fullName = new XmlType(typeName);
      } else {
         fullName = new XmlType(requireImport(coords.namespace), typeName);
      }
      generatedTypes.put(typeName, fullName);
      return fullName;
   }

   protected Element createAny(Element parent) {
      return createAny(parent, 0, 1, XS_OTHER_NAMESPACE);
   }

   protected Element createAny(Element parent, int minOccurs, int maxOccurs, String namespace) {
      Element any = doc.createElementNS(NS_XS, XS_ANY);<commit_msg>Don't use supertype if it has no properties.<commit_after>package org.radargun.config;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;


import org.radargun.utils.Utils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Base class for generators of schemas.
 *
 * @author <NAME> &lt;<EMAIL>&gt;
 */
public abstract class SchemaGenerator {

   protected static final String NS_XS = "http://www.w3.org/2001/XMLSchema";
   protected static final String XS_ELEMENT = "element";
   protected static final String XS_COMPLEX_TYPE = "complexType";
   protected static final String XS_NAME = "name";
   protected static final String THIS_PREFIX = "this:";

   protected static final String XS_ANY = "any";
   protected static final String XS_RESTRICTION = "restriction";
   protected static final String XS_PATTERN = "pattern";
   protected static final String XS_ENUMERATION = "enumeration";
   protected static final String XS_SIMPLE_TYPE = "simpleType";
   protected static final String XS_SEQUENCE = "sequence";
   protected static final String XS_UNION = "union";
   protected static final String XS_MIN_OCCURS = "minOccurs";
   protected static final String XS_MAX_OCCURS = "maxOccurs";
   protected static final String XS_ATTRIBUTE = "attribute";
   protected static final String XS_TYPE = "type";
   protected static final String XS_USE = "use";
   protected static final String XS_REQUIRED = "required";
   protected static final String XS_STRING = "string";
   protected static final XmlType STRING_TYPE = new XmlType(null, XS_STRING);
   protected static final String XS_INTEGER = "integer";
   protected static final String XS_LONG = "long";
   protected static final String XS_FLOAT = "float";
   protected static final String XS_DOUBLE = "double";
   protected static final String XS_BOOLEAN = "boolean";
   protected static final String XS_COMPLEX_CONTENT = "complexContent";
   protected static final String XS_SIMPLE_CONTENT = "simpleContent";
   protected static final String XS_EXTENSION = "extension";
   protected static final String XS_BASE = "base";
   protected static final String XS_VALUE = "value";
   protected static final String XS_ABSTRACT = "abstract";
   protected static final String XS_CHOICE = "choice";
   protected static final String XS_ANNOTATION = "annotation";
   protected static final String XS_DOCUMENTATION = "documentation";
   protected static final String XS_NAMESPACE = "namespace";
   protected static final String XS_OTHER_NAMESPACE = "##other";
   protected static final String XS_ANY_NAMESPACE = "##any";
   protected static final String XS_INCLUDE = "include";
   protected static final String XS_IMPORT = "import";
   protected static final String XS_SCHEMA_LOCATION = "schemaLocation";

   protected final String namespaceRoot;
   protected final String namespace;
   protected final String omitPrefix;
   private final Map<String, String> importedNamespaces = new HashMap<>();
   private int nsCounter = 0;

   protected Document doc;
   protected Element schema;

   protected XmlType intType;
   protected Map<String, XmlType> generatedTypes = new HashMap<>();

   public SchemaGenerator(String namespaceRoot, String namespace, String omitPrefix) {
      this.namespaceRoot = namespaceRoot;
      this.namespace = namespace;
      this.omitPrefix = omitPrefix;
   }

   /**
    * For reusing the generator within another document
    * @param doc
    * @param schema
    */
   void setDocSchema(Document doc, Element schema) {
      this.doc = doc;
      this.schema = schema;
   }

   protected XmlType generateClass(Class<?> clazz) {
      String typeName = class2xmlId(clazz);
      XmlType fullName = generatedTypes.get(typeName);
      if (fullName != null) {
         return fullName;
      }
      XmlType superType = null;
      if (clazz.getSuperclass() != Object.class) {
         superType = generateClass(clazz.getSuperclass());
      }
      NamespaceHelper.Coords coords = NamespaceHelper.getCoords(namespaceRoot, clazz, omitPrefix);
      if (coords == null || coords.namespace.equals(this.namespace)) {
         String source = Utils.getCodePath(clazz);
         if (source == null) source = "unknown source";
         int lastSlash = source.lastIndexOf('/');
         if (lastSlash > 0) source = source.substring(lastSlash + 1);
         schema.appendChild(doc.createComment("From " + source));

         Element typeElement = createComplexType(typeName, superType == null ? null : superType.toString(), true,
            Modifier.isAbstract(clazz.getModifiers()), findDocumentation(clazz));
         Element propertiesSequence = createSequence(typeElement);
         for (Map.Entry<String, Path> property : PropertyHelper.getDeclaredProperties(clazz, true, true)) {
            generateProperty(typeElement, propertiesSequence, property.getKey(), property.getValue(), true);
         }
         fullName = new XmlType(typeName);
      } else {
         if (PropertyHelper.getProperties(clazz, false, true, false).isEmpty()) {
            return null;
         }
         fullName = new XmlType(requireImport(coords.namespace), typeName);
      }
      generatedTypes.put(typeName, fullName);
      return fullName;
   }

   protected Element createAny(Element parent) {
      return createAny(parent, 0, 1, XS_OTHER_NAMESPACE);
   }

   protected Element createAny(Element parent, int minOccurs, int maxOccurs, String namespace) {
      Element any = doc.createElementNS(NS_XS, XS_ANY);
{'fraction_non_alphanumeric': 0.0911344789262204, 'fraction_numerical': 0.0023937761819269898, 'mean_word_length': 4.007705479452055, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 14}, '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': '5393749', 'n_tokens_mistral': 3307, 'n_tokens_neox': 3227, 'n_words': 961}