From 690c815f32dcf0171cde0440f5293a7432401010 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Fri, 28 Feb 2025 15:09:11 -0300 Subject: [PATCH 1/3] build: set version to 4.3.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2738292..7a9ad7d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.flowingcode.vaadin.addons.demo commons-demo - 4.2.1-SNAPSHOT + 4.3.0-SNAPSHOT Commons Demo Common classes for add-ons demo From fb0f250f53bca81f56076a32d212f52d7d3842a2 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Fri, 28 Feb 2025 15:11:38 -0300 Subject: [PATCH 2/3] feat: use DEFAULT_VALUE instead of GITHUB_SOURCE --- .../java/com/flowingcode/vaadin/addons/demo/DemoSource.java | 4 +++- .../java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java b/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java index 32fa014..e9d45af 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java +++ b/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java @@ -43,6 +43,8 @@ @Target(ElementType.TYPE) public @interface DemoSource { + /** @deprecated. Use {@link #DEFAULT_VALUE} */ + @Deprecated static final String GITHUB_SOURCE = "__GITHUB__"; static final String DEFAULT_VALUE = "__DEFAULT__"; @@ -52,7 +54,7 @@ *

* It is an error if both {@code value} and {@link #clazz()} are specified. */ - String value() default GITHUB_SOURCE; + String value() default DEFAULT_VALUE; /** * The class to display, if different from the annotated class. diff --git a/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java b/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java index 5e775bb..fffd7d3 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java +++ b/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java @@ -235,7 +235,7 @@ public void showRouterLayoutContent(HasElement content) { private Optional createSourceCodeTab(Class annotatedClass, DemoSource annotation) { String demoFile; String url = annotation.value(); - if (url.equals(DemoSource.GITHUB_SOURCE)) { + if (url.equals(DemoSource.GITHUB_SOURCE) || url.equals(DemoSource.DEFAULT_VALUE)) { String className; if (annotation.clazz() == DemoSource.class) { className = annotatedClass.getName().replace('.', '/'); From 308eddddec6666b066092278468c25a5d80ffa15 Mon Sep 17 00:00:00 2001 From: Javier Godoy <11554739+javier-godoy@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:08:07 -0300 Subject: [PATCH 3/3] feat: add support for customizable demo URL resolution --- .../addons/demo/DefaultSourceUrlResolver.java | 49 +++++++++++++++++++ .../vaadin/addons/demo/DemoSource.java | 3 ++ .../vaadin/addons/demo/SourceUrlResolver.java | 23 +++++++++ .../vaadin/addons/demo/TabbedDemo.java | 48 +++++++++--------- 4 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/demo/DefaultSourceUrlResolver.java create mode 100644 src/main/java/com/flowingcode/vaadin/addons/demo/SourceUrlResolver.java diff --git a/src/main/java/com/flowingcode/vaadin/addons/demo/DefaultSourceUrlResolver.java b/src/main/java/com/flowingcode/vaadin/addons/demo/DefaultSourceUrlResolver.java new file mode 100644 index 0000000..cc1100a --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/demo/DefaultSourceUrlResolver.java @@ -0,0 +1,49 @@ +package com.flowingcode.vaadin.addons.demo; + +import com.flowingcode.vaadin.addons.GithubBranch; +import com.flowingcode.vaadin.addons.GithubLink; +import java.util.Optional; + +/** + * Implementation of {@code SourceUrlResolver}. + *

+ * If no {@code value} or {@code clazz} is specified, and the demo view is annotated with + * {@link GithubLink}, then the source URL defaults to the location of the annotated class under + * {@code src/test/java} and the branch is determined from the value of {@link GithubBranch} in the + * demo view class (if the annotation is present) or the containing package of the demo view class. + * If the source URL is defaulted and no {@code GithubBranch} annotation is present either in the + * demo view class or its containing package, then the branch defaults to {@code master}. + * + * @author Javier Godoy / Flowing Code + */ +class DefaultSourceUrlResolver implements SourceUrlResolver { + + @Override + public Optional resolveURL(TabbedDemo demo, Class annotatedClass, + DemoSource annotation) { + String demoFile; + String url = annotation.value(); + if (url.equals(DemoSource.GITHUB_SOURCE) || url.equals(DemoSource.DEFAULT_VALUE)) { + String className; + if (annotation.clazz() == DemoSource.class) { + className = annotatedClass.getName().replace('.', '/'); + } else { + className = annotation.clazz().getName().replace('.', '/'); + } + demoFile = "src/test/java/" + className + ".java"; + } else if (url.startsWith("/src/test/")) { + demoFile = url.substring(1); + } else { + demoFile = null; + } + + if (demoFile != null) { + String branch = TabbedDemo.lookupGithubBranch(demo.getClass()); + return Optional.ofNullable(demo.getClass().getAnnotation(GithubLink.class)) + .map(githubLink -> String.format("%s/blob/%s/%s", githubLink.value(), branch, demoFile)); + } else { + return Optional.empty(); + } + } + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java b/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java index e9d45af..81410ab 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java +++ b/src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java @@ -36,7 +36,10 @@ * defaulted and no {@code GithubBranch} annotation is present either in the demo view class or its * containing package, then the branch defaults to {@code master}. * + * This behavior can be globally overridden by configuring a {@link SourceUrlResolver}. + * * @author Javier Godoy / Flowing Code + * @see TabbedDemo#configureSourceUrlResolver(SourceUrlResolver) */ @Repeatable(DemoSources.class) @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/com/flowingcode/vaadin/addons/demo/SourceUrlResolver.java b/src/main/java/com/flowingcode/vaadin/addons/demo/SourceUrlResolver.java new file mode 100644 index 0000000..3e3644b --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/demo/SourceUrlResolver.java @@ -0,0 +1,23 @@ +package com.flowingcode.vaadin.addons.demo; + +import java.util.Optional; + +/** + * Interface for resolving the source URL of a demo class. + * + * @author Javier Godoy / Flowing Code + */ +public interface SourceUrlResolver { + + /** + * Resolves the source URL for a given demo class and annotation. + * + * @param demo The {@link TabbedDemo} instance associated with the source. + * @param annotatedClass The class that is annotated with {@link DemoSource}. + * @param annotation The {@link DemoSource} annotation providing source metadata. + * @return An {@link Optional} containing the resolved URL if available, otherwise an empty + * {@link Optional}. + */ + Optional resolveURL(TabbedDemo demo, Class annotatedClass, DemoSource annotation); + +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java b/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java index fffd7d3..df5cc59 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java +++ b/src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java @@ -20,7 +20,6 @@ package com.flowingcode.vaadin.addons.demo; import com.flowingcode.vaadin.addons.GithubBranch; -import com.flowingcode.vaadin.addons.GithubLink; import com.vaadin.flow.component.AttachEvent; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEventListener; @@ -45,6 +44,7 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; +import lombok.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -232,31 +232,33 @@ public void showRouterLayoutContent(HasElement content) { applyTheme(getElement(), getThemeName()); } - private Optional createSourceCodeTab(Class annotatedClass, DemoSource annotation) { - String demoFile; - String url = annotation.value(); - if (url.equals(DemoSource.GITHUB_SOURCE) || url.equals(DemoSource.DEFAULT_VALUE)) { - String className; - if (annotation.clazz() == DemoSource.class) { - className = annotatedClass.getName().replace('.', '/'); - } else { - className = annotation.clazz().getName().replace('.', '/'); - } - demoFile = "src/test/java/" + className + ".java"; - } else if (url.startsWith("/src/test/")) { - demoFile = url.substring(1); - } else { - demoFile = null; + private static SourceUrlResolver resolver = null; + + /** + * Configures the {@code SourceUrlResolver} for resolving source URLs. This method can only be + * called once; subsequent calls will result in an exception. + * + * @param resolver The {@code SourceUrlResolver} to be used. Must not be {@code null}. + * @throws IllegalStateException if a resolver has already been set. + * @throws NullPointerException if the provided {@code resolver} is {@code null}. + */ + public static void configureSourceUrlResolver(@NonNull SourceUrlResolver resolver) { + if (TabbedDemo.resolver != null) { + throw new IllegalStateException(); } + TabbedDemo.resolver = resolver; + } - if (demoFile != null) { - String branch = lookupGithubBranch(this.getClass()); - url = Optional.ofNullable(this.getClass().getAnnotation(GithubLink.class)) - .map(githubLink -> String.format("%s/blob/%s/%s", githubLink.value(), - branch, demoFile)) - .orElse(null); + private static SourceUrlResolver getResolver() { + if (resolver == null) { + resolver = new DefaultSourceUrlResolver(); } - + return resolver; + } + + private Optional createSourceCodeTab(Class annotatedClass, DemoSource annotation) { + String url = getResolver().resolveURL(this, annotatedClass, annotation).orElse(null); + if (url==null) { return Optional.empty(); }