Search in sources :

Example 1 with MetatypeContainer

use of org.apache.felix.scrplugin.helper.MetatypeContainer in project felix by apache.

the class SCRDescriptorGenerator method createComponent.

/**
 * Create the SCR objects based on the descriptions
 */
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;
}
Also used : ComponentDescription(org.apache.felix.scrplugin.description.ComponentDescription) MetatypeContainer(org.apache.felix.scrplugin.helper.MetatypeContainer) ClassDescription(org.apache.felix.scrplugin.description.ClassDescription) ComponentContainer(org.apache.felix.scrplugin.helper.ComponentContainer) Validator(org.apache.felix.scrplugin.helper.Validator)

Example 2 with MetatypeContainer

use of org.apache.felix.scrplugin.helper.MetatypeContainer in project felix by apache.

the class MetaTypeIO method generateDescriptors.

public static List<String> generateDescriptors(final DescriptionContainer module, final Project project, final Options options, final Log logger) throws SCRDescriptorException {
    // create a list with relevant components
    final List<ComponentContainer> components = new ArrayList<ComponentContainer>();
    for (final ComponentContainer component : module.getComponents()) {
        if (component.getMetatypeContainer() != null) {
            components.add(component);
        }
    }
    // write meta type info
    final File mtDir = options.getMetaTypeDirectory();
    final File parentDir = mtDir.getParentFile();
    if (components.size() > 0) {
        // check for metatype.properties
        // we used to have this in OSGI-INF/metatype, but that is actually not allowed by the spec
        // we should break the build
        final File oldMtProps = new File(project.getClassesDirectory(), OLD_LOCATION + File.separator + PROPS_FILE);
        if (oldMtProps.exists()) {
            throw new SCRDescriptorException("metatype properties file must be stored outside of " + OLD_LOCATION + ", move it to " + NEW_LOCATION, oldMtProps.getAbsolutePath());
        }
        final File mtProps = new File(project.getClassesDirectory(), NEW_LOCATION + File.separator + PROPS_FILE);
        final boolean oldStyle = mtProps.exists();
        final List<String> fileNames = new ArrayList<String>();
        final List<ComponentContainerContainer> containers = ComponentContainerUtil.split(components);
        for (final ComponentContainerContainer ccc : containers) {
            mtDir.mkdirs();
            final File useFile = new File(mtDir, ccc.className + ".xml");
            String metatypeLocation = NEW_LOCATION.replace(File.separatorChar, '/') + "/metatype";
            // check if all labels and descriptions are inlined
            boolean allInlined = true;
            for (final ComponentContainer cc : ccc.components) {
                final MetatypeContainer mc = cc.getMetatypeContainer();
                if (mc.getName() == null) {
                    if (oldStyle) {
                        mc.setName("%" + cc.getComponentDescription().getName() + ".name");
                    } else {
                        mc.setName("Component " + cc.getComponentDescription().getName());
                    }
                }
                if (mc.getName() != null && mc.getName().startsWith("%")) {
                    allInlined = false;
                }
                if (mc.getDescription() == null) {
                    if (oldStyle) {
                        mc.setDescription("%" + cc.getComponentDescription().getName() + ".description");
                    } else {
                        mc.setDescription("Description for " + cc.getComponentDescription().getName());
                    }
                }
                if (mc.getDescription() != null && mc.getDescription().startsWith("%")) {
                    allInlined = false;
                }
                for (final MetatypeAttributeDefinition mad : mc.getProperties()) {
                    if (mad.getName() == null) {
                        if (oldStyle) {
                            mad.setName("%" + mad.getId() + ".name");
                        } else {
                            mad.setName("Property " + mad.getId());
                        }
                    }
                    if (mad.getName() != null && mad.getName().startsWith("%")) {
                        allInlined = false;
                    }
                    if (mad.getDescription() == null) {
                        if (oldStyle) {
                            mad.setDescription("%" + mad.getId() + ".description");
                        } else {
                            mad.setDescription("Description for " + mad.getId());
                        }
                    }
                    if (mad.getDescription() != null && mad.getDescription().startsWith("%")) {
                        allInlined = false;
                    }
                }
            }
            if (allInlined) {
                final Properties metatypeProps = new Properties();
                // externalize all labels and descriptions
                for (final ComponentContainer cc : ccc.components) {
                    final MetatypeContainer mc = cc.getMetatypeContainer();
                    final String baseKey = cc.getComponentDescription().getName().replace("$", ".");
                    if (mc.getName() != null) {
                        final String key = baseKey + ".name";
                        metatypeProps.put(key, mc.getName());
                        mc.setName("%" + key);
                    }
                    if (mc.getDescription() != null) {
                        final String key = baseKey + ".description";
                        metatypeProps.put(key, mc.getDescription());
                        mc.setDescription("%" + key);
                    }
                    for (final MetatypeAttributeDefinition mad : mc.getProperties()) {
                        if (mad.getName() != null) {
                            final String key = baseKey + "." + mad.getId() + ".name";
                            metatypeProps.put(key, mad.getName());
                            mad.setName("%" + key);
                        }
                        if (mad.getDescription() != null) {
                            final String key = baseKey + "." + mad.getId() + ".description";
                            metatypeProps.put(key, mad.getDescription());
                            mad.setDescription("%" + key);
                        }
                    }
                }
                if (metatypeProps.size() > 0) {
                    final int lastDot = useFile.getName().lastIndexOf(".");
                    final String baseName = useFile.getName().substring(0, lastDot);
                    final File propsFile = new File(options.getOutputDirectory(), NEW_LOCATION + File.separator + baseName + ".properties");
                    propsFile.getParentFile().mkdirs();
                    try {
                        final FileOutputStream fos = new FileOutputStream(propsFile);
                        try {
                            metatypeProps.store(fos, null);
                        } finally {
                            fos.close();
                        }
                    } catch (IOException e) {
                        throw new SCRDescriptorException("Unable to create metatype.properties", propsFile.getAbsolutePath());
                    }
                    fileNames.add(NEW_LOCATION.replace(File.separatorChar, '/') + '/' + propsFile.getName());
                    metatypeLocation = NEW_LOCATION.replace(File.separatorChar, '/') + "/" + baseName;
                }
            }
            logger.info("Generating " + ccc.components.size() + " MetaType Descriptors in " + useFile);
            MetaTypeIO.write(module, ccc.components, useFile, metatypeLocation);
            fileNames.add(parentDir.getName() + '/' + mtDir.getName() + '/' + useFile.getName());
        }
        return fileNames;
    }
    if (mtDir.exists() && !options.isIncremental()) {
        for (final File f : mtDir.listFiles()) {
            if (f.isFile()) {
                logger.debug("Removing obsolete metatype file " + f);
                f.delete();
            }
        }
    }
    return null;
}
Also used : MetatypeAttributeDefinition(org.apache.felix.scrplugin.helper.MetatypeAttributeDefinition) ArrayList(java.util.ArrayList) MetatypeContainer(org.apache.felix.scrplugin.helper.MetatypeContainer) IOException(java.io.IOException) Properties(java.util.Properties) ComponentContainerContainer(org.apache.felix.scrplugin.helper.ComponentContainerUtil.ComponentContainerContainer) FileOutputStream(java.io.FileOutputStream) ComponentContainer(org.apache.felix.scrplugin.helper.ComponentContainer) File(java.io.File) SCRDescriptorException(org.apache.felix.scrplugin.SCRDescriptorException)

Aggregations

ComponentContainer (org.apache.felix.scrplugin.helper.ComponentContainer)2 MetatypeContainer (org.apache.felix.scrplugin.helper.MetatypeContainer)2 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Properties (java.util.Properties)1 SCRDescriptorException (org.apache.felix.scrplugin.SCRDescriptorException)1 ClassDescription (org.apache.felix.scrplugin.description.ClassDescription)1 ComponentDescription (org.apache.felix.scrplugin.description.ComponentDescription)1 ComponentContainerContainer (org.apache.felix.scrplugin.helper.ComponentContainerUtil.ComponentContainerContainer)1 MetatypeAttributeDefinition (org.apache.felix.scrplugin.helper.MetatypeAttributeDefinition)1 Validator (org.apache.felix.scrplugin.helper.Validator)1