All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.citygml4j.ADERegistry Maven / Gradle / Ivy

Go to download

citygml4j is a Java class library and API for facilitating work with the City Geography Markup Language (CityGML). citygml4j makes it easy to read, process, and write CityGML datasets, and to develop CityGML-aware software applications.

The newest version!
/*
 * citygml4j - The Open Source Java API for CityGML
 * https://github.com/citygml4j
 *
 * Copyright 2013-2020 Claus Nagel 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.citygml4j;

import org.atteo.classindex.ClassFilter;
import org.atteo.classindex.ClassIndex;
import org.citygml4j.model.CityGMLVersion;
import org.citygml4j.xml.ade.ADEContext;
import org.citygml4j.xml.ade.ADEException;
import org.citygml4j.xml.module.ade.ADEModule;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ADERegistry {
    private static ADERegistry instance;
    private final Map contexts = new ConcurrentHashMap<>();
    private final Map> modules = new ConcurrentHashMap<>();
    private final Map listeners = Collections.synchronizedMap(new WeakHashMap<>());

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

        return instance;
    }

    public boolean hasADEContexts() {
        return !contexts.isEmpty();
    }

    public List getADEContexts() {
        return new ArrayList<>(contexts.values());
    }

    public List getADEModules() {
        return modules.values().stream()
                .map(Map::values)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
    }

    public List getADEModules(CityGMLVersion version) {
        return new ArrayList<>(modules.getOrDefault(version, Collections.emptyMap()).values());
    }

    public ADEModule getADEModule(String namespaceURI) {
        for (Map value : modules.values()) {
            ADEModule module = value.get(namespaceURI);
            if (module != null)
                return module;
        }

        return null;
    }

    public ADEModule getADEModule(String namespaceURI, CityGMLVersion version) {
        return modules.getOrDefault(version, Collections.emptyMap()).get(namespaceURI);
    }

    public Set getADENamespaces() {
        return modules.values().stream()
                .map(Map::keySet)
                .flatMap(Collection::stream)
                .collect(Collectors.toSet());
    }

    public void loadADEContext(ADEContext context) throws ADEException {
        List modules = context.getADEModules();
        if (modules == null || modules.isEmpty())
            throw new ADEException("No ADE module defined for the ADE context " + context.getClass().getName() + ".");

        for (ADEModule module : modules) {
            if (module.getNamespaceURI() == null || module.getNamespaceURI().isEmpty())
                throw new ADEException("The ADE context " + context.getClass().getName() + " defines an ADE module without a namespace URI.");

            if (module.getCityGMLVersion() == null)
                throw new ADEException("The ADE context " + context.getClass().getName() + " defines an ADE module without a CityGML version.");

            if (this.modules.getOrDefault(module.getCityGMLVersion(), Collections.emptyMap()).get(module.getNamespaceURI()) != null) {
                throw new ADEException("An ADE module has already been registered for the namespace '" + module.getNamespaceURI() +
                        "' and the CityGML version " + module.getCityGMLVersion() + ".");
            }

            this.modules.computeIfAbsent(module.getCityGMLVersion(), v -> new ConcurrentHashMap<>()).put(module.getNamespaceURI(), module);
        }

        for (CityGMLContext listener : listeners.keySet())
            listener.loadADEContext(context);

        contexts.put(context.getClass().getName(), context);
    }

    public void loadADEContext(Class type) throws ADEException {
        ADEContext context;
        try {
            context = type.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new ADEException("The ADE context " + type.getName() + " lacks a default constructor.", e);
        }

        loadADEContext(context);
    }

    public void loadADEContexts(ClassLoader classLoader) throws ADEException {
        for (Class type : ClassFilter.only()
                .withoutModifiers(Modifier.ABSTRACT)
                .from(ClassIndex.getSubclasses(ADEContext.class, classLoader))) {
            loadADEContext(type);
        }
    }

    public void unloadADEContext(Class type) {
        ADEContext context = contexts.remove(type.getName());
        if (context != null) {
            for (ADEModule module : context.getADEModules())
                modules.getOrDefault(module.getCityGMLVersion(), Collections.emptyMap()).remove(module.getNamespaceURI());

            listeners.keySet().forEach(v -> v.unloadADEContext(context));
        }
    }

    public void unloadADEContext(ADEContext context) {
        unloadADEContext(context.getClass());
    }

    public void unloadADEContexts(ClassLoader classLoader) {
        for (Class type : ClassFilter.only()
                .withoutModifiers(Modifier.ABSTRACT)
                .from(ClassIndex.getSubclasses(ADEContext.class, classLoader))) {
            unloadADEContext(type);
        }
    }

    void addListener(CityGMLContext context) {
        listeners.put(context, Boolean.TRUE);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy