Skip to content

Commit 74bdfec

Browse files
authored
Setup multi-module project structure (#2)
* Introduce webapp and domain module * Remove target dir * Rename modules * Showcase multi-module use case
1 parent 7ef6945 commit 74bdfec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+478
-182
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/target/
1+
*/target/
22
.idea/
33
.settings
44
.project
@@ -17,4 +17,4 @@ vite.generated.ts
1717
drivers/
1818
# Error screenshots generated by TestBench for failed integration tests
1919
error-screenshots/
20-
webpack.generated.js
20+
webapp/webpack.generated.js

domain/pom.xml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>datamanager</artifactId>
7+
<groupId>life.qbic</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>domain</artifactId>
13+
<name>Data Manager Domain</name>
14+
15+
<properties>
16+
<maven.compiler.source>17</maven.compiler.source>
17+
<maven.compiler.target>17</maven.compiler.target>
18+
</properties>
19+
20+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package life.qbic.datamanagement;
2+
3+
import java.util.Random;
4+
5+
public class Example {
6+
7+
private static final int NUMBER_UPPER_BOUND = Integer.MAX_VALUE;
8+
9+
public static Example create() {
10+
return new Example();
11+
}
12+
13+
private Example() {
14+
}
15+
16+
public int spitOutNumber() {
17+
Random random = new Random();
18+
return random.nextInt(NUMBER_UPPER_BOUND);
19+
}
20+
21+
}

pom.xml

+5-179
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
<artifactId>datamanager</artifactId>
88
<name>Data Manager</name>
99
<version>1.0-SNAPSHOT</version>
10-
<packaging>jar</packaging>
10+
<modules>
11+
<module>webapp</module>
12+
<module>domain</module>
13+
</modules>
14+
<packaging>pom</packaging>
1115

1216
<properties>
1317
<java.version>17</java.version>
@@ -76,182 +80,4 @@
7680
</dependencies>
7781
</dependencyManagement>
7882

79-
<dependencies>
80-
<dependency>
81-
<groupId>com.vaadin</groupId>
82-
<!-- Replace artifactId with vaadin-core to use only free components -->
83-
<artifactId>vaadin</artifactId>
84-
</dependency>
85-
<dependency>
86-
<groupId>com.vaadin</groupId>
87-
<artifactId>vaadin-spring-boot-starter</artifactId>
88-
</dependency>
89-
<dependency>
90-
<groupId>org.springframework.boot</groupId>
91-
<artifactId>spring-boot-starter-security</artifactId>
92-
</dependency>
93-
94-
<dependency>
95-
<groupId>com.vaadin</groupId>
96-
<artifactId>exampledata</artifactId>
97-
<version>4.1.2</version>
98-
</dependency>
99-
100-
<dependency>
101-
<groupId>com.h2database</groupId>
102-
<artifactId>h2</artifactId>
103-
<scope>runtime</scope>
104-
</dependency>
105-
106-
<dependency>
107-
<groupId>org.springframework.boot</groupId>
108-
<artifactId>spring-boot-starter-data-jpa</artifactId>
109-
</dependency>
110-
111-
<dependency>
112-
<groupId>org.springframework.boot</groupId>
113-
<artifactId>spring-boot-starter-validation</artifactId>
114-
</dependency>
115-
<dependency>
116-
<groupId>org.springframework.boot</groupId>
117-
<artifactId>spring-boot-devtools</artifactId>
118-
<optional>true</optional>
119-
</dependency>
120-
<dependency>
121-
<groupId>org.springframework.boot</groupId>
122-
<artifactId>spring-boot-starter-test</artifactId>
123-
<scope>test</scope>
124-
</dependency>
125-
<dependency>
126-
<groupId>com.vaadin</groupId>
127-
<artifactId>vaadin-testbench</artifactId>
128-
<scope>test</scope>
129-
</dependency>
130-
<!-- Include JUnit 4 support for TestBench and others -->
131-
<dependency>
132-
<groupId>org.junit.vintage</groupId>
133-
<artifactId>junit-vintage-engine</artifactId>
134-
<scope>test</scope>
135-
<exclusions>
136-
<exclusion>
137-
<groupId>org.hamcrest</groupId>
138-
<artifactId>hamcrest-core</artifactId>
139-
</exclusion>
140-
</exclusions>
141-
</dependency>
142-
<dependency>
143-
<groupId>io.github.bonigarcia</groupId>
144-
<artifactId>webdrivermanager</artifactId>
145-
<version>5.0.3</version>
146-
<scope>test</scope>
147-
</dependency>
148-
</dependencies>
149-
150-
<build>
151-
<defaultGoal>spring-boot:run</defaultGoal>
152-
<plugins>
153-
<plugin>
154-
<groupId>org.springframework.boot</groupId>
155-
<artifactId>spring-boot-maven-plugin</artifactId>
156-
<!-- Clean build and startup time for Vaadin apps sometimes may exceed
157-
the default Spring Boot's 30sec timeout. -->
158-
<configuration>
159-
<wait>500</wait>
160-
<maxAttempts>240</maxAttempts>
161-
</configuration>
162-
</plugin>
163-
164-
<!--
165-
Take care of synchronizing java dependencies and imports in
166-
package.json and main.js files.
167-
It also creates webpack.config.js if not exists yet.
168-
-->
169-
<plugin>
170-
<groupId>com.vaadin</groupId>
171-
<artifactId>vaadin-maven-plugin</artifactId>
172-
<version>${vaadin.version}</version>
173-
<executions>
174-
<execution>
175-
<goals>
176-
<goal>prepare-frontend</goal>
177-
</goals>
178-
</execution>
179-
</executions>
180-
</plugin>
181-
</plugins>
182-
</build>
183-
184-
<profiles>
185-
<profile>
186-
<!-- Production mode is activated using -Pproduction -->
187-
<id>production</id>
188-
<build>
189-
<plugins>
190-
<plugin>
191-
<groupId>com.vaadin</groupId>
192-
<artifactId>vaadin-maven-plugin</artifactId>
193-
<version>${vaadin.version}</version>
194-
<executions>
195-
<execution>
196-
<goals>
197-
<goal>build-frontend</goal>
198-
</goals>
199-
<phase>compile</phase>
200-
</execution>
201-
</executions>
202-
<configuration>
203-
<productionMode>true</productionMode>
204-
</configuration>
205-
</plugin>
206-
</plugins>
207-
</build>
208-
</profile>
209-
210-
<profile>
211-
<id>it</id>
212-
<build>
213-
<plugins>
214-
<plugin>
215-
<groupId>org.springframework.boot</groupId>
216-
<artifactId>spring-boot-maven-plugin</artifactId>
217-
<executions>
218-
<execution>
219-
<id>start-spring-boot</id>
220-
<phase>pre-integration-test</phase>
221-
<goals>
222-
<goal>start</goal>
223-
</goals>
224-
</execution>
225-
<execution>
226-
<id>stop-spring-boot</id>
227-
<phase>post-integration-test</phase>
228-
<goals>
229-
<goal>stop</goal>
230-
</goals>
231-
</execution>
232-
</executions>
233-
</plugin>
234-
235-
<!-- Runs the integration tests (*IT) after the server is started -->
236-
<plugin>
237-
<groupId>org.apache.maven.plugins</groupId>
238-
<artifactId>maven-failsafe-plugin</artifactId>
239-
<executions>
240-
<execution>
241-
<goals>
242-
<goal>integration-test</goal>
243-
<goal>verify</goal>
244-
</goals>
245-
</execution>
246-
</executions>
247-
<configuration>
248-
<trimStackTrace>false</trimStackTrace>
249-
<enableAssertions>true</enableAssertions>
250-
</configuration>
251-
</plugin>
252-
</plugins>
253-
</build>
254-
</profile>
255-
256-
</profiles>
25783
</project>

.npmrc webapp/.npmrc

File renamed without changes.
File renamed without changes.

webapp/frontend/generated/index.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/******************************************************************************
2+
* This file is auto-generated by Vaadin.
3+
* If you want to customize the entry point, you can copy this file or create
4+
* your own `index.ts` in your frontend directory.
5+
* By default, the `index.ts` file should be in `./frontend/` folder.
6+
*
7+
* NOTE:
8+
* - You need to restart the dev-server after adding the new `index.ts` file.
9+
* After that, all modifications to `index.ts` are recompiled automatically.
10+
* - `index.js` is also supported if you don't want to use TypeScript.
11+
******************************************************************************/
12+
13+
// import Vaadin client-router to handle client-side and server-side navigation
14+
import { Router } from '@vaadin/router';
15+
16+
// import Flow module to enable navigation to Vaadin server-side views
17+
import { Flow } from '@vaadin/flow-frontend/Flow';
18+
19+
const { serverSideRoutes } = new Flow({
20+
imports: () => import('../../target/frontend/generated-flow-imports')
21+
});
22+
23+
const routes = [
24+
// for client-side, place routes below (more info https://vaadin.com/docs/v15/flow/typescript/creating-routes.html)
25+
26+
// for server-side, the next magic line sends all unmatched routes:
27+
...serverSideRoutes // IMPORTANT: this must be the last entry in the array
28+
];
29+
30+
// Vaadin router needs an outlet in the index.html page to display views
31+
const router = new Router(document.querySelector('#outlet'));
32+
router.setRoutes(routes);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import 'construct-style-sheets-polyfill';
2+
3+
const createLinkReferences = (css, target) => {
4+
// Unresolved urls are written as '@import url(text);' to the css
5+
// [0] is the full match
6+
// [1] matches the media query
7+
// [2] matches the url
8+
const importMatcher = /(?:@media\s(.+?))?(?:\s{)?\@import\surl\((.+?)\);(?:})?/g;
9+
10+
var match;
11+
var styleCss = css;
12+
13+
// For each external url import add a link reference
14+
while((match = importMatcher.exec(css)) !== null) {
15+
styleCss = styleCss.replace(match[0], "");
16+
const link = document.createElement('link');
17+
link.rel = 'stylesheet';
18+
link.href = match[2];
19+
if (match[1]) {
20+
link.media = match[1];
21+
}
22+
// For target document append to head else append to target
23+
if (target === document) {
24+
document.head.appendChild(link);
25+
} else {
26+
target.appendChild(link);
27+
}
28+
};
29+
return styleCss;
30+
};
31+
32+
// target: Document | ShadowRoot
33+
export const injectGlobalCss = (css, target, first) => {
34+
if(target === document) {
35+
const hash = getHash(css);
36+
if (window.Vaadin.theme.injectedGlobalCss.indexOf(hash) !== -1) {
37+
return;
38+
}
39+
window.Vaadin.theme.injectedGlobalCss.push(hash);
40+
}
41+
const sheet = new CSSStyleSheet();
42+
sheet.replaceSync(createLinkReferences(css,target));
43+
if (first) {
44+
target.adoptedStyleSheets = [sheet, ...target.adoptedStyleSheets];
45+
} else {
46+
target.adoptedStyleSheets = [...target.adoptedStyleSheets, sheet];
47+
}
48+
};
49+
import stylesCss from 'themes/datamanager/styles.css?inline';
50+
import { typography } from '@vaadin/vaadin-lumo-styles';
51+
import { color } from '@vaadin/vaadin-lumo-styles';
52+
import { spacing } from '@vaadin/vaadin-lumo-styles';
53+
import { badge } from '@vaadin/vaadin-lumo-styles';
54+
import { utility } from '@vaadin/vaadin-lumo-styles';
55+
56+
window.Vaadin = window.Vaadin || {};
57+
window.Vaadin.theme = window.Vaadin.theme || {};
58+
window.Vaadin.theme.injectedGlobalCss = [];
59+
60+
/**
61+
* Calculate a 32 bit FNV-1a hash
62+
* Found here: https://gist.github.com/vaiorabbit/5657561
63+
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
64+
*
65+
* @param {string} str the input value
66+
* @returns {string} 32 bit (as 8 byte hex string)
67+
*/
68+
function hashFnv32a(str) {
69+
/*jshint bitwise:false */
70+
let i, l, hval = 0x811c9dc5;
71+
72+
for (i = 0, l = str.length; i < l; i++) {
73+
hval ^= str.charCodeAt(i);
74+
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
75+
}
76+
77+
// Convert to 8 digit hex string
78+
return ("0000000" + (hval >>> 0).toString(16)).substr(-8);
79+
}
80+
81+
/**
82+
* Calculate a 64 bit hash for the given input.
83+
* Double hash is used to significantly lower the collision probability.
84+
*
85+
* @param {string} input value to get hash for
86+
* @returns {string} 64 bit (as 16 byte hex string)
87+
*/
88+
function getHash(input) {
89+
let h1 = hashFnv32a(input); // returns 32 bit (as 8 byte hex string)
90+
return h1 + hashFnv32a(h1 + input);
91+
}
92+
export const applyTheme = (target) => {
93+
94+
injectGlobalCss(stylesCss.toString(), target);
95+
96+
97+
if (!document['_vaadintheme_datamanager_componentCss']) {
98+
99+
document['_vaadintheme_datamanager_componentCss'] = true;
100+
}
101+
injectGlobalCss(typography.cssText, target, true);
102+
injectGlobalCss(color.cssText, target, true);
103+
injectGlobalCss(spacing.cssText, target, true);
104+
injectGlobalCss(badge.cssText, target, true);
105+
injectGlobalCss(utility.cssText, target, true);
106+
107+
}

webapp/frontend/generated/theme.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const applyTheme: (target: Node) => void;

webapp/frontend/generated/theme.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import {applyTheme as _applyTheme} from './theme-datamanager.generated.js';
2+
export const applyTheme = _applyTheme;

0 commit comments

Comments
 (0)