<commit_before>package org.citygml4j.binding.cityjson;

import org.citygml4j.binding.cityjson.feature.AbstractCityObjectType;
import org.citygml4j.binding.cityjson.feature.BridgeConstructionElementType;
import org.citygml4j.binding.cityjson.feature.BridgeInstallationType;
import org.citygml4j.binding.cityjson.feature.BridgePartType;
import org.citygml4j.binding.cityjson.feature.BridgeType;
import org.citygml4j.binding.cityjson.feature.BuildingInstallationType;
import org.citygml4j.binding.cityjson.feature.BuildingPartType;
import org.citygml4j.binding.cityjson.feature.BuildingType;
import org.citygml4j.binding.cityjson.feature.CityFurnitureType;
import org.citygml4j.binding.cityjson.feature.CityObjectGroupType;
import org.citygml4j.binding.cityjson.feature.GenericCityObjectType;
import org.citygml4j.binding.cityjson.feature.LandUseType;
import org.citygml4j.binding.cityjson.feature.PlantCoverType;
import org.citygml4j.binding.cityjson.feature.RailwayType;
import org.citygml4j.binding.cityjson.feature.RoadType;
import org.citygml4j.binding.cityjson.feature.SolitaryVegetationObjectType;
import org.citygml4j.binding.cityjson.feature.TINReliefType;
import org.citygml4j.binding.cityjson.feature.TransportSquareType;
import org.citygml4j.binding.cityjson.feature.TunnelInstallationType;
import org.citygml4j.binding.cityjson.feature.TunnelPartType;
import org.citygml4j.binding.cityjson.feature.TunnelType;
import org.citygml4j.binding.cityjson.feature.WaterBodyType;
import org.citygml4j.binding.cityjson.geometry.SemanticsType;
import org.citygml4j.model.citygml.ade.ADEException;

import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CityJSONRegistry {
    private static CityJSONRegistry instance;

    private final Map<String, Class<? extends AbstractCityObjectType>> types;
    private final Map<String, Class<? extends SemanticsType>> semanticSurfaces;
    private final Map<Class<? extends AbstractCityObjectType>, Map<String, Type>> attributes;

    private CityJSONRegistry() {
        types = new ConcurrentHashMap<>();
        semanticSurfaces = new ConcurrentHashMap<>();
        attributes = new ConcurrentHashMap<>();

        registerType("Building", BuildingType.class);
        registerType("BuildingPart", BuildingPartType.class);
        registerType("BuildingInstallation", BuildingInstallationType.class);
        registerType("Bridge", BridgeType.class);
        registerType("BridgePart", BridgePartType.class);
        registerType("BridgeInstallation", BridgeInstallationType.class);
        registerType("BridgeConstructionElement", BridgeConstructionElementType.class);
        registerType("TINRelief", TINReliefType.class);
        registerType("WaterBody", WaterBodyType.class);
        registerType("PlantCover", PlantCoverType.class);
        registerType("SolitaryVegetationObject", SolitaryVegetationObjectType.class);
        registerType("LandUse", LandUseType.class);
        registerType("CityFurniture", CityFurnitureType.class);
        registerType("GenericCityObject", GenericCityObjectType.class);
        registerType("Road", RoadType.class);
        registerType("Railway", RailwayType.class);
        registerType("TransportSquare", TransportSquareType.class);
        registerType("Tunnel", TunnelType.class);
        registerType("TunnelPart", TunnelPartType.class);
        registerType("TunnelInstallation", TunnelInstallationType.class);
        registerType("CityObjectGroup", CityObjectGroupType.class);
    }

    public static synchronized CityJSONRegistry getInstance() {
        if (instance == null)
            instance = new CityJSONRegistry();

        return instance;
    }

    public String getCityObjectType(AbstractCityObjectType cityObject) {
        String type = null;
        for (Map.Entry<String, Class<? extends AbstractCityObjectType>> entry : types.entrySet()) {
            if (cityObject.getClass() == entry.getValue()) {
                type = entry.getKey();
                break;
            }
        }

        if (type == null)
            type = cityObject.getClass().getTypeName();

        return type;
    }

    public Class<?> getCityObjectClass(String type) {
        Class<?> typeClass = types.get(type);
        if (typeClass == null) {
            try {
                Class<?> tmp = Class.forName(type);
                if (AbstractCityObjectType.class.isAssignableFrom(tmp))
                    typeClass = tmp;
            } catch (ClassNotFoundException e) {
                //
            }
        }

        return typeClass;
    }

    public void registerCityObject(String type, Class<? extends AbstractCityObjectType> typeClass) throws ADEException {
        if (type == null)
            throw new ADEException("The city object type must not be null.");

        if (typeClass == null)
            throw new ADEException("The city object type class must not be null.");

        if (types.containsKey(type))
            throw new ADEException("The city object type '" + type + "' is already registered.");

        if (types.containsValue(typeClass))
            throw new ADEException("The city object type class '" + typeClass.getTypeName() + "' is already registered.");

        if (!type.startsWith("+"))
            type = "+" + type;

        registerType(type, typeClass);
    }

    private void registerType(String type, Class<? extends AbstractCityObjectType> typeClass) {
        types.put(type, typeClass);
    }

    public void unregisterCityObject(String type) {
        types.remove(type);
    }

    public String getSemanticSurfaceType(SemanticsType semanticsType) {
        String type = null;
        for (Map.Entry<String, Class<? extends SemanticsType>> entry : semanticSurfaces.entrySet()) {
            if (semanticsType.getClass() == entry.getValue()) {
                type = entry.getKey();
                break;
            }
        }
<commit_msg>minor change<commit_after>package org.citygml4j.binding.cityjson;

import org.citygml4j.binding.cityjson.feature.AbstractCityObjectType;
import org.citygml4j.binding.cityjson.feature.BridgeConstructionElementType;
import org.citygml4j.binding.cityjson.feature.BridgeInstallationType;
import org.citygml4j.binding.cityjson.feature.BridgePartType;
import org.citygml4j.binding.cityjson.feature.BridgeType;
import org.citygml4j.binding.cityjson.feature.BuildingInstallationType;
import org.citygml4j.binding.cityjson.feature.BuildingPartType;
import org.citygml4j.binding.cityjson.feature.BuildingType;
import org.citygml4j.binding.cityjson.feature.CityFurnitureType;
import org.citygml4j.binding.cityjson.feature.CityObjectGroupType;
import org.citygml4j.binding.cityjson.feature.GenericCityObjectType;
import org.citygml4j.binding.cityjson.feature.LandUseType;
import org.citygml4j.binding.cityjson.feature.PlantCoverType;
import org.citygml4j.binding.cityjson.feature.RailwayType;
import org.citygml4j.binding.cityjson.feature.RoadType;
import org.citygml4j.binding.cityjson.feature.SolitaryVegetationObjectType;
import org.citygml4j.binding.cityjson.feature.TINReliefType;
import org.citygml4j.binding.cityjson.feature.TransportSquareType;
import org.citygml4j.binding.cityjson.feature.TunnelInstallationType;
import org.citygml4j.binding.cityjson.feature.TunnelPartType;
import org.citygml4j.binding.cityjson.feature.TunnelType;
import org.citygml4j.binding.cityjson.feature.WaterBodyType;
import org.citygml4j.binding.cityjson.geometry.SemanticsType;
import org.citygml4j.model.citygml.ade.ADEException;

import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CityJSONRegistry {
    private static CityJSONRegistry instance;

    private final Map<String, Class<? extends AbstractCityObjectType>> types;
    private final Map<String, Class<? extends SemanticsType>> semanticSurfaces;
    private final Map<Class<? extends AbstractCityObjectType>, Map<String, Type>> attributes;

    private CityJSONRegistry() {
        types = new ConcurrentHashMap<>();
        semanticSurfaces = new ConcurrentHashMap<>();
        attributes = new ConcurrentHashMap<>();

        types.put("Building", BuildingType.class);
        types.put("BuildingPart", BuildingPartType.class);
        types.put("BuildingInstallation", BuildingInstallationType.class);
        types.put("Bridge", BridgeType.class);
        types.put("BridgePart", BridgePartType.class);
        types.put("BridgeInstallation", BridgeInstallationType.class);
        types.put("BridgeConstructionElement", BridgeConstructionElementType.class);
        types.put("TINRelief", TINReliefType.class);
        types.put("WaterBody", WaterBodyType.class);
        types.put("PlantCover", PlantCoverType.class);
        types.put("SolitaryVegetationObject", SolitaryVegetationObjectType.class);
        types.put("LandUse", LandUseType.class);
        types.put("CityFurniture", CityFurnitureType.class);
        types.put("GenericCityObject", GenericCityObjectType.class);
        types.put("Road", RoadType.class);
        types.put("Railway", RailwayType.class);
        types.put("TransportSquare", TransportSquareType.class);
        types.put("Tunnel", TunnelType.class);
        types.put("TunnelPart", TunnelPartType.class);
        types.put("TunnelInstallation", TunnelInstallationType.class);
        types.put("CityObjectGroup", CityObjectGroupType.class);
    }

    public static synchronized CityJSONRegistry getInstance() {
        if (instance == null)
            instance = new CityJSONRegistry();

        return instance;
    }

    public String getCityObjectType(AbstractCityObjectType cityObject) {
        String type = null;
        for (Map.Entry<String, Class<? extends AbstractCityObjectType>> entry : types.entrySet()) {
            if (cityObject.getClass() == entry.getValue()) {
                type = entry.getKey();
                break;
            }
        }

        if (type == null)
            type = cityObject.getClass().getTypeName();

        return type;
    }

    public Class<?> getCityObjectClass(String type) {
        Class<?> typeClass = types.get(type);
        if (typeClass == null) {
            try {
                Class<?> tmp = Class.forName(type);
                if (AbstractCityObjectType.class.isAssignableFrom(tmp))
                    typeClass = tmp;
            } catch (ClassNotFoundException e) {
                //
            }
        }

        return typeClass;
    }

    public void registerCityObject(String type, Class<? extends AbstractCityObjectType> typeClass) throws ADEException {
        if (type == null)
            throw new ADEException("The city object type must not be null.");

        if (typeClass == null)
            throw new ADEException("The city object type class must not be null.");

        if (types.containsKey(type))
            throw new ADEException("The city object type '" + type + "' is already registered.");

        if (types.containsValue(typeClass))
            throw new ADEException("The city object type class '" + typeClass.getTypeName() + "' is already registered.");

        if (!type.startsWith("+"))
            type = "+" + type;

        types.put(type, typeClass);
    }

    public void unregisterCityObject(String type) {
        types.remove(type);
    }

    public String getSemanticSurfaceType(SemanticsType semanticsType) {
        String type = null;
        for (Map.Entry<String, Class<? extends SemanticsType>> entry : semanticSurfaces.entrySet()) {
            if (semanticsType.getClass() == entry.getValue()) {
                type = entry.getKey();
                break;
            }
        }

{'fraction_non_alphanumeric': 0.10506998975759645, 'fraction_numerical': 0.004267668146124957, 'mean_word_length': 3.4721374045801525, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5396264', 'n_tokens_mistral': 3316, 'n_tokens_neox': 3213, 'n_words': 599}