Skip to content

Commit b27aa20

Browse files
committed
fix handling of two-dimensional arrays in JSON deserializer
This is used in Java BIMserver client and the respective test had been failing. It seems that dangling references in two-dimensional arrays are not yet handled in the JSON deserializer (they are in IFC).
1 parent acaaa4e commit b27aa20

File tree

2 files changed

+124
-120
lines changed

2 files changed

+124
-120
lines changed

BimServerClientLib/test/org/bimserver/client/tests/TestIfc4TwoDimensional2.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ public void test() throws Exception {
4545
for (IfcBSplineSurfaceWithKnots bSplineSurface: bSplineSurfaces){
4646
Assert.assertEquals(4, bSplineSurface.getControlPointsList().size());
4747
for(ListOfIfcCartesianPoint pointList: bSplineSurface.getControlPointsList()){
48-
// This assertion fails, error seems to be in client.
49-
// 1st pointlist is of size 1, 2nd of size 2 and so on
50-
// with duplication of the first point's coordinates
5148
Assert.assertEquals(7, pointList.getList().size());
5249
for(IfcCartesianPoint point: pointList.getList()){
5350
Assert.assertNotNull(point);

PluginBase/src/org/bimserver/emf/SharedJsonDeserializer.java

Lines changed: 124 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
package org.bimserver.emf;
2-
3-
/******************************************************************************
4-
* Copyright (C) 2009-2019 BIMserver.org
5-
*
6-
* This program is free software: you can redistribute it and/or modify
7-
* it under the terms of the GNU Affero General Public License as
8-
* published by the Free Software Foundation, either version 3 of the
9-
* License, or (at your option) any later version.
10-
*
11-
* This program is distributed in the hope that it will be useful,
12-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14-
* GNU Affero General Public License for more details.
15-
*
16-
* You should have received a copy of the GNU Affero General Public License
17-
* along with this program. If not, see {@literal<http://www.gnu.org/licenses/>}.
18-
*****************************************************************************/
19-
20-
import java.io.BufferedReader;
21-
1+
package org.bimserver.emf;
2+
3+
/******************************************************************************
4+
* Copyright (C) 2009-2019 BIMserver.org
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see {@literal<http://www.gnu.org/licenses/>}.
18+
*****************************************************************************/
19+
20+
import java.io.BufferedReader;
21+
2222
/******************************************************************************
2323
* Copyright (C) 2009-2018 BIMserver.org
2424
*
@@ -36,53 +36,53 @@
3636
* along with this program. If not, see {@literal<http://www.gnu.org/licenses/>}.
3737
*****************************************************************************/
3838

39-
import java.io.ByteArrayInputStream;
40-
import java.io.ByteArrayOutputStream;
41-
import java.io.File;
42-
import java.io.IOException;
43-
import java.io.InputStream;
44-
import java.io.InputStreamReader;
45-
import java.util.Date;
46-
import java.util.HashSet;
47-
import java.util.List;
48-
import java.util.Set;
49-
import java.util.UUID;
50-
51-
import org.apache.commons.codec.binary.Base64;
52-
import org.apache.commons.io.FileUtils;
53-
import org.apache.commons.io.IOUtils;
54-
import org.bimserver.emf.IdEObjectImpl.State;
55-
import org.bimserver.models.geometry.GeometryFactory;
56-
import org.bimserver.models.geometry.Vector3f;
57-
import org.bimserver.models.ifc2x3tc1.Ifc2x3tc1Factory;
58-
import org.bimserver.models.ifc2x3tc1.IfcGloballyUniqueId;
59-
import org.bimserver.models.store.IfcHeader;
60-
import org.bimserver.models.store.StoreFactory;
61-
import org.bimserver.models.store.StorePackage;
62-
import org.bimserver.plugins.deserializers.DeserializeException;
63-
import org.bimserver.plugins.deserializers.DeserializerErrorCode;
64-
import org.bimserver.shared.ListWaitingObject;
65-
import org.bimserver.shared.WaitingList;
66-
import org.bimserver.shared.exceptions.BimServerClientException;
67-
import org.eclipse.emf.common.util.AbstractEList;
68-
import org.eclipse.emf.common.util.EList;
69-
import org.eclipse.emf.ecore.EAttribute;
70-
import org.eclipse.emf.ecore.EClass;
71-
import org.eclipse.emf.ecore.EClassifier;
72-
import org.eclipse.emf.ecore.EEnum;
73-
import org.eclipse.emf.ecore.EObject;
74-
import org.eclipse.emf.ecore.EReference;
75-
import org.eclipse.emf.ecore.EStructuralFeature;
76-
import org.eclipse.emf.ecore.EcorePackage;
77-
import org.slf4j.Logger;
78-
import org.slf4j.LoggerFactory;
79-
80-
import com.google.common.base.Charsets;
81-
import com.google.gson.stream.JsonReader;
82-
import com.google.gson.stream.JsonToken;
83-
84-
import nl.tue.buildingsmart.schema.Attribute;
85-
import nl.tue.buildingsmart.schema.EntityDefinition;
39+
import java.io.ByteArrayInputStream;
40+
import java.io.ByteArrayOutputStream;
41+
import java.io.File;
42+
import java.io.IOException;
43+
import java.io.InputStream;
44+
import java.io.InputStreamReader;
45+
import java.util.Date;
46+
import java.util.HashSet;
47+
import java.util.List;
48+
import java.util.Set;
49+
import java.util.UUID;
50+
51+
import org.apache.commons.codec.binary.Base64;
52+
import org.apache.commons.io.FileUtils;
53+
import org.apache.commons.io.IOUtils;
54+
import org.bimserver.emf.IdEObjectImpl.State;
55+
import org.bimserver.models.geometry.GeometryFactory;
56+
import org.bimserver.models.geometry.Vector3f;
57+
import org.bimserver.models.ifc2x3tc1.Ifc2x3tc1Factory;
58+
import org.bimserver.models.ifc2x3tc1.IfcGloballyUniqueId;
59+
import org.bimserver.models.store.IfcHeader;
60+
import org.bimserver.models.store.StoreFactory;
61+
import org.bimserver.models.store.StorePackage;
62+
import org.bimserver.plugins.deserializers.DeserializeException;
63+
import org.bimserver.plugins.deserializers.DeserializerErrorCode;
64+
import org.bimserver.shared.ListWaitingObject;
65+
import org.bimserver.shared.WaitingList;
66+
import org.bimserver.shared.exceptions.BimServerClientException;
67+
import org.eclipse.emf.common.util.AbstractEList;
68+
import org.eclipse.emf.common.util.EList;
69+
import org.eclipse.emf.ecore.EAttribute;
70+
import org.eclipse.emf.ecore.EClass;
71+
import org.eclipse.emf.ecore.EClassifier;
72+
import org.eclipse.emf.ecore.EEnum;
73+
import org.eclipse.emf.ecore.EObject;
74+
import org.eclipse.emf.ecore.EReference;
75+
import org.eclipse.emf.ecore.EStructuralFeature;
76+
import org.eclipse.emf.ecore.EcorePackage;
77+
import org.slf4j.Logger;
78+
import org.slf4j.LoggerFactory;
79+
80+
import com.google.common.base.Charsets;
81+
import com.google.gson.stream.JsonReader;
82+
import com.google.gson.stream.JsonToken;
83+
84+
import nl.tue.buildingsmart.schema.Attribute;
85+
import nl.tue.buildingsmart.schema.EntityDefinition;
8686
import nl.tue.buildingsmart.schema.InverseAttribute;
8787

8888
public class SharedJsonDeserializer {
@@ -186,11 +186,11 @@ private IdEObject processObject(IfcModelInterface model, WaitingList<Long> waiti
186186
IdEObjectImpl object = null;
187187
jsonReader.beginObject();
188188
if (jsonReader.nextName().equals("_i")) {
189-
long oid = jsonReader.nextLong();
190-
if (jsonReader.nextName().equals("_u")) {
191-
UUID uuid = UUID.fromString(jsonReader.nextString());
192-
if (jsonReader.nextName().equals("_r")) {
193-
int rid = jsonReader.nextInt();
189+
long oid = jsonReader.nextLong();
190+
if (jsonReader.nextName().equals("_u")) {
191+
UUID uuid = UUID.fromString(jsonReader.nextString());
192+
if (jsonReader.nextName().equals("_r")) {
193+
int rid = jsonReader.nextInt();
194194
if (jsonReader.nextName().equals("_t")) {
195195
String type = jsonReader.nextString();
196196
if (eClass == null) {
@@ -205,13 +205,13 @@ private IdEObject processObject(IfcModelInterface model, WaitingList<Long> waiti
205205
if (eClass == StorePackage.eINSTANCE.getIfcHeader()) {
206206
object = (IdEObjectImpl) StoreFactory.eINSTANCE.createIfcHeader();
207207
} else {
208-
object = (IdEObjectImpl) model.create(eClass, oid);
208+
object = model.create(eClass, oid);
209209
}
210210
}
211211

212-
object.useInverses(false);
213-
((IdEObjectImpl)object).setUuid(uuid);
214-
((IdEObjectImpl)object).setRid(rid);
212+
object.useInverses(false);
213+
object.setUuid(uuid);
214+
object.setRid(rid);
215215

216216
if (jsonReader.nextName().equals("_s")) {
217217
int state = jsonReader.nextInt();
@@ -280,34 +280,42 @@ private IdEObject processObject(IfcModelInterface model, WaitingList<Long> waiti
280280
innerList.add(readPrimitive(jsonReader, listFeature));
281281
}
282282
} else {
283+
int innerIndex = 0;
283284
while (jsonReader.hasNext()){
284-
jsonReader.beginObject();
285+
jsonReader.beginObject();
285286
String nextName = jsonReader.nextName();
286287
if (nextName.equals("_t")){
287288
String t = jsonReader.nextString();
288289
IdEObject wrappedObject = model.create(model.getPackageMetaData().getEClass(t), -1);
289-
EList<EStructuralFeature> eAllStructuralFeatures = wrappedObject.eClass().getEAllStructuralFeatures();
290-
for (EStructuralFeature eStructuralFeature2 : eAllStructuralFeatures) {
291-
if (jsonReader.nextName().contentEquals(eStructuralFeature2.getName())) {
292-
wrappedObject.eSet(eStructuralFeature2, readPrimitive(jsonReader, eStructuralFeature2));
293-
} else {
294-
// trouble
290+
EList<EStructuralFeature> eAllStructuralFeatures = wrappedObject.eClass().getEAllStructuralFeatures();
291+
for (EStructuralFeature eStructuralFeature2 : eAllStructuralFeatures) {
292+
if (jsonReader.nextName().contentEquals(eStructuralFeature2.getName())) {
293+
wrappedObject.eSet(eStructuralFeature2, readPrimitive(jsonReader, eStructuralFeature2));
294+
} else {
295+
// trouble
295296
}
296-
}
297+
}
297298
innerList.add(wrappedObject);
298-
} else if (nextName.equals("_r")) {
299-
// Reference
300-
long referenceOid = jsonReader.nextLong();
301-
if (jsonReader.nextName().equals("_t")) {
302-
String refType = jsonReader.nextString();
303-
IdEObject refObject = (IdEObject) model.create(model.getPackageMetaData().getEClassIncludingDependencies(refType), referenceOid);
304-
((IdEObjectImpl)refObject).setLoadingState(State.OPPOSITE_SETTING);
305-
model.add(refObject.getOid(), refObject);
306-
addToList(listFeature, index, innerList, refObject);
307-
((IdEObjectImpl)refObject).setLoadingState(State.TO_BE_LOADED);
308-
}
299+
} else if (nextName.equals("_r")) {
300+
// Reference
301+
long referenceOid = jsonReader.nextLong();
302+
if (jsonReader.nextName().equals("_t")) {
303+
String refType = jsonReader.nextString();
304+
if(model.containsNoFetch(referenceOid)){
305+
addToList(listFeature, innerIndex, innerList, model.get(referenceOid));
306+
} else {
307+
IdEObject refObject;
308+
refObject = model.create(model.getPackageMetaData().getEClassIncludingDependencies(refType), referenceOid);
309+
((IdEObjectImpl)refObject).setLoadingState(State.OPPOSITE_SETTING);
310+
model.add(refObject.getOid(), refObject);
311+
addToList(listFeature, innerIndex, innerList, refObject);
312+
((IdEObjectImpl)refObject).setLoadingState(State.TO_BE_LOADED);
313+
// TODO use waiting list to track dangling references? - see processRef method which currently does not work for 2D lists
314+
}
315+
}
309316
}
310317
jsonReader.endObject();
318+
innerIndex++;
311319
}
312320
}
313321
jsonReader.endArray();
@@ -318,24 +326,24 @@ private IdEObject processObject(IfcModelInterface model, WaitingList<Long> waiti
318326
String t = jsonReader.nextString();
319327
if (jsonReader.nextName().equals("_v")) {
320328
if (jsonReader.peek() == JsonToken.BEGIN_ARRAY) {
321-
// Embedded array
322-
jsonReader.beginArray();
323-
324-
// Here we are, IfcLineIndex should implement IfcSegmentIndexSelect, just as IfcArcIndex should
325-
326-
IdEObjectImpl listObject = model.create(model.getPackageMetaData().getEClassIncludingDependencies(t));
327-
// addToList(eStructuralFeature, index, list, listObject);
328-
EStructuralFeature listFeature = listObject.eClass().getEStructuralFeature("wrappedValue");
329-
AbstractEList innerList = (AbstractEList) listObject.eGet(listFeature);
330-
while (jsonReader.hasNext()){
331-
innerList.add(readPrimitive(jsonReader, listFeature));
332-
}
333-
jsonReader.endArray();
334-
list.add(listObject);
335-
} else {
336-
IdEObject wrappedObject = (IdEObject) model.create(model.getPackageMetaData().getEClass(t), -1);
337-
EStructuralFeature wv = wrappedObject.eClass().getEStructuralFeature("wrappedValue");
338-
wrappedObject.eSet(wv, readPrimitive(jsonReader, wv));
329+
// Embedded array
330+
jsonReader.beginArray();
331+
332+
// Here we are, IfcLineIndex should implement IfcSegmentIndexSelect, just as IfcArcIndex should
333+
334+
IdEObjectImpl listObject = model.create(model.getPackageMetaData().getEClassIncludingDependencies(t));
335+
// addToList(eStructuralFeature, index, list, listObject);
336+
EStructuralFeature listFeature = listObject.eClass().getEStructuralFeature("wrappedValue");
337+
AbstractEList innerList = (AbstractEList) listObject.eGet(listFeature);
338+
while (jsonReader.hasNext()){
339+
innerList.add(readPrimitive(jsonReader, listFeature));
340+
}
341+
jsonReader.endArray();
342+
list.add(listObject);
343+
} else {
344+
IdEObject wrappedObject = (IdEObject) model.create(model.getPackageMetaData().getEClass(t), -1);
345+
EStructuralFeature wv = wrappedObject.eClass().getEStructuralFeature("wrappedValue");
346+
wrappedObject.eSet(wv, readPrimitive(jsonReader, wv));
339347
list.add(wrappedObject);
340348
}
341349
} else {
@@ -364,7 +372,6 @@ private IdEObject processObject(IfcModelInterface model, WaitingList<Long> waiti
364372
if (jsonReader.nextName().equals("_t")) {
365373
String refType = jsonReader.nextString();
366374
EClass referenceEClass = model.getPackageMetaData().getEClassIncludingDependencies(refType);
367-
368375
if (model.getNoFetch(refOid) != null) {
369376
processRef(model, waitingList, object, eStructuralFeature, index, list, refOid);
370377
} else {
@@ -486,7 +493,7 @@ private IdEObject processObject(IfcModelInterface model, WaitingList<Long> waiti
486493
}
487494
} else {
488495
LOGGER.info("_r expected");
489-
}
496+
}
490497
} else {
491498
LOGGER.info("_u expected");
492499
}
@@ -583,7 +590,7 @@ private Object readPrimitive(JsonReader jsonReader, EStructuralFeature eStructur
583590
return eEnum.getEEnumLiteral(jsonReader.nextString()).getInstance();
584591
}
585592
} else {
586-
throw new DeserializeException(DeserializerErrorCode.UNIMPLEMENTED_BIMSERVER_FEATURE, "Unimplemented type " + eStructuralFeature.getEType().getName());
593+
throw new DeserializeException(DeserializerErrorCode.UNIMPLEMENTED_BIMSERVER_FEATURE, "Unimplemented type " + eStructuralFeature.getEType().getName());
587594
}
588595
}
589596
}

0 commit comments

Comments
 (0)