<commit_before>/**********************************************************************
Copyright (c) 2009 Google Inc.

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.
**********************************************************************/
package com.google.appengine.datanucleus.mapping;

import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.exceptions.NucleusFatalUserException;
import org.datanucleus.identity.OID;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.ClassMetaData;
import org.datanucleus.metadata.ColumnMetaData;
import org.datanucleus.metadata.ColumnMetaDataContainer;
import org.datanucleus.metadata.DiscriminatorMetaData;
import org.datanucleus.metadata.DiscriminatorStrategy;
import org.datanucleus.metadata.FieldPersistenceModifier;
import org.datanucleus.metadata.FieldRole;
import org.datanucleus.metadata.IdentityStrategy;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.metadata.InheritanceStrategy;
import org.datanucleus.metadata.MetaData;
import org.datanucleus.metadata.MetaDataManager;
import org.datanucleus.metadata.OrderMetaData;
import org.datanucleus.metadata.PropertyMetaData;
import org.datanucleus.metadata.Relation;
import org.datanucleus.metadata.VersionMetaData;
import org.datanucleus.plugin.ConfigurationElement;
import org.datanucleus.store.types.sco.SCOUtils;
import org.datanucleus.store.exceptions.NoSuchPersistentFieldException;
import org.datanucleus.store.exceptions.NoTableManagedException;
import org.datanucleus.store.mapped.DatastoreAdapter;
import org.datanucleus.store.mapped.DatastoreClass;
import org.datanucleus.store.mapped.DatastoreField;
import org.datanucleus.store.mapped.DatastoreIdentifier;
import org.datanucleus.store.mapped.IdentifierFactory;
import org.datanucleus.store.mapped.IdentifierType;
import org.datanucleus.store.mapped.MappedStoreManager;
import org.datanucleus.store.mapped.exceptions.DuplicateDatastoreFieldException;
import org.datanucleus.store.mapped.mapping.CorrespondentColumnsMapper;
import org.datanucleus.store.mapped.mapping.DatastoreMapping;
import org.datanucleus.store.mapped.mapping.DiscriminatorLongMapping;
import org.datanucleus.store.mapped.mapping.DiscriminatorStringMapping;
import org.datanucleus.store.mapped.mapping.IndexMapping;
import org.datanucleus.store.mapped.mapping.IntegerMapping;
import org.datanucleus.store.mapped.mapping.JavaTypeMapping;
import org.datanucleus.store.mapped.mapping.LongMapping;
import org.datanucleus.store.mapped.mapping.MappingConsumer;
import org.datanucleus.store.mapped.mapping.OIDMapping;
import org.datanucleus.store.mapped.mapping.PersistableMapping;
import org.datanucleus.util.MultiMap;
import org.datanucleus.util.NucleusLogger;
import org.datanucleus.util.StringUtils;

import com.google.appengine.datanucleus.DatastoreManager;
import com.google.appengine.datanucleus.Utils;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Describes a 'table' in the datastore.  We don't actually have tables, but
 * we need to represent this logically in order to take care of all the nice
 * mapping logic that datanucleus does for us.
 *
 * This code is largely copied from AbstractClassTable, ClassTable, TableImpl, and AbstractTable
 *
 * TODO : Drop the code adding "foreign key" when we drop support for old storage versions
 *
 * @author <NAME> <<EMAIL>>
 */
public class DatastoreTable implements DatastoreClass {

  /** All callbacks for class tables waiting to be performed. */
  private static final MultiMap callbacks = new MultiMap();

  private final DatastoreManager storeMgr;
  private final AbstractClassMetaData cmd;
  private final ClassLoaderResolver clr;
  private final DatastoreAdapter dba;
  protected final DatastoreIdentifier identifier;
  private final Map<String, AbstractClassMetaData> owningClassMetaData = Utils.newHashMap();

  /**
   * Mappings for fields mapped to this table, keyed by the FieldMetaData.
   * Supports fast lookup but also preserves order.
   */
  private final Map<AbstractMemberMetaData, JavaTypeMapping> fieldMappingsMap =
      new LinkedHashMap<AbstractMemberMetaData, JavaTypeMapping>();

  /**
   * Similar to {@link #fieldMappingsMap} except primary key fields are added as
   * well.  This is needed to support persistence capable classes that can be
   * persisted as top-level classes and as embedded classes.
   */
  private final Map<AbstractMemberMetaData, JavaTypeMapping> embeddedFieldMappingsMap =
      new LinkedHashMap<AbstractMemberMetaData, JavaTypeMapping>();

  /**
   * All the properties in the table.  Even though the datastore is schemaless,
   * the mappings provided by the ORM effectively impose a schema.  This allows
   * us to know, up front, what properties we can expect.
   */
  private final List<DatastoreProperty> datastoreProperties = Utils.newArrayList();

  /**
   * Index to the props, keyed by name.
   */
  protected Map<String, DatastoreProperty> datastorePropertiesByName = Utils.newHashMap();

  /** Mapping for datastore identity (optional). */
  private JavaTypeMapping datastoreIDMapping;

  /** Mappings for application identity (optional). */
  private JavaTypeMapping[] pkMappings;

  /** Mapping for the id of the table. */
  private JavaTypeMapping idMapping;

  /** MetaData for discriminator for objects stored in this kind. */
  protected DiscriminatorMetaData discriminatorMetaData;

  /** Mapping for any discriminator column. */
  private JavaTypeMapping discriminatorMapping;
  
  /** Highest absolute field number managed by this table */
  private int highestFieldNumber = 0;

  /**
   * Dependent fields.  Unlike pretty much the rest of this class, this member and the
   * code that populates it is specific to the appengine plugin.
   */
  private final List<AbstractMemberMetaData> sameEntityGroupMemberMetaData = Utils.newArrayList();
  private final Map<AbstractMemberMetaData, JavaTypeMapping> externalFkMappings = Utils.newHashMap();
  private final Map<AbstractMemberMetaData, JavaTypeMapping> externalOrderMappings = Utils.newHashMap();
  private AbstractMemberMetaData parentMappingMemberMetaData;

  /** MetaData for all classes being managed here. */
  private final Collection<AbstractClassMetaData> managedClassMetaData = new HashSet<AbstractClassMetaData>();
  
  public DatastoreTable(String kind, DatastoreManager storeMgr, AbstractClassMetaData cmd,
      ClassLoaderResolver clr, DatastoreAdapter dba) {
    this.storeMgr = storeMgr;
    this.cmd = cmd;
    this.clr = clr;
    this.dba = dba;
    this.identifier = new DatastoreKind(kind);
  }

  public String getType() {
    return cmd.getFullClassName();
  }

  public IdentityType getIdentityType() {
    return cmd.getIdentityType();
  }

  public boolean isObjectIdDatastoreAttributed() {
    return true;
  }

  public boolean isBaseDatastoreClass() {
    return true;
  }

  public DatastoreClass getBaseDatastoreClassWithMember(AbstractMemberMetaData fmd) {
    if (fieldMappingsMap.get(fmd) != null) {
      return this;
    }
    return null;
  }

  public DatastoreClass getSuperDatastoreClass() {
    return null;
  }

  public Collection getSecondaryDatastoreClasses() {
    return null;
  }

  public boolean managesClass(String className) {
    return cmd.getFullClassName().equals(className);
  }<commit_msg>add method that is required by datanucleus-core 3.0.10+<commit_after>/**********************************************************************
Copyright (c) 2009 Google Inc.

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.
**********************************************************************/
package com.google.appengine.datanucleus.mapping;

import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.exceptions.NucleusFatalUserException;
import org.datanucleus.identity.OID;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.ClassMetaData;
import org.datanucleus.metadata.ColumnMetaData;
import org.datanucleus.metadata.ColumnMetaDataContainer;
import org.datanucleus.metadata.DiscriminatorMetaData;
import org.datanucleus.metadata.DiscriminatorStrategy;
import org.datanucleus.metadata.FieldPersistenceModifier;
import org.datanucleus.metadata.FieldRole;
import org.datanucleus.metadata.IdentityStrategy;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.metadata.InheritanceStrategy;
import org.datanucleus.metadata.MetaData;
import org.datanucleus.metadata.MetaDataManager;
import org.datanucleus.metadata.OrderMetaData;
import org.datanucleus.metadata.PropertyMetaData;
import org.datanucleus.metadata.Relation;
import org.datanucleus.metadata.VersionMetaData;
import org.datanucleus.plugin.ConfigurationElement;
import org.datanucleus.store.types.sco.SCOUtils;
import org.datanucleus.store.exceptions.NoSuchPersistentFieldException;
import org.datanucleus.store.exceptions.NoTableManagedException;
import org.datanucleus.store.mapped.DatastoreAdapter;
import org.datanucleus.store.mapped.DatastoreClass;
import org.datanucleus.store.mapped.DatastoreField;
import org.datanucleus.store.mapped.DatastoreIdentifier;
import org.datanucleus.store.mapped.IdentifierFactory;
import org.datanucleus.store.mapped.IdentifierType;
import org.datanucleus.store.mapped.MappedStoreManager;
import org.datanucleus.store.mapped.exceptions.DuplicateDatastoreFieldException;
import org.datanucleus.store.mapped.mapping.CorrespondentColumnsMapper;
import org.datanucleus.store.mapped.mapping.DatastoreMapping;
import org.datanucleus.store.mapped.mapping.DiscriminatorLongMapping;
import org.datanucleus.store.mapped.mapping.DiscriminatorStringMapping;
import org.datanucleus.store.mapped.mapping.IndexMapping;
import org.datanucleus.store.mapped.mapping.IntegerMapping;
import org.datanucleus.store.mapped.mapping.JavaTypeMapping;
import org.datanucleus.store.mapped.mapping.LongMapping;
import org.datanucleus.store.mapped.mapping.MappingConsumer;
import org.datanucleus.store.mapped.mapping.OIDMapping;
import org.datanucleus.store.mapped.mapping.PersistableMapping;
import org.datanucleus.util.MultiMap;
import org.datanucleus.util.NucleusLogger;
import org.datanucleus.util.StringUtils;

import com.google.appengine.datanucleus.DatastoreManager;
import com.google.appengine.datanucleus.Utils;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Describes a 'table' in the datastore.  We don't actually have tables, but
 * we need to represent this logically in order to take care of all the nice
 * mapping logic that datanucleus does for us.
 *
 * This code is largely copied from AbstractClassTable, ClassTable, TableImpl, and AbstractTable
 *
 * TODO : Drop the code adding "foreign key" when we drop support for old storage versions
 *
 * @author <NAME> <<EMAIL>>
 */
public class DatastoreTable implements DatastoreClass {

  /** All callbacks for class tables waiting to be performed. */
  private static final MultiMap callbacks = new MultiMap();

  private final DatastoreManager storeMgr;
  private final AbstractClassMetaData cmd;
  private final ClassLoaderResolver clr;
  private final DatastoreAdapter dba;
  protected final DatastoreIdentifier identifier;
  private final Map<String, AbstractClassMetaData> owningClassMetaData = Utils.newHashMap();

  /**
   * Mappings for fields mapped to this table, keyed by the FieldMetaData.
   * Supports fast lookup but also preserves order.
   */
  private final Map<AbstractMemberMetaData, JavaTypeMapping> fieldMappingsMap =
      new LinkedHashMap<AbstractMemberMetaData, JavaTypeMapping>();

  /**
   * Similar to {@link #fieldMappingsMap} except primary key fields are added as
   * well.  This is needed to support persistence capable classes that can be
   * persisted as top-level classes and as embedded classes.
   */
  private final Map<AbstractMemberMetaData, JavaTypeMapping> embeddedFieldMappingsMap =
      new LinkedHashMap<AbstractMemberMetaData, JavaTypeMapping>();

  /**
   * All the properties in the table.  Even though the datastore is schemaless,
   * the mappings provided by the ORM effectively impose a schema.  This allows
   * us to know, up front, what properties we can expect.
   */
  private final List<DatastoreProperty> datastoreProperties = Utils.newArrayList();

  /**
   * Index to the props, keyed by name.
   */
  protected Map<String, DatastoreProperty> datastorePropertiesByName = Utils.newHashMap();

  /** Mapping for datastore identity (optional). */
  private JavaTypeMapping datastoreIDMapping;

  /** Mappings for application identity (optional). */
  private JavaTypeMapping[] pkMappings;

  /** Mapping for the id of the table. */
  private JavaTypeMapping idMapping;

  /** MetaData for discriminator for objects stored in this kind. */
  protected DiscriminatorMetaData discriminatorMetaData;

  /** Mapping for any discriminator column. */
  private JavaTypeMapping discriminatorMapping;
  
  /** Highest absolute field number managed by this table */
  private int highestFieldNumber = 0;

  /**
   * Dependent fields.  Unlike pretty much the rest of this class, this member and the
   * code that populates it is specific to the appengine plugin.
   */
  private final List<AbstractMemberMetaData> sameEntityGroupMemberMetaData = Utils.newArrayList();
  private final Map<AbstractMemberMetaData, JavaTypeMapping> externalFkMappings = Utils.newHashMap();
  private final Map<AbstractMemberMetaData, JavaTypeMapping> externalOrderMappings = Utils.newHashMap();
  private AbstractMemberMetaData parentMappingMemberMetaData;

  /** MetaData for all classes being managed here. */
  private final Collection<AbstractClassMetaData> managedClassMetaData = new HashSet<AbstractClassMetaData>();
  
  public DatastoreTable(String kind, DatastoreManager storeMgr, AbstractClassMetaData cmd,
      ClassLoaderResolver clr, DatastoreAdapter dba) {
    this.storeMgr = storeMgr;
    this.cmd = cmd;
    this.clr = clr;
    this.dba = dba;
    this.identifier = new DatastoreKind(kind);
  }

  public String getType() {
    return cmd.getFullClassName();
  }

  public IdentityType getIdentityType() {
    return cmd.getIdentityType();
  }

  public boolean isObjectIdDatastoreAttributed() {
    return true;
  }

  public boolean isBaseDatastoreClass() {
    return true;
  }

  public DatastoreClass getBaseDatastoreClass() {
    return this;
  }

  public DatastoreClass getBaseDatastoreClassWithMember(AbstractMemberMetaData fmd) {
    if (fieldMappingsMap.get(fmd) != null) {
      return this;
    }
    return null;
  }

  public DatastoreClass getSuperDatastoreClass() {
    return null;
  }

  public Collection getSecondaryDatastoreClasses() {
    return null;
  }

  public boolean managesClass(String className) {
    return cmd.getFullClassName().equals(className);
  }
{'fraction_non_alphanumeric': 0.09381468403750153, 'fraction_numerical': 0.0013393400706197493, 'mean_word_length': 5.349826053343642, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, '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': '6743294', 'n_tokens_mistral': 4755, 'n_tokens_neox': 4625, 'n_words': 1244}