English Documentation

Release Notes

Version 22.6.8

Fixed Bugs

  • Offline XSD Schema missing (FIPS-9759)

  • Unrestricted Java-Enum does not contain all values (FIPS-10003)

If an Enum (isEnumType=true) is used as custom datatype and is configured as unrestricted in the product configuration we now generate an OrderedValueSet containing all values. The getAllValuesMethod configured in the .ipsproject file is used for this.

Version 22.6.6

Fixed Bugs

  • Recursion in AbstractRuntimeRepository#getEnumValueLookupService is called too often (FIPS-9621)

  • ProductReleaseProzessor throws NullPointerException when encountering model JAR reference (FIPS-9633)

Version 22.6.5

Fixed Bugs

  • When opening the dependencies of an IPS project in the model or product definition explorer an Exception was thrown (FIPS-9306)

Version 22.6.4

Fixed Bugs

  • IpsTests don’t find ToC from Maven dependencies on Windows (FIPS-9196)

Version 22.6.3

Fixed Bugs

  • Unified treatment of null/empty String as default value (FIPS-9042)

Version 22.6.2

Further Features and Improvements

  • Added XSD schema to archetype .ipsproject-Templates (FIPS-9015)

  • Extended IDeltaComputationOptions to ignore MOVED deltas (FIPS-9052)

Fixed Bugs

  • Access to enumeration attributes via name fails with capitalized attribute names (FIPS-9003)

  • Constantly recurring exception when InstanceExplorer is open (FIPS-9029)

  • DecimalRange.getValues() with upperBound=lowerBound + step=null throws an exception (FIPS-9044)

Version 22.6.1

When dividing Decimal value by Decimal.NULL, Decimal.NULL is now returned, as was previously documented in the Javadoc. (FIPS-8989)

Version 22.6.0

New Features and Improvements

Unified Value-Set Methods (FIPS-6497)

The methods to query value sets for attributes configured in the model or products had two problems:

  • they were named differently depending on the type of value set (for example getRangeForLivingSpace,getSetOfAllowedValuesForPaymentMode,getAllowedValuesForDisplacement). The original intention was to see the type of value set from the method name, but that meant already knowing the method name. When programming it turned out to be more common to only know an attribute’s name but not it’s value set type.

  • they required a ValidationContext parameter which was then not used in the generated code, which led to warnings in the code. to use the context to specify different value sets depending on context information, but this way it was not possible to configure this in the products. That meant having to know the type of value set to be able to call the matching method (or generically using the IpsModel) and supplying an unnecessary ValidationContext or null. From Faktor-IPS 22.6 onward, the generator can now be configured to use a unified method name(getAllowedValuesForLivingSpace) for all types of value sets and omit the context parameter. This also makes overwriting value sets for derived value sets easier. Upon migration you can choose to switch to the new unified methods(Unified), keep the old methods(ByValueSetType) or generate both methods(Both).

The return value of the value set methods is unified to ValueSet instead of the more specific types like OrderedValueSet or IntegerRange. This may lead to the need for additional casts of the return values but allows a more flexible overwriting of the methods.

Faktor-IPS even supports different valueSetMethods per project. However, this feature should be used sparsely because the code generator must create additional similar methods so that the java inheritance continues to work as expected. Also we recommend using the Both setting only for migration purposes, but not for the productive code.

Migration

If some value set methods were already manually edited, we suggest the following migration workflow:

  1. Change your base model to Both

  2. Copy all manual code to the new methods

  3. Change line-of-business-models to Both

  4. Copy all manual code to the new methods

  5. Change line-of-business-models to Unified

  6. Change your base model to Unified

For Maven or OSGi projects, the setting valueSetMethods should be configured not only in the .ipsproject file but also in the META-INF/MANIFEST.MF. If that file exists, the migration adds or replaces the Fips-GeneratorConfig section with the current values. When later changing the setting for valueSetMethods it must be manually synchronized. The setting from the manifest is used by the code generator when a referenced project (e.g. the base model) is only referenced as a dependency but not opened as a project in the workspace.

Remaining calls to the old methods in handwritten code parts can be replaced with regular expressions, for example use the following expression in Eclipse to be replaced with .getAllowedValuesFor$1():

\.get(?:Range|(?:SetOf)AllowedValues)For([^(]+)\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)

If value set methods have been redirected through use of the Javadoc tag @generated REDIRECT, the new methods may need to be redirected as well after the migration.

Before the migration, the code looks like this:

  /**
   * Returns the range of allowed values for the property sumInsured.
   *
   * @generated REDIRECT
   */
  @IpsAllowedValues("sumInsured")
  public ValueSet<String> getSetOfAllowedValuesForSumInsured(IValidationContext context) {
    ValueSet<String> allowedValues = getSetOfAllowedValuesForSumInsuredGeneratedRedirection(context);
    // for example some restrictions depending on other attributes
    return allowedValues;
  }

  /**
   * Returns the range of allowed values for the property sumInsured.
   *
   * @generated
   */
  @IpsGenerated
  public ValueSet<String> getSetOfAllowedValuesForSumInsuredGeneratedRedirection(IValidationContext context) {
    return MAX_ALLOWED_VALUES_FOR_SUM_INSURED;
  }

After the migration there is a new method without redirect and the old method marked with @generated REDIRECT:

  /**
   * Returns the range of allowed values for the property sumInsured.
   *
   * @generated
   */
  @IpsAllowedValues("sumInsured")
  @IpsGenerated
  public ValueSet<String> getAllowedValuesForSumInsured() {
    return MAX_ALLOWED_VALUES_FOR_SUM_INSURED;
  }

  /**
   * Returns the range of allowed values for the property sumInsured.
   *
   * @generated REDIRECT
   */
  @IpsAllowedValues("sumInsured")
  public ValueSet<String> getSetOfAllowedValuesForSumInsured(IValidationContext context) {
    ValueSet<String> allowedValues = getSetOfAllowedValuesForSumInsuredGeneratedRedirection(context); (1)
    // for example some restrictions depending on other attributes
    return allowedValues;
  }
1 Here should be a compiler error, because the old method is still called

Now the redirection can be implemented with the new method:

  1. Copy the new method

  2. Add GeneratedRedirection to the method name of the copy (Faktor-IPS will continue to generate its code here)

  3. Add REDIRECT to the @generated Javadoc tag of the original method (Faktor-IPS will no longer touch this code)

  4. Replace the original method’s content with that of the old method marked with @generated REDIRECT

  5. Replace the call to the old redirection method using the new method name and drop the ValidationContext parameter (e.g. getRangeForFoobarGeneratedRedirection(context) is replaced with getAllowedValuesForFoobarGeneratedRedirection())

  6. Delete the old method

Result:

  /**
   * Returns the range of allowed values for the property sumInsured.
   *
   * @generated REDIRECT
   */
  @IpsAllowedValues("sumInsured")
  @IpsGenerated
  public ValueSet<String> getAllowedValuesForSumInsured() {
    ValueSet<String> allowedValues = getAllowedValuesForSumInsuredGeneratedRedirection();
    // for example some restrictions depending on other attributes
    return allowedValues;
  }

  /**
   * Returns the range of allowed values for the property sumInsured.
   *
   * @generated
   */
  @IpsGenerated
  public ValueSet<String> getAllowedValuesForSumInsuredGeneratedRedirection() {
    return MAX_ALLOWED_VALUES_FOR_SUM_INSURED;
  }
Overwriting Ranges with Enumerations

When using the unified value set methods, value sets defined as a range in super classes can now be overwritten to be enumerations (with values contained in the original range).

When using product variants, links are overwritten with cardinality 0..0 to exclude them from a variant. These Links are now excluded from calls to the regular getter (for example getCoverages()). A call to getLinksForCoverages() continues to return all links, from which the respective cardinality can be retrieved. For testing purposes, for example with an InMemoryRuntimeRepository, additionally a setter/adder with a CardinalityRange parameter is generated for product-only associations. This method can be called with the also newly introduced constant CardinalityRange#EXCLUDED.

Deprecation of Model Elements

Model elements that shall no longer be used from a given version on can be marked as "deprecated" analogous to Java code. This can be done on the documentation tab of model classes and elements, where previously already their initial version (@since) could be documented.

DeprecatedAttribute

Besides the version, from which on an element is considered deprecated, it can be marked for removal in a future version. Next to that, a description can be given, for example describing which elements should be used instead.

Deprecated elements are displayed with a strikethrough :

DeprecatedAttributeMarked

The description is also displayed in the model description view:

DeprecatedAttributeModelDescription

When product component classes, enumeration types or table structures are marked as deprecated, product components, enumeration and table contents based on them are marked with a warning that also includes the description:

The Product Component Class "home.AdditionalCoverageType" the Product Component "home.ac.BicycleTheft 2022-01" is based on is deprecated since 22.6.0 (Use specialized subclasses instead).

In the generated code @Deprecated annotations (for Java > 8 with since and forRemoval attribute as needed) as well as @deprecated Javadoc tags including the description are created:

/**
 * Creates a new AdditionalCoverageType.
 *
 * @deprecated for removal since 22.6.0. Use specialized subclasses instead
 * @since 17.3
 *
 * @generated
 */
@Deprecated(since = "22.6.0", forRemoval = true)
public AdditionalCoverageType(IRuntimeRepository repository, String id, String kindId, String versionId) {
    super(repository, id, kindId, versionId);
}
Data Types with Name and ID

The feature previously known from enum data types, allowing them to be displayed as ID, name, or "Name (ID)", has been generalized, so that data types without an enumeration of their values can benefit from it. By implementing the interface NamedDatatype with the methods getValueName(String id) and isSupportingNames() known from EnumDatatype and the new method getValueByName(String valueName) a custom data type (e.g. for a country "Germany (DE)") can be displayed in Faktor-IPS in a more user-friendly way.

Datatypes based on existing classes can be implemented in the .ipsproject-configuration like this:

<Datatype id="Country"
  javaClass="org.faktorips.sample.dt.Country"
  valueObject="true"
  isEnumType="false"
  valueOfMethod="fromIsoCountryCode"
  isParsableMethod="isIsoCountryCode"
  valueToStringMethod="getIsoCountryCode"
  isSupportingNames="true" (1)
  getNameMethod="getFullName" (2)
  getValueByNameMethod="fromFullName" /> (3)
1 Configuration of support for names
2 A parameterless method with String return type
3 A static method, returning a value for a String or CharSequence parameter (as returned from the getNameMethod)
Consistent exceptions when comparing with DecimalNull

From now on, all comparisons (lessThan/greaterThan/compareTo) with or on a DecimalNull will throw an UnsupportedOperationException. Null-objects should only be used to prevent exceptions from arithmetic operations and not compared to regular objects. If a comparison is nonetheless required, a null-aware comparator can be created with Decimals#nullsFirstComparator() or Decimals#nullsLastComparator().

Business Functions removed

Faktor-IPS contained two different concepts with the name "Business Function", which where marked as deprecated since version 21.6. Both are now removed. During the migration, all existing business function files and references in policy component type xmls will be deleted.

Set marker for missing mandatory values in generic validation

The constructor of DefaultGenericAttributeValidationConfiguration now has a field for message markers for missing mandatory values. If a marker is set, it will be set in all messages for missing mandatory values.

Unique qualifier improvements

If two dependent Faktor-IPS projects have the same base package name and the same source folder name, derived resources with the same name will be generated in a package with an equal name. This leads to problems at runtime because the java class loader only sees one of the two files.

So now the uniqueQualifier, if set, is also used to move the validation messages (validation-messages_en.properties) and labels and descriptions (model-label-and-descriptions_en.properties) into a unique package. This is also reflected in the source code, since the full package name is used to load the properties.

Database Mappings
Define the length of the discriminator column

When using Faktor-IPS to generate persistence annotations, it is now possible to define the length of the discriminator column in Faktor-IPS. This can prevent unnecessary memory consumption in the database. The length of the discriminator column is checked in the validation and an error message is generated if a discriminator value exceeds the length. Specifying the length is optional. If no length is defined, it behaves as before and discriminator values of any length can be set.

We suggest setting the maximum to the lowest value so that all existing discriminator values remain valid and performing a database migration, resetting the previous default value for the column length with the new maximum.

The standard Jakarta Persistence (formerly JPA) and the reference implementation EclipseLink are now supported in their respective version 3.0. These differ from their predecessors mainly by the change of package names from javax.persistence to jakarta.persistence. When switching, Maven dependencies should also be updated to jakarta.persistence:jakarta.persistence-api:3.0.0 and org.eclipse.persistence:eclipselink:3.0.2, respectively.

JAXB Adapters for LocalDate/Time

The Faktor-IPS runtime now contains JAXB adapters for the data types LocalDate, LocalTime, LocalDateDatime and MonthDay. Similar adapters have been created by hand in several projects or used from the f10-commons project and had to be manually entered in package-info.java files.

As those adapters are now part of the runtime (which requires Java 8 since Faktor-IPS 21.6), Faktor-IPS generates annotations for the use of these adapters on fields for attributes with the corresponding data types and adds the adapters to the context created with IRuntimeRepository#newJAXBContext(), so the package-info.java-entries are no longer necessary.

Feature Configuration

Faktor-IPS can now save configurations for other Faktor-IPS features (for example the Product Variant) in the .ipsproject file. e.g:

<FeatureConfigurations>
  <FeatureConfiguration featureId="org.faktorips.productvariant">
    <Property name="UseUniqueIds" value="OnlyForVariedComponents" />
  </FeatureConfiguration>
</FeatureConfigurations>
JUnit-5-Adapter für IPS-Tests

For the execution of Faktor-IPS test cases with JUnit there are now new helper classes for JUnit 5 besides the old ones based on JUnit 3. All tests from one repository can now be executed as follows:

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

public class HomeInsuranceJUnitTest extends IpsTestSuiteJUnit5Adapter {
     @TestFactory
     public Stream<DynamicTest> getTests() {
         IRuntimeRepository repository = // e.g. ClassloaderRuntimeRepository#create
         return createTests(repository.getIpsTest(""));
    }
}
Internal Refactoring

We are continuously working on making Faktor-IPS' code more independent of Eclipse. For this we have created abstractions of many concepts used in Eclipse, which our plugins now use. Custom plugins using the Faktor-IPS plugin API may be affected by these changes. Abstraction interfaces can be recognized by a leading A. For example is org.faktorips.devtools.abstraction.AFile replacing the previously used org.eclipse.core.resources.IFile. Because custom plugins remain Eclipse plugins for now, the code written in them may still use the Eclipse API. To get from a Faktor-IPS abstraction to the corresponding Eclipse object, the method unwrap() may be used:

AFile abstractFile = [...]
IFile eclipseFile = abstractFile.unwrap();

When abstractions are needed for calls to Faktor-IPS code, they can be created with the help of the Wrappers class:

import static org.faktorips.devtools.abstraction.Wrappers.wrap;
[...]
IFile eclipseFile = [...]
AFile abstractFile = wrap(eclipseFile).as(AFile.class);
Migration

When migrating to Faktor-IPS 22.6, generation of value-set methods can be changed as described in section Unified Value-Set Methods.

Custom plugins might need refactorings as described in Internal Refactoring. In addition, any existing business functions will be removed.

The code generation for multi-value attributes was fixed. Previously, setMultiValueAttribute(new ArrayList<>()) was generated for attributes with the default value "null". After migration, setMultiValueAttribute(ListUtil.newList(null)) is generated instead. Therefore the previously empty list is now a list containing a null object. In order for an empty list to be generated again (setMultiValueAttribute(ListUtil.newList())), the default value "null" must be removed. This behavioral change should be checked for all multi-value attributes during migration and adjusted if necessary.

In all *.ips* files the UUIDs are removed and the order of elements in categories is no longer saved in ProductCmptPropertyReferences but in 'categoryPosition' attributes.

You should consider setting a discriminator column length and replacing old JAXB adapters for LocalDate/Time.

Further Features and Improvements
  • option to no longer generate getEffectiveFromAsCalendar() (FIPS-7539)

  • Decouple model plugin from Eclipse (FIPS-8425)

  • Update documentation of maven support (FIPS-8584)

  • @Deprecated in IPS model (classes/attributes/associations…​?) (FIPS-451)

  • java.util.Currency as data type (FIPS-4708)

  • Setting for length of discriminator column (FIPS-5278)

  • Make methods for the creation of ranges consistent (FIPS-5358)

  • GenericEnumDatatype should accept collections for all values (FIPS-5440)

  • Unified value set methods (FIPS-6497)

  • Tooltip on product associations should display the name of the policy association (FIPS-7537)

  • DataType: use getNameMethod for non-enums (FIPS-7548)

  • ValueSet of an unrestricted enum attribute should be an OrderedValueSet (FIPS-7802)

  • Getter for associated product components should filter empty cardinalities (FIPS-7905)

  • NaturalOrderedValueSet implementing Range (FIPS-7956)

  • DefaultPolicyAttribute.getDefaultValue() should return value defined in model (FIPS-8095)

  • Remove UUIDs in .ips* (FIPS-8096)

  • Remove deprecated Business Functions (FIPS-8115)

  • PersistenceProvider for jakarta.persistence / EclipseLink 3 (FIPS-8159)

  • I don’t ever again want to manually add XML adapters in package-info.java (FIPS-8231)

  • null-handling in OrderedValueSet problematic (FIPS-8416)

  • Format Delta-ComputationMethod Javadoc (FIPS-8466)

  • Use mavenVersionProvider in Integrationtest (FIPS-8469)

  • Adapt and document PersistenceOptions Default max table column size (FIPS-8515)

  • FormulaEvaluator should only be created when there are formulas (FIPS-8559)

  • StringLengthValueSet#isEmpty() should return true when only null is included (FIPS-8575)

  • null and blank String should be treated the same in String attributes' value sets (FIPS-8662)

  • properties-Datei with validation texts for Default-Relevance with "_en" suffix (FIPS-8708)

  • DefaultGenericAttributeValidationConfiguration should support mandatory attribute markers (FIPS-8740)

  • Simplify DatatypeDefinitions configuration (FIPS-8772)

  • Improve @IpsAssociationRemover for associations (FIPS-8794)

  • Remove associationsInFormulas (FIPS-6753)

  • Allow querying whether a policy association is "qualified" (FIPS-8314)

  • Allow setting of variedBase (FIPS-8807)

  • Allow Enums as subset of Range (FIPS-5698)

  • add hasMarker(IMarker): Matcher<Message> to IpsMatchers (FIPS-8741)

  • Add JUnit 5 Adapters (FIPS-7298)

  • XML schema for .ipsproject (FIPS-8675)

Fixed Bugs

  • @since should always be generated when set, even when no version is set in project (FIPS-6474)

  • For extendable enums with primitive data type ID, equals and hashcode are broken (FIPS-6644)

  • Multi value attributes: empty lists and null (FIPS-6872)

  • Enum contents aren’t really Serializable (FIPS-7198)

  • Consequent Exceptions when comparing with DecimalNull (FIPS-7292)

  • Error for configured subclass of non-configured super class (FIPS-7497)

  • Documentation for valdidation rules is missing in JavaDoc (FIPS-8197)

  • uniqueQualifier are not used for .properties files (FIPS-8401)

  • Performance: AbstractIpsBundleContentIndex#getQualifiedNameTypes() (FIPS-8534)

  • SimpleCache returns nothing (FIPS-8676)

  • When writing the Manifest, " must be escaped (FIPS-8790)

  • Migration adapts MANIFEST.MF even in src/main/resources (FIPS-8937)

  • Explicitly handle null objects in range structures (FIPS-8936)

  • Removed even more blanks (FIPS-8867)

  • Use local XSDs if not online/behind proxy (FIPS-8863)

  • Remove outdated commons-collections dependency (FIPS-8926)

  • Make XML attributes that are mostly empty/false optional and don’t write them (FIPS-8891)

  • Documented migration of @generated REDIRECT for Unified Value-Set Methods (FIPS-8904)

  • ClassCastException at mvn install with faktorips-maven-plugin (FIPS-8796)

  • Restore backwards compatibility to allow code generated with Faktor-IPS 21.6/12 to run with the 22.6 runtime (FIPS-8836)

  • Improve description in the migration dialog to 22.6.0 (FIPS-8838)

  • Migration on Windows changes slashes to backslashes in .ipsproject (FIPS-8859)

  • IPS code generator creates blanks in comments (FIPS-8867)

  • Extensible Enum: new variable must change serialVersionUID (FIPS-8871)

  • Message.Builder#invalidObjectWithProperties deletes already set ObjectProperties (FIPS-8876)

  • MessageListMessageMatcher#describeMismatchSafely should describe the MessageList (FIPS-8878)

  • Asciidoc destroys regex (FIPS-8899)

  • getValueByNameMethod disappears from .ipsproject during migration (FIPS-8917)

  • Labels for product-configured policy attributes not precise (FIPS-8911)

  • For combination of BOTH and UNIFIED FIPS does not generate all necessary methods (FIPS-8906)