BIMserver
BIMserver copied to clipboard
Strange source code in IfcModel that leads to NullPointerException
IfcModel.java line 174:
for (EClassifier classifier : objects.values().iterator().next().eClass().getEPackage().getEClassifiers()) {
if (classifier instanceof EClass) {
Map<String, IdEObject> map = new TreeMap<String, IdEObject>();
guidIndex.put((EClass) classifier, map);
}
}
guidIndex is populated only by classifiers found on the first object in objects map. In my case first EPackage returned is GeometryPackage. But objects map contains other IFC4 objects that needs classifiers from Ifc4 package. That leads to NullPointerException on line 187:
guidIndex.get(value.eClass()).put((String)guid, value);
value.eClass() if an Ifc4 class but guidIndex is populated only by GeometryPackage classifiers so getter returns null...
objects map contains some org.bimserver.models.geometry.impl.BufferImpl at the beginning and that is unexpected behaviour for this code...
The following code fixes the issue:
List<EPackage> packages = objects.values().stream().map(i -> i.eClass().getEPackage()).distinct().collect(Collectors.toList());
for (EPackage pack : packages) {
for (EClassifier classifier : pack.getEClassifiers()) {
if (classifier instanceof EClass) {
Map<String, IdEObject> map = new TreeMap<>();
guidIndex.put((EClass) classifier, map);
}
}
}
Good catch. This code assumes there is no geometry in the in the objects map and I am not sure if there should be. In any case, we need only the IFC classifiers (of either the version 2x3 or 4 IFC package) in the guidIndex. I would check to see if there is another possibility to get the IFC version of the model and thus the right package with all its IFC classifiers for the index.