Search in sources :

Example 1 with FunctionType

use of org.eclipse.persistence.tools.oracleddl.metadata.FunctionType in project eclipselink by eclipse-ee4j.

the class JPAMetadataGenerator method generateXmlEntityMappings.

/**
 * Generate an XMLEntityMappings instance based on a given list of meta-model database types.
 *
 * @param databaseTypes the list of meta-model database types to be used to generate an XMLEntityMappings
 * @see org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType
 */
public XMLEntityMappings generateXmlEntityMappings(List<CompositeDatabaseType> databaseTypes) {
    List<ProcedureType> procedures = new ArrayList<ProcedureType>();
    List<TableType> tables = new ArrayList<TableType>();
    // populate lists of TableTypes and ProcedureTypes
    for (CompositeDatabaseType dbType : databaseTypes) {
        if (dbType.isTableType()) {
            tables.add((TableType) dbType);
        } else if (dbType.isProcedureType()) {
            procedures.add((ProcedureType) dbType);
        }
    }
    // handle stored procedure overloading
    handleOverloading(procedures);
    // process TableTypes
    for (TableType table : tables) {
        EntityAccessor entity = processTableType(table);
        xmlEntityMappings.getEntities().add(entity);
    }
    // process ProcedureTypes
    for (ProcedureType procedure : procedures) {
        // PL/SQL stored procedures and functions will have a PLSQLPackageType as its parent
        PLSQLPackageType pkgType = procedure.getParentType();
        if (pkgType != null) {
            // handle PL/SQL
            if (procedure.isFunctionType()) {
                xmlEntityMappings.getNamedPLSQLStoredFunctionQueries().add(processPLSQLFunctionType((FunctionType) procedure, pkgType));
            } else {
                xmlEntityMappings.getNamedPLSQLStoredProcedureQueries().add(processPLSQLProcedureType(procedure, pkgType));
            }
        } else {
            // handle top-level (non-PL/SQL) functions and procedures
            if (procedure.isFunctionType()) {
                xmlEntityMappings.getNamedStoredFunctionQueries().add(processFunctionType((FunctionType) procedure));
            } else {
                xmlEntityMappings.getNamedStoredProcedureQueries().add(processProcedureType(procedure));
            }
        }
    }
    return xmlEntityMappings;
}
Also used : EntityAccessor(org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor) ProcedureType(org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType) TableType(org.eclipse.persistence.tools.oracleddl.metadata.TableType) ObjectTableType(org.eclipse.persistence.tools.oracleddl.metadata.ObjectTableType) PLSQLPackageType(org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType) FunctionType(org.eclipse.persistence.tools.oracleddl.metadata.FunctionType) ArrayList(java.util.ArrayList) CompositeDatabaseType(org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType)

Example 2 with FunctionType

use of org.eclipse.persistence.tools.oracleddl.metadata.FunctionType in project eclipselink by eclipse-ee4j.

the class OracleHelper method loadProcedures.

/**
 * Generates a {@code List<ProcedureType>} based on a given set of patterns.
 */
@Override
protected List<ProcedureType> loadProcedures(List<String> catalogPatterns, List<String> schemaPatterns, List<String> procedureNamePatterns) {
    List<ProcedureType> allProcsAndFuncs = new ArrayList<ProcedureType>();
    List<String> topLevelSchemaPatterns = new ArrayList<String>();
    List<String> topLevelProcedureNamePatterns = new ArrayList<String>();
    Map<String, Set<String>> packagePatterns = new HashMap<String, Set<String>>();
    for (int i = 0, len = catalogPatterns.size(); i < len; i++) {
        String catalogPattern = catalogPatterns.get(i);
        String schemaPattern = schemaPatterns.get(i);
        if (schemaPattern == null) {
            schemaPattern = dbwsBuilder.getUsername().toUpperCase();
        }
        if (catalogPattern == null || catalogPattern.length() == 0 || TOPLEVEL.equals(catalogPattern)) {
            topLevelSchemaPatterns.add(schemaPattern);
            topLevelProcedureNamePatterns.add(procedureNamePatterns.get(i));
        } else {
            Set<String> packageNames = packagePatterns.get(schemaPattern);
            if (packageNames == null) {
                packageNames = new HashSet<String>();
                packagePatterns.put(schemaPattern, packageNames);
            }
            packageNames.add(catalogPattern);
        }
    }
    if (topLevelProcedureNamePatterns.size() > 0) {
        try {
            List<ProcedureType> topLevelProcedures = dtBuilder.buildProcedures(dbwsBuilder.getConnection(), topLevelSchemaPatterns, topLevelProcedureNamePatterns);
            if (topLevelProcedures != null && topLevelProcedures.size() > 0) {
                allProcsAndFuncs.addAll(topLevelProcedures);
            }
        } catch (ParseException e) {
            dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
        }
        try {
            List<FunctionType> topLevelFunctions = dtBuilder.buildFunctions(dbwsBuilder.getConnection(), topLevelSchemaPatterns, topLevelProcedureNamePatterns);
            if (topLevelFunctions != null && topLevelFunctions.size() > 0) {
                allProcsAndFuncs.addAll(topLevelFunctions);
            }
        } catch (ParseException e) {
            dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
        }
    }
    if (packagePatterns.size() > 0) {
        try {
            // unravel map
            List<String> schemaPats = new ArrayList<String>();
            List<String> packagePats = new ArrayList<String>();
            for (Map.Entry<String, Set<String>> entry : packagePatterns.entrySet()) {
                String schema = entry.getKey();
                for (String packageName : entry.getValue()) {
                    schemaPats.add(schema);
                    packagePats.add(packageName);
                }
            }
            List<PLSQLPackageType> packages = dtBuilder.buildPackages(dbwsBuilder.getConnection(), schemaPats, packagePats);
            if (packages == null || packages.isEmpty()) {
                logPackageNotFoundWarnings(NO_PKG_MSG, schemaPats, packagePats);
            } else {
                for (PLSQLPackageType pakage : packages) {
                    // check DDL generation
                    ShadowDDLGenerator ddlGenerator = new ShadowDDLGenerator(pakage);
                    dbwsBuilder.getTypeDDL().addAll(ddlGenerator.getAllCreateDDLs());
                    dbwsBuilder.getTypeDropDDL().addAll(ddlGenerator.getAllDropDDLs());
                    // check for overloading
                    Map<String, List<ProcedureType>> overloadMap = new HashMap<String, List<ProcedureType>>();
                    List<ProcedureType> procedures = pakage.getProcedures();
                    for (ProcedureType procedure : procedures) {
                        String procedureName = procedure.getProcedureName();
                        List<ProcedureType> multipleProcedures = overloadMap.get(procedureName);
                        if (multipleProcedures == null) {
                            multipleProcedures = new ArrayList<ProcedureType>();
                            overloadMap.put(procedureName, multipleProcedures);
                        }
                        multipleProcedures.add(procedure);
                    }
                    for (List<ProcedureType> procs : overloadMap.values()) {
                        if (procs.size() > 1) {
                            for (int i = 0, len = procs.size(); i < len; i++) {
                                procs.get(i).setOverload(i);
                            }
                        }
                    }
                    // Check against procedureNamePatterns
                    String tmp = buildNamePatternsList(procedureNamePatterns);
                    for (ProcedureType procedure : procedures) {
                        if (sqlMatch(tmp, procedure.getProcedureName())) {
                            allProcsAndFuncs.add(procedure);
                        }
                    }
                }
            }
        } catch (ParseException e) {
            dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
        }
    }
    return allProcsAndFuncs.isEmpty() ? null : allProcsAndFuncs;
}
Also used : ProcedureType(org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType) Set(java.util.Set) HashSet(java.util.HashSet) PLSQLPackageType(org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType) HashMap(java.util.HashMap) FunctionType(org.eclipse.persistence.tools.oracleddl.metadata.FunctionType) ArrayList(java.util.ArrayList) Util.qNameFromString(org.eclipse.persistence.tools.dbws.Util.qNameFromString) ArrayList(java.util.ArrayList) List(java.util.List) ParseException(org.eclipse.persistence.tools.oracleddl.parser.ParseException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 3 with FunctionType

use of org.eclipse.persistence.tools.oracleddl.metadata.FunctionType in project eclipselink by eclipse-ee4j.

the class JDBCHelper method loadProcedures.

protected List<ProcedureType> loadProcedures(String originalCatalogPattern, String originalSchemaPattern, String originalProcedurePattern) {
    List<ProcedureType> dbStoredProcedures = null;
    boolean catalogMatchDontCare = false;
    DatabasePlatform platform = dbwsBuilder.getDatabasePlatform();
    if (platform instanceof MySQLPlatform || platform instanceof DerbyPlatform || platform instanceof PostgreSQLPlatform) {
        // note that get info on other platforms that also require catalogMatchDontCare = true
        catalogMatchDontCare = true;
    }
    String catalogPattern = escapePunctuation(originalCatalogPattern);
    String schemaPattern = escapePunctuation(originalSchemaPattern);
    String procedurePattern = escapePunctuation(originalProcedurePattern);
    // Make sure procedure(s) is/are available
    ResultSet procsInfo = null;
    try {
        DatabaseMetaData databaseMetaData = getDatabaseMetaData(dbwsBuilder.getConnection());
        procsInfo = databaseMetaData.getProcedures(catalogPattern, schemaPattern, procedurePattern);
        // did we get a hit?
        if (procsInfo != null) {
            List<ProcedureType> tmpProcs = new ArrayList<ProcedureType>();
            while (procsInfo.next()) {
                String actualCatalogName = procsInfo.getString(PROCS_INFO_CATALOG);
                String actualSchemaName = procsInfo.getString(PROCS_INFO_SCHEMA);
                String actualProcedureName = procsInfo.getString(PROCS_INFO_NAME);
                short procedureType = procsInfo.getShort(PROCS_INFO_TYPE);
                ProcedureType dbStoredProcedure;
                if (procedureType == procedureReturnsResult) {
                    dbStoredProcedure = new FunctionType(actualProcedureName);
                } else {
                    dbStoredProcedure = new ProcedureType(actualProcedureName);
                }
                if (actualCatalogName != null && actualCatalogName.length() > 0) {
                    dbStoredProcedure.setCatalogName(actualCatalogName);
                }
                if (actualSchemaName != null && actualSchemaName.length() > 0) {
                    dbStoredProcedure.setSchema(actualSchemaName);
                }
                tmpProcs.add(dbStoredProcedure);
            }
            procsInfo.close();
            /* new a temp bucket to hold DbStoredArgs until they can be sorted out with respect
                 * to which DbStoredProcedure owns which args; this has to be done because Oracle can
                 * return multiple hits across multiple packages for the same procedureName.
                 */
            int numProcs = tmpProcs.size();
            if (numProcs > 0) {
                dbStoredProcedures = new ArrayList<ProcedureType>(numProcs);
                ResultSet procedureColumnsInfo = null;
                procedureColumnsInfo = databaseMetaData.getProcedureColumns(catalogPattern, schemaPattern, procedurePattern, "%");
                while (procedureColumnsInfo.next()) {
                    String actualCatalogName = procedureColumnsInfo.getString(PROC_COLS_INFO_CATALOG);
                    String actualSchemaName = procedureColumnsInfo.getString(PROC_COLS_INFO_SCHEMA);
                    String actualProcedureName = procedureColumnsInfo.getString(PROC_COLS_INFO_NAME);
                    String argName = procedureColumnsInfo.getString(PROC_COLS_INFO_COLNAME);
                    // some MySql drivers return empty string, some return null: set to emptyString regardless
                    if (argName == null) {
                        argName = "";
                    }
                    ArgumentType dbStoredArgument = new ArgumentType(argName);
                    short inOut = procedureColumnsInfo.getShort(PROC_COLS_INFO_TYPE);
                    if (inOut == procedureColumnInOut) {
                        dbStoredArgument.setDirection(INOUT);
                    } else if (inOut == procedureColumnOut) {
                        dbStoredArgument.setDirection(OUT);
                    } else if (inOut == procedureColumnReturn) {
                        dbStoredArgument.setDirection(RETURN);
                    } else {
                        // default to ArgumentTypeDirection.IN
                        dbStoredArgument.setDirection(IN);
                    }
                    int jdbcType = procedureColumnsInfo.getInt(PROC_COLS_INFO_DATA_TYPE);
                    int precision = procedureColumnsInfo.getInt(PROC_COLS_INFO_PRECISION);
                    int scale = procedureColumnsInfo.getInt(PROC_COLS_INFO_SCALE);
                    dbStoredArgument.setEnclosedType(buildTypeForJDBCType(jdbcType, precision, scale));
                    // find matching DbStoredProcedure
                    // this dbStoredArgument belongs to a 'regular' procedure
                    ProcedureType matchingProc = null;
                    for (int i = 0; i < tmpProcs.size(); ) {
                        ProcedureType tmpProc = tmpProcs.get(i);
                        if (matches(tmpProc, actualCatalogName, actualSchemaName, actualProcedureName, false, catalogMatchDontCare)) {
                            matchingProc = tmpProc;
                            dbStoredProcedures.add(matchingProc);
                            break;
                        }
                        i++;
                    }
                    if (matchingProc == null) {
                        // look in dbStoredProcedures - matching proc already moved over ?
                        for (ProcedureType dbStoredProcedure : dbStoredProcedures) {
                            if (matches(dbStoredProcedure, actualCatalogName, actualSchemaName, actualProcedureName, false, catalogMatchDontCare)) {
                                matchingProc = dbStoredProcedure;
                                break;
                            }
                        }
                    }
                    if (matchingProc != null) {
                        if (matchingProc.isFunctionType() && dbStoredArgument.getArgumentName().equalsIgnoreCase("")) {
                            ((FunctionType) matchingProc).setReturnArgument(dbStoredArgument);
                        } else {
                            matchingProc.getArguments().add(dbStoredArgument);
                        }
                        tmpProcs.remove(matchingProc);
                    }
                // else some argument that doesn't have a matching proc? ignore for now
                }
                procedureColumnsInfo.close();
                if (!tmpProcs.isEmpty()) {
                    // leftovers are the no-arg procedures
                    dbStoredProcedures.addAll(tmpProcs);
                }
            }
        }
    } catch (SQLException sqlException) {
        throw new IllegalStateException("failure retrieving Stored Procedure metadata", sqlException);
    }
    if (dbStoredProcedures != null && !dbStoredProcedures.isEmpty()) {
        Collections.sort(dbStoredProcedures, new Comparator<ProcedureType>() {

            @Override
            public int compare(ProcedureType o1, ProcedureType o2) {
                String name1 = o1.getProcedureName();
                String name2 = o2.getProcedureName();
                if (!name1.equals(name2)) {
                    return name1.compareTo(name2);
                } else {
                    return o1.getOverload() - o2.getOverload();
                }
            }
        });
    }
    return dbStoredProcedures;
}
Also used : PostgreSQLPlatform(org.eclipse.persistence.platform.database.PostgreSQLPlatform) ProcedureType(org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType) SQLException(java.sql.SQLException) FunctionType(org.eclipse.persistence.tools.oracleddl.metadata.FunctionType) ArrayList(java.util.ArrayList) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) Util.qNameFromString(org.eclipse.persistence.tools.dbws.Util.qNameFromString) DatabaseMetaData(java.sql.DatabaseMetaData) ArgumentType(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType) DerbyPlatform(org.eclipse.persistence.platform.database.DerbyPlatform) ResultSet(java.sql.ResultSet) MySQLPlatform(org.eclipse.persistence.platform.database.MySQLPlatform)

Example 4 with FunctionType

use of org.eclipse.persistence.tools.oracleddl.metadata.FunctionType in project eclipselink by eclipse-ee4j.

the class JDBCHelper method buildProcedureOperation.

@Override
public void buildProcedureOperation(ProcedureOperationModel procedureOperationModel) {
    String name = procedureOperationModel.getName();
    boolean isMySQL = dbwsBuilder.getDatabasePlatform().getClass().getName().contains("MySQL");
    for (ProcedureType storedProcedure : procedureOperationModel.getDbStoredProcedures()) {
        StringBuilder sb = new StringBuilder();
        if (name == null || name.length() == 0) {
            if (storedProcedure.getOverload() > 0) {
                sb.append(storedProcedure.getOverload());
                sb.append('_');
            }
            if (storedProcedure.getCatalogName() != null && storedProcedure.getCatalogName().length() > 0) {
                sb.append(storedProcedure.getCatalogName());
                sb.append('_');
            }
            if (storedProcedure.getSchema() != null && storedProcedure.getSchema().length() > 0) {
                sb.append(storedProcedure.getSchema());
                sb.append('_');
            }
            sb.append(storedProcedure.getProcedureName());
        } else {
            sb.append(name);
        }
        QueryOperation qo = new QueryOperation();
        qo.setName(sb.toString());
        QueryHandler qh;
        if (storedProcedure.isFunctionType()) {
            qh = new StoredFunctionQueryHandler();
        } else {
            qh = new StoredProcedureQueryHandler();
        }
        sb = new StringBuilder();
        if (!isMySQL) {
            if (storedProcedure.getCatalogName() != null && storedProcedure.getCatalogName().length() > 0) {
                sb.append(storedProcedure.getCatalogName());
                sb.append('.');
            }
        }
        if (storedProcedure.getSchema() != null && storedProcedure.getSchema().length() > 0) {
            sb.append(storedProcedure.getSchema());
            sb.append('.');
        }
        sb.append(storedProcedure.getProcedureName());
        ((StoredProcedureQueryHandler) qh).setName(sb.toString());
        dbwsBuilder.logMessage(FINEST, "Building QueryOperation for " + sb.toString());
        // before assigning queryHandler, check for named query in OR project
        List<DatabaseQuery> queries = dbwsBuilder.getOrProject().getQueries();
        if (queries.size() > 0) {
            for (DatabaseQuery q : queries) {
                if (q.getName().equals(qo.getName())) {
                    qh = new NamedQueryHandler();
                    ((NamedQueryHandler) qh).setName(qo.getName());
                }
            }
        }
        qo.setQueryHandler(qh);
        String returnType = procedureOperationModel.getReturnType();
        boolean isCollection = procedureOperationModel.isCollection();
        boolean isSimpleXMLFormat = procedureOperationModel.isSimpleXMLFormat();
        Result result = null;
        if (storedProcedure.isFunctionType()) {
            FunctionType storedFunction = (FunctionType) storedProcedure;
            DatabaseType rarg = storedFunction.getReturnArgument();
            if (rarg.getTypeName().contains("CURSOR")) {
                result = new CollectionResult();
                result.setType(SXF_QNAME_CURSOR);
            } else {
                result = new Result();
                int rargJdbcType = Util.getJDBCTypeFromTypeName(rarg.getTypeName());
                switch(rargJdbcType) {
                    case STRUCT:
                    case ARRAY:
                    case OTHER:
                        if (returnType != null) {
                            result.setType(buildCustomQName(returnType, dbwsBuilder));
                        } else {
                            result.setType(ANY_QNAME);
                        }
                        break;
                    default:
                        result.setType(getXMLTypeFromJDBCType(rargJdbcType));
                        break;
                }
            }
        } else {
            // if user overrides returnType, assume they're right
            if (returnType != null) {
                result = new Result();
                result.setType(buildCustomQName(returnType, dbwsBuilder));
            } else {
                if (isCollection) {
                    result = new CollectionResult();
                    if (isSimpleXMLFormat) {
                        result.setType(SXF_QNAME_CURSOR);
                    }
                } else {
                    result = new Result();
                    result.setType(SXF_QNAME);
                }
            }
        }
        if (procedureOperationModel.getBinaryAttachment()) {
            Attachment attachment = new Attachment();
            attachment.setMimeType("application/octet-stream");
            result.setAttachment(attachment);
        }
        for (ArgumentType arg : storedProcedure.getArguments()) {
            String argName = arg.getArgumentName();
            if (argName != null) {
                ProcedureArgument pa = null;
                Parameter parm = null;
                ArgumentTypeDirection direction = arg.getDirection();
                QName xmlType = null;
                switch(Util.getJDBCTypeFromTypeName(arg.getTypeName())) {
                    case STRUCT:
                    case ARRAY:
                    case OTHER:
                        String typeString = nct.generateSchemaAlias(arg.getTypeName());
                        xmlType = buildCustomQName(typeString, dbwsBuilder);
                        break;
                    default:
                        xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
                        break;
                }
                if (direction == IN) {
                    parm = new Parameter();
                    parm.setName(argName);
                    parm.setType(xmlType);
                    pa = new ProcedureArgument();
                    pa.setName(argName);
                    pa.setParameterName(argName);
                    if (qh instanceof StoredProcedureQueryHandler) {
                        ((StoredProcedureQueryHandler) qh).getInArguments().add(pa);
                    }
                } else {
                    // the first OUT/INOUT arg determines singleResult vs. collectionResult
                    pa = new ProcedureOutputArgument();
                    ProcedureOutputArgument pao = (ProcedureOutputArgument) pa;
                    pao.setName(argName);
                    pao.setParameterName(argName);
                    if (arg.getTypeName().contains("CURSOR") && returnType == null) {
                        // if user overrides returnType, assume they're right
                        pao.setResultType(SXF_QNAME_CURSOR);
                        if (result == null) {
                            result = new CollectionResult();
                            result.setType(SXF_QNAME_CURSOR);
                        }
                    } else {
                        // Hmm, multiple OUT's gonna be a problem - later!
                        if (returnType != null && !isSimpleXMLFormat) {
                            xmlType = qNameFromString("{" + dbwsBuilder.getTargetNamespace() + "}" + returnType, dbwsBuilder.getSchema());
                        }
                        pao.setResultType(xmlType);
                        if (result == null) {
                            if (isCollection) {
                                result = new CollectionResult();
                            } else {
                                result = new Result();
                            }
                            result.setType(xmlType);
                        }
                    }
                    if (direction == INOUT) {
                        parm = new Parameter();
                        parm.setName(argName);
                        parm.setType(xmlType);
                        result.setType(xmlType);
                        // use of INOUT precludes SimpleXMLFormat
                        isSimpleXMLFormat = false;
                        if (qh instanceof StoredProcedureQueryHandler) {
                            ((StoredProcedureQueryHandler) qh).getInOutArguments().add(pao);
                        }
                    } else {
                        if (qh instanceof StoredProcedureQueryHandler) {
                            ((StoredProcedureQueryHandler) qh).getOutArguments().add(pao);
                        }
                    }
                }
                if (parm != null) {
                    qo.getParameters().add(parm);
                }
            }
        }
        handleSimpleXMLFormat(isSimpleXMLFormat, result, procedureOperationModel);
        qo.setResult(result);
        dbwsBuilder.getXrServiceModel().getOperations().put(qo.getName(), qo);
    }
    finishProcedureOperation();
}
Also used : ProcedureType(org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType) StoredProcedureQueryHandler(org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler) StoredFunctionQueryHandler(org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler) QueryHandler(org.eclipse.persistence.internal.xr.QueryHandler) NamedQueryHandler(org.eclipse.persistence.internal.xr.NamedQueryHandler) CompositeDatabaseType(org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType) DatabaseType(org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType) DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) Util.buildCustomQName(org.eclipse.persistence.tools.dbws.Util.buildCustomQName) QName(javax.xml.namespace.QName) FunctionType(org.eclipse.persistence.tools.oracleddl.metadata.FunctionType) StoredProcedureQueryHandler(org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler) Attachment(org.eclipse.persistence.internal.xr.Attachment) Util.qNameFromString(org.eclipse.persistence.tools.dbws.Util.qNameFromString) ArgumentType(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType) ProcedureArgument(org.eclipse.persistence.internal.xr.ProcedureArgument) ProcedureOutputArgument(org.eclipse.persistence.internal.xr.ProcedureOutputArgument) CollectionResult(org.eclipse.persistence.internal.xr.CollectionResult) Result(org.eclipse.persistence.internal.xr.Result) DatabaseMetaData.procedureReturnsResult(java.sql.DatabaseMetaData.procedureReturnsResult) StoredFunctionQueryHandler(org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler) CollectionResult(org.eclipse.persistence.internal.xr.CollectionResult) NamedQueryHandler(org.eclipse.persistence.internal.xr.NamedQueryHandler) Parameter(org.eclipse.persistence.internal.xr.Parameter) QueryOperation(org.eclipse.persistence.internal.xr.QueryOperation) ArgumentTypeDirection(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection)

Example 5 with FunctionType

use of org.eclipse.persistence.tools.oracleddl.metadata.FunctionType in project eclipselink by eclipse-ee4j.

the class OracleHelper method buildProcedureOperation.

/**
 * Builds query operations for a given ProcedureOperationModel.
 */
@Override
public void buildProcedureOperation(ProcedureOperationModel procedureOperationModel) {
    for (ProcedureType storedProcedure : procedureOperationModel.getDbStoredProcedures()) {
        boolean hasComplexArgs = hasComplexArgs(storedProcedure);
        QueryOperation qo = new QueryOperation();
        qo.setName(getNameForQueryOperation(procedureOperationModel, storedProcedure));
        String qualifiedProcName = getQualifiedProcedureName(procedureOperationModel, storedProcedure);
        dbwsBuilder.logMessage(FINEST, BUILDING_QUERYOP_FOR + qualifiedProcName);
        QueryHandler qh = null;
        // before assigning queryHandler, check for named query in OR project
        List<DatabaseQuery> queries = dbwsBuilder.getOrProject().getQueries();
        if (queries.size() > 0) {
            for (DatabaseQuery q : queries) {
                if (q.getName().equals(qo.getName())) {
                    qh = new NamedQueryHandler();
                    ((NamedQueryHandler) qh).setName(qo.getName());
                }
            }
        }
        if (qh == null) {
            if (storedProcedure.isFunctionType()) {
                qh = new StoredFunctionQueryHandler();
            } else {
                qh = new StoredProcedureQueryHandler();
            }
            ((StoredProcedureQueryHandler) qh).setName(qualifiedProcName);
        }
        qo.setQueryHandler(qh);
        String returnType = procedureOperationModel.getReturnType();
        boolean isCollection = procedureOperationModel.isCollection();
        boolean isSimpleXMLFormat = procedureOperationModel.isSimpleXMLFormat();
        Result result = null;
        /**
         * For multiple OUT args as well as a stored function with OUT args, we want
         * the result to be a collection and the type to be "xsd:any".  We will
         * force SimpleXMLFormat for now as well.
         */
        int outArgCount = 0;
        for (ArgumentType argument : storedProcedure.getArguments()) {
            ArgumentTypeDirection argDirection = argument.getDirection();
            if (argDirection == OUT) {
                outArgCount++;
            }
        }
        if (outArgCount > 1 || (outArgCount > 0 && storedProcedure.isFunctionType())) {
            isCollection = true;
            isSimpleXMLFormat = true;
            result = new CollectionResult();
            result.setType(ANY_QNAME);
        } else {
            if (storedProcedure.isFunctionType()) {
                ArgumentType returnArg = ((FunctionType) storedProcedure).getReturnArgument();
                result = buildResultForStoredFunction(returnArg, returnType);
                // tags to better represent the PL/SQL record/table/column type
                if (returnArg.getEnclosedType().isPLSQLCursorType()) {
                    customizeSimpleXMLTagNames((PLSQLCursorType) returnArg.getEnclosedType(), procedureOperationModel);
                }
            } else if (hasComplexArgs) {
                if (Util.noOutArguments(storedProcedure)) {
                    result = new Result();
                    // rowcount
                    result.setType(new QName(SCHEMA_URL, INT, SCHEMA_PREFIX));
                }
            } else {
                // if user overrides returnType, assume they're right
                if (returnType != null) {
                    result = new Result();
                    result.setType(buildCustomQName(returnType, dbwsBuilder));
                } else {
                    if (isCollection) {
                        result = new CollectionResult();
                        if (isSimpleXMLFormat) {
                            result.setType(SXF_QNAME_CURSOR);
                        }
                    } else {
                        result = new Result();
                        result.setType(SXF_QNAME);
                    }
                }
            }
        }
        for (ArgumentType arg : storedProcedure.getArguments()) {
            String argName = arg.getArgumentName();
            if (argName != null) {
                QName xmlType = null;
                ProcedureArgument pa = null;
                // for INOUT's
                ProcedureArgument paShadow = null;
                Parameter parm = null;
                ArgumentTypeDirection direction = arg.getDirection();
                if (!hasComplexArgs) {
                    if (arg.getEnclosedType().isPLSQLCursorType()) {
                        PLSQLCursorType cursorType = (PLSQLCursorType) arg.getEnclosedType();
                        if (cursorType.isWeaklyTyped()) {
                            xmlType = buildCustomQName("SYS_REFCURSOR", dbwsBuilder);
                        }
                    } else {
                        xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
                    }
                } else {
                    // handle PL/SQL records and collections
                    if (arg.getEnclosedType().isPLSQLType()) {
                        String packageName = ((PLSQLType) arg.getEnclosedType()).getParentType().getPackageName();
                        // may need to prepend package name
                        String typeString = (packageName != null && packageName.length() > 0) ? packageName + UNDERSCORE + arg.getTypeName() : arg.getTypeName();
                        // may need to strip off %
                        typeString = typeString.contains(PERCENT) ? typeString.replace(PERCENT, UNDERSCORE) : typeString;
                        xmlType = buildCustomQName(nct.generateSchemaAlias(typeString), dbwsBuilder);
                    } else if (arg.getEnclosedType().isVArrayType() || arg.getEnclosedType().isObjectType() || arg.getEnclosedType().isObjectTableType()) {
                        // handle advanced JDBC types
                        xmlType = buildCustomQName(nct.generateSchemaAlias(arg.getTypeName()), dbwsBuilder);
                    } else {
                        switch(Util.getJDBCTypeFromTypeName(arg.getTypeName())) {
                            case STRUCT:
                            case ARRAY:
                                String typeString = nct.generateSchemaAlias(arg.getTypeName());
                                xmlType = buildCustomQName(typeString, dbwsBuilder);
                                break;
                            default:
                                xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
                                break;
                        }
                    }
                }
                if (direction == null || direction == IN) {
                    parm = new Parameter();
                    parm.setName(argName);
                    parm.setType(xmlType);
                    // handle optional arg
                    parm.setOptional(arg.optional());
                    pa = new ProcedureArgument();
                    pa.setName(argName);
                    pa.setParameterName(argName);
                    if (qh instanceof StoredProcedureQueryHandler) {
                        ((StoredProcedureQueryHandler) qh).getInArguments().add(pa);
                    }
                } else {
                    // the first OUT/INOUT arg determines singleResult vs. collectionResult
                    pa = new ProcedureOutputArgument();
                    ProcedureOutputArgument pao = (ProcedureOutputArgument) pa;
                    pao.setName(argName);
                    pao.setParameterName(argName);
                    boolean isCursor = arg.isPLSQLCursorType() || arg.getTypeName().contains(CURSOR_STR);
                    // tags to better represent the PL/SQL record/table/column type
                    if (arg.isPLSQLCursorType()) {
                        customizeSimpleXMLTagNames((PLSQLCursorType) arg.getEnclosedType(), procedureOperationModel);
                    }
                    if (isCursor && returnType == null) {
                        // if user overrides returnType, assume they're right
                        pao.setResultType(SXF_QNAME_CURSOR);
                        if (result == null) {
                            result = new CollectionResult();
                            result.setType(SXF_QNAME_CURSOR);
                        }
                    } else {
                        // Hmm, multiple OUT's gonna be a problem - later!
                        if (returnType != null && !isSimpleXMLFormat) {
                            xmlType = qNameFromString(OPEN_PAREN + dbwsBuilder.getTargetNamespace() + CLOSE_PAREN + returnType, dbwsBuilder.getSchema());
                        }
                        if (isCursor) {
                            pao.setResultType(new QName(EMPTY_STRING, CURSOR_OF_STR + returnType));
                            Result newResult = new CollectionResult();
                            newResult.setType(result.getType());
                            result = newResult;
                        } else {
                            pao.setResultType(xmlType);
                        }
                        if (result == null) {
                            if (isCollection) {
                                result = new CollectionResult();
                            } else {
                                result = new Result();
                            }
                            result.setType(xmlType);
                        }
                    }
                    if (direction == INOUT) {
                        parm = new Parameter();
                        parm.setName(argName);
                        parm.setType(xmlType);
                        result.setType(xmlType);
                        if (qh instanceof StoredProcedureQueryHandler) {
                            ((StoredProcedureQueryHandler) qh).getInOutArguments().add(pao);
                        }
                        paShadow = new ProcedureArgument();
                        paShadow.setName(argName);
                        paShadow.setParameterName(argName);
                    } else {
                        // OUT arg
                        if (qh instanceof StoredProcedureQueryHandler) {
                            ((StoredProcedureQueryHandler) qh).getOutArguments().add(pao);
                        }
                    }
                }
                // for XMLType, we want the type code to be 'OPAQUE' (2007)
                if (arg.getEnclosedType() == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
                    pa.setJdbcType(getJDBCTypeForTypeName(XMLTYPE_STR));
                }
                if (hasComplexArgs && arg.getEnclosedType().isPLSQLType()) {
                    pa.setComplexTypeName(storedProcedure.getCatalogName() + UNDERSCORE + arg.getTypeName());
                    if (paShadow != null) {
                        paShadow.setComplexTypeName(pa.getComplexTypeName());
                    }
                }
                if (parm != null) {
                    qo.getParameters().add(parm);
                }
            }
        }
        if (procedureOperationModel.getBinaryAttachment()) {
            Attachment attachment = new Attachment();
            attachment.setMimeType(APP_OCTET_STREAM);
            result.setAttachment(attachment);
        }
        // the user may want simpleXMLFormat
        handleSimpleXMLFormat(isSimpleXMLFormat, result, procedureOperationModel);
        qo.setResult(result);
        dbwsBuilder.getXrServiceModel().getOperations().put(qo.getName(), qo);
    }
    finishProcedureOperation();
}
Also used : ProcedureType(org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType) StoredProcedureQueryHandler(org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler) StoredFunctionQueryHandler(org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler) QueryHandler(org.eclipse.persistence.internal.xr.QueryHandler) NamedQueryHandler(org.eclipse.persistence.internal.xr.NamedQueryHandler) DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) Util.buildCustomQName(org.eclipse.persistence.tools.dbws.Util.buildCustomQName) QName(javax.xml.namespace.QName) FunctionType(org.eclipse.persistence.tools.oracleddl.metadata.FunctionType) StoredProcedureQueryHandler(org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler) PLSQLCursorType(org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCursorType) Attachment(org.eclipse.persistence.internal.xr.Attachment) Util.qNameFromString(org.eclipse.persistence.tools.dbws.Util.qNameFromString) ArgumentType(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType) ProcedureArgument(org.eclipse.persistence.internal.xr.ProcedureArgument) ProcedureOutputArgument(org.eclipse.persistence.internal.xr.ProcedureOutputArgument) CollectionResult(org.eclipse.persistence.internal.xr.CollectionResult) Result(org.eclipse.persistence.internal.xr.Result) StoredFunctionQueryHandler(org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler) CollectionResult(org.eclipse.persistence.internal.xr.CollectionResult) NamedQueryHandler(org.eclipse.persistence.internal.xr.NamedQueryHandler) Parameter(org.eclipse.persistence.internal.xr.Parameter) QueryOperation(org.eclipse.persistence.internal.xr.QueryOperation) ArgumentTypeDirection(org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection)

Aggregations

FunctionType (org.eclipse.persistence.tools.oracleddl.metadata.FunctionType)5 ProcedureType (org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType)5 Util.qNameFromString (org.eclipse.persistence.tools.dbws.Util.qNameFromString)4 ArrayList (java.util.ArrayList)3 ArgumentType (org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType)3 QName (javax.xml.namespace.QName)2 Attachment (org.eclipse.persistence.internal.xr.Attachment)2 CollectionResult (org.eclipse.persistence.internal.xr.CollectionResult)2 NamedQueryHandler (org.eclipse.persistence.internal.xr.NamedQueryHandler)2 Parameter (org.eclipse.persistence.internal.xr.Parameter)2 ProcedureArgument (org.eclipse.persistence.internal.xr.ProcedureArgument)2 ProcedureOutputArgument (org.eclipse.persistence.internal.xr.ProcedureOutputArgument)2 QueryHandler (org.eclipse.persistence.internal.xr.QueryHandler)2 QueryOperation (org.eclipse.persistence.internal.xr.QueryOperation)2 Result (org.eclipse.persistence.internal.xr.Result)2 StoredFunctionQueryHandler (org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler)2 StoredProcedureQueryHandler (org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler)2 DatabaseQuery (org.eclipse.persistence.queries.DatabaseQuery)2 Util.buildCustomQName (org.eclipse.persistence.tools.dbws.Util.buildCustomQName)2 ArgumentTypeDirection (org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection)2