Okay, so your ExtensionPointManager needs to be implemented. That should be the (effectively singleton) ‘manager’ that book-keeps all the individual instances you’re going to create.
That interface has two methods that align pretty well with a backing map -
ExtensionPointType getExtensionPoint(String typeId);
List<? extends ExtensionPointType> getExtensionPoints();
ExtensionPointPage implementation will rely on those implementations to drive itself. Your ExtensionPointPage itself should have a type parameter that maps to your ‘base’ record type - whatever common settings there are between your different item types - think things like name, description.
See how it’s implemented on the AlarmJournalPage:
Your base settings record should have (by convention) a StringField named Type:
public static final StringField Type = new StringField(META, "Type", SFieldFlags.SMANDATORY,
Then, each ‘type’ of sub-configurable-thing you have needs to have its own
PersistentRecord implementation, which will have a (by convention) Profile field referencing back to its parent, and a
BaseExtensionPoint subclass, which will define a type ID (that ultimately ends up in the base record’s
Type field). This is what the
Profile field should look like - only with the type parameters for your ‘base’ record class:
public static final LongField ProfileId = new LongField(META, "ProfileId", SFieldFlags.SPRIMARY_KEY);
public static final ReferenceField<AlarmJournalRecord> Profile = new ReferenceField<>(META,
AlarmJournalRecord.META, "Profile", ProfileId
It’s easiest to use the ‘conventional’ names for these things, because it makes everything else automatically work without having to override various other methods.
The ‘type’ that’s passed into
BaseExtensionPointType as a constructor parameter is the same type that will be used to look up the extension point type on the
ExtensionPointManager - this whole area ties together.