<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>25.7.0</version>
</dependency>
</dependencies>
English Documentation
Setting up the Faktor-IPS Product Designer with custom product projects
The following describes what is required to set up the Product Designer manually. However, it is recommended to create the Product Designer via the archetype as described in the chapter 'Product Designer Archetype'. This saves many of the steps described below.
Preconditions:
The Product Designer requires the latest Faktor-IPS version (25.1) and Java 21. The first step is therefore to update the Faktor-IPS dependencies in Eclipse (Updatesite) and rebuild the model projects once.
For more information on compatibilities between Faktor-IPS and Eclipse, please refer to this overview.
Creating a Maven project:
Next, a new Maven project is created with dependencies for the Product Designer, model projects, and Spring Boot starter.
Dependencies:
Productdesigner-Web:
Add required model dependencies – for example:
<dependencies>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-gruppenunfall-produktmodellerw</artifactId>
<version>25.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-basis-produkte</artifactId>
<version>25.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
A main class is required in the Spring Boot plug-in configuration. This is created in the next step. The necessary configuration can already be entered in pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- Insert the Product Designer Application here (see below) -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Below is an example pom.xml
of a Product Designer Maven project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.faktorzehn.commons</groupId>
<artifactId>f10-suite-starter-spring</artifactId>
<version>25.7.0</version>
</parent>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<faktorips.version>25.7.0.release</faktorips.version>
</properties>
<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>25.7.0</version>
</dependency>
<!-- INSERT the model dependencies here -->
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-gruppenunfall-produktmodellerw</artifactId>
<version>25.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.faktorzehn.muster.shu-gewerbe</groupId>
<artifactId>vm-gewerbe-basis-produkte</artifactId>
<version>25.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- Insert the Product Designer Application here -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Creating a Spring Boot Application Class and it’s configuration
As described above, a main class is required. The setting in pom.xml has already been made in the previous step. An application class is now created.
Example: SampleProductDesignerApplication.java
:
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.server.AppShellSettings;
import com.vaadin.flow.spring.annotation.EnableVaadin;
import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.faktorips.productdesigner.core.ProductDesigner;
import org.faktorips.productdesigner.core.ProductDesignerConfigurationProperties;
@Theme(value = "productdesigner", variant = "card-section-pages")
@SpringBootApplication(scanBasePackages = {ProductDesigner.BASE_PACKAGE, <<enter package from SampleProductDesignerApplication>>})
@EnableConfigurationProperties(ProductDesignerConfigurationProperties.class)
@EnableVaadin(value = ProductDesigner.BASE_PACKAGE)
public class SampleProductDesignerApplication implements AppShellConfigurator {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
SpringApplication.run(SampleProductDesignerApplication.class, args);
}
@Override
public void configurePage(AppShellSettings settings) {
settings.addFavIcon("icon", "../favicon.ico", "48x48");
}
}
Note: If the application is in a (sub)package other than ProductDesigner.BASE_PACKAGE
, it is necessary to enter this package next to the ProductDesigner.BASE_PACKAGE
. Otherwise, this package will not be taken into account if it is overwritten. In the next step, a SampleProductDesignerConfig.java
is created, and this is to be integrated automatically; it is therefore necessary to specify this package.
In addition, a bean of the ProductDesignerPermissionService
is required. This class is used to determine the user’s authorizations based on various factors. This service is also necessary if no single-sign-on is used. In the provided DefaultProductDesignerPermissionService
, write permissions are determined by the RuntimeRepositories
, the configuration in the application.yml
and the role by the RoleMapper
. The SampleProductDesignerConfig.java
is created alongside the SampleProductDesignerApplication.java
:
@Primary
@Component
public class SampleProductDesignerConfig {
@SessionScope
@Bean
public ProductDesignerPermissionService permissionService(Optional<User> user,
IModifiableRuntimeRepository repository,
ProductDesignerConfigurationProperties properties) {
return new DefaultProductDesignerPermissionService(user.orElse(new LocalUser()), repository,
properties.readOnlyMode() ? ProductDesignerMode.READ_ONLY_MODE : ProductDesignerMode.EDIT_MODE);
}
}
Creating the Configuration
Now, under src/main/resources/
, create an application.yml
. One example:
logging:
level:
org.springframework: WARN
server:
port: 8080
vaadin:
urlMapping: '/ui/*'
launch-browser: true
ips-product-designer:
local:
ips-project-path: ../../../git/mustercontent/vm/vm.shu.gewerbe/gruppenunfall/produkte/
additional-repos:
- de.faktorzehn.versicherungsmodell.gw.produkte.GwProduktClassloaderRuntimeRepository
- de.faktorzehn.versicherungsmodell.gw.produkte.GwAllgemeinClassloaderRuntimeRepository
read-only-mode: false
Parameters
The following parameters must be set in the Product Designer under ips-product-designer
.
additional-repos |
string[] |
List of additional repositories (class reference, fully qualified name) on which the product project depends. |
read-only-mode |
boolean |
If true: the product designer is started in read-only mode (regardless of which user logs in with which role) |
Version Control Mode
The Product Designer currently supports two modes:
-
local: The Product Designer uses a local folder to load the repository and all its product components. All users use the same folder. If it is still a GIT repository, a commit (to the current branch) can be created here.
-
git: The Product Designer clones the repository into a user directory when logging in. With a “commit”, a commit is created on a new branch (the name is made up of the username, the actual date, and a consecutive number) and then pushed.
One of the modes must be selected. To do this, either write ips-product-designer.local
or ips-product-designer.git
and then the necessary parameters must be set.
Local
Parameters for the local mode:
ipsProjectPath |
string |
Relative or absolute path to the IPS project |
Git
Parameters for the mode with git integration:
relativeIpsProjectPath |
string |
Relative path to the IPS project. (The path must be relative, as the Git repository is checked out in the respective user directory) |
userFolderPath |
string |
Relative or absolute path to the folder in which a folder is created for each user and the repository is cloned |
repositoryUrl |
string |
Git |
branch |
string |
Name of the branch to be checked out by default when cloning |
keyPath |
string |
Path to the private SSH key for the technical user |
For Git mode, a technical user is required to clone, pull, push, etc. the repository. Changes are then made in the name of the technical user. Currently, the Product Designer only supports authentication via SSH and with a passwordless private key (all common encryptions). In order to keep the system as secure as possible, the key should not fall into the hands of third parties and should only be given the most necessary authorizations.
Inclusion of additional repositories
Additional repositories can be integrated under additional-repos
, as described above. In the Java classes, not only product repositories but also the model repositories on which they are based must be linked via addDirectlyReferencedRepository
so that the Product Designer can also find model classes that are not currently used in the product repository.
In other constellations when using Faktor-IPS it was not necessary to specify the model repositories. However, the Product Designer needs this information to analyze the blocks. |
To ensure that the repositories are loaded correctly at runtime, each repository should contain a class with an INSTANCE field
for an IRuntimeRepository
or IRuntimeRepositoryLookup
.
For example, the class GwProduktClassloaderRuntimeRepository
referenced in the .yml
for providing and configuring the singleton repository looks like this:
import org.faktorips.runtime.ClassloaderRuntimeRepository;
import org.faktorips.runtime.formula.groovy.GroovyFormulaEvaluatorFactory;
public class GwProduktClassloaderRuntimeRepository {
public static final ClassloaderRuntimeRepository INSTANCE = ClassloaderRuntimeRepository
.create("de/faktorzehn/versicherungsmodell/gw/produkte/internal/faktorips-repository-toc.xml");
static {
INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE);
INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
}
private GwProduktClassloaderRuntimeRepository() {
// Soll nicht instanziiert werden
}
}
First, a ClassloaderRuntimeRepository INSTANCE
is initialized based on the associated toc.xml
.
In the static initialization block, necessary referenced repositories are then incorporated via their respective instances (INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE)
), and additionally, configurations for the repository instance are defined (INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
).
Adding a Favicon
Finally, to display application icons in the browser tab, a favicon can optionally be placed in src/main/resources/static
.