Skip to content

Commit

Permalink
docs(Java): Fix typos, format snippets, improve guides (#1072)
Browse files Browse the repository at this point in the history
* docs(Java): Fix typos, format snippets, improve guides

* !lint

* use cds add

---------

Co-authored-by: Mahati Shankar <[email protected]>
  • Loading branch information
bugwelle and smahati authored Jul 26, 2024
1 parent dd2a92b commit 74b50c6
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 43 deletions.
11 changes: 6 additions & 5 deletions get-started/in-a-nutshell.md
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ In Node.js, the easiest way to provide implementations for services is through e
<div class="impl java">
In CAP Java, you can add custom handlers for your service as so called EventHandlers. As CAP Java integrates with Spring Boot, you need to provide your custom code in classes, annotated with `@Component`or `@Service`, for example. Use your favorite Java IDE to add a class like the following to the `srv/src/main/java/` folder of your application. {.impl .java}
In CAP Java, you can add custom handlers for your service as so called EventHandlers. As CAP Java integrates with Spring Boot, you need to provide your custom code in classes, annotated with `@Component`, for example. Use your favorite Java IDE to add a class like the following to the `srv/src/main/java/` folder of your application. {.impl .java}
::: code-group
```java [srv/src/main/java/customer/bookshop/handlers/CatalogServiceHandler.java]
Expand Down Expand Up @@ -745,12 +745,13 @@ public class SubmitOrderHandler implements EventHandler {
this.persistenceService = persistenceService;
}
@On()
@On
public void onSubmitOrder(SubmitOrderContext context) {
Select<Books_> byId = Select.from(cds.gen.catalogservice.Books_.class).byId(context.getBook());
Books book = persistenceService.run(byId).single().as(Books.class);
if (context.getQuantity() > book.getStock())
throw new IllegalArgumentException(context.getQuantity() + " exceeds stock for book #" + book.getTitle());
if (context.getQuantity() > book.getStock())
throw new IllegalArgumentException(context.getQuantity() + " exceeds stock for book #" + book.getTitle());
book.setStock(book.getStock() - context.getQuantity());
persistenceService.run(Update.entity(Books_.CDS_NAME).data(book));
Expand Down Expand Up @@ -790,7 +791,7 @@ public class SubmitOrderHandler implements EventHandler {
this.persistenceService = persistenceService;
}
@On()
@On
public void onSubmitOrder(SubmitOrderContext context) {
Select<Books_> byId = Select.from(cds.gen.catalogservice.Books_.class).byId(context.getBook());
Books book = persistenceService.run(byId).single().as(Books.class);
Expand Down
2 changes: 1 addition & 1 deletion get-started/jumpstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ synopsis: Start with a minimal setup and a grow-as-you-go approach.
CAP promotes getting started with **minimal upfront setup**, based on **convention over configuration**, and a **grow-as-you-go** approach, adding settings and tools later on, only when you need them. So, let's get started…

> Looking for other ways to set up and start projects?
> See the _Get Started_ menu in the left-hand sidebar.
> See the _Getting Started_ menu in the left-hand sidebar.
[[toc]]

Expand Down
2 changes: 1 addition & 1 deletion get-started/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ We recommend to implement a proper thread pool and not to rely on these workarou

## OData

### How Do I Generate an OData Response for Error 404?
### How Do I Generate an OData Response in Node.js for Error 404?

If your application(s) endpoints are served with OData and you want to change the standard HTML response to an OData response, adapt the following snippet to your needs and add it in your [custom _server.js_ file](../node.js/cds-serve#custom-server-js).

Expand Down
7 changes: 4 additions & 3 deletions java/cds-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ redirect_from: java/data
uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/9186ed9ab00842e1a31309ff1be38792.html
---

# Working with Data
# Working with CDS Data

<style scoped>
h1:before {
Expand Down Expand Up @@ -436,14 +436,15 @@ You can now either define an accessor interface or use a [generated accessor int
If you define an interface yourself, it could look like the following example:

```java
interface Book extends Map<String, Object> {
interface Books extends Map<String, Object> {
@CdsName("ID") // name of the CDS element
Integer getID();

String getTitle();
void setTitle(String title);
}
```

### Struct

At runtime, the `Struct.access` method is used to create a [proxy](#cds-data) that gives typed access to the data through the accessor interface:
Expand All @@ -452,7 +453,7 @@ At runtime, the `Struct.access` method is used to create a [proxy](#cds-data) th
import static com.sap.cds.Struct.access;
...

Book book = access(data).as(Book.class);
Books book = access(data).as(Books.class);

String title = book.getTitle(); // read the value of the element 'title' from the underlying map
book.setTitle("Miss Betty"); // update the element 'title' in the underlying map
Expand Down
64 changes: 39 additions & 25 deletions java/cqn-services/persistence-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,31 +160,38 @@ Use the [hints](../working-with-cql/query-execution#hana-hints) `hdb.USE_HEX_PLA
::: warning Rare error in `HEX` mode
In some corner cases, particularly when using [native HANA views](../../advanced/hana#create-native-sap-hana-object), queries in `HEX` optimization mode may fail with a "hex enforced but cannot be selected" error. This is the case if the statement execution requires the combination of HEX only features with other features that are not yet supported by the HEX engine. If CAP detects this error it will, as a fallback, execute the query in _legacy_ mode.
If you know upfront that a query can't be executed by the HEX engine, you can add a `hdb.NO_USE_HEX_PLAN` hint to the query, so the SQL generator won't use features that require the HEX engine.
:::
:::

### PostgreSQL { #postgresql-1 }

PostgreSQL can be configured when running locally as well as when running productively in the cloud. Similar to HANA, the datasource is auto-configured based on available service bindings, if the feature `cds-feature-postgresql` is added.

#### Initial Database Schema

To generate a `schema.sql` for PostgreSQL, use the dialect `postgres` with the `cds deploy` command: `cds deploy --to postgres --dry`. The following snippet from _srv/pom.xml_ configures the [cds-maven-plugin](../developing-applications/building#cds-maven-plugin) accordingly:
To generate a `schema.sql` for PostgreSQL, use the dialect `postgres` with the `cds deploy` command: `cds deploy --to postgres --dry`. The following snippet configures the [cds-maven-plugin](../developing-applications/building#cds-maven-plugin) accordingly:

```xml
::: code-group
```xml [srv/pom.xml]
<execution>
<id>schema.sql</id>
<goals>
<goal>cds</goal>
</goals>
<configuration>
<commands>
<command>deploy --to postgres --dry > srv/src/main/resources/schema.sql</command>
<command>deploy --to postgres --dry > "${project.basedir}/src/main/resources/schema.sql"</command>
</commands>
</configuration>
</execution>
```
:::

The generated `schema.sql` can be automatically deployed by Spring if you configure the [sql.init.mode](https://docs.spring.io/spring-boot/docs/2.7.x/reference/html/howto.html#howto.data-initialization.using-basic-sql-scripts) to `always`.
The generated `schema.sql` can be automatically deployed by Spring if you configure the [sql.init.mode](https://docs.spring.io/spring-boot/how-to/data-initialization.html#howto.data-initialization.using-basic-sql-scripts) to `always`.

Using the `@sap/cds-dk` you can add PostgreSQL support to your CAP Java project:
```sh
cds add postgres
```

::: warning
Automatic schema deployment isn't suitable for productive use. Consider using production-ready tools like Flyway or Liquibase. See more on that in the [Database guide for PostgreSQL](../../guides/databases-postgres.md?impl-variant=java#deployment-using-liquibase)
Expand All @@ -211,35 +218,38 @@ spring:

For local development, [H2](https://www.h2database.com/) can be configured to run in-memory or in the file-based mode.

To generate a `schema.sql` for H2, use the dialect `h2` with the `cds deploy` command: `cds deploy --to h2 --dry`. The following snippet from _srv/pom.xml_ configures the [cds-maven-plugin](../developing-applications/building#cds-maven-plugin) accordingly:
To generate a `schema.sql` for H2, use the dialect `h2` with the `cds deploy` command: `cds deploy --to h2 --dry`. The following snippet configures the [cds-maven-plugin](../developing-applications/building#cds-maven-plugin) accordingly:

```xml
::: code-group
```xml [srv/pom.xml]
<execution>
<id>schema.sql</id>
<goals>
<goal>cds</goal>
</goals>
<configuration>
<commands>
<command>deploy --to h2 --dry > srv/src/main/resources/schema.sql</command>
<command>deploy --to h2 --dry > "${project.basedir}/src/main/resources/schema.sql"</command>
</commands>
</configuration>
</execution>
```
:::

In Spring, H2 is automatically initialized in-memory when present on the classpath. See the official [documentation](https://www.h2database.com/html/features.html) for H2 for file-based database configuration.

The `cds-maven-plugin` provides the goal `add` that can be used to add H2 support to the CAP Java project:
Using the `@sap/cds-dk` you can add H2 support to your CAP Java project:
```sh
mvn com.sap.cds:cds-maven-plugin:add -Dfeature=H2 -Dprofile=default
cds add h2
```

### SQLite

#### Initial Database Schema

To generate a `schema.sql` for SQLite, use the dialect `sqlite` with the `cds deploy` command: `cds deploy --to sqlite --dry`. The following snippet from _srv/pom.xml_ configures the [cds-maven-plugin](../developing-applications/building#cds-maven-plugin) accordingly:
To generate a `schema.sql` for SQLite, use the dialect `sqlite` with the `cds deploy` command: `cds deploy --to sqlite --dry`. The following snippet configures the [cds-maven-plugin](../developing-applications/building#cds-maven-plugin) accordingly:

::: code-group
```xml [srv/pom.xml]
<execution>
<id>schema.sql</id>
Expand All @@ -248,15 +258,16 @@ To generate a `schema.sql` for SQLite, use the dialect `sqlite` with the `cds de
</goals>
<configuration>
<commands>
<command>deploy --to sqlite --dry > srv/src/main/resources/schema.sql</command>
<command>deploy --to sqlite --dry > "${project.basedir}/src/main/resources/schema.sql"</command>
</commands>
</configuration>
</execution>
```
:::

The `cds-maven-plugin` provides the goal `add` that can be used to add Sqlite support to the CAP Java project:
Using the `@sap/cds-dk` you can add SQLite support to your CAP Java project:
```sh
mvn com.sap.cds:cds-maven-plugin:add -Dfeature=SQLITE -Dprofile=default
cds add sqlite
```

#### File-Based Storage
Expand Down Expand Up @@ -663,28 +674,28 @@ public interface Books extends CdsData {

The static model and accessor interfaces can be extended with [Javadoc comments](../../cds/cdl#doc-comment).

Currently the generator supports Javadoc comments using the interface and getter/setter methods. The following example shows Javadoc comments defined in the CDS model and how they appear in the generated interfaces.
Currently, the generator supports Javadoc comments using the interface and getter/setter methods. The following example shows Javadoc comments defined in the CDS model and how they appear in the generated interfaces.

```cds
namespace my.bookshop;
/**
* The creator/writer of a book, article, or document.
*/
entity Author {
key Id : Integer;
/**
* The name of the author.
*/
name : String(30);
entity Authors {
key Id : Integer;
/**
* The name of the author.
*/
name : String(30);
}
```

```java
/**
* The creator/writer of a book, article, or document.
*/
@CdsName("my.bookshop.Author")
public interface Author extends CdsData {
@CdsName("my.bookshop.Authors")
public interface Authors extends CdsData {

String ID = "Id";
String NAME = "name";
Expand All @@ -708,9 +719,12 @@ In the query builder, the interfaces reference entities. The interface methods c
lambda expressions to reference elements or to compose path expressions:

```java
Select<Books_> query = Select.from(Books_.class) // Note the usage of model interface Books_ here
// Note the usage of model interface `Books_` here
Select<Books_> query = Select.from(Books_.class)
.columns(book -> book.title())
.where (book -> book.author().name().eq("Edgar Allan Poe"));

List<Books> books = dataStore.execute(query).listOf(Books.class); // After executing the query the result can be converted to a typed representation List of Books.
// After executing the query the result can be converted to
// a typed representation List of Books.
List<Books> books = dataStore.execute(query).listOf(Books.class);
```
2 changes: 1 addition & 1 deletion java/cqn-services/remote-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ cds:
```
:::

The plain service binding of XSUAA or IAS does not contain the URL of the remote API. Therefore it needs to be explicitly configured in the `options` section.
The plain service binding of XSUAA or IAS does not contain the URL of the remote API. Therefore, it needs to be explicitly configured in the `options` section.
As the URL is typically not known at development time, it can be alternatively defined as an environment variable `CDS_REMOTE_SERVICES_<name>_OPTIONS_URL`.

:::tip
Expand Down
1 change: 1 addition & 0 deletions java/developing-applications/properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const { properties, version } = data

The following table lists all configuration properties that can be used to configure
<span class="nowrap">CAP Java {{ version }}</span>.
You can set them in your project's `application.yml`.

::: tip
In property files `<index>` should be replaced with a number and `<key>` with an arbitrary String. In YAML files, you can use standard YAML list and map structures.
Expand Down
4 changes: 4 additions & 0 deletions java/developing-applications/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ In addition to the previously mentioned build tasks, the CDS Maven plugin can al
To automate and accelerate these steps, the `cds-maven-plugin` offers the goal `watch`, which can be executed from the command line by using Maven:

```sh
# from your root directory
mvn com.sap.cds:cds-maven-plugin:watch
# or your srv/ folder
cd srv
mvn cds:watch
```

It builds and starts the application and looks for changes in the CDS model. If you change the CDS model, these are recognized and a restart of the application is initiated to make the changes effective.
Expand Down
6 changes: 4 additions & 2 deletions java/event-handlers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,17 @@ When adding business logic to an Application Service event handlers most commonl
Entity data can be directly accessed in the event handler method, by using an argument of type `CdsData`:

```java
@Before(event = { CqnService.EVENT_CREATE, CqnService.EVENT_UPDATE }, entity = Books_.CDS_NAME)
@Before(event = { CqnService.EVENT_CREATE, CqnService.EVENT_UPDATE },
entity = Books_.CDS_NAME)
public void changeBooks(List<CdsData> data) { }
```
> The `CdsData` interface extends `Map<String, Object>` with some additional JSON serialization capabilities and therefore provides a generic data access capability.
The CAP Java SDK Maven Plugin can generate data accessor interfaces for entities defined in the CDS model. These interfaces allow for a [typed access](../cds-data#typed-access) to data and can be used in arguments as well:

```java
@Before(event = { CqnService.EVENT_CREATE, CqnService.EVENT_UPDATE }, entity = Books_.CDS_NAME)
@Before(event = { CqnService.EVENT_CREATE, CqnService.EVENT_UPDATE },
entity = Books_.CDS_NAME)
public void changeBooks(List<Books> books) { }
```

Expand Down
2 changes: 1 addition & 1 deletion java/operating-applications/observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Spring comes with its own [standard logger groups](https://docs.spring.io/spring
### Logging Service { #logging-service}

The SAP BTP platform offers the [SAP Application Logging service for SAP BTP](https://help.sap.com/docs/r/product/APPLICATION_LOGGING)
and it's recommended successor [SAP Cloud Logging](https://help.sap.com/docs/cloud-logging) service to which bound Cloud Foundry applications can stream logs.
and its recommended successor [SAP Cloud Logging](https://help.sap.com/docs/cloud-logging) service to which bound Cloud Foundry applications can stream logs.

Establishing a connection is the same for both services: The application needs to be [bound to the service](https://help.sap.com/docs/application-logging-service/sap-application-logging-service/produce-logs-container-metrics-and-custom-metrics). To match the log output format and structure expected by the logging service, it's recommended to use a prepared encoder from [cf-java-logging-support](https://github.com/SAP/cf-java-logging-support) that matches the configured logger framework. `logback` is used by default as outlined in [Logging Frameworks](#logging-configuration):

Expand Down
13 changes: 10 additions & 3 deletions java/reflection-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/

## The CDS Model

The interface `CdsModel` represents the complete CDS model of the CAP application and is the starting point for the introspection.
The interface `CdsModel` represents the complete CDS model of the CAP application and is the starting point for the introspection.

The `CdsModel` can be obtained from the `EventContext`:
The `CdsModel` can be obtained from the `EventContext`:

```java
import com.sap.cds.services.handler.annotations.On;
import com.sap.cds.services.EventContext;
import com.sap.cds.reflect.CdsModel;

@On(event = "READ", entity = "my.catalogservice.books")
@On(event = "READ", entity = "CatalogService.Books")
public void readBooksVerify(EventContext context) {
CdsModel model = context.getModel();
...
Expand All @@ -47,6 +48,12 @@ InputStream csnJson = ...;
CdsModel model = CdsModel.read(csnJson);
```

::: tip
Instead of bare string literals, you can also use auto-generated string constants and interfaces in event handlers.

[Learn more about event handlers.](./event-handlers/){.learn-more}
:::

## Examples

The following examples are using this CDS model:
Expand Down
2 changes: 1 addition & 1 deletion java/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ cds:
additional:
email: [email protected]
features:
- cruise
- cruise
- park

- name: Privileged-User
Expand Down

0 comments on commit 74b50c6

Please sign in to comment.