opensourceBIM / BIMserver

The open source BIMserver platform
GNU Affero General Public License v3.0
1.54k stars 608 forks source link

Strange source code in IfcModel that leads to NullPointerException #1242

Open dkurillo opened 2 years ago

dkurillo commented 2 years ago

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...

dkurillo commented 2 years ago

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);
                }
            }
        }
hlg commented 2 years ago

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.