use of org.apache.felix.scrplugin.helper.ComponentContainer 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;
}
use of org.apache.felix.scrplugin.helper.ComponentContainer in project felix by apache.
the class SCRDescriptorGenerator method execute.
/**
* Actually generates the Declarative Services and Metatype descriptors
* scanning the java sources provided by the {@link #setProject(Project)}
*
* @return A list of generated file names, relative to the output directory
*
* @throws SCRDescriptorException
* @throws SCRDescriptorFailureException
*/
public Result execute() throws SCRDescriptorException, SCRDescriptorFailureException {
this.logger.debug("Starting SCR Descriptor Generator....");
if (this.project == null) {
throw new SCRDescriptorFailureException("Project has not been set!");
}
if (this.options == null) {
// use default options
this.options = new Options();
}
if (this.options.getOutputDirectory() == null) {
throw new SCRDescriptorFailureException("Output directory has not been set!");
}
this.logger.debug("..using output directory: " + this.options.getOutputDirectory());
this.logger.debug("..strict mode: " + this.options.isStrictMode());
this.logger.debug("..generating accessors: " + this.options.isGenerateAccessors());
// check speck version configuration
SpecVersion specVersion = options.getSpecVersion();
if (specVersion == null) {
this.logger.debug("..auto detecting spec version");
} else {
this.logger.debug("..using spec version " + specVersion.getName());
}
// create a log
this.iLog = new IssueLog(this.options.isStrictMode());
// create the annotation processor manager
final AnnotationProcessor aProcessor = new AnnotationProcessorManager(this.logger, this.project.getClassLoader());
// create the class scanner - and start scanning
this.scanner = new ClassScanner(logger, iLog, project, aProcessor);
final List<ClassDescription> scannedDescriptions = scanner.scanSources();
// create the result to hold the list of processed source files
final Result result = new Result();
final List<ComponentContainer> processedContainers = new ArrayList<ComponentContainer>();
for (final ClassDescription desc : scannedDescriptions) {
this.logger.debug("Processing component class " + desc.getSource());
result.addProcessedSourceFile(desc.getSource());
// check if there is more than one component definition
if (desc.getDescriptions(ComponentDescription.class).size() > 1) {
iLog.addError("Class has more than one component definition." + " Check the annotations and merge the definitions to a single definition.", desc.getSource());
} else {
final ComponentContainer container = this.createComponent(desc, iLog);
if (container.getComponentDescription().getSpecVersion() != null) {
if (specVersion == null) {
specVersion = container.getComponentDescription().getSpecVersion();
logger.debug("Setting used spec version to " + specVersion);
} else if (container.getComponentDescription().getSpecVersion().ordinal() > specVersion.ordinal()) {
if (this.options.getSpecVersion() != null) {
// if a spec version has been configured and a component requires a higher
// version, this is considered an error!
iLog.addError("Component " + container + " requires spec version " + container.getComponentDescription().getSpecVersion().name() + " but plugin is configured to use version " + this.options.getSpecVersion(), desc.getSource());
} else {
specVersion = container.getComponentDescription().getSpecVersion();
logger.debug("Setting used spec version to " + specVersion);
}
}
} else {
if (this.options.getSpecVersion() != null) {
container.getComponentDescription().setSpecVersion(options.getSpecVersion());
} else {
container.getComponentDescription().setSpecVersion(SpecVersion.VERSION_1_0);
}
}
processedContainers.add(container);
}
}
// if spec version is still not set, we're using lowest available
if (specVersion == null) {
specVersion = SpecVersion.VERSION_1_0;
logger.debug("Using default spec version " + specVersion);
}
this.logger.debug("Generating descriptor for spec version: " + specVersion);
options.setSpecVersion(specVersion);
// in order to create them if possible
if (this.options.isGenerateAccessors()) {
for (final ComponentContainer container : processedContainers) {
this.generateMethods(container);
}
}
// now validate
final DescriptionContainer module = new DescriptionContainer(this.options);
for (final ComponentContainer container : processedContainers) {
final int errorCount = iLog.getNumberOfErrors();
final Validator validator = new Validator(container, project, options, iLog);
validator.validate();
// ignore component if it has errors
if (iLog.getNumberOfErrors() == errorCount) {
module.add(container);
}
}
// log issues
iLog.logMessages(logger);
// after checking all classes, throw if there were any failures
if (iLog.hasErrors()) {
throw new SCRDescriptorFailureException("SCR Descriptor parsing had failures (see log)");
}
// and generate files
result.setMetatypeFiles(MetaTypeIO.generateDescriptors(module, this.project, this.options, this.logger));
result.setScrFiles(ComponentDescriptorIO.generateDescriptorFiles(module, this.options, logger));
return result;
}
use of org.apache.felix.scrplugin.helper.ComponentContainer in project felix by apache.
the class ComponentDescriptorIO method generateXML.
/**
* Generate the xml top level element and start streaming
* the components.
*
* @param components
* @param contentHandler
* @throws SAXException
*/
private static void generateXML(final DescriptionContainer module, final List<ComponentContainer> components, final File descriptorFile, final Log logger) throws SAXException, IOException, TransformerException {
logger.info("Writing " + components.size() + " Service Component Descriptors to " + descriptorFile);
FileOutputStream fos = new FileOutputStream(descriptorFile);
try {
final ContentHandler contentHandler = IOUtils.getSerializer(fos);
// detect namespace to use
final String namespace = module.getOptions().getSpecVersion().getNamespaceUrl();
contentHandler.startDocument();
contentHandler.startPrefixMapping(PREFIX, namespace);
IOUtils.newline(contentHandler);
// wrapper element to generate well formed xml if 0 or more than 1 component
int startIndent = 0;
if (components.size() != 1) {
contentHandler.startElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS, new AttributesImpl());
IOUtils.newline(contentHandler);
startIndent = 1;
}
for (final ComponentContainer component : components) {
generateXML(namespace, module, component, contentHandler, startIndent);
}
// end wrapper element
if (components.size() != 1) {
contentHandler.endElement("", ComponentDescriptorIO.COMPONENTS, ComponentDescriptorIO.COMPONENTS);
IOUtils.newline(contentHandler);
}
contentHandler.endPrefixMapping(PREFIX);
contentHandler.endDocument();
} finally {
fos.close();
}
}
use of org.apache.felix.scrplugin.helper.ComponentContainer in project felix by apache.
the class MetaTypeIO method write.
/**
* Generate the xml top level element and start streaming
* the meta data.
* @param metaData
* @param contentHandler
* @throws SAXException
*/
private static void write(final DescriptionContainer metaData, final List<ComponentContainer> components, final File file, final String localization) throws SCRDescriptorException {
final String namespace = detectMetatypeVersion(metaData);
try {
FileOutputStream fos = new FileOutputStream(file);
try {
final ContentHandler contentHandler = IOUtils.getSerializer(fos);
contentHandler.startDocument();
contentHandler.startPrefixMapping(PREFIX, namespace);
final AttributesImpl ai = new AttributesImpl();
IOUtils.addAttribute(ai, "localization", localization);
contentHandler.startElement(namespace, METADATA_ELEMENT, METADATA_ELEMENT_QNAME, ai);
IOUtils.newline(contentHandler);
for (final ComponentContainer comp : components) {
if (comp.getMetatypeContainer() != null) {
generateOCDXML(comp.getMetatypeContainer(), contentHandler);
generateDesignateXML(comp.getMetatypeContainer(), contentHandler);
}
}
// end wrapper element
contentHandler.endElement(namespace, METADATA_ELEMENT, METADATA_ELEMENT_QNAME);
IOUtils.newline(contentHandler);
contentHandler.endPrefixMapping(PREFIX);
contentHandler.endDocument();
} finally {
fos.close();
}
} catch (final IOException e) {
throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
} catch (final TransformerException e) {
throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
} catch (final SAXException e) {
throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
}
}
use of org.apache.felix.scrplugin.helper.ComponentContainer in project felix by apache.
the class ComponentDescriptorIO method generateDescriptorFiles.
/**
* Generate descriptor file(s)
*/
public static List<String> generateDescriptorFiles(final DescriptionContainer module, final Options options, final Log logger) throws SCRDescriptorException, SCRDescriptorFailureException {
// get the list of all relevant containers
final List<ComponentContainer> components = new ArrayList<ComponentContainer>();
for (final ComponentContainer container : module.getComponents()) {
if (!container.getComponentDescription().isCreateDs()) {
logger.debug("Ignoring descriptor for DS : " + container);
} else if (!container.getComponentDescription().isAbstract()) {
logger.debug("Adding descriptor for DS : " + container);
components.add(container);
}
}
// check descriptor file
final File descriptorDir = options.getComponentDescriptorDirectory();
// terminate if there is nothing else to write
if (components.isEmpty()) {
logger.debug("No Service Component Descriptors found in project.");
// remove files if it exists
if (descriptorDir.exists() && !options.isIncremental()) {
for (final File f : descriptorDir.listFiles()) {
if (f.isFile()) {
logger.debug("Removing obsolete service descriptor " + f);
f.delete();
}
}
}
return null;
}
// finally the descriptors have to be written ....
// ensure parent dir
descriptorDir.mkdirs();
final List<String> fileNames = new ArrayList<String>();
final List<ComponentContainerContainer> containers = ComponentContainerUtil.split(components);
for (final ComponentContainerContainer ccc : containers) {
final SpecVersion globalVersion = module.getOptions().getSpecVersion();
SpecVersion sv = null;
for (final ComponentContainer cc : ccc.components) {
if (sv == null || sv.ordinal() < cc.getComponentDescription().getSpecVersion().ordinal()) {
sv = cc.getComponentDescription().getSpecVersion();
}
}
module.getOptions().setSpecVersion(sv);
final File useFile = new File(descriptorDir, ccc.className + ".xml");
try {
ComponentDescriptorIO.generateXML(module, ccc.components, useFile, logger);
} catch (final IOException e) {
throw new SCRDescriptorException("Unable to generate xml", useFile.toString(), e);
} catch (final TransformerException e) {
throw new SCRDescriptorException("Unable to generate xml", useFile.toString(), e);
} catch (final SAXException e) {
throw new SCRDescriptorException("Unable to generate xml", useFile.toString(), e);
}
fileNames.add(PARENT_NAME + '/' + useFile.getName());
module.getOptions().setSpecVersion(globalVersion);
}
return fileNames;
}
Aggregations