Search in sources :

Example 1 with ModelDescriptor

use of org.openremote.model.ModelDescriptor in project openremote by openremote.

the class ValueUtil method doInitialise.

/**
 * Initialise the asset model and throw an {@link IllegalStateException} exception if a problem is detected; this
 * can be called by applications at startup to fail hard and fast if the asset model is un-usable
 */
protected static void doInitialise() throws IllegalStateException {
    assetInfoMap = new HashMap<>();
    assetTypeMap = new HashMap<>();
    agentLinkMap = new HashMap<>();
    metaItemDescriptors = new ArrayList<>();
    valueDescriptors = new ArrayList<>();
    generator = null;
    // Provide basic Object Mapper and enhance once asset model is initialised
    JSON = configureObjectMapper(new ObjectMapper());
    LOG.info("Initialising asset model...");
    Map<Class<? extends Asset<?>>, List<NameHolder>> assetDescriptorProviders = new TreeMap<>(new ClassHierarchyComparator());
    // noinspection RedundantCast
    assetDescriptorProviders.put((Class<? extends Asset<?>>) (Class<?>) Asset.class, new ArrayList<>(getDescriptorFields(Asset.class)));
    getModelProviders().forEach(assetModelProvider -> {
        LOG.fine("Processing asset model provider: " + assetModelProvider.getClass().getSimpleName());
        LOG.fine("Auto scan = " + assetModelProvider.useAutoScan());
        if (assetModelProvider.useAutoScan()) {
            Set<Class<? extends Asset<?>>> assetClasses = getAssetClasses(assetModelProvider);
            LOG.fine("Found " + assetClasses.size() + " asset class(es)");
            assetClasses.forEach(assetClass -> assetDescriptorProviders.computeIfAbsent(assetClass, aClass -> new ArrayList<>(getDescriptorFields(aClass))));
            ModelDescriptors modelDescriptors = assetModelProvider.getClass().getAnnotation(ModelDescriptors.class);
            if (modelDescriptors != null) {
                for (ModelDescriptor modelDescriptor : modelDescriptors.value()) {
                    Class<? extends Asset<?>> assetClass = (Class<? extends Asset<?>>) modelDescriptor.assetType();
                    assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
                        if (list == null) {
                            list = new ArrayList<>();
                        }
                        list.addAll(getDescriptorFields(modelDescriptor.provider()));
                        return list;
                    });
                }
            }
        }
        if (assetModelProvider.getAssetDescriptors() != null) {
            for (AssetDescriptor<?> assetDescriptor : assetModelProvider.getAssetDescriptors()) {
                Class<? extends Asset<?>> assetClass = assetDescriptor.getType();
                assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
                    if (list == null) {
                        list = new ArrayList<>();
                    }
                    list.add(assetDescriptor);
                    return list;
                });
            }
        }
        if (assetModelProvider.getAttributeDescriptors() != null) {
            assetModelProvider.getAttributeDescriptors().forEach((assetClass, attributeDescriptors) -> assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
                if (list == null) {
                    list = new ArrayList<>();
                }
                list.addAll(attributeDescriptors);
                return list;
            }));
        }
        if (assetModelProvider.getMetaItemDescriptors() != null) {
            assetModelProvider.getMetaItemDescriptors().forEach((assetClass, metaDescriptors) -> assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
                if (list == null) {
                    list = new ArrayList<>();
                }
                list.addAll(metaDescriptors);
                return list;
            }));
        }
        if (assetModelProvider.getValueDescriptors() != null) {
            assetModelProvider.getValueDescriptors().forEach((assetClass, valueDescriptors) -> assetDescriptorProviders.compute(assetClass, (aClass, list) -> {
                if (list == null) {
                    list = new ArrayList<>();
                }
                list.addAll(valueDescriptors);
                return list;
            }));
        }
    });
    // Build each asset info checking that no conflicts occur
    Map<Class<? extends Asset<?>>, List<NameHolder>> copy = new HashMap<>(assetDescriptorProviders);
    assetDescriptorProviders.forEach((assetClass, descriptors) -> {
        // Skip abstract classes as a start point - they should be in the class hierarchy of concrete class
        if (!Modifier.isAbstract(assetClass.getModifiers())) {
            AssetTypeInfo assetInfo = buildAssetInfo(assetClass, copy);
            assetInfoMap.put(assetClass, assetInfo);
            assetTypeMap.put(assetInfo.getAssetDescriptor().getName(), assetClass);
            if (assetInfo.getAssetDescriptor() instanceof AgentDescriptor) {
                AgentDescriptor<?, ?, ?> agentDescriptor = (AgentDescriptor<?, ?, ?>) assetInfo.getAssetDescriptor();
                String agentLinkName = agentDescriptor.getAgentLinkClass().getSimpleName();
                if (agentLinkMap.containsKey(agentLinkName) && agentLinkMap.get(agentLinkName) != agentDescriptor.getAgentLinkClass()) {
                    throw new IllegalStateException("AgentLink simple class name must be unique, duplicate found for: " + agentDescriptor.getAgentLinkClass());
                }
                agentLinkMap.put(agentLinkName, agentDescriptor.getAgentLinkClass());
            }
        }
    });
    // Check each value type implements serializable interface
    List<ValueDescriptor<?>> nonSerializableValueDescriptors = new ArrayList<>();
    valueDescriptors.forEach(vd -> {
        if (!Serializable.class.isAssignableFrom(vd.getType())) {
            nonSerializableValueDescriptors.add(vd);
        }
    });
    if (!nonSerializableValueDescriptors.isEmpty()) {
        String vds = nonSerializableValueDescriptors.stream().map(ValueDescriptor::toString).collect(Collectors.joining(",\n"));
        throw new IllegalStateException("One or more value types do not implement java.io.Serializable: " + vds);
    }
    // Call on finished on each provider
    assetModelProviders.forEach(AssetModelProvider::onAssetModelFinished);
    // Add agent link sub types to object mapper (need to avoid circular dependency)
    NamedType[] agentLinkSubTypes = Arrays.stream(getAgentLinkClasses()).map(agentLinkClass -> new NamedType(agentLinkClass, agentLinkClass.getSimpleName())).toArray(NamedType[]::new);
    JSON.registerSubtypes(agentLinkSubTypes);
    doSchemaInit();
}
Also used : Reflections(org.reflections.Reflections) ModelDescriptor(org.openremote.model.ModelDescriptor) com.fasterxml.jackson.databind.node(com.fasterxml.jackson.databind.node) AgentLink(org.openremote.model.asset.agent.AgentLink) BigDecimal(java.math.BigDecimal) AgentDescriptor(org.openremote.model.asset.agent.AgentDescriptor) JavaTimeModule(com.fasterxml.jackson.datatype.jsr310.JavaTimeModule) NamedType(com.fasterxml.jackson.databind.jsontype.NamedType) BigInteger(java.math.BigInteger) SyslogCategory(org.openremote.model.syslog.SyslogCategory) TypeReference(com.fasterxml.jackson.core.type.TypeReference) ConstraintViolation(javax.validation.ConstraintViolation) java.lang.reflect(java.lang.reflect) Entity(javax.persistence.Entity) ConstructorDetector(com.fasterxml.jackson.databind.cfg.ConstructorDetector) Predicate(java.util.function.Predicate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AssetTypeInfo(org.openremote.model.asset.AssetTypeInfo) Validator(javax.validation.Validator) JsonAutoDetect(com.fasterxml.jackson.annotation.JsonAutoDetect) NotNull(javax.validation.constraints.NotNull) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Jdk8Module(com.fasterxml.jackson.datatype.jdk8.Jdk8Module) ClasspathHelper(org.reflections.util.ClasspathHelper) SimpleFilterProvider(com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider) Serializable(java.io.Serializable) ModelDescriptors(org.openremote.model.ModelDescriptors) JsonSchemaGenerator(com.kjetland.jackson.jsonSchema.JsonSchemaGenerator) Agent(org.openremote.model.asset.agent.Agent) IntStream(java.util.stream.IntStream) java.util(java.util) AssetDescriptor(org.openremote.model.asset.AssetDescriptor) Modifier.isStatic(java.lang.reflect.Modifier.isStatic) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Level(java.util.logging.Level) Attribute(org.openremote.model.attribute.Attribute) Validation(javax.validation.Validation) PropertyAccessor(com.fasterxml.jackson.annotation.PropertyAccessor) AssetModelProvider(org.openremote.model.AssetModelProvider) com.fasterxml.jackson.databind(com.fasterxml.jackson.databind) ConfigurationBuilder(org.reflections.util.ConfigurationBuilder) Asset(org.openremote.model.asset.Asset) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) SerializationHelper(org.hibernate.internal.util.SerializationHelper) ParameterNamesModule(com.fasterxml.jackson.module.paramnames.ParameterNamesModule) SubTypesScanner(org.reflections.scanners.SubTypesScanner) org.openremote.model.value(org.openremote.model.value) Modifier.isPublic(java.lang.reflect.Modifier.isPublic) JsonCreator(com.fasterxml.jackson.annotation.JsonCreator) StandardModelProvider(org.openremote.model.StandardModelProvider) JsonInclude(com.fasterxml.jackson.annotation.JsonInclude) MODEL_AND_VALUES(org.openremote.model.syslog.SyslogCategory.MODEL_AND_VALUES) Serializable(java.io.Serializable) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AssetModelProvider(org.openremote.model.AssetModelProvider) NamedType(com.fasterxml.jackson.databind.jsontype.NamedType) Asset(org.openremote.model.asset.Asset) AgentDescriptor(org.openremote.model.asset.agent.AgentDescriptor) ModelDescriptors(org.openremote.model.ModelDescriptors) AssetTypeInfo(org.openremote.model.asset.AssetTypeInfo) ModelDescriptor(org.openremote.model.ModelDescriptor)

Aggregations

JsonAutoDetect (com.fasterxml.jackson.annotation.JsonAutoDetect)1 JsonCreator (com.fasterxml.jackson.annotation.JsonCreator)1 JsonInclude (com.fasterxml.jackson.annotation.JsonInclude)1 PropertyAccessor (com.fasterxml.jackson.annotation.PropertyAccessor)1 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 TypeReference (com.fasterxml.jackson.core.type.TypeReference)1 com.fasterxml.jackson.databind (com.fasterxml.jackson.databind)1 ConstructorDetector (com.fasterxml.jackson.databind.cfg.ConstructorDetector)1 NamedType (com.fasterxml.jackson.databind.jsontype.NamedType)1 com.fasterxml.jackson.databind.node (com.fasterxml.jackson.databind.node)1 SimpleFilterProvider (com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider)1 Jdk8Module (com.fasterxml.jackson.datatype.jdk8.Jdk8Module)1 JavaTimeModule (com.fasterxml.jackson.datatype.jsr310.JavaTimeModule)1 ParameterNamesModule (com.fasterxml.jackson.module.paramnames.ParameterNamesModule)1 JsonSchemaGenerator (com.kjetland.jackson.jsonSchema.JsonSchemaGenerator)1 Serializable (java.io.Serializable)1 java.lang.reflect (java.lang.reflect)1 Modifier.isPublic (java.lang.reflect.Modifier.isPublic)1 Modifier.isStatic (java.lang.reflect.Modifier.isStatic)1 BigDecimal (java.math.BigDecimal)1