Search in sources :

Example 6 with API

use of org.revapi.API in project revapi by revapi.

the class JavaArchiveAnalyzerTest method testTypeParametersDragIntoAPI.

@Test
public void testTypeParametersDragIntoAPI() throws Exception {
    ArchiveAndCompilationPath compRes = createCompiledJar("a.jar", "misc/Generics.java", "misc/GenericsParams.java");
    JavaArchive api = ShrinkWrap.create(JavaArchive.class, "api.jar").addAsResource(compRes.compilationPath.resolve("Generics.class").toFile(), "Generics.class");
    JavaArchive sup = ShrinkWrap.create(JavaArchive.class, "sup.jar").addAsResource(compRes.compilationPath.resolve("GenericsParams.class").toFile(), "GenericsParams.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeParam.class").toFile(), "GenericsParams$TypeParam.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$ExtendsBound.class").toFile(), "GenericsParams$ExtendsBound.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$SuperBound.class").toFile(), "GenericsParams$SuperBound.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVar.class").toFile(), "GenericsParams$TypeVar.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVarIface.class").toFile(), "GenericsParams$TypeVarIface.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$TypeVarImpl.class").toFile(), "GenericsParams$TypeVarImpl.class").addAsResource(compRes.compilationPath.resolve("GenericsParams$Unused.class").toFile(), "GenericsParams$Unused.class");
    JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(api)), Arrays.asList(new ShrinkwrapArchive(sup))), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
    try {
        JavaElementForest forest = analyzer.analyze();
        Set<TypeElement> roots = forest.getRoots();
        Assert.assertEquals(7, roots.size());
        Assert.assertTrue(roots.stream().anyMatch(hasName("class Generics<T extends GenericsParams.TypeVar, GenericsParams.TypeVarIface, U extends Generics<GenericsParams.TypeVarImpl, ?>>")));
        Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.ExtendsBound")));
        Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.SuperBound")));
        Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeParam")));
        Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeVar")));
        Assert.assertTrue(roots.stream().anyMatch(hasName("interface GenericsParams.TypeVarIface")));
        Assert.assertTrue(roots.stream().anyMatch(hasName("class GenericsParams.TypeVarImpl")));
        Assert.assertFalse(roots.stream().anyMatch(hasName("class GenericsParams.Unused")));
    } finally {
        deleteDir(compRes.compilationPath);
        analyzer.getCompilationValve().removeCompiledResults();
    }
}
Also used : JavaElementForest(org.revapi.java.model.JavaElementForest) TypeElement(org.revapi.java.model.TypeElement) API(org.revapi.API) JavaArchive(org.jboss.shrinkwrap.api.spec.JavaArchive) Test(org.junit.Test)

Example 7 with API

use of org.revapi.API in project revapi by revapi.

the class JavaArchiveAnalyzerTest method testPreventRecursionWhenConstructingInheritedMembers.

@Test
public void testPreventRecursionWhenConstructingInheritedMembers() throws Exception {
    ArchiveAndCompilationPath archive = createCompiledJar("a.jar", "misc/MemberInheritsOwner.java");
    JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(archive.archive)), null), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
    try {
        JavaElementForest forest = analyzer.analyze();
        forest.getRoots();
        Assert.assertEquals(1, forest.getRoots().size());
        Predicate<Element> findMethod = c -> "method void MemberInheritsOwner::method()".equals(c.getFullHumanReadableString());
        Predicate<Element> findMember1 = c -> "interface MemberInheritsOwner.Member1".equals(c.getFullHumanReadableString());
        Predicate<Element> findMember2 = c -> "interface MemberInheritsOwner.Member2".equals(c.getFullHumanReadableString());
        Element root = forest.getRoots().first();
        Assert.assertEquals(3, root.getChildren().size());
        Assert.assertTrue(root.getChildren().stream().anyMatch(findMethod));
        Assert.assertTrue(root.getChildren().stream().anyMatch(findMember1));
        Assert.assertTrue(root.getChildren().stream().anyMatch(findMember2));
        Assert.assertEquals(1, root.getChildren().stream().filter(findMember1).findFirst().get().getChildren().size());
        Assert.assertEquals(1, root.getChildren().stream().filter(findMember2).findFirst().get().getChildren().size());
    } finally {
        deleteDir(archive.compilationPath);
        analyzer.getCompilationValve().removeCompiledResults();
    }
}
Also used : API(org.revapi.API) Arrays(java.util.Arrays) ShrinkWrap(org.jboss.shrinkwrap.api.ShrinkWrap) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) TypeElement(org.revapi.java.model.TypeElement) Element(org.revapi.Element) Set(java.util.Set) JavaElementForest(org.revapi.java.model.JavaElementForest) IOException(java.io.IOException) Test(org.junit.Test) ZipExporter(org.jboss.shrinkwrap.api.exporter.ZipExporter) Executors(java.util.concurrent.Executors) JavaArchive(org.jboss.shrinkwrap.api.spec.JavaArchive) Archive(org.revapi.Archive) Assert(org.junit.Assert) Nonnull(javax.annotation.Nonnull) InclusionFilter(org.revapi.java.compilation.InclusionFilter) InputStream(java.io.InputStream) JavaElementForest(org.revapi.java.model.JavaElementForest) TypeElement(org.revapi.java.model.TypeElement) Element(org.revapi.Element) API(org.revapi.API) Test(org.junit.Test)

Example 8 with API

use of org.revapi.API in project revapi by revapi.

the class BuildTimeReporterTest method testJSONEscapedInIgnoreHint.

@Test
public void testJSONEscapedInIgnoreHint() {
    BuildTimeReporter reporter = new BuildTimeReporter();
    API oldApi = API.builder().build();
    API newApi = API.builder().build();
    AnalysisContext ctx = AnalysisContext.builder().withOldAPI(oldApi).withNewAPI(newApi).withData(BuildTimeReporter.BREAKING_SEVERITY_KEY, DifferenceSeverity.EQUIVALENT).build();
    reporter.initialize(ctx);
    Element oldEl = new SimpleElement() {

        @Nonnull
        @Override
        public API getApi() {
            return oldApi;
        }

        @Nullable
        @Override
        public Archive getArchive() {
            return null;
        }

        @Override
        public int compareTo(Element o) {
            return 0;
        }

        @Override
        public String toString() {
            return "old element";
        }
    };
    Element newEl = new SimpleElement() {

        @Nonnull
        @Override
        public API getApi() {
            return newApi;
        }

        @Nullable
        @Override
        public Archive getArchive() {
            return null;
        }

        @Override
        public int compareTo(Element o) {
            return 0;
        }

        @Override
        public String toString() {
            return "new element";
        }
    };
    Report report = Report.builder().withNew(newEl).withOld(oldEl).addProblem().withCode("diffs\\myDiff").withDescription("the problem").addClassification(CompatibilityType.BINARY, DifferenceSeverity.BREAKING).addAttachment("shouldBeEscaped", "{\"a\", \"b\"}").done().build();
    reporter.report(report);
    String resultMessage = reporter.getAllProblemsMessage();
    Assert.assertNotNull(resultMessage);
    int start = resultMessage.indexOf('{');
    int end = resultMessage.lastIndexOf('}');
    String json = resultMessage.substring(start, end + 1);
    json = json.replace("<<<<< ADD YOUR EXPLANATION FOR THE NECESSITY OF THIS CHANGE >>>>>", "\"\"");
    ModelNode parsed = ModelNode.fromJSONString(json);
    Assert.assertEquals("diffs\\myDiff", parsed.get("code").asString());
    Assert.assertEquals("{\"a\", \"b\"}", parsed.get("shouldBeEscaped").asString());
}
Also used : SimpleElement(org.revapi.simple.SimpleElement) Report(org.revapi.Report) Element(org.revapi.Element) SimpleElement(org.revapi.simple.SimpleElement) API(org.revapi.API) AnalysisContext(org.revapi.AnalysisContext) ModelNode(org.jboss.dmr.ModelNode) Test(org.junit.Test)

Example 9 with API

use of org.revapi.API in project revapi by revapi.

the class Analyzer method resolveArtifacts.

@SuppressWarnings("unchecked")
void resolveArtifacts() {
    if (resolvedOldApi == null) {
        final ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession, project.getRemoteProjectRepositories());
        Function<String, MavenArchive> toFileArchive = gav -> {
            try {
                Artifact a = resolveConstrained(project, gav, versionRegex, resolver);
                return MavenArchive.of(a);
            } catch (ArtifactResolutionException | VersionRangeResolutionException | IllegalArgumentException e) {
                throw new MarkerException(e.getMessage(), e);
            }
        };
        List<MavenArchive> oldArchives = new ArrayList<>(1);
        try {
            if (oldGavs != null) {
                oldArchives = Stream.of(oldGavs).map(toFileArchive).collect(toList());
            }
            if (oldArtifacts != null) {
                oldArchives.addAll(Stream.of(oldArtifacts).map(MavenArchive::of).collect(toList()));
            }
        } catch (MarkerException | IllegalArgumentException e) {
            String message = "Failed to resolve old artifacts: " + e.getMessage() + ".";
            if (failOnMissingArchives) {
                throw new IllegalStateException(message, e);
            } else {
                log.warn(message + " The API analysis will proceed comparing the new archives against an empty" + " archive.");
            }
        }
        List<MavenArchive> newArchives = new ArrayList<>(1);
        try {
            if (newGavs != null) {
                newArchives = Stream.of(newGavs).map(toFileArchive).collect(toList());
            }
            if (newArtifacts != null) {
                newArchives.addAll(Stream.of(newArtifacts).map(MavenArchive::of).collect(toList()));
            }
        } catch (MarkerException | IllegalArgumentException e) {
            String message = "Failed to resolve new artifacts: " + e.getMessage() + ".";
            if (failOnMissingArchives) {
                throw new IllegalStateException(message, e);
            } else {
                log.warn(message + " The API analysis will not proceed.");
                return;
            }
        }
        // now we need to be a little bit clever. When using RELEASE or LATEST as the version of the old artifact
        // it might happen that it gets resolved to the same version as the new artifacts - this notoriously happens
        // when releasing using the release plugin - you first build your artifacts, put them into the local repo
        // and then do the site updates for the released version. When you do the site, maven will find the released
        // version in the repo and resolve RELEASE to it. You compare it against what you just built, i.e. the same
        // code, et voila, the site report doesn't ever contain any found differences...
        Set<MavenArchive> oldTransitiveDeps = new HashSet<>();
        Set<MavenArchive> newTransitiveDeps = new HashSet<>();
        if (resolveDependencies) {
            String[] resolvedOld = oldArchives.stream().map(MavenArchive::getName).toArray(String[]::new);
            String[] resolvedNew = newArchives.stream().map(MavenArchive::getName).toArray(String[]::new);
            oldTransitiveDeps.addAll(collectDeps("old", resolver, resolvedOld));
            newTransitiveDeps.addAll(collectDeps("new", resolver, resolvedNew));
        }
        resolvedOldApi = API.of(oldArchives).supportedBy(oldTransitiveDeps).build();
        resolvedNewApi = API.of(newArchives).supportedBy(newTransitiveDeps).build();
    }
}
Also used : Arrays(java.util.Arrays) VersionRangeResolutionException(org.eclipse.aether.resolution.VersionRangeResolutionException) PlexusConfiguration(org.codehaus.plexus.configuration.PlexusConfiguration) XmlToJson(org.revapi.configuration.XmlToJson) MavenProject(org.apache.maven.project.MavenProject) Locale(java.util.Locale) Map(java.util.Map) ArtifactResolver(org.revapi.maven.utils.ArtifactResolver) API(org.revapi.API) RepositoryPolicy(org.eclipse.aether.repository.RepositoryPolicy) Set(java.util.Set) XmlPullParserException(org.codehaus.plexus.util.xml.pull.XmlPullParserException) Artifact(org.eclipse.aether.artifact.Artifact) AnalysisResult(org.revapi.AnalysisResult) Reader(java.io.Reader) Revapi(org.revapi.Revapi) FileNotFoundException(java.io.FileNotFoundException) ValidationResult(org.revapi.configuration.ValidationResult) List(java.util.List) Stream(java.util.stream.Stream) RepositoryUtils(org.apache.maven.RepositoryUtils) ScopeDependencyTraverser(org.revapi.maven.utils.ScopeDependencyTraverser) ModelNode(org.jboss.dmr.ModelNode) Pattern(java.util.regex.Pattern) Spliterator(java.util.Spliterator) RepositorySystem(org.eclipse.aether.RepositorySystem) Reporter(org.revapi.Reporter) XmlPlexusConfiguration(org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration) Xpp3DomBuilder(org.codehaus.plexus.util.xml.Xpp3DomBuilder) Function(java.util.function.Function) Supplier(java.util.function.Supplier) RepositorySystemSession(org.eclipse.aether.RepositorySystemSession) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Charset(java.nio.charset.Charset) StreamSupport(java.util.stream.StreamSupport) JSONUtil(org.revapi.configuration.JSONUtil) ArtifactResolutionException(org.eclipse.aether.resolution.ArtifactResolutionException) Iterator(java.util.Iterator) AnalysisContext(org.revapi.AnalysisContext) DefaultArtifact(org.eclipse.aether.artifact.DefaultArtifact) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) Log(org.apache.maven.plugin.logging.Log) InputStreamReader(java.io.InputStreamReader) File(java.io.File) DefaultRepositorySystemSession(org.eclipse.aether.DefaultRepositorySystemSession) Collectors.toList(java.util.stream.Collectors.toList) RepositoryException(org.eclipse.aether.RepositoryException) Collections(java.util.Collections) ScopeDependencySelector(org.revapi.maven.utils.ScopeDependencySelector) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) ArtifactResolver(org.revapi.maven.utils.ArtifactResolver) Artifact(org.eclipse.aether.artifact.Artifact) DefaultArtifact(org.eclipse.aether.artifact.DefaultArtifact) HashSet(java.util.HashSet)

Example 10 with API

use of org.revapi.API in project revapi by revapi.

the class JavaArchiveAnalyzerTest method testWithSupplementary.

@Test
public void testWithSupplementary() throws Exception {
    ArchiveAndCompilationPath compRes = createCompiledJar("a.jar", "v1/supplementary/a/A.java", "v1/supplementary/b/B.java", "v1/supplementary/a/C.java");
    JavaArchive api = ShrinkWrap.create(JavaArchive.class, "api.jar").addAsResource(compRes.compilationPath.resolve("A.class").toFile(), "A.class");
    JavaArchive sup = ShrinkWrap.create(JavaArchive.class, "sup.jar").addAsResource(compRes.compilationPath.resolve("B.class").toFile(), "B.class").addAsResource(compRes.compilationPath.resolve("B$T$1.class").toFile(), "B$T$1.class").addAsResource(compRes.compilationPath.resolve("B$T$1$TT$1.class").toFile(), "B$T$1$TT$1.class").addAsResource(compRes.compilationPath.resolve("B$T$2.class").toFile(), "B$T$2.class").addAsResource(compRes.compilationPath.resolve("C.class").toFile(), "C.class").addAsResource(compRes.compilationPath.resolve("B$UsedByIgnoredClass.class").toFile(), "B$UsedByIgnoredClass.class").addAsResource(compRes.compilationPath.resolve("A$PrivateEnum.class").toFile(), "A$PrivateEnum.class");
    JavaArchiveAnalyzer analyzer = new JavaArchiveAnalyzer(new API(Arrays.asList(new ShrinkwrapArchive(api)), Arrays.asList(new ShrinkwrapArchive(sup))), Executors.newSingleThreadExecutor(), null, false, InclusionFilter.acceptAll());
    try {
        JavaElementForest forest = analyzer.analyze();
        Assert.assertEquals(3, forest.getRoots().size());
        Iterator<TypeElement> roots = forest.getRoots().iterator();
        TypeElement A = roots.next();
        TypeElement B_T$1 = roots.next();
        TypeElement B_T$2 = roots.next();
        Assert.assertEquals("A", A.getCanonicalName());
        Assert.assertEquals("A", A.getDeclaringElement().getQualifiedName().toString());
        Assert.assertEquals("B.T$1", B_T$1.getCanonicalName());
        Assert.assertEquals("B.T$1", B_T$1.getDeclaringElement().getQualifiedName().toString());
        Assert.assertEquals("B.T$2", B_T$2.getCanonicalName());
        Assert.assertEquals("B.T$2", B_T$2.getDeclaringElement().getQualifiedName().toString());
    } finally {
        deleteDir(compRes.compilationPath);
        analyzer.getCompilationValve().removeCompiledResults();
    }
}
Also used : JavaElementForest(org.revapi.java.model.JavaElementForest) TypeElement(org.revapi.java.model.TypeElement) API(org.revapi.API) JavaArchive(org.jboss.shrinkwrap.api.spec.JavaArchive) Test(org.junit.Test)

Aggregations

API (org.revapi.API)10 AnalysisContext (org.revapi.AnalysisContext)5 Test (org.junit.Test)4 Element (org.revapi.Element)4 JavaElementForest (org.revapi.java.model.JavaElementForest)4 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 Iterator (java.util.Iterator)2 Set (java.util.Set)2 JavaArchive (org.jboss.shrinkwrap.api.spec.JavaArchive)2 Revapi (org.revapi.Revapi)2 TypeElement (org.revapi.java.model.TypeElement)2 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 AnnotatedElement (java.lang.reflect.AnnotatedElement)1