private void deploy()

in container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java [1355:1838]


    private void deploy(final AppModule app, final PersistenceModule persistenceModule) throws OpenEJBException {
        if (!autoCreateResources) {
            return;
        }

        final Persistence persistence = persistenceModule.getPersistence();
        for (final PersistenceUnit unit : persistence.getPersistenceUnit()) {
            if (unit.getProvider() != null) {
                logger.info("Configuring PersistenceUnit(name=" + unit.getName() + ", provider=" + unit.getProvider() + ")");
            } else {
                logger.info("Configuring PersistenceUnit(name=" + unit.getName() + ")");
            }

            if (unit.getJtaDataSource() == null && unit.getNonJtaDataSource() == null
                    && "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.force-unit-type", unit.getProperty("openejb.force-unit-type", "true")))) {
                unit.setTransactionType(TransactionType.JTA); // 8.2.1.5 of JPA 2.0 spec
            }

            // if jta datasource is specified it can be used as model fo rnon jta datasource
            final boolean resourceLocal = TransactionType.RESOURCE_LOCAL.equals(unit.getTransactionType()) && unit.getJtaDataSource() == null;
            if (resourceLocal && unit.getNonJtaDataSource() == null && isDataSourcePropertiesConfigured(unit.getProperties())) {
                continue;
            }

            final Properties required = new Properties();

            //            if (unit.getJtaDataSource() == null && unit.getNonJtaDataSource() == null){
            //                unit.setJtaDataSource("JtaDataSource");
            //                unit.setNonJtaDataSource("NonJtaDataSource");
            //            } else if (unit.getJtaDataSource() == null){
            //                unit.setJtaDataSource(unit.getNonJtaDataSource()+"Jta");
            //            } else if (unit.getNonJtaDataSource() == null){
            //                unit.setNonJtaDataSource(unit.getJtaDataSource()+"NonJta");
            //            }

            if ("org.apache.openjpa.persistence.PersistenceProviderImpl".equals(unit.getProvider())) {
                if (unit.getJtaDataSource() == null) {
                    unit.setJtaDataSource(unit.getProperty("openjpa.ConnectionFactoryName"));
                }
                if (unit.getNonJtaDataSource() == null) {
                    unit.setNonJtaDataSource(unit.getProperty("openjpa.ConnectionFactory2Name"));
                }
            }

            logger.debug("raw <jta-data-source>" + unit.getJtaDataSource() + "</jta-datasource>");
            logger.debug("raw <non-jta-data-source>" + unit.getNonJtaDataSource() + "</non-jta-datasource>");

            final String originalJtaDataSource = unit.getJtaDataSource(); // keep it can start with java:global for instance
            unit.setJtaDataSource(normalizeResourceId(originalJtaDataSource));
            final String originalNonJtaDataSource = unit.getNonJtaDataSource();
            unit.setNonJtaDataSource(normalizeResourceId(originalNonJtaDataSource));

            logger.debug("normalized <jta-data-source>" + unit.getJtaDataSource() + "</jta-datasource>");
            logger.debug("normalized <non-jta-data-source>" + unit.getNonJtaDataSource() + "</non-jta-datasource>");

            if (logger.isDebugEnabled()) {
                required.put("JtaManaged", "true");
                final List<String> managed = configFactory.getResourceIds("DataSource", required);

                required.put("JtaManaged", "false");
                final List<String> unmanaged = configFactory.getResourceIds("DataSource", required);

                required.clear();
                final List<String> unknown = configFactory.getResourceIds("DataSource", required);

                logger.debug("Available DataSources");
                for (final String name : managed) {
                    logger.debug("DataSource(name=" + name + ", JtaManaged=true)");
                }
                for (final String name : unmanaged) {
                    logger.debug("DataSource(name=" + name + ", JtaManaged=false)");
                }
                for (final String name : unknown) {
                    if (managed.contains(name)) {
                        continue;
                    }
                    if (unmanaged.contains(name)) {
                        continue;
                    }
                    logger.debug("DataSource(name=" + name + ", JtaManaged=<unknown>)");
                }
            }

            final String prefix = app.getModuleId() + "/";

            String jtaDataSourceId = null;
            String nonJtaDataSourceId = null;

            // first try exact matching without JtaManaged which is not mandatory actually (custom DS + JTADataSourceWrapperFactory)
            final String jtaWithJavaAndSlash = replaceJavaAndSlash(unit.getJtaDataSource());
            for (final String potentialName : asList(prefix + jtaWithJavaAndSlash, originalJtaDataSource, jtaWithJavaAndSlash)) {
                if(potentialName == null) {
                    // If unit.getJtaDataSource() is null, one of the potentialName is also null.
                    continue;
                }
                final ResourceInfo jtaInfo = configFactory.getResourceInfo(potentialName);
                if (jtaInfo != null) {
                    if (!"false".equalsIgnoreCase(jtaInfo.properties.getProperty("JtaManaged")) // don't test true since it can be missing
                            && (jtaInfo.types.contains("DataSource") || jtaInfo.types.contains(DataSource.class.getName()))) {
                        jtaDataSourceId = jtaInfo.id;
                        break;
                    } else {
                        logger.warning("Found matching datasource: " + jtaInfo.id + " but this one is not a JTA datasource");
                    }
                }
            }

            final String nonJtaWithJavaAndSlash = replaceJavaAndSlash(unit.getNonJtaDataSource());
            for (final String potentialName : asList(prefix + nonJtaWithJavaAndSlash, originalNonJtaDataSource, nonJtaWithJavaAndSlash)) {
                if(potentialName == null) {
                    // If unit.getNonJtaDataSource() is null, one of the potentialName is also null.
                    continue;
                }
                final ResourceInfo info = configFactory.getResourceInfo(potentialName);
                if (info != null) {
                    if (!"true".equalsIgnoreCase(info.properties.getProperty("JtaManaged"))
                            && (info.types.contains("DataSource") || info.types.contains(DataSource.class.getName()))) {
                        nonJtaDataSourceId = info.id;
                        break;
                    } else {
                        logger.warning("Found matching datasource: " + info.id + " but this one is a JTA datasource");
                    }
                }
            }

            // then that's ok to force configuration
            if (jtaDataSourceId == null && !resourceLocal) {
                required.put("JtaManaged", "true");
                jtaDataSourceId = findResourceId(prefix + jtaWithJavaAndSlash, "DataSource", required, null);
                if (jtaDataSourceId == null) { // test with javax.sql.DataSource before DataSource since RA can register resources without our shortcut
                    jtaDataSourceId = findResourceId(jtaWithJavaAndSlash, "javax.sql.DataSource", required, null);
                }
                /* this shouldn't be mandatory anymore since our DataSource has as alias javax.sql.DataSource
                if (jtaDataSourceId == null) {
                    jtaDataSourceId = findResourceId(replaceJavaAndSlash(unit.getJtaDataSource()), "DataSource", required, null);
                }
                */
            }

            if (nonJtaDataSourceId == null) {
                required.put("JtaManaged", "false");
                nonJtaDataSourceId = findResourceId(prefix + nonJtaWithJavaAndSlash, "DataSource", required, null);
                if (nonJtaDataSourceId == null) {
                    nonJtaDataSourceId = findResourceId(nonJtaWithJavaAndSlash, "DataSource", required, null);
                }
            }

            if ((jtaDataSourceId != null || resourceLocal) && nonJtaDataSourceId != null) {
                // Both DataSources were explicitly configured.
                if (jtaDataSourceId != null) {
                    setJtaDataSource(unit, jtaDataSourceId);
                }
                setNonJtaDataSource(unit, nonJtaDataSourceId);
                continue;
            }

            //
            //  If the jta-data-source or the non-jta-data-source link to
            //  third party resources, then we can't do any auto config
            //  for them.  We give them what they asked for and move on.
            //
            if (jtaDataSourceId == null && nonJtaDataSourceId == null) {
                required.put("JtaManaged", ServiceUtils.NONE);

                if (!resourceLocal) {
                    jtaDataSourceId = findResourceId(unit.getJtaDataSource(), "DataSource", required, null);
                }
                nonJtaDataSourceId = findResourceId(unit.getNonJtaDataSource(), "DataSource", required, null);

                if (jtaDataSourceId != null || nonJtaDataSourceId != null) {
                    if (jtaDataSourceId != null) {
                        setJtaDataSource(unit, jtaDataSourceId);
                    }
                    if (nonJtaDataSourceId != null) {
                        setNonJtaDataSource(unit, nonJtaDataSourceId);
                    }
                    continue;
                }
            }

            //  We are done with the most optimal configuration.
            //
            //  If both the jta-data-source and non-jta-data-source
            //  references were explicitly and correctly configured
            //  to existing datasource, we wouldn't get this far.
            //
            //  At this point we see if either we can't figure out
            //  if there's an issue with their configuration or
            //  if we can't intelligently complete their configuration.

            //
            //  Do both the jta-data-source and non-jta-data-source references
            //  point to the same datasource?
            //
            //  If so, then unlink the invalid one so defaulting rules can
            //  possibly fill in a good value.
            //

            required.put("JtaManaged", ServiceUtils.ANY);
            final String possibleJta = findResourceId(jtaWithJavaAndSlash, "DataSource", required, null);
            final String possibleNonJta = findResourceId(nonJtaWithJavaAndSlash, "DataSource", required, null);
            if (possibleJta != null && possibleJta.equals(possibleNonJta)) {
                final ResourceInfo dataSource = configFactory.getResourceInfo(possibleJta);

                final String jtaManaged = (String) dataSource.properties.get("JtaManaged");

                logger.warning("PeristenceUnit(name=" +
                    unit.getName() +
                    ") invalidly refers to Resource(id=" +
                    dataSource.id +
                    ") as both its <jta-data-source> and <non-jta-data-source>.");

                if ("true".equalsIgnoreCase(jtaManaged)) {
                    nonJtaDataSourceId = null;
                    unit.setNonJtaDataSource(null);

                } else if ("false".equalsIgnoreCase(jtaManaged)) {
                    jtaDataSourceId = null;
                    unit.setJtaDataSource(null);
                }
            }

            //
            //  Do the jta-data-source and non-jta-data-source references
            //  point to innapropriately configured Resources?
            //
            checkUnitDataSourceRefs(unit);

            //
            //  Do either the jta-data-source and non-jta-data-source
            //  references point to the explicit name of a ServiceProvider?
            //
            if (jtaDataSourceId == null && nonJtaDataSourceId == null) {
                jtaDataSourceId = findResourceProviderId(unit.getJtaDataSource());
                nonJtaDataSourceId = findResourceProviderId(unit.getNonJtaDataSource());

                // if one of them is not null we have a match on at least one
                // we can just create the second resource using the first as a template
                if (jtaDataSourceId != null || nonJtaDataSourceId != null) {
                    final Resource jtaResource = new Resource(jtaDataSourceId, "DataSource", jtaDataSourceId);
                    jtaResource.getProperties().setProperty("JtaManaged", "true");

                    final Resource nonJtaResource = new Resource(nonJtaDataSourceId, "DataSource", nonJtaDataSourceId);
                    nonJtaResource.getProperties().setProperty("JtaManaged", "false");

                    if (jtaDataSourceId == null) {
                        jtaResource.setId(nonJtaDataSourceId + "Jta");
                        jtaResource.setProvider(nonJtaDataSourceId);
                    } else if (nonJtaDataSourceId == null) {
                        nonJtaResource.setId(jtaDataSourceId + "NonJta");
                        nonJtaResource.setProvider(jtaDataSourceId);
                    }

                    final ResourceInfo jtaResourceInfo = configFactory.configureService(jtaResource, ResourceInfo.class);
                    final ResourceInfo nonJtaResourceInfo = configFactory.configureService(nonJtaResource, ResourceInfo.class);
                    if (jtaDataSourceId != null && nonJtaDataSourceId == null) {
                        nonJtaResourceInfo.originAppName = jtaResourceInfo.originAppName;
                    }

                    logAutoCreateResource(jtaResourceInfo, "DataSource", unit.getName());
                    jtaDataSourceId = installResource(unit.getName(), jtaResourceInfo);

                    logAutoCreateResource(nonJtaResourceInfo, "DataSource", unit.getName());
                    nonJtaDataSourceId = installResource(unit.getName(), nonJtaResourceInfo);

                    setJtaDataSource(unit, jtaDataSourceId);
                    setNonJtaDataSource(unit, nonJtaDataSourceId);
                    continue;
                }
            }

            // No data sources were specified: 
            // Look for defaults, see https://issues.apache.org/jira/browse/OPENEJB-1027
            if (jtaDataSourceId == null && nonJtaDataSourceId == null) {
                // We check for data sources matching the following names:
                // 1. The persistence unit id
                // 2. The web module id
                // 3. The web module context root
                // 4. The application module id
                final List<String> ids = new ArrayList<>();
                ids.add(unit.getName());
                for (final WebModule webModule : app.getWebModules()) {
                    ids.add(webModule.getModuleId());
                    ids.add(webModule.getContextRoot());
                }
                ids.add(app.getModuleId());

                // Search for a matching data source
                for (final String id : ids) {
                    //Try finding a jta managed data source
                    required.put("JtaManaged", "true");
                    jtaDataSourceId = findResourceId(id, "DataSource", required, null);

                    if (jtaDataSourceId == null) {
                        //No jta managed data source found. Try finding a non-jta managed
                        required.clear();
                        required.put("JtaManaged", "false");
                        nonJtaDataSourceId = findResourceId(id, "DataSource", required, null);
                    }

                    if (jtaDataSourceId == null && nonJtaDataSourceId == null) {
                        // Neither jta nor non-jta managed data sources were found. try to find one with it unset
                        required.clear();
                        required.put("JtaManaged", ServiceUtils.NONE);
                        jtaDataSourceId = findResourceId(id, "DataSource", required, null);
                    }

                    if (jtaDataSourceId != null || nonJtaDataSourceId != null) {
                        //We have found a default. Exit the loop
                        break;
                    }
                }
            }

            //
            //  If neither of the references are valid yet, then let's take
            //  the first valid datasource.
            //
            //  We won't fill in both jta-data-source and non-jta-data-source
            //  this way as the following code does a great job at determining
            //  if any of the existing data sources are a good match or if
            //  one needs to be generated.
            //
            if (jtaDataSourceId == null && nonJtaDataSourceId == null) {

                required.clear();
                required.put("JtaManaged", "true");
                jtaDataSourceId = firstMatching(prefix, "DataSource", required, null);

                if (jtaDataSourceId == null) {
                    required.clear();
                    required.put("JtaManaged", "false");
                    nonJtaDataSourceId = firstMatching(prefix, "DataSource", required, null);
                }
            }

            //
            //  Does the jta-data-source reference point an existing
            //  Resource in the system with JtaManaged=true?
            //
            //  If so, we can search for an existing datasource
            //  configured with identical properties and use it.
            //
            //  If that doesn't work, we can copy the jta-data-source
            //  and auto-create the missing non-jta-data-source
            //  using it as a template, applying the overrides,
            //  and finally setting JtaManaged=false
            //

            if (jtaDataSourceId != null && nonJtaDataSourceId == null) {

                final ResourceInfo jtaResourceInfo = configFactory.getResourceInfo(jtaDataSourceId);

                final Properties jtaProperties = jtaResourceInfo.properties;

                if (jtaProperties.containsKey("JtaManaged")) {

                    // Strategy 1: Best match search

                    required.clear();
                    required.put("JtaManaged", "false");

                    for (final String key : asList("JdbcDriver", "JdbcUrl")) {
                        if (jtaProperties.containsKey(key)) {
                            required.put(key, jtaProperties.get(key));
                        }
                    }

                    nonJtaDataSourceId = firstMatching(prefix, "DataSource", required, null);

                    // Strategy 2: Copy

                    if (nonJtaDataSourceId == null) {
                        final ResourceInfo nonJtaResourceInfo = copy(jtaResourceInfo);
                        nonJtaResourceInfo.id = jtaResourceInfo.id + "NonJta";
                        nonJtaResourceInfo.originAppName = jtaResourceInfo.originAppName;
                        suffixAliases(nonJtaResourceInfo, "NonJta");
                        configureImplicitDataSource(nonJtaResourceInfo);

                        final Properties overrides = ConfigurationFactory.getSystemProperties(nonJtaResourceInfo.id, nonJtaResourceInfo.service);
                        nonJtaResourceInfo.properties.putAll(overrides);
                        nonJtaResourceInfo.properties.setProperty("JtaManaged", "false");
                        nonJtaResourceInfo.properties.remove("Definition"); // if created from annotation we just want live config

                        logAutoCreateResource(nonJtaResourceInfo, "DataSource", unit.getName());
                        logger.info("configureService.configuring", nonJtaResourceInfo.id, nonJtaResourceInfo.service, jtaResourceInfo.id);

                        nonJtaDataSourceId = installResource(unit.getName(), nonJtaResourceInfo);
                    }
                }

            }

            //
            //  Does the jta-data-source reference point an existing
            //  Resource in the system with JtaManaged=false?
            //
            //  If so, we can search for an existing datasource
            //  configured with identical properties and use it.
            //
            //  If that doesn't work, we can copy the jta-data-source
            //  and auto-create the missing non-jta-data-source
            //  using it as a template, applying the overrides,
            //  and finally setting JtaManaged=false
            //

            final String deduceJtaFromNonJta = unit.getProperty(AUTOCREATE_JTA_DATASOURCE_FROM_NON_JTA_ONE_KEY,
                SystemInstance.get().getOptions().get(AUTOCREATE_JTA_DATASOURCE_FROM_NON_JTA_ONE_KEY, (String) null));
            if (nonJtaDataSourceId != null && jtaDataSourceId == null
                // hibernate uses the fact that this ds is missing to get a non jta em instead of a JTA one
                && (!resourceLocal || deduceJtaFromNonJta != null)
                && (deduceJtaFromNonJta == null || deduceJtaFromNonJta != null && Boolean.parseBoolean(deduceJtaFromNonJta))) {

                final ResourceInfo nonJtaResourceInfo = configFactory.getResourceInfo(nonJtaDataSourceId);

                final Properties nonJtaProperties = nonJtaResourceInfo.properties;

                if (nonJtaProperties.containsKey("JtaManaged")) {

                    // Strategy 1: Best match search

                    required.clear();
                    required.put("JtaManaged", "true");

                    for (final String key : asList("JdbcDriver", "JdbcUrl")) {
                        if (nonJtaProperties.containsKey(key)) {
                            required.put(key, nonJtaProperties.get(key));
                        }
                    }

                    jtaDataSourceId = firstMatching(prefix, "DataSource", required, null);

                    // Strategy 2: Copy

                    if (jtaDataSourceId == null) {
                        final ResourceInfo jtaResourceInfo = copy(nonJtaResourceInfo);
                        jtaResourceInfo.id = nonJtaResourceInfo.id + "Jta";
                        suffixAliases(jtaResourceInfo, "Jta");
                        configureImplicitDataSource(jtaResourceInfo);

                        final Properties overrides = ConfigurationFactory.getSystemProperties(jtaResourceInfo.id, jtaResourceInfo.service);
                        jtaResourceInfo.properties.putAll(overrides);
                        jtaResourceInfo.properties.setProperty("JtaManaged", "true");
                        jtaResourceInfo.properties.remove("Definition"); // if created from annotation we just want live config

                        logAutoCreateResource(jtaResourceInfo, "DataSource", unit.getName());
                        logger.info("configureService.configuring", jtaResourceInfo.id, jtaResourceInfo.service, nonJtaResourceInfo.id);

                        jtaDataSourceId = installResource(unit.getName(), jtaResourceInfo);
                    }
                }

            }

            //
            //  By this point if we've found anything at all, both
            //  jta-data-source and non-jta-data-source should be
            //  filled in (provided they aren't using a third party
            //  data source).
            //
            //  Should both references still be null
            //  we can just take a shot in the dark and auto-create
            //  them them both using the built-in templates for jta
            //  and non-jta default datasources.  These are supplied
            //  via the service-jar.xml file.
            //
            if (jtaDataSourceId == null && nonJtaDataSourceId == null) {
                if (!resourceLocal) {
                    required.put("JtaManaged", "true");
                    jtaDataSourceId = autoCreateResource("DataSource", required, unit.getName());
                }

                required.put("JtaManaged", "false");
                nonJtaDataSourceId = autoCreateResource("DataSource", required, unit.getName());
            }

            if (jtaDataSourceId != null) {
                setJtaDataSource(unit, jtaDataSourceId);
            }
            if (nonJtaDataSourceId != null) {
                setNonJtaDataSource(unit, nonJtaDataSourceId);
            }
        }
    }