EN · DE · RU · FR · ES

#751: ProjectForgeRootElement.java

projectforge-business/src/main/java/org/projectforge/framework/xmlstream/ProjectForgeRootElement.java Java abstract class — base class for all XML export root elements. 98 lines. Source: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/ProjectForgeRootElement.java 98 lines · 45 code · 40 comments · 13 blank
Purpose: An abstract base class for XML root elements in ProjectForge's custom XmlStream serialization system. This is not JAXB or XStream — it's a lightweight, custom XML framework built from scratch for project-specific needs: data export/import between ProjectForge instances, user preference persistence, and configuration serialization. The Javadoc explains: "For export and import it's useful to use an instance of this object to define for example the time zone, version etc." — each exported XML file must carry metadata: which timezone was used during export, which ProjectForge version created the file, and when it was created. Without this information, import on another server could misinterpret dates or fail to apply format migrations.

Three Fields — Three Compatibility Aspects

  1. created (Date): when the XML was created. The no-argument setCreated() automatically sets the current time with second precision (milliseconds zeroed — withPrecision(DatePrecision.SECOND) using PFDateTime). This matters: if two XML files have the same created, they were exported from the same batch. The importer uses this timestamp to determine which data is newer in conflict scenarios.
  2. timeZone (java.util.TimeZone): the timezone used during export. Critical for dates: if a server in Berlin exports "2025-05-15 09:00 Europe/Berlin" and import happens in New York, without an explicit timezone the date would be interpreted as 09:00 EST instead of 03:00 EST. An explicit timeZone prevents date shifts during cross-platform import.
  3. version (String, annotated @XmlField(asAttribute=true)): the ProjectForge version that created the file. Used for format migration — if the importer sees version="7.4", it knows to apply converters for the 7.4 → 8.0 format. The @XmlField(asAttribute=true) annotation means the version is written as an attribute of the root element: <projectforge version="8.0">, not a nested tag.

Fluent API — All Setters Return this

Every setter returns ProjectForgeRootElement, enabling chained initialization:

export.setTimeZone(userTZ).setCreated().setVersion("8.0.0");

This is convenient for creating exports — all metadata is configured in one line, and the object is ready for serialization.

Place in the XmlStream Hierarchy

ProjectForgeRootElement is the abstract base class. Concrete root elements (e.g., ProjectForgeData with root tag <projectforgeData>) extend it and add their own child fields. The entire XmlStream system consists of:

This framework coexists in parallel with XStream in ProjectForge. XStream is used for user preferences (serialization of RecentQueue, UserPref), while XmlStream is used for data export/import between instances (where format control, validation, and versioning are needed).

Why Not XStream?

XStream is an excellent library, but it has limitations for the data export use case:

Git History

868d6abb7 2025 → 2026 (copyright year update)
63081666f Source file headers: 2024→2025
5f9bbfbd3 Fix typos in projectforge-business directory
b6092df09 Copyright 2023 → 2024
ab45d51fa Copyright 2001-2022 → 2001-2023
5f7ef41b8 Copyright 2021 → 2022
cd27dd997 package xstream → xmlstream
ceb63e8a1 Source code header: (C) 2001-2021
7c79f1922 Copyright of source header → 2020
24019a0f5 Eliminate DateHolder occurences
32f634b88 Optimize imports
dd5ca38ac CopyRight of all java file-header updated or created
9ebb88522 Initial commit
Notable changes: 24019a0f5 — eliminated DateHolder (pre-Java-8 class) from this class, migrating date handling to PFDateTime (ProjectForge's own date/time wrapper around java.util.Date and java.time). 5f9bbfbd3 — fixed typos in the codebase (including likely in comments or Javadoc). cd27dd997 — package renamed from xstream to xmlstream to avoid XStream confusion. The three core fields (created, timeZone, version) and the fluent API pattern have been stable since the initial commit.