CET 17.0 adds a new core import layer for Part data. cm.core.part.import provides the importer classes, the shared importer-environment model, and the default SIF, PMX, and OFDA XML implementations that now back file-based part import workflows.
The main migration impact is compile-time. Packages that want to import custom part types should now plug into this framework by subclassing PartImporterEnv, returning the correct Part subclass from createPart(...), and,
for OFDA XML, overriding the new OFDA import hooks on Part.
PMX import continues to rely on initializePartFromItemData(...), which was already part of the older PMX import path. The truly new Part interfaces in this area are the OFDA import hooks described below.
PartImporterPartImporter is the new abstract base class for file-based part importers.
Added: public class PartImporter : abstract Added: public PartImporterEnv env Added: public constructor() Added: public constructor auto() Added: extend public Part[] import(Url file, PartImporterEnv env=null) Added: extend public str{} supportedFileSuffixes() Added: extend public bool validFile(Url file)
PartImporterEnvPartImporterEnv is the new abstract environment type paired with PartImporter. Override it to control record import, part creation, and import lifecycle hooks.
Added: public class PartImporterEnv : abstract Added: public bool silent Added: public constructor auto() Added: public constructor() Added: extend public void beginImport(Url file, Part[] parts) Added: extend public void import(Object data, Part[] parts) Added: extend public Part createPart(Object data) Added: extend public void endImport(Url file, Part[] parts)
PartSIFImporter, PartPMXImporter, and PartOFDAImporterThese are the new concrete importers for the built-in file formats.
Added: public class PartSIFImporter extends PartImporter Added: public constructor(bool silent=false) Added: public constructor(PartSIFImporterEnv env) Added: public str{} supportedFileSuffixes() Added: public Part[] import(Url file, PartImporterEnv env=null) Added: public class PartPMXImporter extends PartImporter Added: public constructor(bool silent=false) Added: public constructor(PartPMXImporterEnv env) Added: public str{} supportedFileSuffixes() Added: public Part[] import(Url file, PartImporterEnv env=null) Added: public class PartOFDAImporter extends PartImporter Added: public OFDAHeaderContent header Added: public constructor(bool silent=false) Added: public constructor(PartOFDAImporterEnv env) Added: public str{} supportedFileSuffixes() Added: public Part[] import(Url file, PartImporterEnv env=null) Added: extend public void importHeader(XmlTag root) Added: extend public void importOrderLineItems(XmlTag root, Part[] data, PartImporterEnv env) Added: extend public XmlTag[] getOrderLineItemTags(XmlTag current)
PartSIFImporterEnv, PartPMXImporterEnv, and PartOFDAImporterEnvThese new environments implement the default import behavior for each file type.
Added: public class PartSIFImporterEnv extends PartImporterEnv Added: public Part currentPart Added: public void beginImport(Url file, Part[] parts) Added: public void import(Object data, Part[] parts) Added: extend public void importKeyValue(str key, str value, Part[] parts) Added: extend public void importPartTag(str key, str value) Added: public Part createPart(Object data) Added: public void endImport(Url file, Part[] parts) Added: extend public str headerPartKey() Added: extend public void flushPart(Part[] parts) Added: public class PartPMXImporterEnv extends PartImporterEnv Added: public Part currentPart Added: public void beginImport(Url file, Part[] parts) Added: public void import(Object data, Part[] parts) Added: public Part createPart(Object data) Added: public void endImport(Url file, Part[] parts) Added: extend public void flushPart(Part[] parts) Added: public class PartOFDAImporterEnv extends PartImporterEnv Added: public Part currentPart Added: public void beginImport(Url file, Part[] parts) Added: public void import(Object data, Part[] parts) Added: extend public void importOrderLineItemTag(XmlTag tag, Part[] parts, OFDAHeaderContent header=null) Added: public void endImport(Url file, Part[] part) Added: public Part createPart(Object data) Added: extend public void flushPart(Part[] parts)
Part OFDA import hooksThese are the new import-facing Part interfaces added in 17.0. They are the main Part APIs that packages need to override for the new OFDA XML importer.
Added: extend public void importOFDAOrderLineItemTag(XmlTag tag, OFDAHeaderContent header=null) Added: extend public void importOFDAOrderLineItemChildTag(XmlTag child, XmlTag oliTag, OFDAHeaderContent header=null) Added: extend public void importOFDATag(XmlTag tag, OFDAHeaderContent header=null) Added: extend public void importOFDAPriceTag(XmlTag tag, OFDAHeaderContent header=null) Added: extend public void importOFDASpecItemTag(XmlTag tag, OFDAHeaderContent header=null) Added: extend public void importOFDACatalogTag(XmlTag tag, OFDAHeaderContent header=null)
The PMX hook initializePartFromItemData(ItemData item, ProjectInformation projectInfo) is still used by the new importer package, but that interface was already part of the older PMX import path and is not new for 17.0.
The new importer packages are mostly compile-time additions, but they also change how query import resolves formats and where format-specific customization now plugs in.
The query import flow in cm.core.part.query now asks QueryDialogBehavior.getImporter(str suffix) for a PartImporter and QueryDialogBehavior.getImporterEnv(str suffix) for an optional custom environment. The default mapping is:
sif -> PartSIFImporterpmx -> PartPMXImporterxml -> PartOFDAImporterIf your package needs a different part type or different per-record behavior, override getImporterEnv(...) and return a custom PartImporterEnv subclass instead of replacing the whole UI flow.
All three built-in importers follow the same environment lifecycle:
validFile(file) checks readability and suffix support.beginImport(file, parts) resets environment state.import(data, parts) is called for each parsed record.endImport(file, parts) flushes any remaining state.That means format-specific customization should normally live in the environment type, especially in createPart(...), record import overrides, and flush/finalization hooks.
Part hooksPartOFDAImporter parses OFDA XML into <OrderLineItem> tags, and PartOFDAImporterEnv calls Part.importOFDAOrderLineItemTag(...) for each imported part. From there, Part dispatches to the more specific OFDA hooks such as importOFDAPriceTag(...), importOFDASpecItemTag(...), and importOFDACatalogTag(...).
Packages that need custom OFDA import behavior should therefore override the relevant Part import hook instead of trying to reimplement the XML traversal from scratch.