| /* |
| * Copyright 20012 The Apache Software Foundation. |
| * |
| * 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.apache.aries.versioning.mojo; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.aries.util.manifest.BundleManifest; |
| import org.apache.aries.versioning.check.BundleCompatibility; |
| import org.apache.aries.versioning.check.BundleInfo; |
| import org.apache.aries.versioning.check.VersionChange; |
| import org.apache.maven.artifact.Artifact; |
| import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; |
| import org.apache.maven.execution.MavenSession; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugins.annotations.Component; |
| import org.apache.maven.plugins.annotations.LifecyclePhase; |
| import org.apache.maven.plugins.annotations.Mojo; |
| import org.apache.maven.plugins.annotations.Parameter; |
| import org.apache.maven.project.MavenProject; |
| import org.apache.maven.repository.RepositorySystem; |
| import org.osgi.framework.Version; |
| |
| /** |
| * Check semantic version changes between an explicitly named old artifact and |
| * the project output artifact. Optionally write packageinfo files for wrong |
| * package versions. |
| */ |
| @Mojo(name = "version-check", defaultPhase = LifecyclePhase.VERIFY) |
| public class VersionCheckerMojo extends AbstractMojo { |
| |
| /** |
| * name of old artifact in |
| * groupId:artifactId[:extension[:classifier]]:version notation |
| */ |
| @Parameter(property="aries.oldArtifact") |
| private String oldArtifact; |
| |
| @Parameter(property="aries.skip.version.check", defaultValue = "false") |
| private boolean skip; |
| |
| /** |
| * Location of the file (defaults to main project artifact). |
| */ |
| @Parameter |
| private File newFile; |
| |
| /** |
| * whether to write packageinfo files into source tree |
| */ |
| @Parameter(property="writePackageInfos", defaultValue="false") |
| private boolean writePackageinfos = false; |
| |
| /** |
| * source tree location |
| */ |
| @Parameter(defaultValue="${project.basedir}/src/main/java") |
| private File source; |
| |
| @Parameter |
| private List<String> excludes; |
| |
| @Component |
| private RepositorySystem repository; |
| |
| @Component |
| protected MavenProject project; |
| |
| @Component |
| private MavenSession session; |
| |
| public void execute() throws MojoExecutionException { |
| if (skip) { |
| return; |
| } |
| if ("pom".equals(project.getPackaging())) { |
| return; |
| } |
| if (newFile == null) { |
| newFile = project.getArtifact().getFile(); |
| } |
| if (oldArtifact != null) { |
| try { |
| BundleInfo newBundle = getBundleInfo(newFile); |
| if (newBundle == null || newBundle.getBundleManifest() == null) { |
| //not a bundle type, just return |
| getLog().info(newFile + " is not an OSGi bundle, skipping."); |
| return; |
| } |
| if (null == newBundle.getBundleManifest().getManifestVersion() |
| && null == newBundle.getBundleManifest().getSymbolicName() |
| && Version.emptyVersion.equals(newBundle.getBundleManifest().getVersion())) { |
| //not a bundle type, just return |
| getLog().info(newFile + " is not an OSGi bundle, skipping."); |
| return; |
| } |
| |
| BundleInfo oldBundle = getBundleInfo(resolve(oldArtifact)); |
| String bundleSymbolicName = newBundle.getBundleManifest().getSymbolicName(); |
| URLClassLoader oldClassLoader = new URLClassLoader(new URL[] {oldBundle.getBundle().toURI() |
| .toURL()}); |
| URLClassLoader newClassLoader = new URLClassLoader(new URL[] {newBundle.getBundle().toURI() |
| .toURL()}); |
| BundleCompatibility bundleCompatibility = new BundleCompatibility(bundleSymbolicName, |
| newBundle, oldBundle, |
| oldClassLoader, |
| newClassLoader, |
| excludes); |
| bundleCompatibility.invoke(); |
| String bundleElement = bundleCompatibility.getBundleElement(); |
| String pkgElement = bundleCompatibility.getPkgElements().toString(); |
| |
| boolean failed = false; |
| if ((bundleElement != null) && (bundleElement.trim().length() > 0)) { |
| getLog().error(bundleElement + "\r\n"); |
| failed = true; |
| } |
| if ((pkgElement != null) && (pkgElement.trim().length() > 0)) { |
| getLog().error(pkgElement); |
| failed = true; |
| } |
| |
| if (writePackageinfos) { |
| writePackageInfos(bundleCompatibility); |
| } |
| if (failed) { |
| throw new RuntimeException("Semantic Versioning incorrect"); |
| } else { |
| getLog().info("All package or bundle versions are semanticly versioned correctly."); |
| } |
| } catch (MalformedURLException e) { |
| throw new MojoExecutionException("Problem analyzing sources"); |
| } catch (IOException e) { |
| throw new MojoExecutionException("Problem analyzing sources"); |
| } |
| } |
| } |
| |
| private void writePackageInfos(BundleCompatibility bundleCompatibility) { |
| Map<String, VersionChange> packages = bundleCompatibility.getPackageChanges(); |
| for (Map.Entry<String, VersionChange> packageChange : packages.entrySet()) { |
| VersionChange versionChange = packageChange.getValue(); |
| if (!versionChange.isCorrect()) { |
| String packageName = packageChange.getKey(); |
| String[] bits = packageName.split("\\."); |
| File packageInfo = source; |
| for (String bit : bits) { |
| packageInfo = new File(packageInfo, bit); |
| } |
| packageInfo.mkdirs(); |
| packageInfo = new File(packageInfo, "packageinfo"); |
| try { |
| FileWriter w = new FileWriter(packageInfo); |
| try { |
| w.append("# generated by Apache Aries semantic versioning tool\n"); |
| w.append("version " + versionChange.getRecommendedNewVersion().toString() + "\n"); |
| w.flush(); |
| } finally { |
| w.close(); |
| } |
| } catch (IOException e) { |
| getLog().error("Could not write packageinfo for package " + packageName, e); |
| } |
| } |
| } |
| } |
| |
| private File resolve(String artifactDescriptor) { |
| String[] s = artifactDescriptor.split(":"); |
| |
| String type = (s.length >= 4 ? s[3] : "jar"); |
| Artifact artifact = repository.createArtifact(s[0], s[1], s[2], type); |
| |
| ArtifactResolutionRequest request = new ArtifactResolutionRequest(); |
| request.setArtifact(artifact); |
| |
| request.setResolveRoot(true).setResolveTransitively(false); |
| request.setServers( session.getRequest().getServers() ); |
| request.setMirrors( session.getRequest().getMirrors() ); |
| request.setProxies( session.getRequest().getProxies() ); |
| request.setLocalRepository(session.getLocalRepository()); |
| request.setRemoteRepositories(session.getRequest().getRemoteRepositories()); |
| repository.resolve(request); |
| return artifact.getFile(); |
| } |
| |
| private BundleInfo getBundleInfo(File f) { |
| BundleManifest bundleManifest = BundleManifest.fromBundle(f); |
| return new BundleInfo(bundleManifest, f); |
| } |
| } |