blob: 09dc02a5b5b71c2ffa5e252e73e93170cd9de093 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.ipojo.bnd;
import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Resource;
import aQute.bnd.service.AnalyzerPlugin;
import aQute.bnd.service.Plugin;
import aQute.service.reporter.Reporter;
import org.apache.felix.ipojo.manipulator.ManipulationVisitor;
import org.apache.felix.ipojo.manipulator.Pojoization;
import org.apache.felix.ipojo.manipulator.ResourceStore;
import org.apache.felix.ipojo.manipulator.metadata.AnnotationMetadataProvider;
import org.apache.felix.ipojo.manipulator.metadata.CacheableMetadataProvider;
import org.apache.felix.ipojo.manipulator.metadata.CompositeMetadataProvider;
import org.apache.felix.ipojo.manipulator.metadata.FileMetadataProvider;
import org.apache.felix.ipojo.manipulator.util.Classpath;
import org.apache.felix.ipojo.manipulator.visitor.check.CheckFieldConsistencyVisitor;
import org.apache.felix.ipojo.manipulator.visitor.writer.ManipulatedResourcesWriter;
import org.apache.felix.ipojo.metadata.Element;
import java.io.File;
import java.util.*;
/**
* A {@code BndIpojoPlugin} is ...
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class PojoizationPlugin implements Plugin, AnalyzerPlugin {
private static final String PROPERTY_METADATA = "metadata";
private static final String PROPERTY_USE_LOCAL_SCHEMAS = "use-local-schemas";
private static final String PROPERTY_INCLUDE_EMBED_BUNDLES = "include-embed-bundles";
private static final String DEFAULT_METADATA = "META-INF/metadata.xml";
private static final boolean DEFAULT_USE_LOCAL_SCHEMAS = false;
private static final boolean DEFAULT_INCLUDE_EMBED_BUNDLES = false;
private String m_metadata = DEFAULT_METADATA;
private boolean m_useLocalSchemas = DEFAULT_USE_LOCAL_SCHEMAS;
private boolean m_includeEmbedBundles = DEFAULT_INCLUDE_EMBED_BUNDLES;
private Reporter m_reporter;
public void setProperties(Map<String, String> configuration) {
// Use metadata file if any
if (configuration.containsKey(PROPERTY_METADATA)) {
m_metadata = configuration.get(PROPERTY_METADATA);
}
// Use local schemas ?
if (configuration.containsKey(PROPERTY_USE_LOCAL_SCHEMAS)) {
m_useLocalSchemas = true;
}
// Process embed bundles ?
if (configuration.containsKey(PROPERTY_INCLUDE_EMBED_BUNDLES)) {
m_includeEmbedBundles = true;
}
}
public void setReporter(Reporter reporter) {
m_reporter = reporter;
}
public boolean analyzeJar(Analyzer analyzer) throws Exception {
long start = System.currentTimeMillis();
// Wraps the Bnd Reporter
BndReporter reporter = new BndReporter(this.m_reporter);
// Build ResourceStore
BndJarResourceStore store = new BndJarResourceStore(analyzer, this.m_reporter);
store.setIncludeEmbedComponents(m_includeEmbedBundles);
CompositeMetadataProvider provider = buildMetadataProvider(analyzer, reporter, store);
// Quick exit
CacheableMetadataProvider cache = new CacheableMetadataProvider(provider);
if (cache.getMetadatas().isEmpty() && !hasEmbedComponents(analyzer)) {
return false;
}
// Compute the classpath to build the classloader.
List<Jar> jars = analyzer.getClasspath();
Jar jar = analyzer.getJar();
Set<String> paths = new LinkedHashSet<String>();
if (jar != null && jar.getSource() != null) {
paths.add(jar.getSource().getAbsolutePath());
}
for (Jar j : jars) {
if (j.getSource() != null) {
paths.add(j.getSource().getAbsolutePath());
}
}
Classpath cp = new Classpath(paths);
manipulateComponents(reporter, store, cache, cp.createClassLoader());
int nbComponents = findElements(cache.getMetadatas(), "component").size();
int nbHandlers = findElements(cache.getMetadatas(), "handler").size();
this.m_reporter.trace("iPOJO manipulation performed performed in %s ms (%d components, %d handlers).",
(System.currentTimeMillis() - start),
nbComponents,
nbHandlers);
// Return true if a new run should be performed after the analyze
return false;
}
protected void manipulateComponents(BndReporter reporter, BndJarResourceStore store,
CacheableMetadataProvider cache, ClassLoader classLoader) {
Pojoization pojoization = new Pojoization(reporter);
pojoization.disableAnnotationProcessing();
if (m_useLocalSchemas) {
pojoization.setUseLocalXSD();
}
pojoization.pojoization(store, cache, createVisitor(store, reporter), classLoader);
}
protected CompositeMetadataProvider buildMetadataProvider(Analyzer analyzer, BndReporter reporter, BndJarResourceStore store) {
// Build MetadataProvider
CompositeMetadataProvider provider = new CompositeMetadataProvider(reporter);
File file = new File(m_metadata);
if (file.exists()) {
// Absolute file system resource
FileMetadataProvider fmp = new FileMetadataProvider(file, reporter);
fmp.setValidateUsingLocalSchemas(m_useLocalSchemas);
provider.addMetadataProvider(fmp);
} else {
// In archive resource
Resource resource = analyzer.getJar().getResource(m_metadata);
if (resource != null) {
ResourceMetadataProvider rmp = new ResourceMetadataProvider(resource, reporter);
rmp.setValidateUsingLocalSchemas(m_useLocalSchemas);
provider.addMetadataProvider(rmp);
}
}
provider.addMetadataProvider(new AnnotationMetadataProvider(store, reporter));
return provider;
}
private boolean hasEmbedComponents(Analyzer analyzer) throws Exception {
// We want to process components from embed jars ?
return m_includeEmbedBundles && Manifests.hasEmbedComponents(analyzer);
}
private List<Element> findElements(List<Element> metadatas, String name) {
List<Element> found = new ArrayList<Element>();
for (Element element : metadatas) {
if (name.equalsIgnoreCase(element.getName())) {
found.add(element);
}
}
return found;
}
protected ManipulationVisitor createVisitor(ResourceStore store, BndReporter reporter) {
ManipulatedResourcesWriter writer = new ManipulatedResourcesWriter();
writer.setReporter(reporter);
writer.setResourceStore(store);
CheckFieldConsistencyVisitor checkFieldConsistencyVisitor = new CheckFieldConsistencyVisitor(writer);
checkFieldConsistencyVisitor.setReporter(reporter);
return checkFieldConsistencyVisitor;
}
}