/** * Reads line by line and creates new entities * * @throws IOException * @throws IfcNotFoundException * @throws IfcParserException */ public List<IfcEntity> parseEntities( IfcLineReader reader, IfcSchema schema, boolean isHeaderSection, boolean ignoreUnknownTypes) throws IOException, IfcNotFoundException, IfcParserException { this.schema = schema; this.reader = reader; List<IfcEntity> entities = new ArrayList<>(); String statement; String[] tokens; // // getting entity headers // while ((statement = reader.getNextStatement()) != null) { IfcEntity entity; String entityAttributesString; if (!isHeaderSection) { tokens = RegexUtils.split2(statement, IfcVocabulary.StepFormat.LINE_NUMBER); if (tokens.length != 2) { continue; } tokens = RegexUtils.split2(tokens[1], IfcVocabulary.StepFormat.EQUAL); // // create entity // long lineNumber = Long.parseLong(tokens[0].trim()); entity = getEntity(lineNumber); entityAttributesString = tokens[1].trim(); } else { entity = new IfcEntity(0); entityAttributesString = statement; } // // set entity type // int indexOfOpeningBracket = entityAttributesString.indexOf(StringUtils.OPENING_ROUND_BRACKET); String entityTypeInfoName = entityAttributesString.substring(0, indexOfOpeningBracket).trim(); IfcEntityTypeInfo entityTypeInfo; try { entityTypeInfo = schema.getEntityTypeInfo(entityTypeInfoName); } catch (IfcNotFoundException e) { if (ignoreUnknownTypes) { continue; } else { throw e; } } entity.setTypeInfo(entityTypeInfo); entityAttributesString = entityAttributesString.substring( indexOfOpeningBracket + 1, entityAttributesString.length() - 1); List<IfcAttributeInfo> attributeInfos = entityTypeInfo.getInheritedAttributeInfos(); // // parse attribute string to get attribute values // List<IfcValue> attributeValues = parseAttributeValues( new StrBuilderWrapper(entityAttributesString), entity, attributeInfos, null, null); setEntityAttributeValues(entity, attributeInfos, attributeValues); // // add entity to the model // entities.add(entity); } if (!isHeaderSection) { for (IfcEntity entity : entities) { entity.bindInverseLinks(); } } return entities; }
/** * Parses an entity's attribute string to get attribute values * * @param attributeStringBuilder * @param attributeValueType * @return a single attribute value or list of attribute values * @throws IfcFormatException * @throws IfcNotFoundException * @throws IfcValueTypeConflictException */ private List<IfcValue> parseAttributeValues( StrBuilderWrapper attributeStrBuilderWrapper, IfcEntity entity, List<IfcAttributeInfo> entityAttributeInfos, IfcTypeInfo commonAttributeTypeInfo, EnumSet<IfcTypeEnum> commonValueTypes) throws IfcFormatException, IfcNotFoundException { logger.debug(String.format("Parsing entity '%s'", entity)); List<IfcValue> attributeValues = new ArrayList<>(); for (int attributeIndex = 0; !attributeStrBuilderWrapper.trimLeft().isEmpty(); ++attributeIndex) { EnumSet<IfcTypeEnum> attributeValueTypes; IfcAttributeInfo attributeInfo; IfcTypeInfo attributeTypeInfo; if (commonValueTypes == null) { assert (attributeIndex < entityAttributeInfos.size()) : String.format( "attributeIndex=%d, entityAttributeInfos.size=%s, attributeStrBuilderWrapper='%s'", attributeIndex, entityAttributeInfos, attributeStrBuilderWrapper); attributeInfo = entityAttributeInfos.get(attributeIndex); attributeTypeInfo = attributeInfo.getAttributeTypeInfo(); attributeValueTypes = attributeTypeInfo.getValueTypes(); } else { assert (commonAttributeTypeInfo != null); attributeInfo = entityAttributeInfos.get(0); attributeTypeInfo = commonAttributeTypeInfo; attributeValueTypes = commonValueTypes; } if (attributeTypeInfo instanceof IfcCollectionTypeInfo) { attributeTypeInfo = ((IfcCollectionTypeInfo) attributeTypeInfo).getItemTypeInfo(); } switch (attributeStrBuilderWrapper.charAt(0)) { case IfcVocabulary.StepFormat.LINE_NUMBER_SYMBOL: // Entity attributeStrBuilderWrapper.skip(1); Long remoteLineNumber = attributeStrBuilderWrapper.getLong(); IfcEntity remoteEntity = getEntity(remoteLineNumber); if (remoteEntity == null) { throw new IfcNotFoundException("Entity not found: #" + remoteLineNumber); } attributeValues.add(remoteEntity); break; case IfcVocabulary.StepFormat.STRING_VALUE_SYMBOL: String s = attributeStrBuilderWrapper.getStringBetweenSingleQuotes(); assert attributeValueTypes.size() == 1 : "Expect attributeValueTypes.size() == 1"; // if (!attributeValueTypes.contains(IfcTypeEnum.GUID)) { attributeValues.add(new IfcLiteralValue(s, attributeTypeInfo, IfcTypeEnum.STRING)); // break; // } else { // attributeValues.add(new IfcGuidValue(s)); // break; // } break; case IfcVocabulary.StepFormat.ENUMERATION_VALUE_SYMBOL: s = attributeStrBuilderWrapper.getStringBetweenSimilarCharacters( IfcVocabulary.StepFormat.ENUMERATION_VALUE_SYMBOL); assert attributeValueTypes.size() == 1 : "Expect attributeValueTypes.size() == 1"; if (!attributeValueTypes.contains(IfcTypeEnum.LOGICAL)) { attributeValues.add(new IfcLiteralValue(s, attributeTypeInfo, IfcTypeEnum.ENUM)); } else { switch (s) { case "T": case "TRUE": attributeValues.add( new IfcLiteralValue( LogicalEnum.TRUE.toString(), attributeTypeInfo, IfcTypeEnum.LOGICAL)); break; case "F": case "FALSE": attributeValues.add( new IfcLiteralValue( LogicalEnum.FALSE.toString(), attributeTypeInfo, IfcTypeEnum.LOGICAL)); break; default: attributeValues.add( new IfcLiteralValue( LogicalEnum.UNKNOWN.toString(), attributeTypeInfo, IfcTypeEnum.LOGICAL)); break; } } break; case IfcVocabulary.StepFormat.NULL_SYMBOL: // $ attributeValues.add(IfcValue.NULL); attributeStrBuilderWrapper.skip(1); break; case IfcVocabulary.StepFormat.ANY_SYMBOL: // * attributeValues.add(IfcValue.ANY); attributeStrBuilderWrapper.skip(1); break; case StringUtils.OPENING_ROUND_BRACKET_CHAR: // List or Set String stringBetweenBrackets = attributeStrBuilderWrapper.getStringBetweenRoundBrackets(); StrBuilderWrapper sbWrapper = new StrBuilderWrapper(stringBetweenBrackets); List<IfcAttributeInfo> attributeInfos = new ArrayList<>(1); attributeInfos.add(attributeInfo); List<IfcValue> values = parseAttributeValues( sbWrapper, null, attributeInfos, attributeTypeInfo, attributeValueTypes); attributeValues.add(new IfcTemporaryCollectionValueWrapper(values)); break; default: if (Character.isAlphabetic(attributeStrBuilderWrapper.charAt(0))) { // // parsing sub entity // String subEntityTypeInfoName = attributeStrBuilderWrapper.getIdentifierName(); IfcNonEntityTypeInfo subNonEntityTypeInfo = schema.getNonEntityTypeInfo(subEntityTypeInfoName); attributeValueTypes = subNonEntityTypeInfo.getValueTypes(); s = attributeStrBuilderWrapper.getStringBetweenRoundBrackets(); assert (s != null); attributeInfos = new ArrayList<>(1); attributeInfos.add(attributeInfo); values = parseAttributeValues( new StrBuilderWrapper(s), null, attributeInfos, subNonEntityTypeInfo, attributeValueTypes); assert values.size() == 1 : "Expect only 1 argument: " + entity + ":" + values.toString(); // attributeValues.add(new IfcShortEntity(subNonEntityTypeInfo, // (IfcLiteralValue)values.get(0))); attributeValues.add((IfcLiteralValue) values.get(0)); } else { // // parsing number or datetime // assert attributeValueTypes.size() == 1 : "Expect attributeValueTypes.size() == 1"; IfcTypeEnum attributeValueType = (IfcTypeEnum) attributeValueTypes.toArray()[0]; Object value; if (attributeValueType == IfcTypeEnum.INTEGER) { value = attributeStrBuilderWrapper.getLong(); } else if (attributeValueType == IfcTypeEnum.REAL) { value = attributeStrBuilderWrapper.getDouble(); } else { assert attributeValueType == IfcTypeEnum.DATETIME; long timeStamp = attributeStrBuilderWrapper.getLong(); value = Calendar.getInstance(); ((Calendar) value).setTimeInMillis(timeStamp * 1000); } attributeValues.add( new IfcLiteralValue( value, (IfcNonEntityTypeInfo) attributeTypeInfo, attributeValueType)); } break; } attributeStrBuilderWrapper.trimLeft(); attributeStrBuilderWrapper.getFirstMatch(StrMatcher.commaMatcher()); } return attributeValues; }