@Override
    public PersistenceServiceUnit createPersistenceServiceUnit(ClassLoader loader, String... entityClassNames) throws Exception {
        final boolean trace = TraceComponent.isAnyTracingEnabled();
        if (trace && tc.isEntryEnabled())
            Tr.entry(this, tc, "createPersistenceServiceUnit", loader, Arrays.asList(entityClassNames));

        Map<String, Object> puProps = new HashMap<String, Object>();
        tablePrefix = (String) properties.get("tablePrefix");
        tablePrefixLength = tablePrefix.length();
        for (int i = 0; i < tablePrefixLength; i++) {
            int codepoint = tablePrefix.codePointAt(i);
            if (!Character.isLetterOrDigit(codepoint) && codepoint != 95) { // alphanumeric or _ character
                Tr.error(tc, "ILLEGAL_IDENTIFIER_CWWKD0200E", tablePrefix);
                throw new IllegalArgumentException(Tr.formatMessage(tc, "ILLEGAL_IDENTIFIER_CWWKD0200E", tablePrefix));
            }
        }

        schema = (String) properties.get("schema");
        schemaLength = schema == null ? -1 : schema.length();
        for (int i = 0; i < schemaLength; i++) {
            int codepoint = schema.codePointAt(i);
            if (!Character.isLetterOrDigit(codepoint) && codepoint != 95) { // alphanumeric or _ character
                Tr.error(tc, "ILLEGAL_IDENTIFIER_CWWKD0201E", schema);
                throw new IllegalArgumentException(Tr.formatMessage(tc, "ILLEGAL_IDENTIFIER_CWWKD0201E", schema));
            }
        }

        // Look for EclipseLink persistence properties
        if (properties.get("persistenceProperties.0.config.referenceType") != null) {
            for (String key : Collections.list(properties.keys())) {
                if (key.startsWith("persistenceProperties.0") && !key.equals("persistenceProperties.0.config.referenceType")) {
                    Object value = properties.get(key);
                    key = key.substring(24);
                    puProps.put(key, value);
                }
            }
        }

        ResourceConfig resourceInfo = resourceConfigFactory.createResourceConfig(DataSource.class.getName());
        resourceInfo.setSharingScope(ResourceConfig.SHARING_SCOPE_SHAREABLE);
        resourceInfo.setIsolationLevel(Connection.TRANSACTION_READ_COMMITTED);
        resourceInfo.setResAuthType(ResourceConfig.AUTH_CONTAINER);

        if (authDataRef != null) {
            String authDataId = (String) authDataRef.getProperty("id");
            resourceInfo.addLoginProperty("DefaultPrincipalMapping",
                                          authDataId.matches(".*(\\]/).*(\\[default-\\d*\\])")
                                                          ? (String) authDataRef.getProperty("config.displayId")
                                                          : authDataId);
            if (trace && tc.isDebugEnabled()) {
                Tr.debug(this, tc, "DefaultPrincipalMapping " + resourceInfo);
                Tr.debug(this, tc, "AuthData id = " + authDataId);
            }
        }

        DataSource dataSource = (DataSource) dataSourceFactory.createResource(resourceInfo);
        String dbProductName = getDatabaseProductName(((WSDataSource) dataSource)).toLowerCase();
        if (dbProductName.contains("informix") || dbProductName.startsWith("ids/")) {
            // Defect 168450 - PersistenceService is currently disabled when running with Informix.
            // Once the informix issues are fixed, this exception will be removed.
            // When informix is using a DB2 driver, the product name is determined by db2 and is
            // similar to: ids/nt64
            throw new UnsupportedOperationException(dbProductName);
        }

        DataSource nonJTADataSource;
        if (nonJTADataSourceFactory == null)
            nonJTADataSource = null;
        else {
            resourceInfo.setSharingScope(ResourceConfig.SHARING_SCOPE_UNSHAREABLE);
            nonJTADataSource = (DataSource) nonJTADataSourceFactory.createResource(resourceInfo);
        }

        if (deactivated) {
            Tr.error(tc, "DEACTIVATED_CWWKD0202E");
            String errMsg = Tr.formatMessage(tc, "DEACTIVATED_CWWKD0202E");

            if (trace && tc.isEntryEnabled())
                Tr.exit(this, tc, "createPersistenceServiceUnit", "deactivated");
            throw new IllegalStateException(errMsg);
        }

        strategy = (String) properties.get("keyGenerationStrategy");
        if ("AUTO".equals(strategy)) {
            strategy = dbProductName.contains("oracle") ? "SEQUENCE"
                            : dbProductName.contains("adaptive server") || dbProductName.contains("sybase") ? "TABLE"
                                            : "IDENTITY";
        }

        // TODO: replace temporary code specific to persistentExecutor with general solution that applies the
        // table prefix, schema, and keyGenerationStrategy to all entities

        InMemoryMappingFile ormFile = null;
        SpecialEntitySet entitySet = recognizeSpecialEntityPackage(entityClassNames[0]);
        if (entitySet.equals(SpecialEntitySet.PERSISTENT_EXECUTOR)) {
            String ormFileContents = createOrmFileContentsForPersistentExecutor();
            ormFile = new InMemoryMappingFile(ormFileContents.getBytes("UTF-8"));
        } else if (entitySet.equals(SpecialEntitySet.BATCH)) {
            String ormFileContents = createOrmFileContentsForBatch(entityClassNames);
            ormFile = new InMemoryMappingFile(ormFileContents.getBytes("UTF-8"));
        } else {
            ormFile = createOrmFile(schema, tablePrefix, entityClassNames);
        }

        PersistenceServiceUnitConfig config = new PersistenceServiceUnitConfig();
        config.setClasses(Arrays.asList(entityClassNames));
        config.setConsumerLoader(loader);
        config.setProperties(puProps);
        if (ormFile != null)
            config.setInMemoryMappingFiles(Collections.singletonList(ormFile));
        config.setJtaDataSource(dataSource);
        if (nonJTADataSource != null)
            config.setNonJtaDataSource(nonJTADataSource);

        if (deactivated) {
            Tr.error(tc, "DEACTIVATED_CWWKD0202E");
            String errMsg = Tr.formatMessage(tc, "DEACTIVATED_CWWKD0202E");
            if (trace && tc.isEntryEnabled())
                Tr.exit(this, tc, "createPersistenceServiceUnit", "deactivated");
            throw new IllegalStateException(errMsg);
        }

        PersistenceServiceUnit persistenceServiceUnit = persistenceService.createPersistenceServiceUnit(config);
        boolean successful = false;
        try {
            if (deactivated) {
                if (trace && tc.isEntryEnabled())
                    Tr.exit(this, tc, "createPersistenceServiceUnit", "deactivated");
                throw new IllegalStateException();
            }

            if ((Boolean) properties.get("createTables"))
                createTables(persistenceServiceUnit);

            if (deactivated) {
                if (trace && tc.isEntryEnabled())
                    Tr.exit(this, tc, "createPersistenceServiceUnit", "deactivated");
                throw new IllegalStateException();
            }

            successful = true;
        } finally {
            if (!successful)
                persistenceServiceUnit.close();
        }

        if (trace && tc.isEntryEnabled())
            Tr.exit(this, tc, "createPersistenceServiceUnit", persistenceServiceUnit);
        return persistenceServiceUnit;
    }
@ Override public PersistenceServiceUnit createPersistenceServiceUnit ( ClassLoader loader , String ... entityClassNames ) throws Exception { final boolean trace = TraceComponent . isAnyTracingEnabled ( ) ; if ( trace && tc . isEntryEnabled ( ) ) Tr . entry ( this , tc , "createPersistenceServiceUnit" , loader , Arrays . asList ( entityClassNames ) ) ; Map < String , Object > puProps = new HashMap < String , Object > ( ) ; tablePrefix = ( String ) properties . get ( "tablePrefix" ) ; tablePrefixLength = tablePrefix . length ( ) ; for ( int i = 0 ; i < tablePrefixLength ; i ++ ) { int codepoint = tablePrefix . codePointAt ( i ) ; if ( ! Character . isLetterOrDigit ( codepoint ) && codepoint != 95 ) { Tr . error ( tc , "ILLEGAL_IDENTIFIER_CWWKD0200E" , tablePrefix ) ; throw new IllegalArgumentException ( Tr . formatMessage ( tc , "ILLEGAL_IDENTIFIER_CWWKD0200E" , tablePrefix ) ) ; } } schema = ( String ) properties . get ( "schema" ) ; schemaLength = schema == null ? - 1 : schema . length ( ) ; for ( int i = 0 ; i < schemaLength ; i ++ ) { int codepoint = schema . codePointAt ( i ) ; if ( ! Character . isLetterOrDigit ( codepoint ) && codepoint != 95 ) { Tr . error ( tc , "ILLEGAL_IDENTIFIER_CWWKD0201E" , schema ) ; throw new IllegalArgumentException ( Tr . formatMessage ( tc , "ILLEGAL_IDENTIFIER_CWWKD0201E" , schema ) ) ; } } if ( properties . get ( "persistenceProperties.0.config.referenceType" ) != null ) { for ( String key : Collections . list ( properties . keys ( ) ) ) { if ( key . startsWith ( "persistenceProperties.0" ) && ! key . equals ( "persistenceProperties.0.config.referenceType" ) ) { Object value = properties . get ( key ) ; key = key . substring ( 24 ) ; puProps . put ( key , value ) ; } } } ResourceConfig resourceInfo = resourceConfigFactory . createResourceConfig ( DataSource . class . getName ( ) ) ; resourceInfo . setSharingScope ( ResourceConfig . SHARING_SCOPE_SHAREABLE ) ; resourceInfo . setIsolationLevel ( Connection . TRANSACTION_READ_COMMITTED ) ; resourceInfo . setResAuthType ( ResourceConfig . AUTH_CONTAINER ) ; if ( authDataRef != null ) { String authDataId = ( String ) authDataRef . getProperty ( "id" ) ; resourceInfo . addLoginProperty ( "DefaultPrincipalMapping" , authDataId . matches ( ".*(\\]/).*(\\[default-\\d*\\])" ) ? ( String ) authDataRef . getProperty ( "config.displayId" ) : authDataId ) ; if ( trace && tc . isDebugEnabled ( ) ) { Tr . debug ( this , tc , "DefaultPrincipalMapping " + resourceInfo ) ; Tr . debug ( this , tc , "AuthData id = " + authDataId ) ; } } DataSource dataSource = ( DataSource ) dataSourceFactory . createResource ( resourceInfo ) ; String dbProductName = getDatabaseProductName ( ( ( WSDataSource ) dataSource ) ) . toLowerCase ( ) ; if ( dbProductName . contains ( "informix" ) || dbProductName . startsWith ( "ids/" ) ) { throw new UnsupportedOperationException ( dbProductName ) ; } DataSource nonJTADataSource ; if ( nonJTADataSourceFactory == null ) nonJTADataSource = null ; else { resourceInfo . setSharingScope ( ResourceConfig . SHARING_SCOPE_UNSHAREABLE ) ; nonJTADataSource = ( DataSource ) nonJTADataSourceFactory . createResource ( resourceInfo ) ; } if ( deactivated ) { Tr . error ( tc , "DEACTIVATED_CWWKD0202E" ) ; String errMsg = Tr . formatMessage ( tc , "DEACTIVATED_CWWKD0202E" ) ; if ( trace && tc . isEntryEnabled ( ) ) Tr . exit ( this , tc , "createPersistenceServiceUnit" , "deactivated" ) ; throw new IllegalStateException ( errMsg ) ; } strategy = ( String ) properties . get ( "keyGenerationStrategy" ) ; if ( "AUTO" . equals ( strategy ) ) { strategy = dbProductName . contains ( "oracle" ) ? "SEQUENCE" : dbProductName . contains ( "adaptive server" ) || dbProductName . contains ( "sybase" ) ? "TABLE" : "IDENTITY" ; } InMemoryMappingFile ormFile = null ; SpecialEntitySet entitySet = recognizeSpecialEntityPackage ( entityClassNames [ 0 ] ) ; if ( entitySet . equals ( SpecialEntitySet . PERSISTENT_EXECUTOR ) ) { String ormFileContents = createOrmFileContentsForPersistentExecutor ( ) ; ormFile = new InMemoryMappingFile ( ormFileContents . getBytes ( "UTF-8" ) ) ; } else if ( entitySet . equals ( SpecialEntitySet . BATCH ) ) { String ormFileContents = createOrmFileContentsForBatch ( entityClassNames ) ; ormFile = new InMemoryMappingFile ( ormFileContents . getBytes ( "UTF-8" ) ) ; } else { ormFile = createOrmFile ( schema , tablePrefix , entityClassNames ) ; } PersistenceServiceUnitConfig config = new PersistenceServiceUnitConfig ( ) ; config . setClasses ( Arrays . asList ( entityClassNames ) ) ; config . setConsumerLoader ( loader ) ; config . setProperties ( puProps ) ; if ( ormFile != null ) config . setInMemoryMappingFiles ( Collections . singletonList ( ormFile ) ) ; config . setJtaDataSource ( dataSource ) ; if ( nonJTADataSource != null ) config . setNonJtaDataSource ( nonJTADataSource ) ; if ( deactivated ) { Tr . error ( tc , "DEACTIVATED_CWWKD0202E" ) ; String errMsg = Tr . formatMessage ( tc , "DEACTIVATED_CWWKD0202E" ) ; if ( trace && tc . isEntryEnabled ( ) ) Tr . exit ( this , tc , "createPersistenceServiceUnit" , "deactivated" ) ; throw new IllegalStateException ( errMsg ) ; } PersistenceServiceUnit persistenceServiceUnit = persistenceService . createPersistenceServiceUnit ( config ) ; boolean successful = false ; try { if ( deactivated ) { if ( trace && tc . isEntryEnabled ( ) ) Tr . exit ( this , tc , "createPersistenceServiceUnit" , "deactivated" ) ; throw new IllegalStateException ( ) ; } if ( ( Boolean ) properties . get ( "createTables" ) ) createTables ( persistenceServiceUnit ) ; if ( deactivated ) { if ( trace && tc . isEntryEnabled ( ) ) Tr . exit ( this , tc , "createPersistenceServiceUnit" , "deactivated" ) ; throw new IllegalStateException ( ) ; } successful = true ; } finally { if ( ! successful ) persistenceServiceUnit . close ( ) ; } if ( trace && tc . isEntryEnabled ( ) ) Tr . exit ( this , tc , "createPersistenceServiceUnit" , persistenceServiceUnit ) ; return persistenceServiceUnit ; }
@see com.ibm.wsspi.persistence.DatabaseStore#createPersistenceServiceUnit(java.lang.ClassLoader, java.lang.String[])