All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.dynamic.DynamicHelper Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998, 2024 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:
//     dclarke, mnorman - Dynamic Persistence
//       http://wiki.eclipse.org/EclipseLink/Development/Dynamic
//       (https://bugs.eclipse.org/bugs/show_bug.cgi?id=200045)
//     14/05/2012-2.4 Guy Pelletier
//       - 376603: Provide for table per tenant support for multitenant applications
package org.eclipse.persistence.dynamic;

//javase imports

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl;
import org.eclipse.persistence.internal.dynamic.DynamicPropertiesManager;
import org.eclipse.persistence.internal.dynamic.DynamicTypeImpl;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.tools.schemaframework.DynamicSchemaManager;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * A DynamicHelper provides some utility methods to simplify application
 * development with dynamic types. Since the application does not have static
 * references to the dynamic types it must use entity names. This helper
 * provides simplified access to methods that would typically require the static
 * classes.
 *
 * @author dclarke, mnorman
 * @since EclipseLink 1.2
 */
public class DynamicHelper {

    protected DatabaseSession session;
    protected Map fqClassnameToDescriptor =
        new HashMap<>();

    public DynamicHelper(DatabaseSession session) {
        this.session = session;
        Collection descriptors = session.getDescriptors().values();
        for (ClassDescriptor desc : descriptors) {
            if (desc.getJavaClassName() != null) {
                fqClassnameToDescriptor.put(desc.getJavaClassName(), desc);
            }
        }
    }

    public DatabaseSession getSession() {
        return this.session;
    }

    /**
     * Lookup the dynamic type for an alias. This is required to get the type
     * for factory creation but can also be used to provide the application with
     * access to the metamodel (type and properties) allowing for dynamic use
     * as well as optimized data value retrieval from an entity.
     */
    public DynamicType getType(String typeName) {
        ClassDescriptor cd = fqClassnameToDescriptor.get(typeName);
        if (cd == null) {
            cd = getSession().getClassDescriptorForAlias(typeName);
        }

        if (cd == null) {
            return null;
        }
        return getType(cd);
    }

    public static DynamicType getType(ClassDescriptor descriptor) {
        return (DynamicType) descriptor.getProperty(DynamicType.DESCRIPTOR_PROPERTY);
    }

    /**
     * Provide access to the entity's type.
     *
     * @throws ClassCastException
     *             if entity is not an instance of {@link DynamicEntityImpl}
     */
    public static DynamicType getType(DynamicEntity entity) throws ClassCastException {
        return ((DynamicEntityImpl) entity).getType();
    }

    /**
     * Remove a dynamic type from the system.
     * 

* This implementation assumes that the dynamic type has no relationships to * it and that it is not involved in an inheritance relationship. If there * are concurrent processes using this type when it is removed some * exceptions may occur. * */ public void removeType(String typeName) { DynamicType type = getType(typeName); if (type != null) { getSession().getIdentityMapAccessor().initializeIdentityMap(type.getJavaClass()); ClassDescriptor descriptor = type.getDescriptor(); fqClassnameToDescriptor.remove(descriptor.getJavaClassName()); getSession().getProject().getOrderedDescriptors().remove(descriptor); getSession().getProject().getDescriptors().remove(type.getJavaClass()); //bug 430318 - clear the parsed cache as queries in that cache could be using this descriptor getSession().getProject().getJPQLParseCache().clear(); ((AbstractSession)getSession()).getCommitManager().getCommitOrder().remove(type.getJavaClass()); } } /** * */ public DynamicEntity newDynamicEntity(String typeName) { DynamicType type = getType(typeName); if (type == null) { throw new IllegalArgumentException("DynamicHelper.createQuery: Dynamic type not found: " + typeName); } return type.newDynamicEntity(); } /** * Helper method to simplify creating a native ReadAllQuery using the entity * type name (descriptor alias) */ public ReadAllQuery newReadAllQuery(String typeName) { DynamicType type = getType(typeName); if (type == null) { throw new IllegalArgumentException("DynamicHelper.createQuery: Dynamic type not found: " + typeName); } return new ReadAllQuery(type.getJavaClass()); } /** * Helper method to simplify creating a native ReadObjectQuery using the * entity type name (descriptor alias) */ public ReadObjectQuery newReadObjectQuery(String typeName) { DynamicType type = getType(typeName); if (type == null) { throw new IllegalArgumentException("DynamicHelper.createQuery: Dynamic type not found: " + typeName); } return new ReadObjectQuery(type.getJavaClass()); } /** * Helper method to simplify creating a native ReportQuery using the entity * type name (descriptor alias) */ public ReportQuery newReportQuery(String typeName, ExpressionBuilder builder) { DynamicType type = getType(typeName); if (type == null) { throw new IllegalArgumentException("DynamicHelper.createQuery: Dynamic type not found: " + typeName); } return new ReportQuery(type.getJavaClass(), builder); } public DynamicClassLoader getDynamicClassLoader() { return DynamicClassLoader.lookup(getSession()); } /** * Add one or more EntityType instances to a session and optionally generate * needed tables with or without FK constraints. * */ public void addTypes(boolean createMissingTables, boolean generateFKConstraints, DynamicType... types) { if (types == null || types.length == 0) { throw new IllegalArgumentException("No types provided"); } Collection descriptors = new ArrayList<>(types.length); for (int index = 0; index < types.length; index++) { DynamicType typ = types[index]; ClassDescriptor desc = typ.getDescriptor(); DynamicTypeImpl typImpl = ((DynamicTypeImpl)typ); typImpl.setDescriptor(desc); try { Field dpmField = desc.getJavaClass().getField(DynamicPropertiesManager.PROPERTIES_MANAGER_FIELD); DynamicPropertiesManager dpm = (DynamicPropertiesManager)dpmField.get(null); dpm.setType(typImpl); typImpl.setDynamicPropertiesManager(dpm); } catch (Exception e) { // this is bad! Without the dpmField, not much to do but die :-( ... e.printStackTrace(); return; } descriptors.add(desc); if (!types[index].getDescriptor().requiresInitialization((AbstractSession) session)) { types[index].getDescriptor().getInstantiationPolicy().initialize((AbstractSession) session); } } session.addDescriptors(descriptors); for (ClassDescriptor desc : descriptors) { if (desc.getJavaClassName() != null) { fqClassnameToDescriptor.put(desc.getJavaClassName(), desc); } } if (createMissingTables) { if (!getSession().isConnected()) { getSession().login(); } new DynamicSchemaManager(session).createTables(generateFKConstraints, types); } } /** * A SessionCustomizer which configures all descriptors as dynamic entity * types. */ public static class SessionCustomizer implements org.eclipse.persistence.sessions.SessionCustomizer { /** * Default constructor. */ public SessionCustomizer() { } @Override public void customize(Session session) throws Exception { DynamicClassLoader dcl = DynamicClassLoader.lookup(session); for (Iterator i = session.getProject().getDescriptors().values().iterator(); i.hasNext();) { new DynamicTypeBuilder(dcl, (ClassDescriptor) i.next(), null); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy