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.osgifier.maven.p2; import static java.util.Collections.singletonList; import static org.apache.commons.io.FileUtils.copyFile; import static org.sourcepit.common.utils.file.FileUtils.deleteFileOrDirectory; import static org.sourcepit.common.utils.io.IO.buffOut; import static org.sourcepit.common.utils.io.IO.fileOut; import static org.sourcepit.common.utils.lang.Exceptions.pipe; import static org.sourcepit.osgifier.maven.p2.BundleSelectorUtils.selectBundles; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.LinkedHashSet; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.io.IOUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.model.Dependency; import org.apache.maven.project.MavenProject; import org.sourcepit.common.manifest.osgi.BundleManifest; import org.sourcepit.common.manifest.osgi.BundleSymbolicName; import org.sourcepit.common.utils.io.IOOperation; import org.sourcepit.common.utils.lang.Exceptions; import org.sourcepit.common.utils.path.PathMatcher; import org.sourcepit.common.utils.props.LinkedPropertiesMap; import org.sourcepit.common.utils.props.PropertiesSource; import org.sourcepit.osgifier.core.model.context.BundleCandidate; import org.sourcepit.osgifier.core.model.context.OsgifierContext; import org.sourcepit.osgifier.core.packaging.Repackager; import org.sourcepit.osgifier.maven.DefaultOsgifierContextInflatorFilter; import org.sourcepit.osgifier.maven.context.LegacyOsgifierModelBuilder; import org.sourcepit.osgifier.maven.context.LegacyOsgifierModelBuilder.NativeBundleStrategy; import org.sourcepit.osgifier.p2.P2Publisher; @Named public class P2UpdateSiteGenerator { public static final String OPTION_FORCE_MANIFEST_GENERATION = "forceManifestGeneration"; public static final String OPTION_COMPRESS_REPOSITORY = "compressRepository"; public static final String OPTION_FORKED_PROCESS_TIMEOUT_IN_SECONDS = "forkedProcessTimeoutInSeconds"; @Inject private LegacyOsgifierModelBuilder modelBuilder; @Inject private Repackager repackager; @Inject private P2Publisher p2Publisher; public OsgifierContext generateUpdateSite(File siteDir, MavenProject project, List<ArtifactRepository> remoteArtifactRepositories, ArtifactRepository localRepository, String repositoryName, PropertiesSource options) { return generateUpdateSite(siteDir, project.getArtifact(), remoteArtifactRepositories, localRepository, repositoryName, options); } public OsgifierContext generateUpdateSite(File siteDir, Artifact artifact, List<ArtifactRepository> remoteArtifactRepositories, ArtifactRepository localRepository, String repositoryName, PropertiesSource options) { final LegacyOsgifierModelBuilder.Request request = modelBuilder.createBundleRequest(artifact, Artifact.SCOPE_COMPILE, false, remoteArtifactRepositories, localRepository); return generateUpdateSite(request, siteDir, repositoryName, options == null ? new LinkedPropertiesMap() : options, BundleSelector.ALL); } @Inject private org.sourcepit.osgifier.maven.OsgifierModelBuilder modelBuilder2; public OsgifierContext generateUpdateSite(File siteDir, List<Dependency> dependencies, boolean includeSources, List<ArtifactRepository> remoteArtifactRepositories, ArtifactRepository localRepository, String repositoryName, PropertiesSource options, Date startTime, BundleSelector bundleSelector) { final OsgifierContext model = modelBuilder2.build(new DefaultOsgifierContextInflatorFilter(), options == null ? new LinkedPropertiesMap() : options, dependencies, startTime); final Collection<BundleCandidate> selectedBundles = new LinkedHashSet<BundleCandidate>(); selectBundles(selectedBundles, model, bundleSelector); final boolean compressRepository = options.getBoolean(OPTION_COMPRESS_REPOSITORY, true); final int forkedProcessTimeoutInSeconds = options.getInt(OPTION_FORKED_PROCESS_TIMEOUT_IN_SECONDS, 0); generateUpdateSite(selectedBundles, siteDir, repositoryName, compressRepository, forkedProcessTimeoutInSeconds); return model; } private OsgifierContext generateUpdateSite(final LegacyOsgifierModelBuilder.Request request, File siteDir, String repositoryName, PropertiesSource options, BundleSelector bundleSelector) { request.setNativeBundleStrategy(getNativeBundleStrategy(options)); final OsgifierContext bundleContext = modelBuilder.build(request); final Collection<BundleCandidate> selectedBundles = new LinkedHashSet<BundleCandidate>(); selectBundles(selectedBundles, bundleContext, bundleSelector); final boolean compressRepository = options.getBoolean(OPTION_COMPRESS_REPOSITORY, true); final int forkedProcessTimeoutInSeconds = options.getInt(OPTION_FORKED_PROCESS_TIMEOUT_IN_SECONDS, 0); generateUpdateSite(selectedBundles, siteDir, repositoryName, compressRepository, forkedProcessTimeoutInSeconds); return bundleContext; } private NativeBundleStrategy getNativeBundleStrategy(PropertiesSource options) { final String forceMfPatterns = options.get(OPTION_FORCE_MANIFEST_GENERATION); if (forceMfPatterns != null) { final PathMatcher matcher = PathMatcher.parse(forceMfPatterns, ".", ","); return new LegacyOsgifierModelBuilder.NativeBundleStrategy() { public boolean isNativeBundle(Artifact artifact, MavenProject project, BundleCandidate bundleCandidate) { final String symbolicName = getBundleSymbolicName(bundleCandidate); if (symbolicName != null && matcher.isMatch(symbolicName)) { return false; } return LegacyOsgifierModelBuilder.NativeBundleStrategy.DEFAULT.isNativeBundle(artifact, project, bundleCandidate); } private String getBundleSymbolicName(BundleCandidate bundleCandidate) { BundleManifest manifest = bundleCandidate.getManifest(); if (manifest != null) { BundleSymbolicName bundleSymbolicName = manifest.getBundleSymbolicName(); if (bundleSymbolicName != null) { return bundleSymbolicName.getSymbolicName(); } } return null; } }; } return LegacyOsgifierModelBuilder.NativeBundleStrategy.DEFAULT; } private void generateUpdateSite(Collection<BundleCandidate> bundles, File siteDir, String repositoryName, boolean compressRepository, int forkedProcessTimeoutInSeconds) { final File bundlesDir = getCleanDir(siteDir, "plugins"); copyJarsAndInjectManifests(bundles, bundlesDir); p2Publisher.publishBundles(siteDir, repositoryName, singletonList(bundlesDir), compressRepository, forkedProcessTimeoutInSeconds); final File categoryFile = new File(siteDir, "category.xml"); writeCategoryXml(categoryFile); p2Publisher.publishCategories(siteDir, categoryFile, compressRepository, forkedProcessTimeoutInSeconds); } private static void writeCategoryXml(File categoryFile) { final StringBuilder sb = new StringBuilder(); sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); sb.append("<site>\n"); sb.append(" <category-def name=\"all\" label=\"All Bundles\"/>\n"); sb.append(" <iu>\n"); sb.append(" <category name=\"all\"/>\n"); sb.append(" <query>\n"); sb.append( " <expression type=\"match\">providedCapabilities.exists(p | p.namespace == 'osgi.bundle')</expression>\n"); sb.append(" </query>\n"); sb.append(" </iu>\n"); sb.append("</site>\n"); new IOOperation<OutputStream>(buffOut(fileOut(categoryFile, true))) { @Override protected void run(OutputStream output) throws IOException { IOUtils.copy(new ByteArrayInputStream(sb.toString().getBytes("UTF-8")), output); } }.run(); } private List<File> copyJarsAndInjectManifests(Collection<BundleCandidate> bundles, final File workDir) { List<File> bundleJars = new ArrayList<File>(); for (BundleCandidate bundle : bundles) { final File bundleJar = new File(workDir, bundle.getSymbolicName() + "_" + bundle.getVersion().toFullString() + ".jar"); if (bundle.isNativeBundle()) { try { copyFile(bundle.getLocation(), bundleJar); } catch (IOException e) { throw pipe(e); } } else { repackager.copyJarAndInjectManifest(bundle.getLocation(), bundleJar, bundle.getManifest(), bundle.getLocalization()); } bundle.setLocation(bundleJar); bundleJars.add(bundleJar); } return bundleJars; } private static File getCleanDir(File workDir, String name) { final File siteDir = new File(workDir, name); if (siteDir.exists()) { try { deleteFileOrDirectory(siteDir); } catch (IOException e) { throw Exceptions.pipe(e); } } siteDir.mkdirs(); return siteDir; } }