private void validateReference()

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


    private void validateReference(final ReferenceDescription ref, final boolean componentIsAbstract)
    throws SCRDescriptorException {
        final int currentIssueCount = iLog.getNumberOfErrors();

        // validate name
        if (StringUtils.isEmpty(ref.getName())) {
            if (this.options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1.ordinal() ) {
                this.logError(ref, "Reference has no name");
            }
        }

        // validate interface
        if (StringUtils.isEmpty(ref.getInterfaceName())) {
            this.logError(ref, "Missing interface name");
        } else {
            try {
                this.project.getClassLoader().loadClass(ref.getInterfaceName());
            } catch (final ClassNotFoundException e) {
                this.logError(ref, "Interface class can't be loaded: " + ref.getInterfaceName());
            }
        }

        // validate cardinality
        if (ref.getCardinality() == null) {
            ref.setCardinality(ReferenceCardinality.MANDATORY_UNARY);
        }

        // validate policy
        if (ref.getPolicy() == null) {
            ref.setPolicy(ReferencePolicy.STATIC);
        }

        // validate policy option
        if ( ref.getPolicyOption() == null ) {
            ref.setPolicyOption(ReferencePolicyOption.RELUCTANT);
        }
        if ( ref.getPolicyOption() != ReferencePolicyOption.RELUCTANT ) {
            if ( this.options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_2.ordinal() ) {
                this.logError(ref, "ReferencePolicyOption " + ref.getPolicyOption().name() +
                                " requires spec version " + SpecVersion.VERSION_1_2.getName() + " or higher.");
            }
        }
        // validate strategy
        if (ref.getStrategy() == null) {
            ref.setStrategy(ReferenceStrategy.EVENT);
        }

        // validate methods only if interface name is set
        if (!StringUtils.isEmpty(ref.getInterfaceName())) {
            // validate bind and unbind methods
            if (ref.getStrategy() != ReferenceStrategy.LOOKUP) {
                String bindName = ref.getBind();
                String unbindName = ref.getUnbind();

                final boolean canGenerate = this.options.isGenerateAccessors() &&
                                ref.getField() != null
                                && (ref.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || ref.getCardinality() == ReferenceCardinality.MANDATORY_UNARY);
                if (bindName == null && !canGenerate ) {
                    bindName = "bind";
                }
                if (unbindName == null && !canGenerate ) {
                    unbindName = "unbind";
                }

                if ( bindName != null ) {
                    bindName = this.validateMethod(ref, bindName, componentIsAbstract);
                    if ( bindName == null && ref.getField() != null ) {
                        this.logError(ref, "Something went wrong: " + canGenerate + " - " + this.options.isGenerateAccessors() + " - " + ref.getCardinality());
                    }
                } else {
                    bindName = "bind" + Character.toUpperCase(ref.getName().charAt(0)) + ref.getName().substring(1);
                }
                if ( unbindName != null ) {
                    if ( "-".equals(unbindName) )
                    {
                        unbindName = null;
                    } else {
                        unbindName = this.validateMethod(ref, unbindName, componentIsAbstract);
                    }
                } else {
                    unbindName = "unbind" + Character.toUpperCase(ref.getName().charAt(0)) + ref.getName().substring(1);
                }

                // check for volatile on dynamic field reference with cardinality unary
                if ( !this.options.isSkipVolatileCheck() ) {
                    if ( ref.getField() != null
                         && (ref.getCardinality() == ReferenceCardinality.OPTIONAL_UNARY || ref.getCardinality() == ReferenceCardinality.MANDATORY_UNARY)
                         && ref.getPolicy() == ReferencePolicy.DYNAMIC ) {
                        final boolean fieldIsVolatile = Modifier.isVolatile(ref.getField().getModifiers());

                        if ( ref.isBindMethodCreated() || ref.isUnbindMethodCreated() ) {
                            // field must be volatile
                            if (!fieldIsVolatile) {
                                this.logError(ref, "Dynamic field must be declared volatile for unary references");
                            }
                        }
                    }
                }

                if (iLog.getNumberOfErrors() == currentIssueCount) {
                    ref.setBind(bindName);
                    ref.setUnbind(unbindName);
                }

            } else {
                ref.setBind(null);
                ref.setUnbind(null);
            }

            // validate updated method
            if (ref.getUpdated() != null) {
                if (this.options.getSpecVersion().ordinal() < SpecVersion.VERSION_1_1_FELIX.ordinal()) {
                    this.logError(ref, "Updated method declaration requires version "
                                    + SpecVersion.VERSION_1_1_FELIX.getName() + ", " + SpecVersion.VERSION_1_2.getName() + " or newer");
                }
                this.validateMethod(ref, ref.getUpdated(), componentIsAbstract);
            }
        }
    }