Search in sources :

Example 1 with ClassNotResolvedException

use of org.datanucleus.exceptions.ClassNotResolvedException in project datanucleus-rdbms by datanucleus.

the class DatastoreAdapterFactory method getNewDatastoreAdapter.

/**
 * Accessor for the adapter for a specified datastore product.
 * @param clr ClassLoader resolver for resolving the adapter class
 * @param metadata Database MetaData for the RDBMS
 * @param adapterClassName Name of the class of the database adapter (null implies use autodetect)
 * @param pluginMgr the Plug-in manager
 * @return Instance of the database adapter
 */
protected DatastoreAdapter getNewDatastoreAdapter(ClassLoaderResolver clr, DatabaseMetaData metadata, String adapterClassName, PluginManager pluginMgr) {
    if (metadata == null) {
        return null;
    }
    String productName = null;
    if (adapterClassName == null) {
        // No adapter specified, so use "autodetection" based on the metadata to find the most suitable
        try {
            productName = metadata.getDatabaseProductName();
            if (productName == null) {
                NucleusLogger.DATASTORE.error(Localiser.msg("051024"));
                return null;
            }
        } catch (SQLException sqe) {
            NucleusLogger.DATASTORE.error(Localiser.msg("051025", sqe));
            return null;
        }
    }
    // Instantiate the adapter class
    final Object adapter_obj;
    try {
        Class adapterClass = getAdapterClass(pluginMgr, adapterClassName, productName, clr);
        if (adapterClass == null) {
            return null;
        }
        final Object[] ctr_args = new Object[] { metadata };
        final Class[] ctr_args_classes = new Class[] { DatabaseMetaData.class };
        // Create an instance of the datastore adapter
        final Constructor ctr = adapterClass.getConstructor(ctr_args_classes);
        try {
            adapter_obj = ctr.newInstance(ctr_args);
        } catch (InvocationTargetException ite) {
            if (ite.getTargetException() != null && ite.getTargetException() instanceof NucleusDataStoreException) {
                throw (NucleusDataStoreException) ite.getTargetException();
            }
            return null;
        } catch (Exception e) {
            NucleusLogger.DATASTORE.error(Localiser.msg("051026", adapterClassName, e));
            return null;
        }
    } catch (ClassNotResolvedException ex) {
        NucleusLogger.DATASTORE.error(Localiser.msg("051026", adapterClassName, ex));
        return null;
    } catch (NoSuchMethodException nsme) {
        NucleusLogger.DATASTORE.error(Localiser.msg("051026", adapterClassName, nsme));
        return null;
    }
    return (DatastoreAdapter) adapter_obj;
}
Also used : SQLException(java.sql.SQLException) Constructor(java.lang.reflect.Constructor) DatabaseMetaData(java.sql.DatabaseMetaData) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) InvocationTargetException(java.lang.reflect.InvocationTargetException) SQLException(java.sql.SQLException) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) InvocationTargetException(java.lang.reflect.InvocationTargetException) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException)

Example 2 with ClassNotResolvedException

use of org.datanucleus.exceptions.ClassNotResolvedException in project datanucleus-rdbms by datanucleus.

the class ObjectExpression method is.

/**
 * An "is" (instanceOf) expression, providing a BooleanExpression whether this expression is an instanceof the provided type.
 * @param expr The expression representing the type
 * @param not Whether the operator is "!instanceof"
 * @return Whether this expression is an instance of the provided type
 */
public BooleanExpression is(SQLExpression expr, boolean not) {
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    ClassLoaderResolver clr = stmt.getClassLoaderResolver();
    // Extract instanceOf type
    String instanceofClassName = null;
    SQLExpression classExpr = expr;
    if (expr instanceof TypeConverterLiteral) {
        // For some reason the user has input "TYPE(field) = :param" and param is a type-converted value
        classExpr = ((TypeConverterLiteral) expr).getDelegate();
    }
    if (classExpr instanceof StringLiteral) {
        instanceofClassName = (String) ((StringLiteral) classExpr).getValue();
    } else if (classExpr instanceof CollectionLiteral) {
        // "a instanceof (b1,b2,b3)"
        CollectionLiteral typesLiteral = (CollectionLiteral) classExpr;
        Collection values = (Collection) typesLiteral.getValue();
        if (values.size() == 1) {
            Object value = values.iterator().next();
            String valueStr = null;
            if (value instanceof Class) {
                valueStr = ((Class) value).getCanonicalName();
            } else if (value instanceof String) {
                valueStr = (String) value;
            } else {
                throw new NucleusUserException("Do not support CollectionLiteral of element type " + value.getClass().getName());
            }
            return is(new StringLiteral(stmt, typesLiteral.getJavaTypeMapping(), valueStr, typesLiteral.getParameterName()), not);
        }
        List<BooleanExpression> listExp = new LinkedList<>();
        for (Object value : values) {
            String valueStr = null;
            if (value instanceof Class) {
                valueStr = ((Class) value).getCanonicalName();
            } else if (value instanceof String) {
                valueStr = (String) value;
            } else {
                throw new NucleusUserException("Do not support CollectionLiteral of element type " + value.getClass().getName());
            }
            listExp.add(is(new StringLiteral(stmt, typesLiteral.getJavaTypeMapping(), valueStr, typesLiteral.getParameterName()), false));
        }
        BooleanExpression result = null;
        for (BooleanExpression sqlExpression : listExp) {
            result = result == null ? sqlExpression : result.ior(sqlExpression);
        }
        if (result != null) {
            return not ? result.not() : result;
        }
    } else {
        throw new NucleusUserException("Do not currently support `instanceof` with class expression of type " + classExpr);
    }
    Class type = null;
    try {
        type = stmt.getQueryGenerator().resolveClass(instanceofClassName);
    } catch (ClassNotResolvedException cnre) {
        type = null;
    }
    if (type == null) {
        throw new NucleusUserException(Localiser.msg("037016", instanceofClassName));
    }
    // Extract type of member and check obvious conditions
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    Class memberType = clr.classForName(mapping.getType());
    if (!memberType.isAssignableFrom(type) && !type.isAssignableFrom(memberType)) {
        // Member type and instanceof type are totally incompatible, so just return false
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, not));
    } else if (memberType == type) {
        // instanceof type is the same as the member type therefore must comply (can't store supertypes)
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, !not));
    }
    if (mapping instanceof EmbeddedMapping) {
        // Don't support embedded instanceof expressions
        AbstractClassMetaData fieldCmd = storeMgr.getMetaDataManager().getMetaDataForClass(mapping.getType(), clr);
        if (fieldCmd.hasDiscriminatorStrategy()) {
            // Embedded field with inheritance so add discriminator restriction
            JavaTypeMapping discMapping = ((EmbeddedMapping) mapping).getDiscriminatorMapping();
            AbstractClassMetaData typeCmd = storeMgr.getMetaDataManager().getMetaDataForClass(type, clr);
            SQLExpression discExpr = stmt.getSQLExpressionFactory().newExpression(stmt, table, discMapping);
            SQLExpression discValExpr = stmt.getSQLExpressionFactory().newLiteral(stmt, discMapping, typeCmd.getDiscriminatorValue());
            BooleanExpression typeExpr = (not ? discExpr.ne(discValExpr) : discExpr.eq(discValExpr));
            Iterator<String> subclassIter = storeMgr.getSubClassesForClass(type.getName(), true, clr).iterator();
            while (subclassIter.hasNext()) {
                String subclassName = subclassIter.next();
                AbstractClassMetaData subtypeCmd = storeMgr.getMetaDataManager().getMetaDataForClass(subclassName, clr);
                Object subtypeDiscVal = subtypeCmd.getDiscriminatorValue();
                discValExpr = stmt.getSQLExpressionFactory().newLiteral(stmt, discMapping, subtypeDiscVal);
                BooleanExpression subtypeExpr = (not ? discExpr.ne(discValExpr) : discExpr.eq(discValExpr));
                if (not) {
                    typeExpr = typeExpr.and(subtypeExpr);
                } else {
                    typeExpr = typeExpr.ior(subtypeExpr);
                }
            }
            return typeExpr;
        }
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, not));
    } else if (mapping instanceof PersistableMapping || mapping instanceof ReferenceMapping) {
        // Field has its own table, so join to it
        AbstractClassMetaData memberCmd = storeMgr.getMetaDataManager().getMetaDataForClass(mapping.getType(), clr);
        DatastoreClass memberTable = null;
        if (memberCmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.SUBCLASS_TABLE) {
            // Field is a PC class that uses "subclass-table" inheritance strategy (and so has multiple possible tables to join to)
            AbstractClassMetaData[] cmds = storeMgr.getClassesManagingTableForClass(memberCmd, clr);
            if (cmds != null) {
                // TODO Allow for all possible tables. Can we do an OR of the tables ? How ?
                if (cmds.length > 1) {
                    NucleusLogger.QUERY.warn(Localiser.msg("037006", mapping.getMemberMetaData().getFullFieldName(), cmds[0].getFullClassName()));
                }
                memberTable = storeMgr.getDatastoreClass(cmds[0].getFullClassName(), clr);
            } else {
                // No subclasses with tables to join to, so throw a user error
                throw new NucleusUserException(Localiser.msg("037005", mapping.getMemberMetaData().getFullFieldName()));
            }
        } else {
            // Class of the field will have its own table
            memberTable = storeMgr.getDatastoreClass(mapping.getType(), clr);
        }
        DiscriminatorMetaData dismd = memberTable.getDiscriminatorMetaData();
        DiscriminatorMapping discMapping = (DiscriminatorMapping) memberTable.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
        if (discMapping != null) {
            SQLTable targetSqlTbl = null;
            if (mapping.getTable() != memberTable) {
                // FK is on source table so inner join to target table (holding the discriminator)
                targetSqlTbl = stmt.getTable(memberTable, null);
                if (targetSqlTbl == null) {
                    targetSqlTbl = stmt.join(JoinType.INNER_JOIN, getSQLTable(), mapping, memberTable, null, memberTable.getIdMapping(), null, null);
                }
            } else {
                // FK is on target side and already joined
                targetSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, getSQLTable(), discMapping);
            }
            // Add restrict to discriminator for the instanceOf type and subclasses
            SQLTable discSqlTbl = targetSqlTbl;
            BooleanExpression discExpr = null;
            if (!Modifier.isAbstract(type.getModifiers())) {
                discExpr = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, type.getName(), dismd, discMapping, discSqlTbl, clr);
            }
            Iterator<String> subclassIter = storeMgr.getSubClassesForClass(type.getName(), true, clr).iterator();
            boolean multiplePossibles = false;
            while (subclassIter.hasNext()) {
                String subclassName = subclassIter.next();
                Class subclass = clr.classForName(subclassName);
                if (Modifier.isAbstract(subclass.getModifiers())) {
                    continue;
                }
                BooleanExpression discExprSub = SQLStatementHelper.getExpressionForDiscriminatorForClass(stmt, subclassName, dismd, discMapping, discSqlTbl, clr);
                if (discExpr != null) {
                    multiplePossibles = true;
                    discExpr = discExpr.ior(discExprSub);
                } else {
                    discExpr = discExprSub;
                }
            }
            if (multiplePossibles && discExpr != null) {
                discExpr.encloseInParentheses();
            }
            return ((not && discExpr != null) ? discExpr.not() : discExpr);
        }
        // No discriminator, so the following is likely incomplete.
        // Join to member table
        DatastoreClass table = null;
        if (memberCmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.SUBCLASS_TABLE) {
            // Field is a PC class that uses "subclass-table" inheritance strategy (and so has multiple possible tables to join to)
            AbstractClassMetaData[] cmds = storeMgr.getClassesManagingTableForClass(memberCmd, clr);
            if (cmds != null) {
                // TODO Allow for all possible tables. Can we do an OR of the tables ? How ?
                if (cmds.length > 1) {
                    NucleusLogger.QUERY.warn(Localiser.msg("037006", mapping.getMemberMetaData().getFullFieldName(), cmds[0].getFullClassName()));
                }
                table = storeMgr.getDatastoreClass(cmds[0].getFullClassName(), clr);
            } else {
                // No subclasses with tables to join to, so throw a user error
                throw new NucleusUserException(Localiser.msg("037005", mapping.getMemberMetaData().getFullFieldName()));
            }
        } else {
            // Class of the field will have its own table
            table = storeMgr.getDatastoreClass(mapping.getType(), clr);
        }
        if (table.managesClass(type.getName())) {
            // This type is managed in this table so must be an instance TODO Is this correct, what if member is using discrim?
            JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
            return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, !not));
        }
        if (table == stmt.getPrimaryTable().getTable()) {
            // This is member table, so just need to restrict to the instanceof type now
            JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
            if (stmt instanceof SelectStatement) {
                SelectStatement selectStmt = (SelectStatement) stmt;
                if (selectStmt.getNumberOfUnions() == 0) {
                    // No UNIONs so just check the main statement and return according to whether it is allowed
                    Class mainCandidateCls = clr.classForName(stmt.getCandidateClassName());
                    if (type.isAssignableFrom(mainCandidateCls) == not) {
                        SQLExpression returnExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
                        return (BooleanExpression) returnExpr;
                    }
                    SQLExpression returnExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
                    return (BooleanExpression) returnExpr;
                }
                NucleusLogger.QUERY.warn("TYPE/INSTANCEOF operator for class=" + memberCmd.getFullClassName() + " on table=" + memberTable + " for type=" + instanceofClassName + " but there is no discriminator and using UNIONs. Any subsequent handling is likely incorrect TODO");
                // a). we have unions for the member, so restrict to just the applicable unions
                // Note that this is only really valid is wanting "a instanceof SUB1".
                // It fails when we want to do "a instanceof SUB1 || a instanceof SUB2"
                // TODO What if this "OP_IS" is in the SELECT clause??? Need to update QueryToSQLMapper.compileResult
                Class mainCandidateCls = clr.classForName(stmt.getCandidateClassName());
                if (type.isAssignableFrom(mainCandidateCls) == not) {
                    SQLExpression unionClauseExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
                    stmt.whereAnd((BooleanExpression) unionClauseExpr, false);
                }
                List<SelectStatement> unionStmts = selectStmt.getUnions();
                for (SelectStatement unionStmt : unionStmts) {
                    Class unionCandidateCls = clr.classForName(unionStmt.getCandidateClassName());
                    if (type.isAssignableFrom(unionCandidateCls) == not) {
                        SQLExpression unionClauseExpr = exprFactory.newLiteral(unionStmt, m, true).eq(exprFactory.newLiteral(unionStmt, m, false));
                        // TODO Avoid using whereAnd
                        unionStmt.whereAnd((BooleanExpression) unionClauseExpr, false);
                    }
                }
                // Just return true since we applied the condition direct to the unions
                SQLExpression returnExpr = exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
                return (BooleanExpression) returnExpr;
            }
            // b). The member table doesn't manage the instanceof type, so do inner join to
            // the table of the instanceof to impose the instanceof condition
            DatastoreClass instanceofTable = storeMgr.getDatastoreClass(type.getName(), clr);
            stmt.join(JoinType.INNER_JOIN, this.table, this.table.getTable().getIdMapping(), instanceofTable, null, instanceofTable.getIdMapping(), null, this.table.getGroupName());
            return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, !not));
        }
        // Do inner join to this table to impose the instanceOf
        DatastoreClass instanceofTable = storeMgr.getDatastoreClass(type.getName(), clr);
        stmt.join(JoinType.INNER_JOIN, this.table, this.table.getTable().getIdMapping(), instanceofTable, null, instanceofTable.getIdMapping(), null, this.table.getGroupName());
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, !not));
    } else {
        // TODO Implement instanceof for other types
        throw new NucleusException("Dont currently support " + this + " instanceof " + type.getName());
    }
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) Iterator(java.util.Iterator) LinkedList(java.util.LinkedList) List(java.util.List) DiscriminatorMapping(org.datanucleus.store.rdbms.mapping.java.DiscriminatorMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) EmbeddedMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedMapping) Collection(java.util.Collection) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 3 with ClassNotResolvedException

use of org.datanucleus.exceptions.ClassNotResolvedException in project datanucleus-rdbms by datanucleus.

the class ObjectExpression method cast.

/**
 * Cast operator. Called when the query contains "(type)obj" where "obj" is this object.
 * @param expr Expression representing the type to cast to
 * @return Scalar expression representing the cast object.
 */
public SQLExpression cast(SQLExpression expr) {
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    ClassLoaderResolver clr = stmt.getClassLoaderResolver();
    // Extract cast type
    String castClassName = (String) ((StringLiteral) expr).getValue();
    Class type = null;
    try {
        type = stmt.getQueryGenerator().resolveClass(castClassName);
    } catch (ClassNotResolvedException cnre) {
        type = null;
    }
    if (type == null) {
        throw new NucleusUserException(Localiser.msg("037017", castClassName));
    }
    // Extract type of this object and check obvious conditions
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    Class memberType = clr.classForName(mapping.getType());
    if (!memberType.isAssignableFrom(type) && !type.isAssignableFrom(memberType)) {
        // object type and cast type are totally incompatible, so just return false
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, false).eq(exprFactory.newLiteral(stmt, m, true));
    } else if (memberType == type) {
        // Just return this expression since it is already castable
        return this;
    }
    if (mapping instanceof EmbeddedMapping) {
        // Don't support embedded casts
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, false).eq(exprFactory.newLiteral(stmt, m, true));
    } else if (mapping instanceof ReferenceMapping) {
        // This expression will be for the table containing the reference so need to join now
        ReferenceMapping refMapping = (ReferenceMapping) mapping;
        if (refMapping.getMappingStrategy() != ReferenceMapping.PER_IMPLEMENTATION_MAPPING) {
            throw new NucleusUserException("Impossible to do cast of interface to " + type.getName() + " since interface is persisted as embedded String." + " Use per-implementation mapping to allow this query");
        }
        JavaTypeMapping[] implMappings = refMapping.getJavaTypeMapping();
        for (int i = 0; i < implMappings.length; i++) {
            Class implType = clr.classForName(implMappings[i].getType());
            if (type.isAssignableFrom(implType)) {
                DatastoreClass castTable = storeMgr.getDatastoreClass(type.getName(), clr);
                SQLTable castSqlTbl = stmt.join(JoinType.LEFT_OUTER_JOIN, table, implMappings[i], refMapping, castTable, null, castTable.getIdMapping(), null, null, null, true, null);
                return exprFactory.newExpression(stmt, castSqlTbl, castTable.getIdMapping());
            }
        }
        // No implementation matching this cast type, so return false
        NucleusLogger.QUERY.warn("Unable to process cast of interface field to " + type.getName() + " since it has no implementations that match that type");
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        return exprFactory.newLiteral(stmt, m, false).eq(exprFactory.newLiteral(stmt, m, true));
    } else if (mapping instanceof PersistableMapping) {
        // Check if there is already the cast table in the current table group
        DatastoreClass castTable = storeMgr.getDatastoreClass(type.getName(), clr);
        SQLTable castSqlTbl = stmt.getTable(castTable, table.getGroupName());
        if (castSqlTbl == null) {
            // Join not present, so join to the cast table
            castSqlTbl = stmt.join(JoinType.LEFT_OUTER_JOIN, table, table.getTable().getIdMapping(), castTable, null, castTable.getIdMapping(), null, table.getGroupName());
        }
        if (castSqlTbl == table) {
            AbstractClassMetaData castCmd = storeMgr.getMetaDataManager().getMetaDataForClass(type, clr);
            if (castCmd.hasDiscriminatorStrategy()) {
                // TODO How do we handle this? If this is part of the filter then need to hang a BooleanExpression off the ObjectExpression and apply later.
                // If this is part of the result, do we just return null when this is not the right type?
                NucleusLogger.QUERY.warn(">> Currently do not support adding restriction on discriminator for table=" + table + " to " + type);
            }
        }
        // Return an expression based on the cast table
        return exprFactory.newExpression(stmt, castSqlTbl, castTable.getIdMapping());
    } else {
    // TODO Handle other casts
    }
    // TODO Implement cast (left outer join to table of type, then return new ObjectExpression)
    throw new NucleusUserException("Dont currently support ObjectExpression.cast(" + type + ")");
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) EmbeddedMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedMapping) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 4 with ClassNotResolvedException

use of org.datanucleus.exceptions.ClassNotResolvedException in project datanucleus-rdbms by datanucleus.

the class SQLExpressionFactory method getMethod.

/**
 * Accessor for the method defined by the class/method names and supplied args.
 * Throws a NucleusException is the method is not supported.
 * Note that if the class name passed in is not for a listed class with that method defined then will check all remaining defined methods for a superclass.
 * @param className Class we are invoking the method on
 * @param methodName Name of the method
 * @param args Any arguments to the method call (ignored currently) TODO Check the arguments
 * @return The method
 */
protected SQLMethod getMethod(String className, String methodName, List args) {
    String datastoreId = storeMgr.getDatastoreAdapter().getVendorID();
    // Try to find datastore-dependent evaluator for class+method
    MethodKey methodKey1 = getSQLMethodKey(datastoreId, className, methodName);
    MethodKey methodKey2 = null;
    SQLMethod method = sqlMethodsByKey.get(methodKey1);
    if (method == null) {
        // Try to find datastore-independent evaluator for class+method
        methodKey2 = getSQLMethodKey(null, className, methodName);
        method = sqlMethodsByKey.get(methodKey2);
    }
    if (method != null) {
        return method;
    }
    // No existing instance, so check the built-in SQLMethods from DatastoreAdapter
    Class sqlMethodCls = storeMgr.getDatastoreAdapter().getSQLMethodClass(className, methodName, clr);
    if (sqlMethodCls != null) {
        // Built-in SQLMethod found, so instantiate it, cache it and return it
        try {
            method = (SQLMethod) sqlMethodCls.getDeclaredConstructor().newInstance();
            MethodKey key = getSQLMethodKey(datastoreId, className, methodName);
            sqlMethodsByKey.put(key, method);
            return method;
        } catch (Exception e) {
            throw new NucleusException("Error creating SQLMethod of type " + sqlMethodCls.getName() + " for class=" + className + " method=" + methodName);
        }
    }
    // Check the plugin mechanism
    // 1). Try datastore-dependent key
    boolean datastoreDependent = true;
    if (!pluginSqlMethodsKeysSupported.contains(methodKey1)) {
        // 2). No datastore-dependent method, so try a datastore-independent key
        datastoreDependent = false;
        if (!pluginSqlMethodsKeysSupported.contains(methodKey2)) {
            // Not listed as supported for this particular class+method, so maybe is for a superclass
            boolean unsupported = true;
            if (!StringUtils.isWhitespace(className)) {
                Class cls = clr.classForName(className);
                // Try datastore-dependent
                for (MethodKey methodKey : pluginSqlMethodsKeysSupported) {
                    if (methodKey.methodName.equals(methodName) && methodKey.datastoreName.equals(datastoreId)) {
                        Class methodCls = null;
                        try {
                            methodCls = clr.classForName(methodKey.clsName);
                        } catch (ClassNotResolvedException cnre) {
                        // Maybe generic array support?
                        }
                        if (methodCls != null && methodCls.isAssignableFrom(cls)) {
                            // This one is usable here, for superclass
                            method = sqlMethodsByKey.get(methodKey);
                            if (method != null) {
                                MethodKey superMethodKey = new MethodKey();
                                superMethodKey.clsName = className;
                                superMethodKey.methodName = methodKey.methodName;
                                superMethodKey.datastoreName = methodKey.datastoreName;
                                // Cache the same method under this class also
                                sqlMethodsByKey.put(superMethodKey, method);
                                return method;
                            }
                            className = methodKey.clsName;
                            datastoreId = methodKey.datastoreName;
                            datastoreDependent = true;
                            unsupported = false;
                            break;
                        }
                    }
                }
                if (unsupported) {
                    // Try datastore-independent
                    for (MethodKey methodKey : pluginSqlMethodsKeysSupported) {
                        if (methodKey.methodName.equals(methodName) && methodKey.datastoreName.equals("ALL")) {
                            Class methodCls = null;
                            try {
                                methodCls = clr.classForName(methodKey.clsName);
                            } catch (ClassNotResolvedException cnre) {
                            // Maybe generic array support?
                            }
                            if (methodCls != null && methodCls.isAssignableFrom(cls)) {
                                // This one is usable here, for superclass
                                method = sqlMethodsByKey.get(methodKey);
                                if (method != null) {
                                    MethodKey superMethodKey = new MethodKey();
                                    superMethodKey.clsName = className;
                                    superMethodKey.methodName = methodKey.methodName;
                                    superMethodKey.datastoreName = methodKey.datastoreName;
                                    // Cache the same method under this class also
                                    sqlMethodsByKey.put(superMethodKey, method);
                                    return method;
                                }
                                className = methodKey.clsName;
                                datastoreId = methodKey.datastoreName;
                                datastoreDependent = false;
                                unsupported = false;
                                break;
                            }
                        }
                    }
                }
            }
            if (unsupported) {
                if (className != null) {
                    throw new NucleusUserException(Localiser.msg("060008", methodName, className));
                }
                throw new NucleusUserException(Localiser.msg("060009", methodName));
            }
        }
    }
    // Fallback to plugin lookup of class+method[+datastore]
    PluginManager pluginMgr = storeMgr.getNucleusContext().getPluginManager();
    String[] attrNames = (datastoreDependent ? new String[] { "class", "method", "datastore" } : new String[] { "class", "method" });
    String[] attrValues = (datastoreDependent ? new String[] { className, methodName, datastoreId } : new String[] { className, methodName });
    try {
        method = (SQLMethod) pluginMgr.createExecutableExtension("org.datanucleus.store.rdbms.sql_method", attrNames, attrValues, "evaluator", new Class[] {}, new Object[] {});
        // Register the method
        sqlMethodsByKey.put(getSQLMethodKey(datastoreDependent ? datastoreId : null, className, methodName), method);
        return method;
    } catch (Exception e) {
        throw new NucleusUserException(Localiser.msg("060011", "class=" + className + " method=" + methodName), e);
    }
}
Also used : PluginManager(org.datanucleus.plugin.PluginManager) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) SQLMethod(org.datanucleus.store.rdbms.sql.method.SQLMethod) NucleusException(org.datanucleus.exceptions.NucleusException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) NucleusException(org.datanucleus.exceptions.NucleusException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException)

Example 5 with ClassNotResolvedException

use of org.datanucleus.exceptions.ClassNotResolvedException in project datanucleus-core by datanucleus.

the class AbstractClassMetaData method determineSuperClassName.

/**
 * Determine the nearest superclass that is persistable (if any).
 * @param clr The ClassLoaderResolver
 * @param cls This class
 * @throws InvalidMetaDataException if the super class cannot be loaded by the <code>clr</code>.
 * @throws InvalidMetaDataException if the declared <code>persistence-capable-superclass</code> is not actually assignable from <code>cls</code>
 * @throws InvalidMetaDataException if any of the super classes is persistable, but the MetaData says that class is not persistent.
 */
protected void determineSuperClassName(ClassLoaderResolver clr, Class cls) {
    // Find the true superclass name (using reflection)
    String realPcSuperclassName = null;
    Collection<Class<?>> superclasses;
    if (cls.isInterface()) {
        superclasses = ClassUtils.getSuperinterfaces(cls);
    } else {
        superclasses = ClassUtils.getSuperclasses(cls);
    }
    for (Class<?> superclass : superclasses) {
        AbstractClassMetaData superCmd = mmgr.getMetaDataForClassInternal(superclass, clr);
        if (superCmd != null && superCmd.getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE) {
            realPcSuperclassName = superclass.getName();
            break;
        }
    }
    persistableSuperclass = realPcSuperclassName;
    if (persistableSuperclass != null) {
        Class pcsc = null;
        try {
            // Load using same class loader resolver as this class
            pcsc = clr.classForName(persistableSuperclass);
        } catch (ClassNotResolvedException cnre) {
            throw new InvalidClassMetaDataException("044081", fullName, persistableSuperclass);
        }
        if (persistableSuperclass.equals(fullName) || !clr.isAssignableFrom(pcsc.getName(), cls)) {
            throw new InvalidClassMetaDataException("044082", fullName, persistableSuperclass);
        }
        // Retrieve the Meta-Data for the superclass
        if (mmgr != null) {
            // Normal operation will have a MetaDataManager and so ask that for MetaData of superclass.
            pcSuperclassMetaData = mmgr.getMetaDataForClassInternal(pcsc, clr);
            if (pcSuperclassMetaData == null) {
                // Superclass isn't persistence capable since no MetaData could be found.
                throw new InvalidClassMetaDataException("044083", fullName, persistableSuperclass);
            }
        } else {
            // The enhancer doesn't need MetaDataManager so just navigate to FileMetaData and find it.
            // NOTE : assumes that the class is specified in the same file
            String superclassPkgName = persistableSuperclass.substring(0, persistableSuperclass.lastIndexOf('.'));
            PackageMetaData pmd = getPackageMetaData().getFileMetaData().getPackage(superclassPkgName);
            if (pmd != null) {
                String superclassClsName = persistableSuperclass.substring(persistableSuperclass.lastIndexOf('.') + 1);
                pcSuperclassMetaData = pmd.getClass(superclassClsName);
            }
        }
        if (pcSuperclassMetaData == null) {
            throw new InvalidClassMetaDataException("044084", fullName, persistableSuperclass);
        }
        if (!pcSuperclassMetaData.isPopulated() && !pcSuperclassMetaData.isInitialised()) {
            // Populate the superclass since we will be needing it
            pcSuperclassMetaData.populate(clr, cls.getClassLoader(), mmgr);
        }
    }
    if (persistableSuperclass != null && !isDetachable() && pcSuperclassMetaData.isDetachable()) {
        // Inherit detachable flag from superclass
        detachable = true;
    }
}
Also used : MacroString(org.datanucleus.util.MacroString) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException)

Aggregations

ClassNotResolvedException (org.datanucleus.exceptions.ClassNotResolvedException)34 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)18 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)13 NucleusException (org.datanucleus.exceptions.NucleusException)10 HashSet (java.util.HashSet)8 ArrayList (java.util.ArrayList)6 Iterator (java.util.Iterator)6 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)6 IOException (java.io.IOException)5 Collection (java.util.Collection)5 Method (java.lang.reflect.Method)4 List (java.util.List)4 ApiAdapter (org.datanucleus.api.ApiAdapter)4 Field (java.lang.reflect.Field)3 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)3 SCOID (org.datanucleus.identity.SCOID)3 ObjectProvider (org.datanucleus.state.ObjectProvider)3 Constructor (java.lang.reflect.Constructor)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 URL (java.net.URL)2