public void validate()

in tools/org.apache.felix.scr.generator/src/main/java/org/apache/felix/scrplugin/helper/Validator.java [86:200]


    public void validate()
    throws SCRDescriptorException {
        final ComponentDescription component = this.container.getComponentDescription();

        // nothing to check if this is ignored
        if (!component.isCreateDs()) {
            return;
        }

        final int currentIssueCount = iLog.getNumberOfErrors();

        // if the component is abstract, we do not validate everything
        if (!component.isAbstract()) {
            // if configuration pid is set and different from name, we need 1.2
            if ( component.getConfigurationPid() != null && !component.getConfigurationPid().equals(component.getName())
                 && options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
                this.logError(component, "Different configuration pid requires "
                                + SpecVersion.VERSION_1_2.getName() + " or higher.");
            }

            // ensure non-abstract, public class
            if (!Modifier.isPublic(this.container.getClassDescription().getDescribedClass().getModifiers())) {
                this.logError(component, "Class must be public: "
                                + this.container.getClassDescription().getDescribedClass().getName());
            }
            if (Modifier.isAbstract(this.container.getClassDescription().getDescribedClass().getModifiers())
                            || this.container.getClassDescription().getDescribedClass().isInterface()) {
                this.logError(component, "Class must be concrete class (not abstract or interface) : "
                                + this.container.getClassDescription().getDescribedClass().getName());
            }

            // no errors so far, let's continue
            if (iLog.getNumberOfErrors() == currentIssueCount) {

                final String activateName = component.getActivate() == null ? "activate" : component.getActivate();
                final String deactivateName = component.getDeactivate() == null ? "deactivate" : component.getDeactivate();

                // check activate and deactivate methods
                this.checkLifecycleMethod(activateName, true, component.getActivate() != null);
                this.checkLifecycleMethod(deactivateName, false, component.getDeactivate() != null);

                if (component.getModified() != null) {
                    if ( this.options.getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
                        this.checkLifecycleMethod(component.getModified(), true, true);
                    } else {
                        this.logError(component, "If modified version is specified, spec version must be " +
                            SpecVersion.VERSION_1_1.name() + " or higher : " + component.getModified());
                    }
                }

                // ensure public default constructor
                boolean constructorFound = true;
                Constructor<?>[] constructors = this.container.getClassDescription().getDescribedClass().getDeclaredConstructors();
                for (int i = 0; constructors != null && i < constructors.length; i++) {
                    // if public default, succeed
                    if (Modifier.isPublic(constructors[i].getModifiers())
                        && (constructors[i].getParameterTypes() == null || constructors[i].getParameterTypes().length == 0)) {
                        constructorFound = true;
                        break;
                    }

                    // non-public/non-default constructor found, must have
                    // explicit
                    constructorFound = false;
                }

                if (!constructorFound) {
                    this.logError(component, "Class must have public default constructor: " + this.container.getClassDescription().getDescribedClass().getName());
                }

                // verify properties
                for (final PropertyDescription prop : this.container.getProperties().values()) {
                    this.validateProperty(prop);
                }

                // verify service
                boolean isServiceFactory = false;
                if (this.container.getServiceDescription() != null) {
                    if (this.container.getServiceDescription().getInterfaces().size() == 0) {
                        this.logError(component, "Service interface information is missing!");
                    }
                    this.validateService(this.container.getServiceDescription());
                    isServiceFactory = this.container.getServiceDescription().isServiceFactory();
                }

                // serviceFactory must not be true for immediate of component factory
                if (isServiceFactory && component.getImmediate() != null && component.getImmediate().booleanValue()
                    && component.getFactory() != null) {
                    this.logError(component,
                        "Component must not be a ServiceFactory, if immediate and/or component factory: "
                        + this.container.getClassDescription().getDescribedClass().getName());
                }

                // immediate must not be true for component factory
                if (component.getImmediate() != null && component.getImmediate().booleanValue() && component.getFactory() != null) {
                    this.logError(component,
                        "Component must not be immediate if component factory: " + this.container.getClassDescription().getDescribedClass().getName());
                }
            }

            // additional check for metatype (FELIX-4035)
            if ( this.container.getMetatypeContainer() != null ) {
                if ( this.container.getMetatypeContainer().getProperties().size() == 0 ) {
                    this.logError(component, "Component is defined to generate metatype information, however no properties or only private properties have been " +
                        "defined; in case no properties or only private properties are wanted, consider to use 'metatype=false'");
                }
            }
            if (iLog.getNumberOfErrors() == currentIssueCount) {
                // verify references
                for (final ReferenceDescription ref : this.container.getReferences().values()) {
                    this.validateReference(ref, component.isAbstract());
                }
            }
        }
    }