<dependencies>
<dependency>
<groupId>org.faktorips.productdesigner</groupId>
<artifactId>productdesigner-web</artifactId>
<version>25.7.0</version>
</dependency>
</dependencies>
Setup
Manuelles Einrichten des Faktor-IPS Product Designers mit eigenen Produktprojekten
Im Folgenden wird beschrieben, was notwendig ist, um den Produkt Designer manuell einzurichten. Es wird jedoch empfohlen, den Product Designer über den Archetype, wie im Kapitel 'Product Designer Archetype' beschrieben, zu erstellen. Das erspart viele der folgenden beschriebenen Schritte.
Voraussetzungen:
Der Product Designer setzt die neueste Faktor-IPS-Version (25.1) sowie Java 21 voraus. Im ersten Schritt müssen daher zunächst die Faktor-IPS-Dependencies im Eclipse aktualisiert werden (Updatesite) und die Modellprojekte einmal neu gebaut werden.
Für weitere Informationen zu Kompatibilitäten zwischen Faktor-IPS und Eclipse bitte diese Übersicht beachten.
Anlage eines Maven-Projekts:
Im zweiten Schritt wird ein neues Maven-Projekt mit Dependencies für den Product Designer, Modellprojekte und Spring-Boot-Starter angelegt.
Dependencies:
Productdesigner-Web:
Gewünschte Modellabhängigkeiten hinzufügen – z. B.:
<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>
In der Spring-Boot-Plugin-Configuration wird eine Main-Klasse benötigt. Im nächsten Schritt wird diese angelegt. Die notwendige Konfiguration kann im pom.xml bereits eingetragen werden:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<wait>500</wait>
<maxAttempts>240</maxAttempts>
<!-- HIER die Product-Designer-Application eintragen (s.u.) -->
<mainClass>org.faktorips.productdesigner.demo.SampleProductDesignerApplication</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Nachfolgend eine beispielhafte pom.xml
eines Product Designer-Maven-Projekts:
<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>
<!-- HIER MODELL-Dependencie(s) angeben -->
<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>
<!-- HIER die Product-Designer-Application angeben (s.u.) -->
<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>
Anlage einer SpringBoot-Application-Klasse und Konfiguration
Wie zuvor beschrieben – wird eine Main-Klasse benötigt. Die Einstellung im pom.xml wurde im vorherigen Schritt bereits durchgeführt. Nun wird eine Application-Klasse angelegt.
Beispiel: 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, <<Package von SampleProductDesignerApplication eintragen>>})
@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");
}
}
Hinweis: Falls die Application in einem anderen (Sub-)Package als ProductDesigner.BASE_PACKAGE
liegt, ist es notwendig, dieses Package neben dem ProductDesigner.BASE_PACKAGE
einzutragen. Durch das Überschreiben wird ansonsten dieses Package nicht berücksichtigt. Es wird im nächsten Schritt eine SampleProductDesignerConfig.java
angelegt und diese soll automatisch eingebunden werden – daher ist es erforderlich dieses Package anzugeben.
Zusätzlich braucht es eine Bean des ProductDesignerPermissionService
. Mit dieser Klasse werden anhand unterschiedlicher Faktoren die Berechtigungen des Benutzers bestimmt. Dieser Service ist auch notwendig, wenn kein Single-Sign-On verwendet wird. Im bereitgestellten DefaultProductDesignerPermissionService
werden die Schreibberechtigungen anhand des RuntimeRepositories
, der Konfiguration im application.yml
und der Rolle durch den RoleMapper
ermittelt. Die SampleProductDesignerConfig.java
wird neben der SampleProductDesignerApplication.java
erstellt:
@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);
}
}
Anlegen der Config
Unter src/main/resources/
wird nun eine application.yml
angelegt. Ein Beispiel hierfür:
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
Parameter
Die folgenden Parameter müssen am Product Designer unter ips-product-designer
gesetzt werden.
additional-repos |
string[] |
Liste von zusätzliche Repositories (Klassenreferenz, fully qualified name), von denen das Produktprojekt abhängt. |
read-only-mode |
boolean |
Wenn true: der Product Desinger wird im Read-Only Modus gestartet (egal welcher Benutzer mit welcher Rolle sich anmeldet) |
Version Control Mode
Der Product Designer unterstützt derzeit zwei Modi:
-
local: Der Product Designer nutzt einen lokalen Ordner, um das Repository und alle Bausteine zu laden. Alle Benutzer nutzen hier denselben Ordner. Sollte es sich trotzdem um ein GIT Repository handeln, kann auch hier ein Commit (auf den aktuellen Branch) erstellt werden.
-
git: Der Product Designer klont beim Log-In das Repository in ein Userverzeichnis. Bei einem "Commit" wird ein Commit auf einem neuen Branch erstellt (der Name setzt sich aus dem Usernamen, dem aktuellen Datum und einer fortlaufenden Nummer zusammen) und dann gepusht.
Es muss einer der Modus ausgewählt werden. Dazu muss entweder ips-product-designer.local
oder ips-product-designer.git
und dann die dafür notwendigen Paramter gesetzt werden.
Local
Parameter für den lokalen Modus:
ipsProjectPath |
string |
Relativer oder absoluter Pfad zum IPS Projekt |
Git
Parameter für den Modus mit git Integration:
relativeIpsProjectPath |
string |
Relativer Pfad zum IPS Projekt. (Der Pfad muss relativ sein, da das Git Repository im jeweiligen User Verzeichnis ausgecheckt wird) |
userFolderPath |
string |
Relativer oder absoluter Pfad zum Ordner in dem pro User ein Ordner angelegt wird und das Repository geklont wird |
repositoryUrl |
string |
Git Repository Url um das Projekt zu clonen |
branch |
string |
Name des Branches der standardmäßig beim clonen ausgecheckt werden soll |
keyPath |
string |
Pfad zum private SSH Key für den technischen User |
Für den Git-Modus wird ein technischer Benutzer benötigt, um das Repository zu klonen, pullen, pushen etc. Änderungen werden dann in dessen Namen durchgeführt. Derzeit unterstützt der Product Designer nur die Authentifizierung via SSH und mit einem passwortlosen private Key (alle gängigen Verschlüsselungen). Um das System so sicher wie möglich zu gestalten soll der Key nicht in fremde Hände gelangen und nur die allernotwendigsten Berechtigungen erhalten.
Einbinden zusätzlicher Repositories
Unter additional-repos
können, wie zuvor beschrieben, zusätzliche Repositories eingebunden werden. In den Java Klassen müssen nicht nur Produkt-Repositories sondern auch die Modell-Repositories, auf denen sie basieren via addDirectlyReferencedRepository
verknüpft werden, damit der Product Designer auch Modellklassen finden kann, die derzeit im Produktrepository nicht genutzt werden.
In anderen Konstellationen bei Verwendung mit Faktor-IPS war es bisher nicht notwendig die Modell-Repositories anzugeben. Der Product Designer braucht für die Analyse der Bausteine jedoch dies Informationen. |
Damit die Repositories zur Laufzeit korrekt geladen werden, sollte je Repository eine Klasse mit einem INSTANCE-Field
für ein IRuntimeRepository
oder IRuntimeRepositoryLookup
enthalten sein.
Am Beispiel des in der .yml
referenzierten Repositories sieht die Klasse GwProduktClassloaderRuntimeRepository
zur Bereitstellung und Konfiguration des Singleton-Repositories wie folgt aus:
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
}
}
Zunächst wird eine ClassloaderRuntimeRepository INSTANCE
, auf Basis der zugehörigen toc.xml
initialisiert.
Im statischen Initialisierungsblock werden dann notwendige, referenzierte Repositories über ihre jeweiligen Instanzen eingebunden (INSTANCE.addDirectlyReferencedRepository(GwAllgemeinClassloaderRuntimeRepository.INSTANCE);
), sowie zusätzlich auch Konfigurationen für die Repository Instanz definiert (INSTANCE.setFormulaEvaluatorFactory(new GroovyFormulaEvaluatorFactory());
).
Favicon hinzufügen
Um schließlich im Browser-Tab Icons der Anwendung anzeigen zu lassen, wird optional ein Favicon in src/main/resources/static
abgelegt.