From 6246e6a68829e471b68ee45988257a8f7920d6f8 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Tue, 9 May 2023 18:28:16 -0400 Subject: [PATCH 01/13] checkpointing --- examples/pico/README.md | 11 +++ examples/pico/basics/README.md | 35 +++++++ examples/pico/basics/pom.xml | 88 +++++++++++++++++ .../io/helidon/examples/pico/basics/Big.java | 31 ++++++ .../examples/pico/basics/BigHammer.java | 30 ++++++ .../helidon/examples/pico/basics/Hammer.java | 44 +++++++++ .../helidon/examples/pico/basics/Little.java | 30 ++++++ .../examples/pico/basics/LittleHammer.java | 30 ++++++ .../io/helidon/examples/pico/basics/Main.java | 65 ++++++++++++ .../io/helidon/examples/pico/basics/Tool.java | 34 +++++++ .../helidon/examples/pico/basics/ToolBox.java | 98 +++++++++++++++++++ .../examples/pico/basics/package-info.java | 20 ++++ .../src/main/resources/logging.properties | 26 +++++ examples/pico/pom.xml | 40 ++++++++ examples/pico/providers/README.md | 40 ++++++++ examples/pico/providers/pom.xml | 95 ++++++++++++++++++ .../pico/providers/AngleGrinderSaw.java | 56 +++++++++++ .../examples/pico/providers/Blade.java | 29 ++++++ .../pico/providers/BladeProvider.java | 78 +++++++++++++++ .../examples/pico/providers/CircularSaw.java | 49 ++++++++++ .../examples/pico/providers/HandSaw.java | 47 +++++++++ .../helidon/examples/pico/providers/Main.java | 24 +++++ .../helidon/examples/pico/providers/Nail.java | 29 ++++++ .../examples/pico/providers/NailGun.java | 55 +++++++++++ .../examples/pico/providers/NailProvider.java | 41 ++++++++ .../helidon/examples/pico/providers/Saw.java | 29 ++++++ .../examples/pico/providers/SizedBlade.java | 47 +++++++++ .../examples/pico/providers/StandardNail.java | 34 +++++++ .../examples/pico/providers/TableSaw.java | 50 ++++++++++ .../src/main/resources/logging.properties | 26 +++++ .../examples/pico/providers/AllenWrench.java | 30 ++++++ .../pico/providers/ProvidersTest.java | 32 ++++++ .../examples/pico/providers/Wrench.java | 23 +++++ examples/pom.xml | 1 + 34 files changed, 1397 insertions(+) create mode 100644 examples/pico/README.md create mode 100644 examples/pico/basics/README.md create mode 100644 examples/pico/basics/pom.xml create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Big.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/BigHammer.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Hammer.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Little.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/LittleHammer.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Tool.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java create mode 100644 examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/package-info.java create mode 100644 examples/pico/basics/src/main/resources/logging.properties create mode 100644 examples/pico/pom.xml create mode 100644 examples/pico/providers/README.md create mode 100644 examples/pico/providers/pom.xml create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Blade.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/BladeProvider.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/CircularSaw.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/HandSaw.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Nail.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailGun.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailProvider.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Saw.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/StandardNail.java create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/TableSaw.java create mode 100644 examples/pico/providers/src/main/resources/logging.properties create mode 100644 examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/AllenWrench.java create mode 100644 examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java create mode 100644 examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/Wrench.java diff --git a/examples/pico/README.md b/examples/pico/README.md new file mode 100644 index 00000000000..906826a9849 --- /dev/null +++ b/examples/pico/README.md @@ -0,0 +1,11 @@ + +# Helidon Pico Examples + +Each subdirectory contains example code that highlights specific aspects of +Helidon Pico. + +Suggested path to follow: +1. [basics](./basics) +2. [providers](./providers) +3. [configdriven](./configdriven) +4. [application](./application) diff --git a/examples/pico/basics/README.md b/examples/pico/basics/README.md new file mode 100644 index 00000000000..f2105b9eb20 --- /dev/null +++ b/examples/pico/basics/README.md @@ -0,0 +1,35 @@ +# Helidon Pico Basic Example + +This example shows the basics of using Helidon Pico. The +[Main.java](./src/main/java/io/helidon/examples/pico/basics/Main.java) class shows: + +* programmatic lookup of services in Pico's Services registry in [Main](./src/main/java/io/helidon/examples/pico/basics/Main.java). +* declarative injection in [ToolBox.java](./src/main/java/io/helidon/examples/pico/basics/ToolBox.java). +* lifecycle via PostConstruct and RunLevel in [Main](./src/main/java/io/helidon/examples/pico/basics/Main.java). +* annotation processing and source code generation (see [pom.xml](pom.xml) and [generated-sources](./target/generated-sources/annotations/io/helidon/examples/pico/basics)). + +## Build and run + +```bash +mvn package +java -jar target/helidon-examples-pico-basics.jar +``` + +Expected Output: +``` +Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT] +Highest weighted service provider: ToolBox:INIT +----- +Preferred Big Tool: Big Hammer +Optional Little Hammer: Optional[Little Hammer] +----- +ToolBox Contents: +Hammer:INIT +BigHammer:ACTIVE +LittleHammer:ACTIVE +----- +Highest weighted service provider (after activation): ToolBox +----- +All service providers (after all activations): [ToolBox:ACTIVE] +----- +``` diff --git a/examples/pico/basics/pom.xml b/examples/pico/basics/pom.xml new file mode 100644 index 00000000000..79dff56a637 --- /dev/null +++ b/examples/pico/basics/pom.xml @@ -0,0 +1,88 @@ + + + + + 4.0.0 + + io.helidon.applications + helidon-se + 4.0.0-SNAPSHOT + ../../../applications/se/pom.xml + + io.helidon.examples.pico + helidon-examples-pico-basics + Helidon Pico Examples Basics + + + Examples of programmatic and declarative usages of Pico. + + + + io.helidon.examples.pico.basics.Main + + + + + io.helidon.pico + helidon-pico-api + + + io.helidon.pico + helidon-pico-runtime + + + jakarta.annotation + jakarta.annotation-api + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -Apico.autoAddNonContractInterfaces=false + -Apico.debug=false + + true + + + io.helidon.pico + helidon-pico-processor + ${helidon.version} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + + diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Big.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Big.java new file mode 100644 index 00000000000..974cb24d366 --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Big.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import jakarta.inject.Qualifier; + +/** + * Custom annotation. + */ +@Qualifier +@Retention(RetentionPolicy.CLASS) +public @interface Big { + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/BigHammer.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/BigHammer.java new file mode 100644 index 00000000000..39b3411f8dd --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/BigHammer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import jakarta.inject.Singleton; + +@Big +@Singleton +class BigHammer extends Hammer { + + @Override + public String name() { + return "Big " + super.name(); + } + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Hammer.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Hammer.java new file mode 100644 index 00000000000..74b48ad093c --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Hammer.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import io.helidon.common.Weight; +import io.helidon.common.Weighted; + +import jakarta.inject.Singleton; + +/** + * By adding the {@link Singleton} annotation results in Hammer becoming a Pico service. Services can be looked up + * programmatically or declaratively injected via {@link jakarta.inject.Inject}. + *

+ * Here {@link Weight} is used that is higher than the default, making it more preferred in weighted rankings. + */ +@Singleton +@Weight(Weighted.DEFAULT_WEIGHT + 1) +class Hammer implements Tool { + + @Override + public String name() { + return "Hammer"; + } + + @Override + public String toString() { + return name(); + } + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Little.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Little.java new file mode 100644 index 00000000000..3d2b75b8da7 --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Little.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import jakarta.inject.Qualifier; + +/** + * Custom annotation. + */ +@Qualifier +@Retention(RetentionPolicy.CLASS) +public @interface Little { +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/LittleHammer.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/LittleHammer.java new file mode 100644 index 00000000000..7facc0ac59e --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/LittleHammer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import jakarta.inject.Singleton; + +@Little +@Singleton +class LittleHammer extends Hammer { + + @Override + public String name() { + return "Little " + super.name(); + } + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java new file mode 100644 index 00000000000..4f7a8f6d879 --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import java.util.List; + +import io.helidon.pico.api.PicoServices; +import io.helidon.pico.api.RunLevel; +import io.helidon.pico.api.ServiceInfoCriteria; +import io.helidon.pico.api.ServiceInfoCriteriaDefault; +import io.helidon.pico.api.ServiceProvider; +import io.helidon.pico.api.Services; + +/** + * Basics example. + */ +public class Main { + + /** + * Executes the example. + * + * @param args arguments + */ + public static void main(String... args) { + Services services = PicoServices.realizedServices(); + + // 0. Demonstrates programmatic lookup from Pico's Services registry. + // 1. when a service is being managed by a DI provider (like Pico) it should be "looked up" or injected instead of new'ed + // 2. Notice we get a ServiceProvider - service providers allow for lazy initialization + ServiceInfoCriteria criteria = ServiceInfoCriteriaDefault.builder() + .runLevel(RunLevel.STARTUP) + .build(); + + List> startupServiceProviders = services.lookupAll(criteria); + System.out.println("Startup service providers (ranked according to weight, pre-activated): " + startupServiceProviders); + + ServiceProvider highestWeightedServiceProvider = services.lookupFirst(criteria); + System.out.println("Highest weighted service provider: " + highestWeightedServiceProvider); + System.out.println("-----"); + + // trigger lazy activations for the highest weighted service provider + System.out.println("Highest weighted service provider (after activation): " + highestWeightedServiceProvider.get()); + System.out.println("-----"); + + // trigger all activations for the (remaining unactivated) startup service providers + startupServiceProviders.forEach(ServiceProvider::get); + System.out.println("All service providers (after all activations): " + startupServiceProviders); + System.out.println("-----"); + } + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Tool.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Tool.java new file mode 100644 index 00000000000..339ae70d629 --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Tool.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import io.helidon.pico.api.Contract; + +/** + * An example Tool interface contract. + */ +@Contract +public interface Tool { + + /** + * The name of the tool. + * + * @return name of the tool + */ + String name(); + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java new file mode 100644 index 00000000000..3729cb51c69 --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.basics; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import io.helidon.common.Weight; +import io.helidon.common.Weighted; +import io.helidon.pico.api.RunLevel; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import jakarta.inject.Singleton; + +/** + * By adding the {@link Singleton} annotation results in ToolBox becoming a Pico service. Services can be looked up + * programmatically or declaratively injected via {@link jakarta.inject.Inject}. + *

+ * Here {@link Weight} is used that is higher than the default, making it more preferred in weighted rankings. + */ +@Singleton +@RunLevel(RunLevel.STARTUP) +@Weight(Weighted.DEFAULT_WEIGHT + 1) +public class ToolBox { + + private final List> allToolProviders; + private Tool preferredBigTool; + + // Pico field injection is supported for non-static, non-private methods (but not recommended) + // Here we are using it to also showcase for Optional usages. + @Inject Optional optionalLittleHammer; + + /** + * Here the constructor injects all {@link Tool} provider instances available. {@link Provider} is used to allow lazy + * activation of services until {@link Provider#get()} is called. + * + * @param allToolProviders all tool providers + */ + @Inject + ToolBox(List> allToolProviders) { + this.allToolProviders = Objects.requireNonNull(allToolProviders); + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } + + /** + * Example of setter based injection. + * + * @param preferredBigTool the preferred big tool + */ + @Inject + @SuppressWarnings("unused") + void setPreferredBigTool(@Big Tool preferredBigTool) { + this.preferredBigTool = Objects.requireNonNull(preferredBigTool); + } + + /** + * This method will be called by Pico after this instance is lazily initialized (because this is the {@link PostConstruct} + * method). + */ + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println("Preferred Big Tool: " + preferredBigTool); + System.out.println("Optional Little Hammer: " + optionalLittleHammer); + System.out.println("-----"); + System.out.println("ToolBox Contents:"); + printToolBoxContents(); + System.out.println("-----"); + } + + void printToolBoxContents() { + for (Provider tool : allToolProviders) { + System.out.println(tool); + } + } + +} diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/package-info.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/package-info.java new file mode 100644 index 00000000000..92acf790e40 --- /dev/null +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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. + */ + +/** + * Examples of programmatic and declarative usages of Pico. + */ +package io.helidon.examples.pico.basics; diff --git a/examples/pico/basics/src/main/resources/logging.properties b/examples/pico/basics/src/main/resources/logging.properties new file mode 100644 index 00000000000..bd06e0ed087 --- /dev/null +++ b/examples/pico/basics/src/main/resources/logging.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# 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. +# + + +handlers = java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = FINEST +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n + +.level = INFO +io.helidon.config.level = WARNING +io.helidon.config.examples.level = FINEST diff --git a/examples/pico/pom.xml b/examples/pico/pom.xml new file mode 100644 index 00000000000..72e7c7a2fd2 --- /dev/null +++ b/examples/pico/pom.xml @@ -0,0 +1,40 @@ + + + + + 4.0.0 + + io.helidon.examples + helidon-examples-project + 4.0.0-SNAPSHOT + + io.helidon.examples.pico + helidon-examples-pico-project + pom + Helidon Pico Examples + + + basics + providers + + + + + diff --git a/examples/pico/providers/README.md b/examples/pico/providers/README.md new file mode 100644 index 00000000000..404d925524c --- /dev/null +++ b/examples/pico/providers/README.md @@ -0,0 +1,40 @@ +# Helidon Pico Providers Example + +This example shows how providers can be leveraged to develop using Helidon Pico. The +[Main.java](./src/main/java/io/helidon/examples/pico/providers/Main.java) class shows: + +* programmatic lookup of services in Pico's Services registry in [Main](./src/main/java/io/helidon/examples/pico/basics/Main.java). +* declarative injection in [ToolBox.java](./src/main/java/io/helidon/examples/pico/basics/ToolBox.java). +* lifecycle via PostConstruct and RunLevel in [Main](./src/main/java/io/helidon/examples/pico/basics/Main.java). + +## Build and run + +```bash +mvn package +java -jar target/helidon-examples-pico-providers.jar +``` + +Expected Output: +``` +Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT, CircularSaw:INIT, TableSaw:INIT] +Highest weighted service provider: ToolBox:INIT +----- +Preferred Big Tool: Big Hammer +Optional Little Hammer: Optional[Little Hammer] +----- +ToolBox Contents: +Hammer:INIT +BigHammer:ACTIVE +LittleHammer:ACTIVE +AngleGrinderSaw:INIT +CircularSaw:INIT +HandSaw:INIT +NailGun:INIT +TableSaw:INIT +----- +Highest weighted service provider (after activation): ToolBox +----- +Table Saw: blade = null; initialized +All service providers (after all activations): [ToolBox:ACTIVE, CircularSaw:ACTIVE, TableSaw:ACTIVE] +----- +``` diff --git a/examples/pico/providers/pom.xml b/examples/pico/providers/pom.xml new file mode 100644 index 00000000000..95f75fc9dba --- /dev/null +++ b/examples/pico/providers/pom.xml @@ -0,0 +1,95 @@ + + + + + 4.0.0 + + io.helidon.applications + helidon-se + 4.0.0-SNAPSHOT + ../../../applications/se/pom.xml + + io.helidon.examples.pico + helidon-examples-pico-providers + Helidon Pico Examples Providers + + + Examples usages of Pico Providers. + + + + io.helidon.examples.pico.providers.Main + + + + + io.helidon.examples.pico + helidon-examples-pico-basics + ${helidon.version} + + + jakarta.annotation + jakarta.annotation-api + provided + + + org.hamcrest + hamcrest-all + test + + + org.junit.jupiter + junit-jupiter-api + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + true + + -Apico.autoAddNonContractInterfaces=true + -Apico.debug=false + + + + io.helidon.pico + helidon-pico-processor + ${helidon.version} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + + diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java new file mode 100644 index 00000000000..c93f6b1b8be --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.Optional; + +import io.helidon.examples.pico.basics.Little; +import io.helidon.pico.api.RunLevel; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; + +/** + * Intentionally leaving this out as a {@link RunLevel#STARTUP} service. + * + * @see CircularSaw + * @see TableSaw + */ +@Singleton +//@RunLevel(RunLevel.STARTUP) +class AngleGrinderSaw implements Saw { + + private final Blade blade; + + @Inject + AngleGrinderSaw(@Little Optional blade) { + this.blade = blade.orElse(null); + } + + @Override + public String name() { + return "Angle Grinder Saw: (blade=" + blade + ")"; + } + + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println(name() + "; initialized"); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Blade.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Blade.java new file mode 100644 index 00000000000..ab906b7021f --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Blade.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +/** + * Normally, one would need to place {@link io.helidon.pico.api.Contract} on interfaces. Here, however, we used + * {@code -Apico.autoAddNonContractInterfaces=true} in the {@code pom.xml} thereby making all interfaces into contracts that + * can be found via {@link io.helidon.pico.api.Services#lookup}. + */ +//@Contract +public interface Blade { + + String name(); + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/BladeProvider.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/BladeProvider.java new file mode 100644 index 00000000000..c53b5d567c6 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/BladeProvider.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Optional; + +import io.helidon.common.LazyValue; +import io.helidon.examples.pico.basics.Big; +import io.helidon.examples.pico.basics.Little; +import io.helidon.pico.api.ContextualServiceQuery; +import io.helidon.pico.api.InjectionPointInfo; +import io.helidon.pico.api.InjectionPointProvider; +import io.helidon.pico.api.QualifierAndValue; +import io.helidon.pico.api.ServiceInfoCriteria; + +import jakarta.inject.Singleton; + +import static io.helidon.common.LazyValue.create; + +@Singleton +public class BladeProvider implements InjectionPointProvider { + + static final LazyValue> LARGE_BLADE = create(() -> Optional.of(new SizedBlade(SizedBlade.Size.LARGE))); + static final LazyValue> SMALL_BLADE = create(() -> Optional.of(new SizedBlade(SizedBlade.Size.SMALL))); + + /** + * Here we are creating the right sized blade based upon the injection point's criteria. Note that the scope/cardinality + * is still (0..1), meaning there will be at most 1 LARGE and at most 1 SMALL blades provided. + * All {@code Provider}s control the scope of the service instances they provide. + * + * @param query the service query + * @return the blade appropriate for the injection point, or empty if nothing matches + * + * @see NailProvider + */ + @Override + public Optional first(ContextualServiceQuery query) { + ServiceInfoCriteria criteria = query.serviceInfoCriteria(); + if (contains(criteria.qualifiers(), Big.class)) { + return logAndReturn(LARGE_BLADE.get(), query); + } else if (contains(criteria.qualifiers(), Little.class)) { + return logAndReturn(SMALL_BLADE.get(), query); + } + return logAndReturn(Optional.empty(), query); + } + + static Optional logAndReturn(Optional result, + ContextualServiceQuery query) { + InjectionPointInfo ip = query.injectionPointInfo().orElse(null); + // note: a "regular" service lookup via Pico will not have an injection point associated with it + if (ip != null) { + System.out.println(ip.serviceTypeName() + "::" + ip.elementName() + " will be injected with " + result); + } + return result; + } + + static boolean contains(Collection qualifiers, + Class anno) { + return qualifiers.stream().anyMatch(it -> it.typeName().name().equals(anno.getName())); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/CircularSaw.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/CircularSaw.java new file mode 100644 index 00000000000..e529ca3eb40 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/CircularSaw.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.Optional; + +import io.helidon.pico.api.RunLevel; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; + +@Singleton +@RunLevel(RunLevel.STARTUP) +class CircularSaw implements Saw { + + private final Blade blade; + + @Inject + CircularSaw(Optional blade) { + this.blade = blade.orElse(null); + } + + @Override + public String name() { + return "Circular Saw: (blade=" + blade + ")"; + } + + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println(name() + "; initialized"); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/HandSaw.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/HandSaw.java new file mode 100644 index 00000000000..07dff59e9bb --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/HandSaw.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.Optional; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import jakarta.inject.Singleton; + +@Singleton +class HandSaw implements Saw { + + private final Blade blade; + + @Inject + HandSaw(@Named("replacement-blade-that-does-not-exist") Optional blade) { + this.blade = blade.orElse(null); + } + + @Override + public String name() { + return "Hand Saw: (blade=" + blade + ")"; + } + + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println(name() + "; initialized"); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java new file mode 100644 index 00000000000..c3b4cba8c74 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +/** + * Providers example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. + */ +public class Main extends io.helidon.examples.pico.basics.Main { + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Nail.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Nail.java new file mode 100644 index 00000000000..c1ddcf9143e --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Nail.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +/** + * Normally, one would need to place {@link io.helidon.pico.api.Contract} on interfaces. Here, however, we used + * {@code -Apico.autoAddNonContractInterfaces=true} in the {@code pom.xml} thereby making all interfaces into contracts that + * can be found via {@link io.helidon.pico.api.Services#lookup}. + */ +//@Contract +public interface Nail { + + int id(); + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailGun.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailGun.java new file mode 100644 index 00000000000..21921f20cd2 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailGun.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.Objects; + +import io.helidon.examples.pico.basics.Tool; +import io.helidon.pico.api.RunLevel; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import jakarta.inject.Singleton; + +@Singleton +@RunLevel(RunLevel.STARTUP) +class NailGun implements Tool { + + private final Provider nailProvider; + + @Inject + NailGun(Provider nailProvider) { + this.nailProvider = Objects.requireNonNull(nailProvider); + } + + @Override + public String name() { + return "Nail Gun: (nail provider=" + nailProvider + ")"; + } + + /** + * This method will be called by Pico after this instance is lazily initialized (because this is the {@link PostConstruct} + * method). + */ + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println(name() + "; initialized"); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailProvider.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailProvider.java new file mode 100644 index 00000000000..77f54b7eac3 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/NailProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import jakarta.inject.Provider; +import jakarta.inject.Singleton; + +/** + * Showcases dependent scope-creating a nail for caller's demand for a {@link Nail} to be provided. + * All {@code Provider}s control the scope of the service instances they provide. + * + * @see BladeProvider + */ +@Singleton +class NailProvider implements Provider { + + /** + * Creates a new nail every its called. + * + * @return a new nail instance + */ + @Override + public Nail get() { + return new StandardNail(); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Saw.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Saw.java new file mode 100644 index 00000000000..317a85b5759 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Saw.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import io.helidon.examples.pico.basics.Tool; + +/** + * Normally, one would need to place {@link io.helidon.pico.api.Contract} on interfaces. Here, however, we used + * {@code -Apico.autoAddNonContractInterfaces=true} in the {@code pom.xml} thereby making all interfaces into contracts that + * can be found via {@link io.helidon.pico.api.Services#lookup}. + */ +//@Contract +public interface Saw extends Tool { + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java new file mode 100644 index 00000000000..4f59659cf12 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.Objects; + +/** + * See {@link Blade} + */ +public class SizedBlade implements Blade { + + private final Size size; + + public enum Size { + SMALL, + LARGE + } + + public SizedBlade(Size size) { + this.size = Objects.requireNonNull(size); + } + + @Override + public String name() { + return size + " Blade"; + } + + @Override + public String toString() { + return name(); + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/StandardNail.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/StandardNail.java new file mode 100644 index 00000000000..75103a3c842 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/StandardNail.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.concurrent.atomic.AtomicInteger; + +class StandardNail implements Nail { + + private static final AtomicInteger counter = new AtomicInteger(); + private final int id = counter.incrementAndGet(); + + StandardNail() { + } + + @Override + public int id() { + return id; + } + +} diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/TableSaw.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/TableSaw.java new file mode 100644 index 00000000000..006e59694eb --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/TableSaw.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import java.util.Optional; + +import io.helidon.examples.pico.basics.Big; +import io.helidon.pico.api.RunLevel; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; + +@Singleton +@RunLevel(RunLevel.STARTUP) +class TableSaw implements Saw { + + private final Blade blade; + + @Inject + TableSaw(@Big Optional blade) { + this.blade = blade.orElse(null); + } + + @Override + public String name() { + return "Table Saw: (blade=" + blade + ")"; + } + + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println(name() + "; initialized"); + } + +} diff --git a/examples/pico/providers/src/main/resources/logging.properties b/examples/pico/providers/src/main/resources/logging.properties new file mode 100644 index 00000000000..bd06e0ed087 --- /dev/null +++ b/examples/pico/providers/src/main/resources/logging.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# 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. +# + + +handlers = java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = FINEST +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n + +.level = INFO +io.helidon.config.level = WARNING +io.helidon.config.examples.level = FINEST diff --git a/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/AllenWrench.java b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/AllenWrench.java new file mode 100644 index 00000000000..d984d1c61f0 --- /dev/null +++ b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/AllenWrench.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import jakarta.inject.Singleton; + +@Singleton +@SuppressWarnings("unused") +public class AllenWrench implements Wrench { + + @Override + public String name() { + return "Allen Wrench"; + } + +} diff --git a/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java new file mode 100644 index 00000000000..5e7cc6ff9ef --- /dev/null +++ b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import org.junit.jupiter.api.Test; + +class ProvidersTest { + + /** + * Through testing, I will now additionally have an {@link AllenWrench} in my {@link io.helidon.examples.pico.basics.ToolBox} + * also. + */ + @Test + void main() { + Main.main(); + } + +} diff --git a/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/Wrench.java b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/Wrench.java new file mode 100644 index 00000000000..f8cd0580ba2 --- /dev/null +++ b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/Wrench.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.providers; + +import io.helidon.examples.pico.basics.Tool; + +public interface Wrench extends Tool { + +} diff --git a/examples/pom.xml b/examples/pom.xml index 532c70d3e3d..f14135d77aa 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -63,6 +63,7 @@ metrics jbatch nima + pico From ecc81724447cc8dc0d17b5d8edfc4e8906caeefa Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Tue, 9 May 2023 19:49:58 -0400 Subject: [PATCH 02/13] checkpoint --- examples/pico/application/README.md | 19 +++ examples/pico/application/pom.xml | 117 ++++++++++++++++++ .../helidon/examples/pico/basics/ToolBox.java | 9 +- examples/pico/configdriven/README.md | 50 ++++++++ examples/pico/configdriven/pom.xml | 96 ++++++++++++++ .../examples/pico/configdriven/Drill.java | 48 +++++++ .../pico/configdriven/DrillConfig.java | 26 ++++ .../examples/pico/configdriven/Main.java | 60 +++++++++ .../src/main/resources/application.yaml | 25 ++++ .../src/main/resources/logging.properties | 26 ++++ examples/pico/pom.xml | 4 +- examples/pico/providers/README.md | 17 ++- examples/pico/providers/pom.xml | 2 +- .../examples/pico/providers/SizedBlade.java | 2 +- .../examples/pico/providers/package-info.java | 20 +++ 15 files changed, 507 insertions(+), 14 deletions(-) create mode 100644 examples/pico/application/README.md create mode 100644 examples/pico/application/pom.xml create mode 100644 examples/pico/configdriven/README.md create mode 100644 examples/pico/configdriven/pom.xml create mode 100644 examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Drill.java create mode 100644 examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java create mode 100644 examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java create mode 100644 examples/pico/configdriven/src/main/resources/application.yaml create mode 100644 examples/pico/configdriven/src/main/resources/logging.properties create mode 100644 examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/package-info.java diff --git a/examples/pico/application/README.md b/examples/pico/application/README.md new file mode 100644 index 00000000000..c091918389f --- /dev/null +++ b/examples/pico/application/README.md @@ -0,0 +1,19 @@ +# Helidon Pico Providers Example + +This example shows how providers can be leveraged to develop using Helidon Pico. The +[Main.java](./src/main/java/io/helidon/examples/pico/providers/Main.java) class shows: + +* multi-module usage (i.e., this example extends [basics](../basics), [providers](../providers), and [configdriven](../configdriven) ). +* compile-time generation for the entire multi-module project using the pico-maven-plugin (see [pom.xml](./pom.xml)). +* TestingSupport + +## Build and run + +```bash +mvn package +java -jar target/helidon-examples-pico-providers.jar +``` + +Expected Output: +``` +``` diff --git a/examples/pico/application/pom.xml b/examples/pico/application/pom.xml new file mode 100644 index 00000000000..8df7a0b6c40 --- /dev/null +++ b/examples/pico/application/pom.xml @@ -0,0 +1,117 @@ + + + + + 4.0.0 + + io.helidon.applications + helidon-se + 4.0.0-SNAPSHOT + ../../../applications/se/pom.xml + + io.helidon.examples.pico + helidon-examples-pico-application + Helidon Pico Examples Application + + + Example usages of a Pico Application. + + + + io.helidon.examples.pico.providers.Main + + + + + io.helidon.examples.pico + helidon-examples-pico-providers + ${helidon.version} + + + io.helidon.examples.pico + helidon-examples-pico-configdriven + ${helidon.version} + + + jakarta.annotation + jakarta.annotation-api + provided + + + org.hamcrest + hamcrest-all + test + + + org.junit.jupiter + junit-jupiter-api + test + + + io.helidon.pico + helidon-pico-testing + test + + + + + + + io.helidon.pico + helidon-pico-maven-plugin + ${helidon.version} + + + compile + compile + + application-create + + + + testCompile + test-compile + + test-application-create + + + + + NAMED + + io.helidon.pico.tests.pico.provider.MyServices$MyConcreteClassContractPerRequestIPProvider + io.helidon.pico.tests.pico.provider.MyServices$MyConcreteClassContractPerRequestProvider + io.helidon.pico.tests.pico.ASerialProviderImpl + io.helidon.pico.tests.pico.tbox.impl.BladeProvider + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + + diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java index 3729cb51c69..8e2d46f976e 100644 --- a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java @@ -83,16 +83,17 @@ void setPreferredBigTool(@Big Tool preferredBigTool) { void init() { System.out.println("Preferred Big Tool: " + preferredBigTool); System.out.println("Optional Little Hammer: " + optionalLittleHammer); - System.out.println("-----"); - System.out.println("ToolBox Contents:"); + printToolBoxContents(); - System.out.println("-----"); } - void printToolBoxContents() { + public void printToolBoxContents() { + System.out.println("-----"); + System.out.println("ToolBox Contents:"); for (Provider tool : allToolProviders) { System.out.println(tool); } + System.out.println("-----"); } } diff --git a/examples/pico/configdriven/README.md b/examples/pico/configdriven/README.md new file mode 100644 index 00000000000..4e6ad8f80c4 --- /dev/null +++ b/examples/pico/configdriven/README.md @@ -0,0 +1,50 @@ +# Helidon Pico Config-Driven Example + +This example shows the basics of using Helidon Pico's Config-Driven Services. The +[Main.java](./src/main/java/io/helidon/examples/pico/configdriven/Main.java) class shows: + +* setting up the bootstrap [configuration](./src/main/resources/application.yaml). +* [ConfigBean](src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java). +* [ConfiguredBy](src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java) Services. +* annotation processing and source code generation (see [pom.xml](pom.xml) and [generated-sources](./target/generated-sources/annotations/io/helidon/examples/pico/configdriven)). + +## Build and run + +```bash +mvn package +java -jar target/helidon-examples-pico-configdriven.jar +``` + +Expected Output: +``` +Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT] +Highest weighted service provider: ToolBox:INIT +----- +Preferred Big Tool: Big Hammer +Optional Little Hammer: Optional[Little Hammer] +----- +ToolBox Contents: +Hammer:INIT +BigHammer:ACTIVE +LittleHammer:ACTIVE +Drill{Hand}:PENDING +Drill{Impact}:PENDING +----- +Highest weighted service provider (after activation): ToolBox +----- +All service providers (after all activations): [ToolBox:ACTIVE] +----- +Hand; initialized +io.helidon.examples.pico.configdriven.Drill@c33b74f +Impact; initialized +io.helidon.examples.pico.configdriven.Drill@130161f7 +Ending +----- +ToolBox Contents: +Hammer:INIT +BigHammer:ACTIVE +LittleHammer:ACTIVE +Drill{Hand}:ACTIVE +Drill{Impact}:ACTIVE +----- +``` diff --git a/examples/pico/configdriven/pom.xml b/examples/pico/configdriven/pom.xml new file mode 100644 index 00000000000..f2a0d27f961 --- /dev/null +++ b/examples/pico/configdriven/pom.xml @@ -0,0 +1,96 @@ + + + + + 4.0.0 + + io.helidon.applications + helidon-se + 4.0.0-SNAPSHOT + ../../../applications/se/pom.xml + + io.helidon.examples.pico + helidon-examples-pico-configdriven + Helidon Pico Examples Config-Driven + + + Examples of Config-driven services in Pico. + + + + io.helidon.examples.pico.configdriven.Main + + + + + io.helidon.examples.pico + helidon-examples-pico-basics + ${helidon.version} + + + io.helidon.pico.configdriven + helidon-pico-configdriven-runtime + + + io.helidon.config + helidon-config-yaml + + + jakarta.annotation + jakarta.annotation-api + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + true + + + + io.helidon.pico.configdriven + helidon-pico-configdriven-processor + ${helidon.version} + + + + io.helidon.builder + helidon-builder-config-processor + ${helidon.version} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + + diff --git a/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Drill.java b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Drill.java new file mode 100644 index 00000000000..b840af85c3a --- /dev/null +++ b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Drill.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.configdriven; + +import java.util.Objects; + +import io.helidon.examples.pico.basics.Tool; +import io.helidon.pico.configdriven.api.ConfiguredBy; + +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; + +@ConfiguredBy(DrillConfig.class) +class Drill implements Tool { + + private final DrillConfig cfg; + + @Inject + Drill(DrillConfig cfg) { + this.cfg = Objects.requireNonNull(cfg); + } + + @Override + public String name() { + return cfg.name(); + } + + @PostConstruct + @SuppressWarnings("unused") + void init() { + System.out.println(name() + "; initialized"); + } + +} diff --git a/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java new file mode 100644 index 00000000000..74c7b8b82a8 --- /dev/null +++ b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.configdriven; + +import io.helidon.builder.config.ConfigBean; + +@ConfigBean(repeatable = true) +public interface DrillConfig { + + String name(); + +} diff --git a/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java new file mode 100644 index 00000000000..3676bac7354 --- /dev/null +++ b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.configdriven; + +import java.util.List; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; +import io.helidon.examples.pico.basics.ToolBox; +import io.helidon.pico.api.BootstrapDefault; +import io.helidon.pico.api.PicoServices; +import io.helidon.pico.api.ServiceProvider; +import io.helidon.pico.api.Services; + +public class Main extends io.helidon.examples.pico.basics.Main { + + /** + * Executes the example. + * + * @param args arguments + */ + public static void main(String... args) { + // we need to first initialize Pico - informing Pico where to find the application's Config + Config config = Config.builder() + .addSource(ConfigSources.classpath("application.yaml")) + .disableSystemPropertiesSource() + .disableEnvironmentVariablesSource() + .build(); + BootstrapDefault bootstrap = BootstrapDefault.builder() + .config(config) + .build(); + PicoServices.globalBootstrap(bootstrap); + + // the rest is handled normally as before + io.helidon.examples.pico.basics.Main.main(args); + + // activate all of the drills + Services services = PicoServices.realizedServices(); + List> allDrillProviders = services.lookupAll(Drill.class); + allDrillProviders.forEach(it -> System.out.println(it.get())); + + System.out.println("Ending"); + services.lookupFirst(ToolBox.class).get().printToolBoxContents(); + } + +} diff --git a/examples/pico/configdriven/src/main/resources/application.yaml b/examples/pico/configdriven/src/main/resources/application.yaml new file mode 100644 index 00000000000..4c37d537241 --- /dev/null +++ b/examples/pico/configdriven/src/main/resources/application.yaml @@ -0,0 +1,25 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# 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. +# + +# these are only needed for unit testing - if there is a repeated setup and tear down, etc. +pico: + permits-dynamic: true + +drill: + hand: + name: "Hand" + impact: + name: "Impact" diff --git a/examples/pico/configdriven/src/main/resources/logging.properties b/examples/pico/configdriven/src/main/resources/logging.properties new file mode 100644 index 00000000000..b8635a5024e --- /dev/null +++ b/examples/pico/configdriven/src/main/resources/logging.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2017, 2021 Oracle and/or its affiliates. +# +# 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. +# + + +handlers = java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = FINEST +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n + +.level = INFO +io.helidon.config.level = WARNING +io.helidon.config.examples.level = FINEST diff --git a/examples/pico/pom.xml b/examples/pico/pom.xml index 72e7c7a2fd2..590fb2653ca 100644 --- a/examples/pico/pom.xml +++ b/examples/pico/pom.xml @@ -33,8 +33,8 @@ basics providers - - + configdriven + application diff --git a/examples/pico/providers/README.md b/examples/pico/providers/README.md index 404d925524c..215e42ab20a 100644 --- a/examples/pico/providers/README.md +++ b/examples/pico/providers/README.md @@ -3,9 +3,10 @@ This example shows how providers can be leveraged to develop using Helidon Pico. The [Main.java](./src/main/java/io/helidon/examples/pico/providers/Main.java) class shows: -* programmatic lookup of services in Pico's Services registry in [Main](./src/main/java/io/helidon/examples/pico/basics/Main.java). -* declarative injection in [ToolBox.java](./src/main/java/io/helidon/examples/pico/basics/ToolBox.java). -* lifecycle via PostConstruct and RunLevel in [Main](./src/main/java/io/helidon/examples/pico/basics/Main.java). +* multi-module usage (i.e., this example extends [basics](../basics)). +* [standard Providers](src/main/java/io/helidon/examples/pico/providers/NailProvider.java). +* [InjectionPoint Providers](src/main/java/io/helidon/examples/pico/providers/BladeProvider.java). +* additional lifecycle examples via PostConstruct and RunLevel. ## Build and run @@ -16,7 +17,7 @@ java -jar target/helidon-examples-pico-providers.jar Expected Output: ``` -Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT, CircularSaw:INIT, TableSaw:INIT] +Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT, CircularSaw:INIT, NailGun:INIT, TableSaw:INIT] Highest weighted service provider: ToolBox:INIT ----- Preferred Big Tool: Big Hammer @@ -34,7 +35,11 @@ TableSaw:INIT ----- Highest weighted service provider (after activation): ToolBox ----- -Table Saw: blade = null; initialized -All service providers (after all activations): [ToolBox:ACTIVE, CircularSaw:ACTIVE, TableSaw:ACTIVE] +io.helidon.examples.pico.providers.CircularSaw:: will be injected with Optional.empty +Circular Saw: (blade=null); initialized +Nail Gun: (nail provider=NailProvider:INIT); initialized +io.helidon.examples.pico.providers.TableSaw:: will be injected with Optional[LARGE Blade] +Table Saw: (blade=LARGE Blade); initialized +All service providers (after all activations): [ToolBox:ACTIVE, CircularSaw:ACTIVE, NailGun:ACTIVE, TableSaw:ACTIVE] ----- ``` diff --git a/examples/pico/providers/pom.xml b/examples/pico/providers/pom.xml index 95f75fc9dba..c6132239117 100644 --- a/examples/pico/providers/pom.xml +++ b/examples/pico/providers/pom.xml @@ -31,7 +31,7 @@ Helidon Pico Examples Providers - Examples usages of Pico Providers. + Example usages of Pico Providers. diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java index 4f59659cf12..2593c5b6524 100644 --- a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/SizedBlade.java @@ -21,7 +21,7 @@ /** * See {@link Blade} */ -public class SizedBlade implements Blade { +class SizedBlade implements Blade { private final Size size; diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/package-info.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/package-info.java new file mode 100644 index 00000000000..117b5eef258 --- /dev/null +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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. + */ + +/** + * Examples of providers in Pico. + */ +package io.helidon.examples.pico.providers; From 2ce858908e5a9cc9843ac32041c14af94f5492f1 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Wed, 10 May 2023 08:21:24 -0400 Subject: [PATCH 03/13] checkpoint --- examples/pico/application/README.md | 10 ++-- .../pico/application/package-info.java | 20 +++++++ .../pico/application/PicoApplicationTest.java | 58 +++++++++++++++++++ .../pico/configdriven/package-info.java | 20 +++++++ 4 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 examples/pico/application/src/main/java/io/helidon/examples/pico/application/package-info.java create mode 100644 examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java create mode 100644 examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/package-info.java diff --git a/examples/pico/application/README.md b/examples/pico/application/README.md index c091918389f..4c037a3e5d7 100644 --- a/examples/pico/application/README.md +++ b/examples/pico/application/README.md @@ -1,17 +1,17 @@ -# Helidon Pico Providers Example +# Helidon Pico Application Example -This example shows how providers can be leveraged to develop using Helidon Pico. The -[Main.java](./src/main/java/io/helidon/examples/pico/providers/Main.java) class shows: +This example shows how a multi-module application can be created using Helidon Pico. The +[Main.java](./src/main/java/io/helidon/examples/pico/application/Main.java) class shows: * multi-module usage (i.e., this example extends [basics](../basics), [providers](../providers), and [configdriven](../configdriven) ). -* compile-time generation for the entire multi-module project using the pico-maven-plugin (see [pom.xml](./pom.xml)). +* compile-time generation for the entire multi-module project using the _pico-maven-plugin_ (see [pom.xml](./pom.xml)). * TestingSupport ## Build and run ```bash mvn package -java -jar target/helidon-examples-pico-providers.jar +java -jar target/helidon-examples-pico-application.jar ``` Expected Output: diff --git a/examples/pico/application/src/main/java/io/helidon/examples/pico/application/package-info.java b/examples/pico/application/src/main/java/io/helidon/examples/pico/application/package-info.java new file mode 100644 index 00000000000..27ac09e0919 --- /dev/null +++ b/examples/pico/application/src/main/java/io/helidon/examples/pico/application/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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. + */ + +/** + * Examples of multi-module Application generation in Pico. + */ +package io.helidon.examples.pico.application; diff --git a/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java b/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java new file mode 100644 index 00000000000..7d47906c45a --- /dev/null +++ b/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.application; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; +import io.helidon.examples.pico.basics.Main; +import io.helidon.pico.api.PicoServices; +import io.helidon.pico.api.Services; +import io.helidon.pico.testing.PicoTestingSupport; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; + +import static io.helidon.pico.testing.PicoTestingSupport.testableServices; + +class PicoApplicationTest { + + protected PicoServices picoServices; + protected Services services; + + @AfterAll + static void tearDown() { + PicoTestingSupport.resetAll(); + } + + protected void resetWith(Config config) { + PicoTestingSupport.resetAll(); + this.picoServices = testableServices(config); + this.services = picoServices.services(); + } + + @Test + void main() { + Config config = Config.builder() + .addSource(ConfigSources.classpath("application.yaml")) + .disableSystemPropertiesSource() + .disableEnvironmentVariablesSource() + .build(); + resetWith(config); + Main.main(); + } + +} diff --git a/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/package-info.java b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/package-info.java new file mode 100644 index 00000000000..0b5b1906098 --- /dev/null +++ b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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. + */ + +/** + * Examples of Config-Driven Services in Pico. + */ +package io.helidon.examples.pico.configdriven; From 0cfd9ee1c8c62abc29af20b706b341e85e85031f Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Wed, 10 May 2023 12:10:46 -0400 Subject: [PATCH 04/13] final checkpoint before tests and cleanup --- examples/pico/application/pom.xml | 8 ++++---- .../pico/maven/plugin/AbstractApplicationCreatorMojo.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/pico/application/pom.xml b/examples/pico/application/pom.xml index 8df7a0b6c40..62bb62b8b55 100644 --- a/examples/pico/application/pom.xml +++ b/examples/pico/application/pom.xml @@ -94,12 +94,12 @@ + io.helidon.examples.pico.application + NAMED - io.helidon.pico.tests.pico.provider.MyServices$MyConcreteClassContractPerRequestIPProvider - io.helidon.pico.tests.pico.provider.MyServices$MyConcreteClassContractPerRequestProvider - io.helidon.pico.tests.pico.ASerialProviderImpl - io.helidon.pico.tests.pico.tbox.impl.BladeProvider + io.helidon.examples.pico.providers.BladeProvider + io.helidon.examples.pico.providers.NailProvider diff --git a/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java b/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java index a1dccf9260c..72f7fe0692d 100644 --- a/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java +++ b/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java @@ -40,7 +40,7 @@ import io.helidon.pico.api.PicoServices; import io.helidon.pico.api.PicoServicesConfig; import io.helidon.pico.api.ServiceInfoCriteriaDefault; -import io.helidon.pico.api.ServiceProvider; + import io.helidon.pico.api.ServiceProvider; import io.helidon.pico.api.ServiceProviderProvider; import io.helidon.pico.api.Services; import io.helidon.pico.runtime.DefaultServiceBinder; From 0c106bfaa21031872dac5473040a1542257b8782 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Wed, 10 May 2023 14:17:53 -0400 Subject: [PATCH 05/13] finishing the example --- examples/pico/application/README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/examples/pico/application/README.md b/examples/pico/application/README.md index 4c037a3e5d7..a03f379698b 100644 --- a/examples/pico/application/README.md +++ b/examples/pico/application/README.md @@ -5,7 +5,7 @@ This example shows how a multi-module application can be created using Helidon P * multi-module usage (i.e., this example extends [basics](../basics), [providers](../providers), and [configdriven](../configdriven) ). * compile-time generation for the entire multi-module project using the _pico-maven-plugin_ (see [pom.xml](./pom.xml)). -* TestingSupport +* TestingSupport in [ApplicationTest](src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java) ## Build and run @@ -16,4 +16,31 @@ java -jar target/helidon-examples-pico-application.jar Expected Output: ``` +Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT, CircularSaw:INIT, NailGun:INIT, TableSaw:INIT] +Highest weighted service provider: ToolBox:INIT +----- +Preferred Big Tool: Big Hammer +Optional Little Hammer: Optional[Little Hammer] +----- +ToolBox Contents: +Hammer:INIT +BigHammer:ACTIVE +LittleHammer:ACTIVE +Drill{root}:PENDING +AngleGrinderSaw:INIT +CircularSaw:INIT +HandSaw:INIT +NailGun:INIT +TableSaw:INIT +----- +Highest weighted service provider (after activation): ToolBox +----- +io.helidon.examples.pico.providers.CircularSaw:: will be injected with Optional.empty +Circular Saw: (blade=null); initialized +Nail Gun: (nail provider=NailProvider:INIT); initialized +io.helidon.examples.pico.providers.TableSaw:: will be injected with Optional[LARGE Blade] +Table Saw: (blade=LARGE Blade); initialized +All service providers (after all activations): [ToolBox:ACTIVE, CircularSaw:ACTIVE, NailGun:ACTIVE, TableSaw:ACTIVE] ``` + +While the output of this provider may look similar to the one from the previous [providers](../providers) example, the implementation is different. This module builds [Application.java](target/generated-sources/annotations/io/helidon/examples/pico/application/Pico$$Application.java) at compile-time - establishing direct binding to every injection point in your application that is not dynamic in nature (i.e., config-driven services and _Provider_ types). From 6c8bb23754a242c5b0f8836c917274a0dbc1f129 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Wed, 10 May 2023 15:09:26 -0400 Subject: [PATCH 06/13] tweaks --- .../src/main/resources/logging.properties | 26 +++++++++++++++++++ .../src/main/resources/logging.properties | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 examples/pico/application/src/main/resources/logging.properties diff --git a/examples/pico/application/src/main/resources/logging.properties b/examples/pico/application/src/main/resources/logging.properties new file mode 100644 index 00000000000..bd06e0ed087 --- /dev/null +++ b/examples/pico/application/src/main/resources/logging.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# 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. +# + + +handlers = java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = FINEST +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n + +.level = INFO +io.helidon.config.level = WARNING +io.helidon.config.examples.level = FINEST diff --git a/examples/pico/configdriven/src/main/resources/logging.properties b/examples/pico/configdriven/src/main/resources/logging.properties index b8635a5024e..bd06e0ed087 100644 --- a/examples/pico/configdriven/src/main/resources/logging.properties +++ b/examples/pico/configdriven/src/main/resources/logging.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2021 Oracle and/or its affiliates. +# Copyright (c) 2023 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From f46e09a539f3902c4d99d09c02c4011022a8b7d3 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Thu, 11 May 2023 11:42:19 -0400 Subject: [PATCH 07/13] fix indentation --- .../pico/maven/plugin/AbstractApplicationCreatorMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java b/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java index 72f7fe0692d..a1dccf9260c 100644 --- a/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java +++ b/pico/maven-plugin/src/main/java/io/helidon/pico/maven/plugin/AbstractApplicationCreatorMojo.java @@ -40,7 +40,7 @@ import io.helidon.pico.api.PicoServices; import io.helidon.pico.api.PicoServicesConfig; import io.helidon.pico.api.ServiceInfoCriteriaDefault; - import io.helidon.pico.api.ServiceProvider; +import io.helidon.pico.api.ServiceProvider; import io.helidon.pico.api.ServiceProviderProvider; import io.helidon.pico.api.Services; import io.helidon.pico.runtime.DefaultServiceBinder; From 2de00dc3c8ee4fe88beb22d550315802bbedeef8 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Thu, 11 May 2023 14:03:47 -0400 Subject: [PATCH 08/13] add a pico interceptor example --- examples/pico/README.md | 3 +- examples/pico/interceptors/README.md | 37 ++++++++ examples/pico/interceptors/pom.xml | 91 +++++++++++++++++++ .../examples/pico/interceptors/Main.java | 49 ++++++++++ .../pico/interceptors/ScrewDriver.java | 40 ++++++++ .../examples/pico/interceptors/Turn.java | 23 +++++ .../pico/interceptors/TurnInterceptor.java | 45 +++++++++ .../pico/interceptors/TurningTool.java | 27 ++++++ .../src/main/resources/logging.properties | 26 ++++++ examples/pico/pom.xml | 1 + 10 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 examples/pico/interceptors/README.md create mode 100644 examples/pico/interceptors/pom.xml create mode 100644 examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java create mode 100644 examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java create mode 100644 examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Turn.java create mode 100644 examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurnInterceptor.java create mode 100644 examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurningTool.java create mode 100644 examples/pico/interceptors/src/main/resources/logging.properties diff --git a/examples/pico/README.md b/examples/pico/README.md index 906826a9849..ebec97c4343 100644 --- a/examples/pico/README.md +++ b/examples/pico/README.md @@ -8,4 +8,5 @@ Suggested path to follow: 1. [basics](./basics) 2. [providers](./providers) 3. [configdriven](./configdriven) -4. [application](./application) +4. [interceptors](./interceptors) +5. [application](./application) diff --git a/examples/pico/interceptors/README.md b/examples/pico/interceptors/README.md new file mode 100644 index 00000000000..c9a2f7a813d --- /dev/null +++ b/examples/pico/interceptors/README.md @@ -0,0 +1,37 @@ +# Helidon Pico Providers Example + +This example shows how interceptors can be leveraged to develop using Helidon Pico. The +[Main.java](./src/main/java/io/helidon/examples/pico/providers/Main.java) class shows: + +* Interception basics of Pico. + +## Build and run + +```bash +mvn package +java -jar target/helidon-examples-pico-interceptors.jar +``` + +Expected Output: +``` +Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT] +Highest weighted service provider: ToolBox:INIT +----- +Preferred Big Tool: Big Hammer +Optional Little Hammer: Optional[Little Hammer] +----- +ToolBox Contents: +Hammer:INIT +ScrewDriver$$Pico$$Interceptor:INIT +BigHammer:ACTIVE +LittleHammer:ACTIVE +----- +Highest weighted service provider (after activation): ToolBox +----- +All service providers (after all activations): [ToolBox:ACTIVE] +----- +Screw Driver (1st turn): +Screw Driver turning right +Screw Driver (2nd turn): +Screw Driver turning right +``` diff --git a/examples/pico/interceptors/pom.xml b/examples/pico/interceptors/pom.xml new file mode 100644 index 00000000000..6c129d6abbb --- /dev/null +++ b/examples/pico/interceptors/pom.xml @@ -0,0 +1,91 @@ + + + + + 4.0.0 + + io.helidon.applications + helidon-se + 4.0.0-SNAPSHOT + ../../../applications/se/pom.xml + + io.helidon.examples.pico + helidon-examples-pico-interceptors + Helidon Pico Examples Interceptors + + + Example usages of Pico Interceptors. + + + + io.helidon.examples.pico.interceptors.Main + + + + + io.helidon.examples.pico + helidon-examples-pico-basics + ${helidon.version} + + + jakarta.annotation + jakarta.annotation-api + provided + + + org.hamcrest + hamcrest-all + test + + + org.junit.jupiter + junit-jupiter-api + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + true + + + io.helidon.pico + helidon-pico-processor + ${helidon.version} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-libs + + + + + + diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java new file mode 100644 index 00000000000..3fc6ca6b3c9 --- /dev/null +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.interceptors; + +import io.helidon.pico.api.PicoServices; +import io.helidon.pico.api.ServiceProvider; +import io.helidon.pico.api.Services; + +/** + * Providers example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. + */ +public class Main extends io.helidon.examples.pico.basics.Main { + + /** + * Executes the example. + * + * @param args arguments + */ + public static void main(String... args) { + io.helidon.examples.pico.basics.Main.main(args); + + Services services = PicoServices.realizedServices(); + + // use the intercepted screwdriver - note that hashCode(), equals(), and toString() are not intercepted + ServiceProvider screwDriver = services.lookupFirst(ScrewDriver.class); + System.out.println(screwDriver.get() + " (1st turn): "); + screwDriver.get().turn("left"); + + // use the intercepted screwdriver turning tool - note that hashCode(), equals(), and toString() are not intercepted + ServiceProvider turningTool = services.lookupFirst(TurningTool.class); + System.out.println(turningTool.get() + " (2nd turn): "); + turningTool.get().turn("left"); + } + +} diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java new file mode 100644 index 00000000000..48c45f22eb4 --- /dev/null +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.interceptors; + +import jakarta.inject.Singleton; + +@Singleton +public class ScrewDriver implements TurningTool { + + @Override + public String name() { + return "Screw Driver"; + } + + @Turn + @Override + public void turn(String direction) { + System.out.println(name() + " turning " + direction); + } + + @Override + public String toString() { + return name(); + } + +} diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Turn.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Turn.java new file mode 100644 index 00000000000..54241cce136 --- /dev/null +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Turn.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.interceptors; + +import io.helidon.pico.api.InterceptedTrigger; + +@InterceptedTrigger +public @interface Turn { +} diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurnInterceptor.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurnInterceptor.java new file mode 100644 index 00000000000..8b53e52ed1b --- /dev/null +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurnInterceptor.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.interceptors; + +import io.helidon.pico.api.ClassNamed; +import io.helidon.pico.api.InvocationContext; + +import jakarta.inject.Singleton; + +@ClassNamed(Turn.class) +@Singleton +@SuppressWarnings("unused") +class TurnInterceptor implements io.helidon.pico.api.Interceptor { + + @Override + @SuppressWarnings("unchecked") + public V proceed(InvocationContext ctx, + Chain chain, + Object... args) { + // in "real life" you'd use the ctx to determine the best decision - this is just for simple demonstration only! + if (args.length == 1) { + // this is the call to turn() + args[0] = "right"; + } else if (args.length == 0 && ctx.elementInfo().elementName().equals("name")) { + return (V) ("intercepted: " + chain.proceed(args)); + } + + return chain.proceed(args); + } + +} diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurningTool.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurningTool.java new file mode 100644 index 00000000000..3d3a296d469 --- /dev/null +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/TurningTool.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.interceptors; + +import io.helidon.examples.pico.basics.Tool; +import io.helidon.pico.api.Contract; + +@Contract +public interface TurningTool extends Tool { + + void turn(String direction); + +} diff --git a/examples/pico/interceptors/src/main/resources/logging.properties b/examples/pico/interceptors/src/main/resources/logging.properties new file mode 100644 index 00000000000..bd06e0ed087 --- /dev/null +++ b/examples/pico/interceptors/src/main/resources/logging.properties @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# +# 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. +# + + +handlers = java.util.logging.ConsoleHandler + +java.util.logging.ConsoleHandler.level = FINEST +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format = [%1$tc] %4$s: %2$s - %5$s %6$s%n + +.level = INFO +io.helidon.config.level = WARNING +io.helidon.config.examples.level = FINEST diff --git a/examples/pico/pom.xml b/examples/pico/pom.xml index 590fb2653ca..aaf8c818dd4 100644 --- a/examples/pico/pom.xml +++ b/examples/pico/pom.xml @@ -34,6 +34,7 @@ basics providers configdriven + interceptors application From 64bcc2e5cf05877c02b37b0136670e0c5e56c1a3 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Thu, 11 May 2023 14:06:23 -0400 Subject: [PATCH 09/13] add a package-info --- .../pico/interceptors/package-info.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/package-info.java diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/package-info.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/package-info.java new file mode 100644 index 00000000000..a337af36d05 --- /dev/null +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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. + */ + +/** + * Examples of Intercepted services in Pico. + */ +package io.helidon.examples.pico.interceptors; From 2d27242a0517136d8c8be2283b24e3892beb8d1d Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Thu, 11 May 2023 14:13:14 -0400 Subject: [PATCH 10/13] a few small tweaks --- examples/pico/configdriven/README.md | 2 +- .../io/helidon/examples/pico/interceptors/ScrewDriver.java | 2 +- .../java/io/helidon/examples/pico/providers/ProvidersTest.java | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/pico/configdriven/README.md b/examples/pico/configdriven/README.md index 4e6ad8f80c4..5f7f757266b 100644 --- a/examples/pico/configdriven/README.md +++ b/examples/pico/configdriven/README.md @@ -5,7 +5,7 @@ This example shows the basics of using Helidon Pico's Config-Driven Services. Th * setting up the bootstrap [configuration](./src/main/resources/application.yaml). * [ConfigBean](src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java). -* [ConfiguredBy](src/main/java/io/helidon/examples/pico/configdriven/DrillConfig.java) Services. +* [ConfiguredBy](src/main/java/io/helidon/examples/pico/configdriven/Drill.java) Services. * annotation processing and source code generation (see [pom.xml](pom.xml) and [generated-sources](./target/generated-sources/annotations/io/helidon/examples/pico/configdriven)). ## Build and run diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java index 48c45f22eb4..f4f0eb0e26c 100644 --- a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/ScrewDriver.java @@ -19,7 +19,7 @@ import jakarta.inject.Singleton; @Singleton -public class ScrewDriver implements TurningTool { +class ScrewDriver implements TurningTool { @Override public String name() { diff --git a/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java index 5e7cc6ff9ef..880762ee70c 100644 --- a/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java +++ b/examples/pico/providers/src/test/java/io/helidon/examples/pico/providers/ProvidersTest.java @@ -21,8 +21,7 @@ class ProvidersTest { /** - * Through testing, I will now additionally have an {@link AllenWrench} in my {@link io.helidon.examples.pico.basics.ToolBox} - * also. + * Through testing, this will additionally have an {@link AllenWrench} in the {@link io.helidon.examples.pico.basics.ToolBox}. */ @Test void main() { From f1c07eb71a3edbe3908d41a752b089a310736e55 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Wed, 17 May 2023 10:17:35 -0400 Subject: [PATCH 11/13] Address review comments --- examples/pico/application/README.md | 20 ++++++---- examples/pico/application/pom.xml | 2 +- .../examples/pico/application/Main.java | 39 +++++++++++++++++++ .../pico/application/PicoApplicationTest.java | 1 - examples/pico/basics/pom.xml | 2 +- examples/pico/configdriven/pom.xml | 2 +- examples/pico/interceptors/pom.xml | 2 +- .../examples/pico/interceptors/Main.java | 2 +- examples/pico/providers/pom.xml | 2 +- 9 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 examples/pico/application/src/main/java/io/helidon/examples/pico/application/Main.java diff --git a/examples/pico/application/README.md b/examples/pico/application/README.md index a03f379698b..2d68bb49021 100644 --- a/examples/pico/application/README.md +++ b/examples/pico/application/README.md @@ -3,8 +3,8 @@ This example shows how a multi-module application can be created using Helidon Pico. The [Main.java](./src/main/java/io/helidon/examples/pico/application/Main.java) class shows: -* multi-module usage (i.e., this example extends [basics](../basics), [providers](../providers), and [configdriven](../configdriven) ). -* compile-time generation for the entire multi-module project using the _pico-maven-plugin_ (see [pom.xml](./pom.xml)). +* multi-module usage (i.e., this module amalgamates [basics](../basics), [providers](../providers), [configdriven](../configdriven), and [interceptors](../interceptors) ). +* compile-time generation of the DI model for the entire multi-module project using the _pico-maven-plugin_ (see [pom.xml](./pom.xml)). * TestingSupport in [ApplicationTest](src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java) ## Build and run @@ -17,7 +17,10 @@ java -jar target/helidon-examples-pico-application.jar Expected Output: ``` Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT, CircularSaw:INIT, NailGun:INIT, TableSaw:INIT] -Highest weighted service provider: ToolBox:INIT +Highest weighted service provider: NailGun:INIT +----- +Nail Gun: (nail provider=NailProvider:INIT); initialized +Highest weighted service provider (after activation): io.helidon.examples.pico.providers.NailGun@7cbd9d24 ----- Preferred Big Tool: Big Hammer Optional Little Hammer: Optional[Little Hammer] @@ -30,17 +33,18 @@ Drill{root}:PENDING AngleGrinderSaw:INIT CircularSaw:INIT HandSaw:INIT -NailGun:INIT +NailGun:ACTIVE TableSaw:INIT ----- -Highest weighted service provider (after activation): ToolBox ------ io.helidon.examples.pico.providers.CircularSaw:: will be injected with Optional.empty Circular Saw: (blade=null); initialized -Nail Gun: (nail provider=NailProvider:INIT); initialized io.helidon.examples.pico.providers.TableSaw:: will be injected with Optional[LARGE Blade] Table Saw: (blade=LARGE Blade); initialized All service providers (after all activations): [ToolBox:ACTIVE, CircularSaw:ACTIVE, NailGun:ACTIVE, TableSaw:ACTIVE] +----- +Service lookup count: 2 ``` -While the output of this provider may look similar to the one from the previous [providers](../providers) example, the implementation is different. This module builds [Application.java](target/generated-sources/annotations/io/helidon/examples/pico/application/Pico$$Application.java) at compile-time - establishing direct binding to every injection point in your application that is not dynamic in nature (i.e., config-driven services and _Provider_ types). +While the output of this example may look similar to the previous [providers](../providers) example, the implementation is different since this example builds (at compile time) [Application.java](target/generated-sources/annotations/io/helidon/examples/pico/application/Pico$$Application.java). This establishes direct bindings to each and every injection point in your application avoiding runtime resolution with the exception for truly dynamic runtime providers (i.e., anything that is config-driven services or _Provider_ type implementations). + +Note that the lookup count is 2 based upon the direct lookup calls used in the delegated [Main](../basics/src/main/java/io/helidon/examples/pico/basics/Main.java). diff --git a/examples/pico/application/pom.xml b/examples/pico/application/pom.xml index 62bb62b8b55..21dd8a9ce85 100644 --- a/examples/pico/application/pom.xml +++ b/examples/pico/application/pom.xml @@ -24,7 +24,7 @@ io.helidon.applications helidon-se 4.0.0-SNAPSHOT - ../../../applications/se/pom.xml + ../../../applications/nima/pom.xml io.helidon.examples.pico helidon-examples-pico-application diff --git a/examples/pico/application/src/main/java/io/helidon/examples/pico/application/Main.java b/examples/pico/application/src/main/java/io/helidon/examples/pico/application/Main.java new file mode 100644 index 00000000000..e1226b1246b --- /dev/null +++ b/examples/pico/application/src/main/java/io/helidon/examples/pico/application/Main.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. + * + * 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 io.helidon.examples.pico.application; + +import io.helidon.pico.api.Metrics; +import io.helidon.pico.api.PicoServices; + +/** + * Application example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. + */ +public class Main extends io.helidon.examples.pico.basics.Main { + + /** + * Executes the example. + * + * @param args arguments + */ + public static void main(String... args) { + io.helidon.examples.pico.basics.Main.main(args); + + Metrics metrics = PicoServices.picoServices().orElseThrow().metrics().get(); + System.out.println("Service lookup count: " + metrics.lookupCount().get()); + } + +} diff --git a/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java b/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java index 7d47906c45a..a3c45923dc0 100644 --- a/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java +++ b/examples/pico/application/src/test/java/io/helidon/examples/pico/application/PicoApplicationTest.java @@ -18,7 +18,6 @@ import io.helidon.config.Config; import io.helidon.config.ConfigSources; -import io.helidon.examples.pico.basics.Main; import io.helidon.pico.api.PicoServices; import io.helidon.pico.api.Services; import io.helidon.pico.testing.PicoTestingSupport; diff --git a/examples/pico/basics/pom.xml b/examples/pico/basics/pom.xml index 79dff56a637..2e3fe1cfe61 100644 --- a/examples/pico/basics/pom.xml +++ b/examples/pico/basics/pom.xml @@ -24,7 +24,7 @@ io.helidon.applications helidon-se 4.0.0-SNAPSHOT - ../../../applications/se/pom.xml + ../../../applications/nima/pom.xml io.helidon.examples.pico helidon-examples-pico-basics diff --git a/examples/pico/configdriven/pom.xml b/examples/pico/configdriven/pom.xml index f2a0d27f961..ed6e2b947f9 100644 --- a/examples/pico/configdriven/pom.xml +++ b/examples/pico/configdriven/pom.xml @@ -24,7 +24,7 @@ io.helidon.applications helidon-se 4.0.0-SNAPSHOT - ../../../applications/se/pom.xml + ../../../applications/nima/pom.xml io.helidon.examples.pico helidon-examples-pico-configdriven diff --git a/examples/pico/interceptors/pom.xml b/examples/pico/interceptors/pom.xml index 6c129d6abbb..56302f041f7 100644 --- a/examples/pico/interceptors/pom.xml +++ b/examples/pico/interceptors/pom.xml @@ -24,7 +24,7 @@ io.helidon.applications helidon-se 4.0.0-SNAPSHOT - ../../../applications/se/pom.xml + ../../../applications/nima/pom.xml io.helidon.examples.pico helidon-examples-pico-interceptors diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java index 3fc6ca6b3c9..496981fd983 100644 --- a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java @@ -21,7 +21,7 @@ import io.helidon.pico.api.Services; /** - * Providers example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. + * Interceptors example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. */ public class Main extends io.helidon.examples.pico.basics.Main { diff --git a/examples/pico/providers/pom.xml b/examples/pico/providers/pom.xml index c6132239117..9e2b62d0dbd 100644 --- a/examples/pico/providers/pom.xml +++ b/examples/pico/providers/pom.xml @@ -24,7 +24,7 @@ io.helidon.applications helidon-se 4.0.0-SNAPSHOT - ../../../applications/se/pom.xml + ../../../applications/nima/pom.xml io.helidon.examples.pico helidon-examples-pico-providers From 986454279c574561ccf186449f70f9144afb6208 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Wed, 17 May 2023 10:22:56 -0400 Subject: [PATCH 12/13] fix parent pom ref --- examples/pico/application/pom.xml | 2 +- examples/pico/basics/pom.xml | 2 +- examples/pico/configdriven/pom.xml | 2 +- examples/pico/interceptors/pom.xml | 2 +- examples/pico/providers/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/pico/application/pom.xml b/examples/pico/application/pom.xml index 21dd8a9ce85..6d69509e3d1 100644 --- a/examples/pico/application/pom.xml +++ b/examples/pico/application/pom.xml @@ -22,7 +22,7 @@ 4.0.0 io.helidon.applications - helidon-se + helidon-nima 4.0.0-SNAPSHOT ../../../applications/nima/pom.xml diff --git a/examples/pico/basics/pom.xml b/examples/pico/basics/pom.xml index 2e3fe1cfe61..d8f944b91e6 100644 --- a/examples/pico/basics/pom.xml +++ b/examples/pico/basics/pom.xml @@ -22,7 +22,7 @@ 4.0.0 io.helidon.applications - helidon-se + helidon-nima 4.0.0-SNAPSHOT ../../../applications/nima/pom.xml diff --git a/examples/pico/configdriven/pom.xml b/examples/pico/configdriven/pom.xml index ed6e2b947f9..d3b18a3830a 100644 --- a/examples/pico/configdriven/pom.xml +++ b/examples/pico/configdriven/pom.xml @@ -22,7 +22,7 @@ 4.0.0 io.helidon.applications - helidon-se + helidon-nima 4.0.0-SNAPSHOT ../../../applications/nima/pom.xml diff --git a/examples/pico/interceptors/pom.xml b/examples/pico/interceptors/pom.xml index 56302f041f7..990b5bce979 100644 --- a/examples/pico/interceptors/pom.xml +++ b/examples/pico/interceptors/pom.xml @@ -22,7 +22,7 @@ 4.0.0 io.helidon.applications - helidon-se + helidon-nima 4.0.0-SNAPSHOT ../../../applications/nima/pom.xml diff --git a/examples/pico/providers/pom.xml b/examples/pico/providers/pom.xml index 9e2b62d0dbd..3faf2de02d8 100644 --- a/examples/pico/providers/pom.xml +++ b/examples/pico/providers/pom.xml @@ -22,7 +22,7 @@ 4.0.0 io.helidon.applications - helidon-se + helidon-nima 4.0.0-SNAPSHOT ../../../applications/nima/pom.xml From eeda1fb235595990a54acfa41b93a3a7a8270d74 Mon Sep 17 00:00:00 2001 From: Jeff Trent Date: Fri, 19 May 2023 11:40:00 -0400 Subject: [PATCH 13/13] address review comments --- examples/pico/basics/README.md | 17 +++------ .../io/helidon/examples/pico/basics/Main.java | 3 -- .../helidon/examples/pico/basics/ToolBox.java | 10 ++--- examples/pico/configdriven/README.md | 38 ++++--------------- .../examples/pico/configdriven/Main.java | 19 ++++------ examples/pico/interceptors/README.md | 16 -------- .../examples/pico/interceptors/Main.java | 6 +-- examples/pico/providers/README.md | 29 ++++++-------- .../pico/providers/AngleGrinderSaw.java | 8 ---- .../helidon/examples/pico/providers/Main.java | 33 +++++++++++++++- 10 files changed, 69 insertions(+), 110 deletions(-) diff --git a/examples/pico/basics/README.md b/examples/pico/basics/README.md index f2105b9eb20..b91b7aae5ff 100644 --- a/examples/pico/basics/README.md +++ b/examples/pico/basics/README.md @@ -19,17 +19,12 @@ Expected Output: ``` Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT] Highest weighted service provider: ToolBox:INIT ------ -Preferred Big Tool: Big Hammer -Optional Little Hammer: Optional[Little Hammer] ------ -ToolBox Contents: -Hammer:INIT -BigHammer:ACTIVE -LittleHammer:ACTIVE ------ +Preferred (highest weighted) 'Big' Tool: Big Hammer +Optional 'Little' Hammer: Optional[Little Hammer] +Tools in the virtual ToolBox: + tool: Hammer:INIT + tool: BigHammer:ACTIVE + tool: LittleHammer:ACTIVE Highest weighted service provider (after activation): ToolBox ------ All service providers (after all activations): [ToolBox:ACTIVE] ------ ``` diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java index 4f7a8f6d879..62275493610 100644 --- a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/Main.java @@ -50,16 +50,13 @@ public static void main(String... args) { ServiceProvider highestWeightedServiceProvider = services.lookupFirst(criteria); System.out.println("Highest weighted service provider: " + highestWeightedServiceProvider); - System.out.println("-----"); // trigger lazy activations for the highest weighted service provider System.out.println("Highest weighted service provider (after activation): " + highestWeightedServiceProvider.get()); - System.out.println("-----"); // trigger all activations for the (remaining unactivated) startup service providers startupServiceProviders.forEach(ServiceProvider::get); System.out.println("All service providers (after all activations): " + startupServiceProviders); - System.out.println("-----"); } } diff --git a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java index 8e2d46f976e..0d167aca57f 100644 --- a/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java +++ b/examples/pico/basics/src/main/java/io/helidon/examples/pico/basics/ToolBox.java @@ -81,19 +81,17 @@ void setPreferredBigTool(@Big Tool preferredBigTool) { @PostConstruct @SuppressWarnings("unused") void init() { - System.out.println("Preferred Big Tool: " + preferredBigTool); - System.out.println("Optional Little Hammer: " + optionalLittleHammer); + System.out.println("Preferred (highest weighted) 'Big' Tool: " + preferredBigTool); + System.out.println("Optional 'Little' Hammer: " + optionalLittleHammer); printToolBoxContents(); } public void printToolBoxContents() { - System.out.println("-----"); - System.out.println("ToolBox Contents:"); + System.out.println("Tools in the virtual ToolBox:"); for (Provider tool : allToolProviders) { - System.out.println(tool); + System.out.println(" tool: " + tool); } - System.out.println("-----"); } } diff --git a/examples/pico/configdriven/README.md b/examples/pico/configdriven/README.md index 5f7f757266b..3d8dcd3f0a5 100644 --- a/examples/pico/configdriven/README.md +++ b/examples/pico/configdriven/README.md @@ -17,34 +17,12 @@ java -jar target/helidon-examples-pico-configdriven.jar Expected Output: ``` -Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT] -Highest weighted service provider: ToolBox:INIT ------ -Preferred Big Tool: Big Hammer -Optional Little Hammer: Optional[Little Hammer] ------ -ToolBox Contents: -Hammer:INIT -BigHammer:ACTIVE -LittleHammer:ACTIVE -Drill{Hand}:PENDING -Drill{Impact}:PENDING ------ -Highest weighted service provider (after activation): ToolBox ------ -All service providers (after all activations): [ToolBox:ACTIVE] ------ -Hand; initialized -io.helidon.examples.pico.configdriven.Drill@c33b74f -Impact; initialized -io.helidon.examples.pico.configdriven.Drill@130161f7 -Ending ------ -ToolBox Contents: -Hammer:INIT -BigHammer:ACTIVE -LittleHammer:ACTIVE -Drill{Hand}:ACTIVE -Drill{Impact}:ACTIVE ------ +Preferred (highest weighted) 'Big' Tool: Big Hammer +Optional 'Little' Hammer: Optional[Little Hammer] +Tools in the virtual ToolBox: + tool: Hammer:INIT + tool: BigHammer:ACTIVE + tool: LittleHammer:ACTIVE + tool: Drill{Hand}:PENDING + tool: Drill{Impact}:PENDING ``` diff --git a/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java index 3676bac7354..738b5ab0beb 100644 --- a/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java +++ b/examples/pico/configdriven/src/main/java/io/helidon/examples/pico/configdriven/Main.java @@ -16,17 +16,17 @@ package io.helidon.examples.pico.configdriven; -import java.util.List; - import io.helidon.config.Config; import io.helidon.config.ConfigSources; import io.helidon.examples.pico.basics.ToolBox; import io.helidon.pico.api.BootstrapDefault; import io.helidon.pico.api.PicoServices; -import io.helidon.pico.api.ServiceProvider; import io.helidon.pico.api.Services; -public class Main extends io.helidon.examples.pico.basics.Main { +/** + * Config-driven example. + */ +public class Main { /** * Executes the example. @@ -45,16 +45,11 @@ public static void main(String... args) { .build(); PicoServices.globalBootstrap(bootstrap); - // the rest is handled normally as before - io.helidon.examples.pico.basics.Main.main(args); - - // activate all of the drills + // this drives config-driven service activations (see the contents of the toolbox being output) Services services = PicoServices.realizedServices(); - List> allDrillProviders = services.lookupAll(Drill.class); - allDrillProviders.forEach(it -> System.out.println(it.get())); - System.out.println("Ending"); - services.lookupFirst(ToolBox.class).get().printToolBoxContents(); + // this will trigger the PostConstruct method to display the contents of the toolbox + services.lookupFirst(ToolBox.class).get(); } } diff --git a/examples/pico/interceptors/README.md b/examples/pico/interceptors/README.md index c9a2f7a813d..57e31529381 100644 --- a/examples/pico/interceptors/README.md +++ b/examples/pico/interceptors/README.md @@ -14,22 +14,6 @@ java -jar target/helidon-examples-pico-interceptors.jar Expected Output: ``` -Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT] -Highest weighted service provider: ToolBox:INIT ------ -Preferred Big Tool: Big Hammer -Optional Little Hammer: Optional[Little Hammer] ------ -ToolBox Contents: -Hammer:INIT -ScrewDriver$$Pico$$Interceptor:INIT -BigHammer:ACTIVE -LittleHammer:ACTIVE ------ -Highest weighted service provider (after activation): ToolBox ------ -All service providers (after all activations): [ToolBox:ACTIVE] ------ Screw Driver (1st turn): Screw Driver turning right Screw Driver (2nd turn): diff --git a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java index 496981fd983..ab9f6dd2176 100644 --- a/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java +++ b/examples/pico/interceptors/src/main/java/io/helidon/examples/pico/interceptors/Main.java @@ -21,9 +21,9 @@ import io.helidon.pico.api.Services; /** - * Interceptors example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. + * Interceptors example. */ -public class Main extends io.helidon.examples.pico.basics.Main { +public class Main { /** * Executes the example. @@ -31,8 +31,6 @@ public class Main extends io.helidon.examples.pico.basics.Main { * @param args arguments */ public static void main(String... args) { - io.helidon.examples.pico.basics.Main.main(args); - Services services = PicoServices.realizedServices(); // use the intercepted screwdriver - note that hashCode(), equals(), and toString() are not intercepted diff --git a/examples/pico/providers/README.md b/examples/pico/providers/README.md index 215e42ab20a..3014fb949e4 100644 --- a/examples/pico/providers/README.md +++ b/examples/pico/providers/README.md @@ -18,28 +18,21 @@ java -jar target/helidon-examples-pico-providers.jar Expected Output: ``` Startup service providers (ranked according to weight, pre-activated): [ToolBox:INIT, CircularSaw:INIT, NailGun:INIT, TableSaw:INIT] -Highest weighted service provider: ToolBox:INIT ------ -Preferred Big Tool: Big Hammer -Optional Little Hammer: Optional[Little Hammer] ------ -ToolBox Contents: -Hammer:INIT -BigHammer:ACTIVE -LittleHammer:ACTIVE -AngleGrinderSaw:INIT -CircularSaw:INIT -HandSaw:INIT -NailGun:INIT -TableSaw:INIT ------ -Highest weighted service provider (after activation): ToolBox ------ +Preferred (highest weighted) 'Big' Tool: Big Hammer +Optional 'Little' Hammer: Optional[Little Hammer] +Tools in the virtual ToolBox: + tool: Hammer:INIT + tool: BigHammer:ACTIVE + tool: LittleHammer:ACTIVE + tool: AngleGrinderSaw:INIT + tool: CircularSaw:INIT + tool: HandSaw:INIT + tool: NailGun:INIT + tool: TableSaw:INIT io.helidon.examples.pico.providers.CircularSaw:: will be injected with Optional.empty Circular Saw: (blade=null); initialized Nail Gun: (nail provider=NailProvider:INIT); initialized io.helidon.examples.pico.providers.TableSaw:: will be injected with Optional[LARGE Blade] Table Saw: (blade=LARGE Blade); initialized All service providers (after all activations): [ToolBox:ACTIVE, CircularSaw:ACTIVE, NailGun:ACTIVE, TableSaw:ACTIVE] ------ ``` diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java index c93f6b1b8be..a133dae5a49 100644 --- a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/AngleGrinderSaw.java @@ -19,20 +19,12 @@ import java.util.Optional; import io.helidon.examples.pico.basics.Little; -import io.helidon.pico.api.RunLevel; import jakarta.annotation.PostConstruct; import jakarta.inject.Inject; import jakarta.inject.Singleton; -/** - * Intentionally leaving this out as a {@link RunLevel#STARTUP} service. - * - * @see CircularSaw - * @see TableSaw - */ @Singleton -//@RunLevel(RunLevel.STARTUP) class AngleGrinderSaw implements Saw { private final Blade blade; diff --git a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java index c3b4cba8c74..0a044ac3ebf 100644 --- a/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java +++ b/examples/pico/providers/src/main/java/io/helidon/examples/pico/providers/Main.java @@ -16,9 +16,38 @@ package io.helidon.examples.pico.providers; +import java.util.List; + +import io.helidon.pico.api.PicoServices; +import io.helidon.pico.api.RunLevel; +import io.helidon.pico.api.ServiceInfoCriteria; +import io.helidon.pico.api.ServiceInfoCriteriaDefault; +import io.helidon.pico.api.ServiceProvider; +import io.helidon.pico.api.Services; + /** - * Providers example. Uses the same {@code main()} as {@link io.helidon.examples.pico.basics.Main}. + * Providers example. */ -public class Main extends io.helidon.examples.pico.basics.Main { +public class Main { + + /** + * Executes the example. + * + * @param args arguments + */ + public static void main(String... args) { + Services services = PicoServices.realizedServices(); + + ServiceInfoCriteria criteria = ServiceInfoCriteriaDefault.builder() + .runLevel(RunLevel.STARTUP) + .build(); + + List> startupServiceProviders = services.lookupAll(criteria); + System.out.println("Startup service providers (ranked according to weight, pre-activated): " + startupServiceProviders); + + // trigger all activations for startup service providers + startupServiceProviders.forEach(ServiceProvider::get); + System.out.println("All service providers (after all activations): " + startupServiceProviders); + } }