| /////////////////////////////////////////////////////////////// |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| /////////////////////////////////////////////////////////////// |
| |
| [[ten-minutes-intro,Zest™ in 10 minutes]] |
| = Zest™ in 10 minutes = |
| |
| TIP: Theses tutorials are based on actual code found in the `tutorials/` directory of the |
| https://zest.apache.org/download.html[Zest™ SDK sources]. You should start your favorite editor and find the code related to |
| this tutorial, run it and play with it. |
| |
| |
| * Zest™ does not introduce any new programming language, no additional compilers needed and all your existing tools |
| work just like before. It is pure Java. |
| * Zest™ works with Composites. |
| * The equivalent of an Object instance in OOP, is a Composite instance in Zest™. |
| * Composites are constructed from Fragments. |
| * Fragments are Mixins, Concerns, Constraints and SideEffects. |
| * Only Mixins carry Composite state. The others are shared between Composite instances. |
| |
| If you want to reproduce what's explained in this tutorial, remember to depend on the Core Runtime artifact that depends |
| on Core API, Core SPI, Core Bootstrap and Core Functional & I/O APIs: |
| |
| include::../../../../../core/runtime/build/docs/buildinfo/artifact.txt[] |
| |
| Moreover, you'll need an EntityStore for persistence and an Indexing engine for querying. Choose among the available |
| implementations listed in the <<extensions>> section. |
| |
| See the <<howto-depend-on-zest>> tutorial for details. |
| |
| Composition is done with Java interfaces and Annotations. Example; |
| [snippet,java] |
| ----------- |
| source=tutorials/introduction/tenminutes/src/main/java/org/apache/zest/demo/tenminute/OrderEntity.java |
| tag=mainClass |
| ----------- |
| |
| This Composite is potentially complete. The Composite interface has a Mixin declared which is always present, the |
| PropertyMixin, which will handle all properties we use. The two Concerns are interceptors that are placed on the |
| methods that they declare, for instance; |
| |
| [snippet,java] |
| ----------- |
| source=tutorials/introduction/tenminutes/src/main/java/org/apache/zest/demo/tenminute/InventoryConcern.java |
| tag=allClass |
| ----------- |
| |
| Extending the ConcernOf is a convenience mechanism, instead of an explicit @ConcernFor annotation on a private field, |
| which can be used in rare occasions when you are not able to extend. This base class defines the `next` field, which is |
| set up by the Zest™ runtime and points to the next fragment in the call stack. |
| |
| We can also see that the InventoryService is provided to the concern, which is done with dependency injection. Zest™ |
| also supports dependency injection via constructors and methods. |
| |
| The above example is obviously doing persistence, and we have no code handling this. But Zest™ supports persistence |
| directly in its Core, and it is taken care of by Zest™, since it is declared as an EntityComposite. |
| Nothing else is needed, provided that the Zest™ Runtime has been setup with one or more persisted EntityStores. But |
| we have a naming convention that EntityComposites have "Entity" as the suffix in its name. |
| |
| There are other built-in Composite subtypes as well, such as ValueComposite and ServiceComposite. This distinction helps |
| both to communicate intent as well as having more precisely defined functionality. |
| |
| Now, let's say that we want to send a mail to sales@mycompany.com when the order is confirmed. This is a SideEffect, and |
| will execute after the Constraints, Concerns and Mixins. We add the SideEffect to the OrderEntity; |
| |
| [snippet,java] |
| ----------- |
| source=tutorials/introduction/tenminutes/src/main/java/org/apache/zest/demo/tenminute/OrderEntity.java |
| tag=sideEffect |
| ----------- |
| |
| The SideEffect implementation is fairly simple. |
| |
| [snippet,java] |
| ----------- |
| source=tutorials/introduction/tenminutes/src/main/java/org/apache/zest/demo/tenminute/MailNotifySideEffect.java |
| tag=allClass |
| ----------- |
| The MailService is dependency injected, as we have seen before. |
| |
| @This is telling Zest™ that the SideEffect needs a reference to the Composite instance that it belongs to. |
| |
| By asking for both the HasCustomer and the HasLineItems types, we get type-safety and don't need to bother with casts. |
| In fact, Zest™ will ensure that you can't even cast the `hasCustomer` instance to the HasLineItems type. |
| |
| By not referencing the aggregated interface OrderEntity, we reduce the coupling of this SideEffect and it can be used |
| in any other Composite where the HasCustomer and HasLineItems combination is used, for instance in an InvoiceEntity. |
| |
| So, build the report, send it via the MailService. |
| |
| == Conclusion == |
| |
| In this short introduction, we have covered the essence of Zest™. We have looked at what is a Composite, seen some of the |
| Fragments in action, and how simple it is to turn a Composite into a persisted Composite, known as an EntityComposite. |