public static List generateDescriptors()

in tools/org.apache.felix.scr.generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java [84:237]


    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;
    }