private void process()

in src/main/java/org/apache/sling/feature/maven/Preprocessor.java [127:242]


    private void process(final Environment env,
            final FeatureProjectInfo info,
            final FeatureProjectConfig config) {
        if ( (config.isTestConfig() && info.testFeatureDone == true )
             || (!config.isTestConfig() && info.featureDone == true) ) {
            env.logger.debug("Return assembled " + config.getName() + " for " + info.project.getId());
            return;
        }

        // prevent recursion and multiple processing
        if ( config.isTestConfig() ) {
            info.testFeatureDone = true;
        } else {
            info.featureDone = true;
        }
        env.logger.debug("Processing " + config.getName() + " in project " + info.project.getId());

        // read project features
        readProjectFeatures(env.logger, info, config);
        if ( (config.isTestConfig() ? info.testFeatures : info.features).isEmpty() ) {
            env.logger.debug("No " + config.getName() + " found in project " + info.project.getId());
            return;
        }

        // process attachments (only for jar or bundle)
        if ( "jar".equals(info.project.getPackaging())
             || "bundle".equals(info.project.getPackaging())) {
            if ( config.isSkipAddJarToFeature() ) {
                env.logger.debug("Skip adding jar to " + config.getName());
            } else {
                if ( info.features.size() > 1 ) {
                    throw new RuntimeException("Jar can only be added if just one feature is defined in the project");
                }
                final Artifact jar = new Artifact(new ArtifactId(info.project.getGroupId(),
                        info.project.getArtifactId(),
                        info.project.getVersion(),
                        null,
                        "jar"));
                if ( config.getJarStartOrder() != null ) {
                    jar.setStartOrder(Integer.valueOf(config.getJarStartOrder()));
                }
                // add to first feature
                (config.isTestConfig() ? info.testFeatures : info.features).values().iterator().next().getBundles().add(jar);
            }
        }

        // assemble features
        final Map<String, Feature> features = (config.isTestConfig() ? info.testFeatures : info.features);
        final Map<String, Feature> processFeatures = new HashMap<>(features);
        final Map<String, Feature> aggregatedFeatures = (config.isTestConfig() ? info.assembledTestFeatures : info.assembledFeatures);
        while ( aggregatedFeatures.size() < features.size() ) {
        	final int start = aggregatedFeatures.size();

        	final Iterator<Map.Entry<String, Feature>> iter = processFeatures.entrySet().iterator();
        	while ( iter.hasNext() ) {
        		final Map.Entry<String, Feature> entry = iter.next();
        		boolean process = false;
                if ( entry.getValue().getPrototype() == null ) {
        			// no include we can process
        			process = true;
        		} else {
                    final ArtifactId prototype = entry.getValue().getPrototype().getId();
                    if ( !prototype.getGroupId().equals(info.project.getGroupId())
                      || !prototype.getArtifactId().equals(info.project.getArtifactId())
                      || !prototype.getVersion().equals(info.project.getVersion()) ) {
        		    	process = true;
        		    } else {
        		    	// same project
        		    	for(final Feature f : aggregatedFeatures.values()) {
                            if ( f.getId().equals(prototype) ) {
        		    			process = true;
        		    			break;
        		    		}
        		    	}
        		    }
        		}
        		if ( process ) {
        			iter.remove();
    	            final Feature assembledFeature = FeatureBuilder.assemble(entry.getValue(), new BuilderContext(this.createFeatureProvider(env,
    		                info,
    		                config.isTestConfig(),
    		                config.isSkipAddDependencies(),
                                    config.getScope(), null))
                                            .setArtifactProvider(
                                                    aid ->
                                                    {
                                                        try
                                                        {
                                                            return ProjectHelper
                                                                    .getOrResolveArtifact(info.project, env.session,
                                                                            env.artifactHandlerManager, env.repoSystem, aid)
                                                                    .getFile().toURI().toURL();
                                                        }
                                                        catch (Exception e)
                                                        {
                                                            env.logger.error(e.getMessage(), e);
                                                            return null;
                                                        }
                                                    }));
    	            aggregatedFeatures.put(entry.getKey(), assembledFeature);
    	            break;
        		}
        	}
        	if ( aggregatedFeatures.size() == start ) {
        		throw new RuntimeException("Circular dependency in features in project " + info.project.getId());
        	}
        }

        if ( config.isSkipAddDependencies() ) {
            env.logger.debug("Not adding artifacts from features as dependencies");
        } else {
            for(final Feature f : (config.isTestConfig() ? info.assembledTestFeatures : info.assembledFeatures).values()) {
                addDependenciesFromFeature(env, info, f, config.getScope());
            }
        }
    }