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

fiftyone.mobile.detection.entities.Component Maven / Gradle / Ivy

The newest version!
/* *********************************************************************
 * This Source Code Form is copyright of 51Degrees Mobile Experts Limited. 
 * Copyright © 2017 51Degrees Mobile Experts Limited, 5 Charlotte Close,
 * Caversham, Reading, Berkshire, United Kingdom RG4 7BY
 * 
 * This Source Code Form is the subject of the following patents and patent
 * applications, owned by 51Degrees Mobile Experts Limited of 5 Charlotte
 * Close, Caversham, Reading, Berkshire, United Kingdom RG4 7BY: 
 * European Patent No. 2871816;
 * European Patent Application No. 17184134.9;
 * United States Patent Nos. 9,332,086 and 9,350,823; and
 * United States Patent Application No. 15/686,066.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0.
 * 
 * If a copy of the MPL was not distributed with this file, You can obtain
 * one at http://mozilla.org/MPL/2.0/.
 * 
 * This Source Code Form is "Incompatible With Secondary Licenses", as
 * defined by the Mozilla Public License, v. 2.0.
 * ********************************************************************* */
package fiftyone.mobile.detection.entities;

import fiftyone.mobile.detection.Dataset;
import fiftyone.mobile.detection.readers.BinaryReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Every device can be split into the major components of hardware, operating
 * system, crawler and browser. Each component has a number of properties and 
 * profiles assigned to it.
 * 

* Components are always held in memory as there is only a small number of them. *

* Full list of components in the data set can be retrieved like: * {@code dataSet.getComponents();}. Data set also provides a way to retrieve a * specific component: *

    *
  • Hardware component: {@code dataSet.getHardware();} *
  • Software component: {@code dataSet.getSoftware();} *
  • Browser component: {@code dataSet.getBrowsers();} *
  • Crawler component: {@code dataSet.getCrawlers();} *
*

* Component can be used to retrieve {@link #getProfiles() profiles} and * {@link #getProperties() properties}. *

* Objects of this class should not be created directly as they are part of the * internal logic. Use the relevant {@link Dataset} method to access these * objects. *

* For more information see: * * 51Degrees pattern data model. */ public abstract class Component extends BaseEntity implements Comparable { /** * Offset for the default profile that should be returned for the component. */ private final int defaultProfileOffset; /** * Offset for the unique name of the component. */ private final int nameOffset; /** * Constructs a new instance of Component * * @param dataSet The data set whose components list the component is * contained within. * @param index Index of the component within the list. * @param reader the BinaryReader object to be used. */ public Component(Dataset dataSet, int index, BinaryReader reader) { super(dataSet, index); componentId = reader.readByte(); nameOffset = reader.readInt32(); defaultProfileOffset = reader.readInt32(); } /** * Compares this component to another using the numeric ComponentId field. * * @param other The component to be compared against. * @return Indication of relative value based on ComponentId field. */ @Override public int compareTo(Component other) { return getComponentId() - other.getComponentId(); } /** * The default profile that should be returned for the component. * * @return default profile that should be returned for the component. * @throws java.io.IOException If there was a problem accessing data file. */ @SuppressWarnings("DoubleCheckedLocking") public Profile getDefaultProfile() throws IOException { Profile localDefaultProfile = defaultProfile; if (localDefaultProfile == null) { synchronized (this) { localDefaultProfile = defaultProfile; if (localDefaultProfile == null) { defaultProfile = localDefaultProfile = getDataSet().getProfiles().get(defaultProfileOffset); } } } return localDefaultProfile; } private volatile Profile defaultProfile; /** * An array of profiles associated with the component. * * @return an array of the {@link Profile profiles}. * @throws java.io.IOException if there was a problem accessing data file. */ @SuppressWarnings("DoubleCheckedLocking") public Profile[] getProfiles() throws IOException { Profile[] localProfiles = profiles; if (localProfiles == null) { synchronized (this) { localProfiles = profiles; if (localProfiles == null) { profiles = localProfiles = doGetProfiles(); } } } return localProfiles; } @SuppressWarnings("VolatileArrayField") private volatile Profile[] profiles; /** * Array of properties the component relates to. * * @return array of {@link Property properties} the component relates to. * @throws IOException if there was a problem accessing data file. */ @SuppressWarnings("DoubleCheckedLocking") public Property[] getProperties() throws IOException { Property[] localProperties = properties; if (localProperties == null) { synchronized (this) { localProperties = properties; if (localProperties == null) { properties = localProperties = doGetProperties(); } } } return localProperties; } @SuppressWarnings("VolatileArrayField") private volatile Property[] properties; /** * Initialises the references to profiles. * This method should not be called as it is part of the internal logic. * * @throws java.io.IOException if there was a problem accessing data file. */ public void init() throws IOException { if (name == null) name = getName(); if (defaultProfile == null) defaultProfile = getDataSet().getProfiles().get(defaultProfileOffset); if (profiles == null) profiles = doGetProfiles(); } /** * The unique name of the component as a string. * * @return unique name of the component as a string. * @throws java.io.IOException if there was a problem accessing data file. */ @SuppressWarnings("DoubleCheckedLocking") public String getName() throws IOException { String localName = name; if (localName == null) { synchronized (this) { localName = name; if (localName == null) { name = localName = getDataSet().strings.get(nameOffset).toString(); } } } return localName; } private volatile String name; /** * Returns an array of all the profiles that relate to this component. * @return An array of profiles associated with the component. */ private Profile[] doGetProfiles() throws IOException { List temp = new ArrayList(); for (Profile profile : getDataSet().getProfiles()) { if (profile.getComponent().getComponentId() == componentId) { temp.add(profile); } } return temp.toArray(new Profile[temp.size()]); } /** * Returns an array of the properties associated with the component. * @return An array of the properties associated with the component. */ private Property[] doGetProperties() throws IOException { List tempProperties = new ArrayList(); for (Property property : getDataSet().getProperties()) { if (property.getComponent().getComponentId() == componentId) { tempProperties.add(property); } } return tempProperties.toArray(new Property[tempProperties.size()]); } /** * The unique Id of the component. Does not change between different data * sets. Consists of four {@link Profile} IDs. * * @return The unique Id of the component. */ public int getComponentId() { return componentId; } private final int componentId; /** * Returns the components name. * * @return Returns the components name. */ @Override public String toString() { try { return this.getName(); } catch (IOException e) { return "Null"; } } /** * List of HTTP headers that should be checked in order to perform a * detection where more headers than User-Agent are available. * This data is used by methods that can HTTP Header collections. * * @return List of HTTP headers that should be checked in order to perform * detection. * @throws java.io.IOException if there was a problem accessing data file. */ public abstract String[] getHttpheaders() throws IOException; /** * Compares this instance to another using the component Id. * * @param other The component to be compared against. * @return True if {@link #componentId} of this component is equal to the * ComponentId of the other component. */ public boolean equals(Component other) { return getComponentId() == other.getComponentId(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy