/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     08/10/2009-2.0 Guy Pelletier
//       - 267391: JPA 2.0 implement/extend/use an APT tooling library for MetaModel API canonical classes
//     11/20/2009-2.0 Guy Pelletier/Mitesh Meswani
//       - 295376: Improve usability of MetaModel generator
//     04/27/2010-2.1 Guy Pelletier
//       - 309856: MappedSuperclasses from XML are not being initialized properly
//     06/01/2010-2.1 Guy Pelletier
//       - 315195: Add new property to avoid reading XML during the canonical model generation
//     11/23/2010-2.2 Guy Pelletier
//       - 330660: Canonical model generator throws ClassCastException when using package-info.java
//     02/14/2013-2.5 Guy Pelletier
//       - 338610: JPA 2.1 Functionality for Java EE 7 (JSR-338)
//     05/26/2016-2.7 Tomas Kraus
//       - 494610: Session Properties map should be Map<String, Object>
//     10/09/2017-2.7 Lukas Jungmann
//       - 521954: Eclipselink 2.7 is not able to parse ORM XML files using the 2.2 schema
package org.eclipse.persistence.internal.jpa.modelgen.objects;

import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_EMBEDDABLE;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ENTITY;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_MAPPED_SUPERCLASS;
import static org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties.CANONICAL_MODEL_PREFIX;
import static org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties.CANONICAL_MODEL_SUB_PACKAGE;
import static org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties.CANONICAL_MODEL_SUFFIX;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitProperty;
import org.eclipse.persistence.internal.jpa.metadata.MetadataHelper;
import org.eclipse.persistence.internal.jpa.metadata.MetadataProject;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.MappedSuperclassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotation;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsReader;
import org.eclipse.persistence.internal.jpa.modelgen.MetadataMirrorFactory;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.XMLContext;

/**
 * A representation of a persistence unit definition.
 *
 * @author Guy Pelletier, Doug Clarke
 * @since EclipseLink 1.2
 */
public class PersistenceUnit {
    protected List<XMLEntityMappings> xmlEntityMappings;

    protected MetadataProject project;
    protected MetadataMirrorFactory factory;
    protected PersistenceUnitReader persistenceUnitReader;
    protected ProcessingEnvironment processingEnv;
    protected SEPersistenceUnitInfo persistenceUnitInfo;
    protected HashMap<String, Object> persistenceUnitProperties;

    /**
     * INTERNAL:
     */
    public PersistenceUnit(SEPersistenceUnitInfo puInfo, MetadataMirrorFactory mirrorFactory, PersistenceUnitReader reader) {
        factory = mirrorFactory;
        persistenceUnitInfo = puInfo;
        persistenceUnitReader = reader;

        // Ask the factory for the project and processing environment
        processingEnv = factory.getProcessingEnvironment();
        project = factory.getMetadataProject(persistenceUnitInfo);

        // Init our OX mapped properties into a map.
        initPersistenceUnitProperties();

        // Init our mapping files. This method relies on properties being
        // initialized first.
        initXMLEntityMappings();
    }

    /**
     * INTERNAL:
     * Add an element decorated with an Embeddable annotation.
     *
     * The possibilities here:
     * 1 - New element and not exclude unlisted classes - add it
     * 2 - New element but exclude unlisted classes - ignore it.
     * 3 - Existing element, but accessor loaded from XML - don't touch it
     * 4 - Existing element, but accessor loaded from Annotations - add new accessor overriding the old.
     */
    public void addEmbeddableAccessor(Element element) {
        MetadataClass metadataClass = factory.getMetadataClass(element);

        // Remove the accessor from other maps if the type changed.
        removeEntityAccessor(metadataClass);
        removeMappedSuperclassAccessor(metadataClass);

        if (project.hasEmbeddable(metadataClass)) {
            EmbeddableAccessor embeddableAccessor = project.getEmbeddableAccessor(metadataClass);

            // If it was loaded from XML, reset the pre-processed flag.
            if (embeddableAccessor.loadedFromXML()) {
                embeddableAccessor.clearPreProcessed();
            } else {
                // Was not loaded from XML and existed in the project.
                if (excludeUnlistedClasses(metadataClass)) {
                    // Exclude unlisted classes is now false, remove it!
                    removeEmbeddableAccessor(metadataClass);
                } else {
                    // Otherwise, override the existing accessor!
                    addEmbeddableAccessor(new EmbeddableAccessor(metadataClass.getAnnotation(JPA_EMBEDDABLE), metadataClass, project));
                }
            }
        } else if (! excludeUnlistedClasses(metadataClass)) {
            // add it!
            addEmbeddableAccessor(new EmbeddableAccessor(metadataClass.getAnnotation(JPA_EMBEDDABLE), metadataClass, project));
        }
    }

    /**
     * INTERNAL:
     * Add an embeddable accessor to the project, preserving any previous
     * owning descriptors set if applicable.
     */
    protected void addEmbeddableAccessor(EmbeddableAccessor embeddableAccessor) {
        // We need to preserve owning descriptors to ensure we process
        // an embeddable accessor in the correct context. That is, if the
        // user changed only the embeddable class then we won't process
        // the owning entity (which ensures the owning descriptor, itself,
        // is set on the embeddable accessor).
        // If ownership changed, then those entities involved will be
        // in the round elements and we will correctly set the owning
        // descriptor in the pre-process stage of those entities, overriding
        // this setting)
        if (project.hasEmbeddable(embeddableAccessor.getJavaClass())) {
            EmbeddableAccessor existingEmbeddableAccessor = project.getEmbeddableAccessor(embeddableAccessor.getJavaClass());
            embeddableAccessor.addEmbeddingAccessors(existingEmbeddableAccessor.getEmbeddingAccessors());
            embeddableAccessor.addOwningDescriptors(existingEmbeddableAccessor.getOwningDescriptors());
        }

        project.addEmbeddableAccessor(embeddableAccessor);
    }

    /**
     * INTERNAL:
     * Add an element decorated with an Entity annotation.
     *
     * The possibilities here:
     * 1 - New element and not exclude unlisted classes - add it
     * 2 - New element but exclude unlisted classes - ignore it.
     * 3 - Existing element, loaded from XML - don't touch it
     * 4 - Existing element, loaded from Annotations - add new accessor overriding the old.
     */
    public void addEntityAccessor(Element element) {
        MetadataClass metadataClass = factory.getMetadataClass(element);

        // Remove the accessor from other maps if the type changed.
        removeEmbeddableAccessor(metadataClass);
        removeMappedSuperclassAccessor(metadataClass);

        if (project.hasEntity(metadataClass)) {
            EntityAccessor entityAccessor = project.getEntityAccessor(metadataClass);

            // If it was loaded from XML, reset the pre-processed flag.
            if (entityAccessor.loadedFromXML()) {
                entityAccessor.clearPreProcessed();
            } else {
                // Was not loaded from XML and existed in the project.
                if (excludeUnlistedClasses(metadataClass)) {
                    // Exclude unlisted classes is now false, remove it!
                    removeEntityAccessor(metadataClass);
                } else {
                    // Otherwise, override the existing accessor!
                    project.addEntityAccessor(new EntityAccessor(metadataClass.getAnnotation(JPA_ENTITY), metadataClass, project));
                }
            }
        } else if (! excludeUnlistedClasses(metadataClass)) {
            // add it!
            project.addEntityAccessor(new EntityAccessor(metadataClass.getAnnotation(JPA_ENTITY), metadataClass, project));
        }
    }

    /**
     * INTERNAL:
     * Add an element decorated with a MappedSuperclass annotation.
     *
     * The possibilities here:
     * 1 - New element and not exclude unlisted classes - add it
     * 2 - New element but exclude unlisted classes - ignore it.
     * 3 - Existing element, but accessor loaded from XML - don't touch it
     * 4 - Existing element, but accessor loaded from Annotations - add new accessor overridding the old.
     */
    public void addMappedSuperclassAccessor(Element element) {
        MetadataClass metadataClass = factory.getMetadataClass(element);

        // Remove the accessor from other maps if the type changed.
        removeEntityAccessor(metadataClass);
        removeEmbeddableAccessor(metadataClass);

        if (project.hasMappedSuperclass(metadataClass)) {
            MappedSuperclassAccessor mappedSuperclassAccessor = project.getMappedSuperclassAccessor(metadataClass);

            // If it was loaded from XML, reset the pre-processed flag.
            if (mappedSuperclassAccessor.loadedFromXML()) {
                mappedSuperclassAccessor.clearPreProcessed();
            } else {
                // Was not loaded from XML and existed in the project.
                if (excludeUnlistedClasses(metadataClass)) {
                    // Exclude unlisted classes is now false, remove it!
                    project.removeMappedSuperclassAccessor(metadataClass);
                } else {
                    // Otherwise, override the existing accessor!
                    project.addMappedSuperclass(new MappedSuperclassAccessor(metadataClass.getAnnotation(JPA_MAPPED_SUPERCLASS), metadataClass, project));
                }
            }
        } else if (! excludeUnlistedClasses(metadataClass)) {
            // add it!
            project.addMappedSuperclass(new MappedSuperclassAccessor(metadataClass.getAnnotation(JPA_MAPPED_SUPERCLASS), metadataClass, project));
        }
    }

    /**
     * INTERNAL:
     */
    protected void addPropertyFromOptions(String propertyName) {
        if (! persistenceUnitProperties.containsKey(propertyName) || persistenceUnitProperties.get(propertyName) == null) {
            persistenceUnitProperties.put(propertyName, processingEnv.getOptions().get(propertyName));
        }
    }

    /**
     * INTERNAL:
     */
    protected void addXMLEntityMappings(String mappingFile, XMLContext context) {
        // If the input stream is null, we didn't find the mapping file, so
        // don't bother trying to read it.
        InputStream inputStream = persistenceUnitReader.getInputStream(mappingFile, false);

        if (inputStream != null) {
            try {
                XMLEntityMappings entityMappings = (XMLEntityMappings) context.createUnmarshaller().unmarshal(inputStream);
                // For eclipselink-orm merging and overriding these need to be set.
                entityMappings.setIsEclipseLinkORMFile(mappingFile.equals(MetadataHelper.ECLIPSELINK_ORM_FILE));
                entityMappings.setMappingFile(mappingFile);
                factory.getLogger().getSession().getSessionLog().log(SessionLog.INFO, SessionLog.PROCESSOR,
                            "File loaded : {0}, is eclipselink-orm file: {1}",
                            new Object[] {mappingFile, entityMappings.isEclipseLinkORMFile()}, false);
                xmlEntityMappings.add(entityMappings);
            } finally {
                persistenceUnitReader.closeInputStream(inputStream);
            }
        }
    }

    /**
     * INTERNAL:
     */
    protected void addXMLEntityMappings(String mappingFile) {
        try {
            // Try eclipselink project
            addXMLEntityMappings(mappingFile, XMLEntityMappingsReader.getEclipseLinkOrmProject());
        } catch (XMLMarshalException e) {
            try {
                // Try Persistence 3.0 project
                addXMLEntityMappings(mappingFile, XMLEntityMappingsReader.getOrm3_0Project());
            } catch (XMLMarshalException xe) {
                try {
                    // Try JPA 2.2 project
                    addXMLEntityMappings(mappingFile, XMLEntityMappingsReader.getOrm2_2Project());
                } catch (XMLMarshalException xme) {
                    try {
                        // Try JPA 2.1 project
                        addXMLEntityMappings(mappingFile, XMLEntityMappingsReader.getOrm2_1Project());
                    } catch (XMLMarshalException ee) {
                        try {
                            // Try JPA 2.0 project
                            addXMLEntityMappings(mappingFile, XMLEntityMappingsReader.getOrm2_0Project());
                        } catch (XMLMarshalException eee) {
                            // Try JPA 1.0 project (don't catch exceptions at this point)
                            addXMLEntityMappings(mappingFile, XMLEntityMappingsReader.getOrm1_0Project());
                        }
                    }
                }
            }
        }
    }

    /**
     * INTERNAL:
     * If the accessor is no longer valid it we should probably look into
     * removing the accessor from the project. For now I don't think it's
     * a big deal.
     */
    public boolean containsClass(MetadataClass metadataClass) {
        if (project.hasEntity(metadataClass)) {
            return isValidAccessor(project.getEntityAccessor(metadataClass), metadataClass.getAnnotation(JPA_ENTITY));
        }

        if (project.hasEmbeddable(metadataClass)) {
            return isValidAccessor(project.getEmbeddableAccessor(metadataClass), metadataClass.getAnnotation(JPA_EMBEDDABLE));
        }

        if (project.hasMappedSuperclass(metadataClass)) {
            return isValidAccessor(project.getMappedSuperclassAccessor(metadataClass), metadataClass.getAnnotation(JPA_MAPPED_SUPERCLASS));
        }

        return false;
    }

    /**
     * INTERNAL:
     * Return true if the metadata class given is not a managed class and
     * exclude-unlisted-classes is set to true for this PU.
     */
    protected boolean excludeUnlistedClasses(MetadataClass cls) {
        return (! persistenceUnitInfo.getManagedClassNames().contains(cls.getName())) && persistenceUnitInfo.excludeUnlistedClasses();
    }

    /**
     * INTERNAL:
     */
    public ClassAccessor getClassAccessor(MetadataClass metadataClass) {
        if (project.hasEntity(metadataClass)) {
            return project.getEntityAccessor(metadataClass);
        }

        if (project.hasEmbeddable(metadataClass)) {
            return project.getEmbeddableAccessor(metadataClass);
        }

        if (project.hasMappedSuperclass(metadataClass)) {
            return project.getMappedSuperclassAccessor(metadataClass);
        }

        return null;
    }

    /**
     * INTERNAL:
     */
    public String getQualifiedCanonicalName(String qualifiedName) {
        return MetadataHelper.getQualifiedCanonicalName(qualifiedName, persistenceUnitProperties);
    }

    /**
     * INTERNAL:
     * Get persistence unit property value by name.
     *
     * @param name persistence unit property name
     * @return persistence unit property value
     */
    public String getPersistenceUnitProperty(final String name) {
        Object objVal = persistenceUnitProperties.get(name);
        if (objVal instanceof String) {
            return String.class.cast(objVal);
        } else {
            return objVal != null ? objVal.toString() : null;
        }
    }

    /**
     * INTERNAL:
     */
    public void initPersistenceUnitProperties() {
        persistenceUnitProperties = new HashMap<>();

        // Determine how much validation we want to do. For now, last one
        // in wins (in the case of multiple settings) and we ignore null
        // named properties.
        for (SEPersistenceUnitProperty property : persistenceUnitInfo.getPersistenceUnitProperties()) {
            if (property.getName() != null) {
                factory.getLogger().getSession().getSessionLog().log(SessionLog.FINE, SessionLog.PROCESSOR,
                            "Key: {0} , value: {1}",
                            new Object[] {property.getName(), property.getValue()}, false);
                persistenceUnitProperties.put(property.getName(), property.getValue());
            }
        }

        // Check for user specified options and add them to the properties
        // if they were not specified in the persistence.xml.
        addPropertyFromOptions(CANONICAL_MODEL_PREFIX);
        addPropertyFromOptions(CANONICAL_MODEL_SUFFIX);
        addPropertyFromOptions(CANONICAL_MODEL_SUB_PACKAGE);
    }

    /**
     * INTERNAL:
     */
    protected void initXMLEntityMappings() {
        xmlEntityMappings = new ArrayList<>();

        // Load the orm.xml if it exists.
        addXMLEntityMappings(MetadataHelper.JPA_ORM_FILE);

        // Load the eclipselink-orm.xml if it exists and is not excluded.
        Boolean excludeEclipseLinkORM = false;
        if (persistenceUnitProperties.containsKey(PersistenceUnitProperties.EXCLUDE_ECLIPSELINK_ORM_FILE)) {
            excludeEclipseLinkORM = Boolean.valueOf((String) persistenceUnitProperties.get(PersistenceUnitProperties.EXCLUDE_ECLIPSELINK_ORM_FILE));
        }

        if (! excludeEclipseLinkORM) {
            addXMLEntityMappings(MetadataHelper.ECLIPSELINK_ORM_FILE);
        }

        // Load the listed mapping files.
        for (String mappingFile : persistenceUnitInfo.getMappingFileNames()) {
            if (! mappingFile.equals(MetadataHelper.JPA_ORM_FILE) && ! mappingFile.equals(MetadataHelper.ECLIPSELINK_ORM_FILE)) {
                addXMLEntityMappings(mappingFile);
            }
        }

        // 1 - Iterate through the classes that are defined in the <mapping>
        // files and add them to the map. This will merge the accessors where
        // necessary.
        for (XMLEntityMappings entityMappings : xmlEntityMappings) {
            entityMappings.setLoader(factory.getLoader());
            entityMappings.setProject(project);
            entityMappings.setMetadataFactory(factory);
            entityMappings.setLoadedForCanonicalModel(true);

            // Process the persistence unit metadata if defined.
            entityMappings.processPersistenceUnitMetadata();
        }

        // 2 - Iterate through the classes that are defined in the <mapping>
        // files and add them to the map. This will merge the accessors where
        // necessary.
        HashMap<String, EntityAccessor> entities = new HashMap<>();
        HashMap<String, EmbeddableAccessor> embeddables = new HashMap<>();

        for (XMLEntityMappings entityMappings : xmlEntityMappings) {
            entityMappings.initPersistenceUnitClasses(entities, embeddables);
        }

        // 3 - Iterate through all the XML entities and add them to the project
        // and apply any persistence unit defaults.
        for (EntityAccessor entity : entities.values()) {
            // This will apply global persistence unit defaults.
            project.addEntityAccessor(entity);

            // This will override any global settings.
            entity.getEntityMappings().processEntityMappingsDefaults(entity);
        }

        // 4 - Iterate though all the XML embeddables and add them to the
        // project and apply any persistence unit defaults.
        for (EmbeddableAccessor embeddable : embeddables.values()) {
            // This will apply global persistence unit defaults.
            addEmbeddableAccessor(embeddable);

            // This will override any global settings.
            embeddable.getEntityMappings().processEntityMappingsDefaults(embeddable);
        }
    }

    /**
     * INTERNAL:
     */
    protected boolean isValidAccessor(ClassAccessor accessor, MetadataAnnotation annotation) {
        if (! accessor.loadedFromXML()) {
            // If it wasn't loaded from XML, we need to look at it further. It
            // could have been deleted and brought back (without an annotation)
            // or simply have had its annotation removed. Check for an annotation.
            return annotation != null;
        }

        return true;
    }

    /**
     * INTERNAL:
     * Steps are important here, so don't change them.
     */
    public void preProcessForCanonicalModel() {
        // 1 - Pre-Process the list of entities first. This will discover/build
        // the list of embeddable accessors.
        for (EntityAccessor entityAccessor : project.getEntityAccessors()) {
            // Some entity accessors can be fast tracked for pre-processing.
            // That is, an inheritance subclass will tell its parents to
            // pre-process. So don't pre-process it again.
            if (shouldPreProcess(entityAccessor)) {
                // Update the accessible object in case it changed.
                entityAccessor.setAccessibleObject(factory.getMetadataClass(entityAccessor.getAccessibleObjectName()));

                // Pre-process the accessor now.
                entityAccessor.preProcessForCanonicalModel();
            }
        }

        // 2 - Pre-Process the list of mapped superclasses.
        for (MappedSuperclassAccessor mappedSuperclassAccessor : project.getMappedSuperclasses()) {
            if (shouldPreProcess(mappedSuperclassAccessor)) {
                // Update the accessible object first, in case it changed.
                mappedSuperclassAccessor.setAccessibleObject(factory.getMetadataClass(mappedSuperclassAccessor.getAccessibleObjectName()));

                // Pre-process the accessor now.
                mappedSuperclassAccessor.preProcessForCanonicalModel();
            }
        }

        // 3 - Pre-process the list of root embeddable accessors. This list will
        // have been built from step 1. Root embeddable accessors will have
        // an owning descriptor (used to determine access type).
        for (EmbeddableAccessor embeddableAccessor : project.getRootEmbeddableAccessors()) {
            if (shouldPreProcess(embeddableAccessor)) {
                // Update the accessible object first, in case it changed.
                embeddableAccessor.setAccessibleObject(factory.getMetadataClass(embeddableAccessor.getAccessibleObjectName()));

                // Pre-process the accessor now.
                embeddableAccessor.preProcessForCanonicalModel();
            }
        }

        // 4 - Go through the whole list of embeddables and process any that
        // were not pre-processed. Only way this is true is if the embeddable
        // was not referenced from an entity (be it root or nested in a root
        // embeddable)
        for (EmbeddableAccessor embeddableAccessor : project.getEmbeddableAccessors()) {
            if (shouldPreProcess(embeddableAccessor)) {
                // Update the accessible object first, in case it changed.
                embeddableAccessor.setAccessibleObject(factory.getMetadataClass(embeddableAccessor.getAccessibleObjectName()));

                // Pre-process the accessor now.
                embeddableAccessor.preProcessForCanonicalModel();
            }
        }
    }

    /**
     * INTERNAL:
     * If it is not already pre-processed or is included in the round elements
     * (presumably because something changed), then pre-process the accessor.
     * You may get a previously loaded and processed XML class accessor that
     * may have had a change made to its associated class (that does not have
     * either an Entity, Embeddable or MappedSuperclass annotation) with the
     * load xml flag turned off. Therefore we must make sure we preProcess the
     * accessor again.
     */
    protected boolean shouldPreProcess(ClassAccessor accessor) {
        MetadataClass cls = (MetadataClass) accessor.getAccessibleObject();

        if (accessor.isPreProcessed() && factory.isRoundElement(cls)) {
            accessor.clearPreProcessed();
        }

        return ! accessor.isPreProcessed();
    }

    /**
     * INTERNAL:
     * Remove the entity accessor for the given metadata class if one exists.
     */
    protected void removeEntityAccessor(MetadataClass metadataClass) {
        if (project.hasEntity(metadataClass)) {
            project.removeEntityAccessor(metadataClass);
        }
    }

    /**
     * INTERNAL:
     * Remove the embeddable accessor for the given metadata class if one exists.
     */
    protected void removeEmbeddableAccessor(MetadataClass metadataClass) {
        if (project.hasEmbeddable(metadataClass)) {
            project.removeEmbeddableAccessor(metadataClass);
        }
    }

    /**
     * INTERNAL:
     * Remove the embeddable accessor for the given metadata class if one exists.
     */
    protected void removeMappedSuperclassAccessor(MetadataClass metadataClass) {
        if (project.hasMappedSuperclass(metadataClass)) {
            project.removeMappedSuperclassAccessor(metadataClass);
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public String toString() {
        return persistenceUnitInfo.getPersistenceUnitName();
    }
}

