Java tutorial
/* * Copyright 2014 Bernd Vogt and others. * * Licensed 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.sourcepit.b2.p2; import static com.google.common.collect.Collections2.filter; import static org.sourcepit.b2.internal.maven.util.MavenDepenenciesUtils.removeDependencies; import static org.sourcepit.common.utils.lang.Exceptions.pipe; import static org.sourcepit.osgifier.maven.p2.BundleSelectorUtils.selectBundles; import java.io.File; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import javax.inject.Inject; import javax.inject.Named; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.model.Repository; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.project.MavenProject; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.sourcepit.b2.files.ModuleDirectory; import org.sourcepit.b2.generator.GeneratorType; import org.sourcepit.b2.generator.IB2GenerationParticipant; import org.sourcepit.b2.internal.generator.AbstractPomGenerator; import org.sourcepit.b2.internal.generator.ITemplates; import org.sourcepit.b2.model.interpolation.internal.module.ResolutionContextResolver; import org.sourcepit.b2.model.interpolation.layout.IInterpolationLayout; import org.sourcepit.b2.model.interpolation.layout.LayoutManager; import org.sourcepit.b2.model.interpolation.module.ModuleInterpolatorLifecycleParticipant; import org.sourcepit.b2.model.module.AbstractFacet; import org.sourcepit.b2.model.module.AbstractModule; import org.sourcepit.b2.model.module.ModuleModelFactory; import org.sourcepit.b2.model.module.PluginProject; import org.sourcepit.b2.model.module.PluginsFacet; import org.sourcepit.common.maven.model.ArtifactKey; import org.sourcepit.common.maven.model.MavenArtifact; import org.sourcepit.common.modeling.Annotatable; import org.sourcepit.common.utils.lang.ThrowablePipe; import org.sourcepit.common.utils.path.PathMatcher; import org.sourcepit.common.utils.props.PropertiesSource; import org.sourcepit.maven.dependency.model.DependencyModel; import org.sourcepit.osgifier.core.model.context.BundleCandidate; import org.sourcepit.osgifier.core.model.context.BundleReference; import org.sourcepit.osgifier.core.model.context.OsgifierContext; import org.sourcepit.osgifier.maven.p2.AbstractBundleTreeSelector; import org.sourcepit.osgifier.maven.p2.BundleSelector; import org.sourcepit.osgifier.maven.p2.P2UpdateSiteGenerator; import com.google.common.base.Predicate; import com.google.common.base.Strings; @Named public class MavenDependenciesSiteGenerator extends AbstractPomGenerator implements ModuleInterpolatorLifecycleParticipant, IB2GenerationParticipant { private Predicate<Dependency> JARS = new Predicate<Dependency>() { public boolean apply(Dependency dependency) { return "jar".equals(dependency.getType()); } }; @Inject private LegacySupport legacySupport; @Inject private P2UpdateSiteGenerator updateSiteGenerator; @Inject private LayoutManager layoutManager; public void preInterpolation(AbstractModule module, final PropertiesSource moduleProperties) { final MavenSession session = legacySupport.getSession(); final MavenProject project = session.getCurrentProject(); final List<Dependency> dependencies = new ArrayList<Dependency>(filter(project.getDependencies(), JARS)); if (!dependencies.isEmpty()) { final IInterpolationLayout layout = layoutManager.getLayout(module.getLayoutId()); final File siteDir = new File(layout.pathOfMetaDataFile(module, "maven-dependencies")); final String repositoryName = "maven-dependencies@" + project.getArtifactId(); final List<ArtifactRepository> remoteRepositories = project.getRemoteArtifactRepositories(); final ArtifactRepository localRepository = session.getLocalRepository(); final Date startTime = session.getStartTime(); final String pattern = moduleProperties.get("osgifier.updateSiteBundles"); final PathMatcher bundleMatcher = pattern == null ? null : PathMatcher.parsePackagePatterns(pattern); BundleSelector bundleSelector = new AbstractBundleTreeSelector() { @Override public Collection<BundleCandidate> selectRootBundles(OsgifierContext bundleContext) { final DependencyModel dependencyModel = bundleContext.getExtension(DependencyModel.class); final Map<ArtifactKey, BundleCandidate> artifactKeyToBundle = new HashMap<ArtifactKey, BundleCandidate>(); for (BundleCandidate bundle : bundleContext.getBundles()) { artifactKeyToBundle.put(getArtifactKey(bundle), bundle); } final List<BundleCandidate> rootBundles = new ArrayList<BundleCandidate>(); for (MavenArtifact artifact : dependencyModel.getRootArtifacts()) { final BundleCandidate rootBundle = artifactKeyToBundle.get(artifact.getArtifactKey()); if (rootBundle != null && select(rootBundle)) { rootBundles.add(rootBundle); } } return rootBundles; } private ArtifactKey getArtifactKey(BundleCandidate bundle) { return bundle.getExtension(MavenArtifact.class).getArtifactKey(); } @Override public boolean select(Stack<BundleCandidate> path, BundleReference reference) { return !reference.isOptional() && super.select(path, reference); } @Override protected boolean select(BundleCandidate bundle) { return bundleMatcher == null || bundleMatcher.isMatch(bundle.getSymbolicName()); } }; final OsgifierContext bundleContext = updateSiteGenerator.generateUpdateSite(siteDir, dependencies, true, remoteRepositories, localRepository, repositoryName, moduleProperties, startTime, bundleSelector); try { module.setAnnotationData("b2.mavenDependencies", "repositoryURL", siteDir.toURI().toURL().toExternalForm()); } catch (MalformedURLException e) { throw pipe(e); } module.setAnnotationData("b2.mavenDependencies", "repositoryName", repositoryName); final Collection<BundleCandidate> selectedBundles = new LinkedHashSet<BundleCandidate>(); selectBundles(selectedBundles, bundleContext, bundleSelector); interpolatePlugins(module, moduleProperties, selectedBundles); } } private static void interpolatePlugins(final AbstractModule module, PropertiesSource moduleProperties, Collection<BundleCandidate> selectedBundles) { ModuleModelFactory eFactory = ModuleModelFactory.eINSTANCE; PluginsFacet pluginsFacet = eFactory.createPluginsFacet(); pluginsFacet.setName(getFacetName(moduleProperties)); pluginsFacet.setDerived(true); PluginsFacet sourcesFacet = eFactory.createPluginsFacet(); sourcesFacet.setName(getSourcesFacetName(moduleProperties)); sourcesFacet.setDerived(true); if (pluginsFacet.getName().equals(sourcesFacet.getName())) { sourcesFacet = pluginsFacet; } for (BundleCandidate bundle : selectedBundles) { PluginProject pluginProject = eFactory.createPluginProject(); pluginProject.setDerived(true); pluginProject.setId(bundle.getSymbolicName()); pluginProject.setVersion(bundle.getVersion().toFullString()); pluginProject.setBundleManifest(EcoreUtil.copy(bundle.getManifest())); if (pluginProject.getBundleManifest().getHeader("Eclipse-SourceBundle") == null) { pluginsFacet.getProjects().add(pluginProject); } else { sourcesFacet.getProjects().add(pluginProject); } } if (!pluginsFacet.getProjects().isEmpty()) { module.getFacets().add(pluginsFacet); } if (sourcesFacet != pluginsFacet && !sourcesFacet.getProjects().isEmpty()) { module.getFacets().add(sourcesFacet); } } private static String getSourcesFacetName(PropertiesSource moduleProperties) { final String sourcesClassifier = moduleProperties.get("b2.featuresSourceClassifier", "sources"); final StringBuilder sb = new StringBuilder(); sb.append(getFacetName(moduleProperties)); if (!Strings.isNullOrEmpty(sourcesClassifier)) { sb.append('.'); sb.append(sourcesClassifier); } return sb.toString(); } private static String getFacetName(PropertiesSource moduleProperties) { return moduleProperties.get("b2.mavenDependenciesFacetName", "dependencies"); } @Inject private ResolutionContextResolver contextResolver; public void postInterpolation(AbstractModule module, PropertiesSource moduleProperties, ThrowablePipe errors) { final String repositoryURL = module.getAnnotationData("b2.mavenDependencies", "repositoryURL"); if (repositoryURL != null) { AbstractFacet facet = module.getFacetByName(getFacetName(moduleProperties)); if (facet != null) { module.getFacets().remove(facet); } facet = module.getFacetByName(getSourcesFacetName(moduleProperties)); if (facet != null) { module.getFacets().remove(facet); } } } @Override protected void generate(Annotatable inputElement, boolean skipFacets, PropertiesSource propertie, ITemplates templates, ModuleDirectory moduleDirectory) { if (inputElement instanceof AbstractModule) { final AbstractModule module = (AbstractModule) inputElement; final Set<AbstractModule> requiredModules = new LinkedHashSet<AbstractModule>(); requiredModules.add(module); requiredModules.addAll(contextResolver.resolveResolutionContext(module, false).keySet()); requiredModules.addAll(contextResolver.resolveResolutionContext(module, true).keySet()); final Set<File> projectDirs = new HashSet<File>(); for (MavenProject project : legacySupport.getSession().getProjects()) { projectDirs.add(project.getBasedir()); } for (AbstractModule requiredModule : requiredModules) { if (projectDirs.contains(requiredModule.getDirectory())) // only if in reactor { addMavenDependenciesRepository(module, requiredModule); } } } } private void addMavenDependenciesRepository(final AbstractModule module, AbstractModule requiredModule) { final String repositoryURL = requiredModule.getAnnotationData("b2.mavenDependencies", "repositoryURL"); if (repositoryURL != null) { final File pomFile = resolvePomFile(module); final Model pom = readMavenModel(pomFile); removeDependencies(pom, JARS); final String repositoryName = requiredModule.getAnnotationData("b2.mavenDependencies", "repositoryName"); final Repository repository = new Repository(); repository.setId(repositoryName); repository.setLayout("p2"); repository.setUrl(repositoryURL); pom.addRepository(repository); writeMavenModel(pomFile, pom); } } @Override protected void addInputTypes(Collection<Class<? extends EObject>> inputTypes) { inputTypes.add(AbstractModule.class); } @Override public GeneratorType getGeneratorType() { return GeneratorType.MODULE_RESOURCE_FILTER; } }