private ComponentContainer createComponent()

in tools/org.apache.felix.scr.generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java [295:456]


    private ComponentContainer createComponent(final ClassDescription desc,
                    final IssueLog iLog)
    throws SCRDescriptorException {
        final ComponentDescription componentDesc = desc.getDescription(ComponentDescription.class);

        final SpecVersion intitialComponentSpecVersion = componentDesc.getSpecVersion();

        // configuration pid in 1.2
        if ( componentDesc.getConfigurationPid() != null && !componentDesc.getConfigurationPid().equals(componentDesc.getName())) {
            componentDesc.setSpecVersion(SpecVersion.VERSION_1_2);
        }

        final ComponentContainer container = new ComponentContainer(desc, componentDesc);

        // Create metatype (if required)
        final MetatypeContainer ocd;
        if ( !componentDesc.isAbstract() && componentDesc.isCreateMetatype() ) {
            // OCD
            ocd = new MetatypeContainer();
            container.setMetatypeContainer( ocd );
            ocd.setId( componentDesc.getName() );
            if ( componentDesc.getLabel() != null ) {
                ocd.setName( componentDesc.getLabel() );
            }
            if ( componentDesc.getDescription() != null ) {
                ocd.setDescription( componentDesc.getDescription() );
            }

            // Factory pid
            if ( componentDesc.isSetMetatypeFactoryPid() ) {
                if ( componentDesc.getFactory() == null ) {
                    ocd.setFactoryPid( componentDesc.getName() );
                } else {
                    iLog.addWarning( "Component factory " + componentDesc.getName()
                        + " should not set metatype factory pid.", desc.getSource() );
                }
            }
        } else {
            ocd = null;
        }
        // metatype checks if metatype is not generated (FELIX-4033)
        if ( !componentDesc.isAbstract() && !componentDesc.isCreateMetatype() ) {
            if ( componentDesc.getLabel() != null && componentDesc.getLabel().trim().length() > 0 ) {
                iLog.addWarning(" Component " + componentDesc.getName() + " has set a label. However metatype is set to false. This label is ignored.",
                        desc.getSource());
            }
            if ( componentDesc.getDescription() != null && componentDesc.getDescription().trim().length() > 0 ) {
                iLog.addWarning(" Component " + componentDesc.getName() + " has set a description. However metatype is set to false. This description is ignored.",
                        desc.getSource());
            }
        }

        ClassDescription current = desc;
        boolean inherit;
        do {
            final ComponentDescription cd = current.getDescription(ComponentDescription.class);
            inherit = (cd == null ? true : cd.isInherit());

            if ( cd != null ) {
                if ( current != desc ) {
                    iLog.addWarning(" Component " + componentDesc.getName() + " is using the " +
                                    "deprecated inheritance feature and inherits from " + current.getDescribedClass().getName() +
                                    ". This feature will be removed in future versions.",
                                    desc.getSource());
                }
                // handle enabled and immediate
                if ( componentDesc.getEnabled() == null ) {
                    componentDesc.setEnabled(cd.getEnabled());
                }
                if ( componentDesc.getImmediate() == null ) {
                    componentDesc.setImmediate(cd.getImmediate());
                }

                // lifecycle methods
                if ( componentDesc.getActivate() == null && cd.getActivate() != null ) {
                    componentDesc.setActivate(cd.getActivate());
                }
                if ( componentDesc.getDeactivate() == null && cd.getDeactivate() != null ) {
                    componentDesc.setDeactivate(cd.getDeactivate());
                }
                if ( componentDesc.getModified() == null && cd.getModified() != null ) {
                    componentDesc.setModified(cd.getModified());
                }
                if ( componentDesc.getActivate() != null || componentDesc.getDeactivate() != null || componentDesc.getModified() != null ) {
                    // spec version must be at least 1.1
                    componentDesc.setSpecVersion(SpecVersion.VERSION_1_1);
                }
                if ( componentDesc.getConfigurationPolicy() != ComponentConfigurationPolicy.OPTIONAL ) {
                    // policy requires 1.1
                    componentDesc.setSpecVersion(SpecVersion.VERSION_1_1);
                }

            }
            // services, properties, references
            this.processServices(current, container);
            this.processProperties(current, container, ocd);
            this.processReferences(current, container);


            // go up in the class hierarchy
            if ( !inherit || current.getDescribedClass().getSuperclass() == null ) {
                current = null;
            } else {
                try {
                    current = this.scanner.getDescription(current.getDescribedClass().getSuperclass());
                } catch ( final SCRDescriptorFailureException sde) {
                    this.logger.debug(sde.getMessage(), sde);
                    iLog.addError(sde.getMessage(), current.getSource());
                } catch ( final SCRDescriptorException sde) {
                    this.logger.debug(sde.getSourceLocation() + " : " + sde.getMessage(), sde);
                    iLog.addError(sde.getMessage(), sde.getSourceLocation());
                }
            }
        } while ( current != null);

        // check service interfaces for properties
        if ( container.getServiceDescription() != null ) {
            for(final String interfaceName : container.getServiceDescription().getInterfaces()) {
                try {
                    final Class<?> interfaceClass = project.getClassLoader().loadClass(interfaceName);
                    final ClassDescription interfaceDesc = this.scanner.getDescription(interfaceClass);
                    if ( interfaceDesc != null ) {
                        this.processProperties(interfaceDesc, container, ocd);
                    }
                } catch ( final SCRDescriptorFailureException sde) {
                    this.logger.debug(sde.getMessage(), sde);
                    iLog.addError(sde.getMessage(), interfaceName);
                } catch ( final SCRDescriptorException sde) {
                    this.logger.debug(sde.getSourceLocation() + " : " + sde.getMessage(), sde);
                    iLog.addError(sde.getMessage(), sde.getSourceLocation());
                } catch (ClassNotFoundException e) {
                    this.logger.debug(e.getMessage(), e);
                    iLog.addError(e.getMessage(), interfaceName);
                }
            }
        }

        // global properties
        this.processGlobalProperties(desc, container.getProperties());

        // check lifecycle methods
        if ( componentDesc.getActivate() == null ) {
            final Validator.MethodResult result = Validator.findLifecycleMethod(project, container, "activate", true);
            if ( result.method != null ) {
                componentDesc.setSpecVersion(result.requiredSpecVersion);
            }
        }
        if ( componentDesc.getDeactivate() == null ) {
            final Validator.MethodResult result = Validator.findLifecycleMethod(project, container, "deactivate", false);
            if ( result.method != null ) {
                componentDesc.setSpecVersion(result.requiredSpecVersion);
            }
        }

        // check if component has spec version configured but requires a higher one
        if ( intitialComponentSpecVersion != null && componentDesc.getSpecVersion().ordinal() > intitialComponentSpecVersion.ordinal() ) {
            iLog.addError("Component " + container + " requires spec version " + container.getComponentDescription().getSpecVersion().name()
                    + " but component is configured to use version " + intitialComponentSpecVersion.name(),
                    desc.getSource());
        }
        return container;
    }