private void resolveDestinationLinks()

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


    private void resolveDestinationLinks(final AppModule appModule) throws OpenEJBException {
        // build up a link resolver
        final LinkResolver<MessageDestination> destinationResolver = new LinkResolver<>();
        for (final EjbModule ejbModule : appModule.getEjbModules()) {
            final AssemblyDescriptor assembly = ejbModule.getEjbJar().getAssemblyDescriptor();
            if (assembly != null) {
                for (final MessageDestination destination : assembly.getMessageDestination()) {
                    destinationResolver.add(ejbModule.getModuleUri(), destination.getMessageDestinationName(), destination);
                }
            }
        }
        for (final ClientModule clientModule : appModule.getClientModules()) {
            for (final MessageDestination destination : clientModule.getApplicationClient().getMessageDestination()) {
                destinationResolver.add(appModule.getModuleUri(), destination.getMessageDestinationName(), destination);
            }
        }
        for (final WebModule webModule : appModule.getWebModules()) {
            for (final MessageDestination destination : webModule.getWebApp().getMessageDestination()) {
                destinationResolver.add(appModule.getModuleUri(), destination.getMessageDestinationName(), destination);
            }
        }

        // remember the type of each destination so we can use it to fillin MDBs that don't declare destination type
        final Map<MessageDestination, String> destinationTypes = new HashMap<>();

        // resolve all MDBs with destination links
        // if MessageDestination does not have a mapped name assigned, give it the destination from the MDB
        for (final EjbModule ejbModule : appModule.getEjbModules()) {
            final AssemblyDescriptor assembly = ejbModule.getEjbJar().getAssemblyDescriptor();
            if (assembly == null) {
                continue;
            }

            final URI moduleUri = ejbModule.getModuleUri();
            final OpenejbJar openejbJar = ejbModule.getOpenejbJar();

            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                // MDB destination is deploymentId if none set
                if (bean instanceof MessageDrivenBean) {
                    final MessageDrivenBean mdb = (MessageDrivenBean) bean;

                    final EjbDeployment ejbDeployment = openejbJar.getDeploymentsByEjbName().get(bean.getEjbName());
                    if (ejbDeployment == null) {
                        throw new OpenEJBException("No ejb deployment found for ejb " + bean.getEjbName());
                    }

                    // skip destination refs without a destination link
                    final String link = mdb.getMessageDestinationLink();
                    if (link == null || link.length() == 0) {
                        continue;
                    }

                    // resolve the destination... if we don't find one it is a configuration bug
                    final MessageDestination destination = destinationResolver.resolveLink(link, moduleUri);
                    if (destination == null) {
                        throw new OpenEJBException("Message destination " + link + " for message driven bean " + mdb.getEjbName() + " not found");
                    }

                    // get the destinationId is the mapped name
                    String destinationId = destination.getMappedName();
                    if (destinationId == null) {
                        // if we don't have a mapped name use the destination of the mdb
                        final Properties properties = mdb.getActivationConfig().toProperties();
                        destinationId = properties.getProperty("destination");
                        destination.setMappedName(destinationId);
                    }

                    if (mdb.getMessageDestinationType() != null && !destinationTypes.containsKey(destination)) {
                        destinationTypes.put(destination, mdb.getMessageDestinationType());
                    }

                    // destination identifier
                    ResourceLink resourceLink = ejbDeployment.getResourceLink("openejb/destination");
                    if (resourceLink == null) {
                        resourceLink = new ResourceLink();
                        resourceLink.setResRefName("openejb/destination");
                        ejbDeployment.addResourceLink(resourceLink);
                    }
                    resourceLink.setResId(destinationId);
                }
            }
        }

        // resolve all message destination refs with links and assign a ref id to the reference
        for (final EjbModule ejbModule : appModule.getEjbModules()) {
            final AssemblyDescriptor assembly = ejbModule.getEjbJar().getAssemblyDescriptor();
            if (assembly == null) {
                continue;
            }

            final URI moduleUri = ejbModule.getModuleUri();
            final OpenejbJar openejbJar = ejbModule.getOpenejbJar();

            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                final EjbDeployment ejbDeployment = openejbJar.getDeploymentsByEjbName().get(bean.getEjbName());
                if (ejbDeployment == null) {
                    throw new OpenEJBException("No ejb deployment found for ejb " + bean.getEjbName());
                }

                for (final MessageDestinationRef ref : bean.getMessageDestinationRef()) {
                    // skip destination refs with a resource link already assigned
                    if (ref.getMappedName() == null && ejbDeployment.getResourceLink(ref.getName()) == null) {
                        final String destinationId = resolveDestinationId(ref, appModule, moduleUri, destinationResolver, destinationTypes);
                        if (destinationId != null) {
                            // build the link and add it
                            final ResourceLink resourceLink = new ResourceLink();
                            resourceLink.setResId(destinationId);
                            resourceLink.setResRefName(ref.getName());
                            ejbDeployment.addResourceLink(resourceLink);
                        }

                    }
                }
            }
        }

        for (final ClientModule clientModule : appModule.getClientModules()) {
            final URI moduleUri = clientModule.getModuleUri();
            for (final MessageDestinationRef ref : clientModule.getApplicationClient().getMessageDestinationRef()) {
                final String destinationId = resolveDestinationId(ref, appModule, moduleUri, destinationResolver, destinationTypes);
                if (destinationId != null) {
                    // for client modules we put the destinationId in the mapped name
                    ref.setMappedName(destinationId);
                }
            }
        }

        for (final WebModule webModule : appModule.getWebModules()) {
            final URI moduleUri = URLs.uri(webModule.getModuleId());
            for (final MessageDestinationRef ref : webModule.getWebApp().getMessageDestinationRef()) {
                final String destinationId = resolveDestinationId(ref, appModule, moduleUri, destinationResolver, destinationTypes);
                if (destinationId != null) {
                    // for web modules we put the destinationId in the mapped name
                    ref.setMappedName(destinationId);
                }
            }
        }

        // Process MDBs one more time...
        // this time fill in the destination type (if not alreday specified) with
        // the info from the destination (which got filled in from the references)
        for (final EjbModule ejbModule : appModule.getEjbModules()) {
            final AssemblyDescriptor assembly = ejbModule.getEjbJar().getAssemblyDescriptor();
            if (assembly == null) {
                continue;
            }

            final URI moduleUri = URLs.uri(ejbModule.getModuleId());
            final OpenejbJar openejbJar = ejbModule.getOpenejbJar();

            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                // MDB destination is deploymentId if none set
                if (bean instanceof MessageDrivenBean) {
                    final MessageDrivenBean mdb = (MessageDrivenBean) bean;

                    if (!isJms(mdb)) {
                        continue;
                    }

                    final EjbDeployment ejbDeployment = openejbJar.getDeploymentsByEjbName().get(bean.getEjbName());
                    if (ejbDeployment == null) {
                        throw new OpenEJBException("No ejb deployment found for ejb " + bean.getEjbName());
                    }

                    // if destination type is already set in, continue
                    String destinationType = mdb.getMessageDestinationType();
                    if (destinationType != null) {
                        continue;
                    }

                    final String link = mdb.getMessageDestinationLink();
                    if (link != null && link.length() != 0) {
                        // resolve the destination... if we don't find one it is a configuration bug
                        final MessageDestination destination = destinationResolver.resolveLink(link, moduleUri);
                        if (destination == null) {
                            throw new OpenEJBException("Message destination " + link + " for message driven bean " + mdb.getEjbName() + " not found");
                        }
                        destinationType = destinationTypes.get(destination);
                    }

                    if (destinationType == null) {
                        // couldn't determine type... we'll have to guess

                        // if destination name contains the string "queue" or "topic" we use that
                        final Properties properties = mdb.getActivationConfig().toProperties();
                        final String destination = properties.getProperty("destination").toLowerCase();
                        if (destination.contains("queue")) {
                            destinationType = Queue.class.getName();
                        } else if (destination.contains("topic")) {
                            destinationType = Topic.class.getName();
                        } else {
                            // Queue is the default
                            destinationType = Queue.class.getName();
                        }
                        logger.info("Auto-configuring a message driven bean " +
                            ejbDeployment.getDeploymentId() +
                            " destination " +
                            properties.getProperty("destination") +
                            " to be destinationType " +
                            destinationType);
                    }

                    if (destinationType != null) {
                        mdb.getActivationConfig().addProperty("destinationType", destinationType);
                        mdb.setMessageDestinationType(destinationType);

                        // topics need a clientId and subscriptionName
                        if ("jakarta.jms.Topic".equals(destinationType)) {
                            final Properties properties = mdb.getActivationConfig().toProperties();
                            if (!properties.containsKey("clientId")) {
                                mdb.getActivationConfig().addProperty("clientId", ejbDeployment.getDeploymentId());
                            }
                            if (!properties.containsKey("subscriptionName")) {
                                mdb.getActivationConfig().addProperty("subscriptionName", ejbDeployment.getDeploymentId() + "_subscription");
                            }
                        }
                    }
                }
            }
        }

    }