
fiftyone.devicedetection.shared.DeviceDataBaseOnPremise Maven / Gradle / Ivy
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
* Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
*
* This Original Work is licensed under the European Union Public Licence
* (EUPL) v.1.2 and is subject to its terms as set out below.
*
* If a copy of the EUPL was not distributed with this file, You can obtain
* one at https://opensource.org/licenses/EUPL-1.2.
*
* The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
* amended by the European Commission) shall be deemed incompatible for
* the purposes of the Work and the provisions of the compatibility
* clause in Article 5 of the EUPL shall not apply.
*
* If using the Work as, or as part of, a network application, by
* including the attribution notice(s) required under Article 5 of the EUPL
* in the end user terms of the application under an appropriate heading,
* such notice(s) shall fulfill the requirements of that article.
* ********************************************************************* */
package fiftyone.devicedetection.shared;
import fiftyone.pipeline.core.data.ElementPropertyMetaData;
import fiftyone.pipeline.core.data.FlowData;
import fiftyone.pipeline.core.data.TryGetResult;
import fiftyone.pipeline.core.data.types.JavaScript;
import fiftyone.pipeline.engines.data.AspectData;
import fiftyone.pipeline.engines.data.AspectPropertyMetaData;
import fiftyone.pipeline.engines.data.AspectPropertyValue;
import fiftyone.pipeline.engines.flowelements.AspectEngine;
import fiftyone.pipeline.engines.services.MissingPropertyService;
import org.slf4j.Logger;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static fiftyone.pipeline.util.Types.getPrimitiveTypeMap;
/**
* Base class used for all 51Degrees on-premise device detection results classes.
*/
public abstract class DeviceDataBaseOnPremise extends DeviceDataBase {
protected final Map, Class>> primitiveTypes;
private final Object dataLock = new Object();
private final Object getLock = new Object();
private boolean mapPopulated = false;
/**
* Constructs a new instance.
* @param logger used for logging
* @param flowData the {@link FlowData} instance this element data will be
* associated with
* @param engine the engine which created the instance
* @param missingPropertyService service used to determine the reason for
* a property value being missing
*/
protected DeviceDataBaseOnPremise(
Logger logger,
FlowData flowData,
AspectEngine extends AspectData, ? extends AspectPropertyMetaData> engine,
MissingPropertyService missingPropertyService) {
super(logger, flowData, engine, missingPropertyService);
primitiveTypes = getPrimitiveTypeMap();
}
/**
* Determine whether a property is available to return values from the
* underlying results.
* @param propertyName name of the property to check
* @return true if the property is available
*/
protected abstract boolean propertyIsAvailable(String propertyName);
/**
* Get the values for the specified property as a {@link List}. For
* on-premise engines, this is the raw form they are stored in the data file
* as.
* @param propertyName name of the property to get values for
* @return values as a list
*/
public abstract AspectPropertyValue> getValues(
String propertyName);
/**
* Get the value for the specified property as a {@link String}.
* @param propertyName name of the property to the the value for
* @return value as a string
*/
protected abstract AspectPropertyValue getValueAsString(
String propertyName);
/**
* Get the value for the specified property as an {@link Integer}. If the
* property cannot be represented as an {@link Integer}, then the result
* will have no value i.e. {@link AspectPropertyValue#hasValue()} == false.
* @param propertyName name of the property to get the value for
* @return value a an integer
*/
protected abstract AspectPropertyValue getValueAsInteger(
String propertyName);
/**
* Get the value for the specified property as a {@link Boolean}. If the
* property cannot be represented as a {@link Boolean}, then the result
* will have no value i.e. {@link AspectPropertyValue#hasValue()} == false.
* @param propertyName name of the property to get the value for
* @return value a an integer
*/
protected abstract AspectPropertyValue getValueAsBool(
String propertyName);
/**
* Get the value for the specified property as a {@link Double}. If the
* property cannot be represented as a {@link Double}, then the result
* will have no value i.e. {@link AspectPropertyValue#hasValue()} == false.
* @param propertyName name of the property to get the value for
* @return value a an integer
*/
protected abstract AspectPropertyValue getValueAsDouble(
String propertyName);
/**
* Get the value for the specified property as a {@link JavaScript}.
* @param propertyName name of the property to the the value for
* @return value as a JavaScript
*/
protected abstract AspectPropertyValue getValueAsJavaScript(
String propertyName);
/**
* By default, the base map will not be populated as doing so is a fairly
* expensive operation. Instead, we override the AsDictionary method to
* populate the dictionary on-demand.
* @return the data
*/
@Override
public Map asKeyMap() {
if (mapPopulated == false) {
synchronized (dataLock) {
if (mapPopulated == false) {
Map map = new TreeMap<>(
String.CASE_INSENSITIVE_ORDER);
for (ElementPropertyMetaData property : getPipeline()
.getElementAvailableProperties()
.get(getEngines().get(0).getElementDataKey()).values()) {
map.put(property.getName().toLowerCase(),
getAs(property.getName(),
AspectPropertyValue.class,
property.getType()));
}
populateFromMap(map);
mapPopulated = true;
}
}
}
// Now that the base map has been populated,
// we can return it.
return super.asKeyMap();
}
/**
* Get the {@link Class} representing the type values a property contains
* from its name.
* @param propertyName name of the property
* @return value type, or {@link Object} if unknown
*/
@SuppressWarnings("unchecked")
protected Class> getPropertyType(String propertyName) {
Class> type = Object.class;
Map properties =
getPipeline().getElementAvailableProperties()
.get(getEngines().get(0).getElementDataKey());
if (properties != null) {
ElementPropertyMetaData property = properties.get(propertyName);
if (property != null) {
type = (Class
© 2015 - 2025 Weber Informatics LLC | Privacy Policy