Advertisement
nerru86

Use 51Degrees data file to build interdependent menu.

Sep 2nd, 2015
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.04 KB | None | 0 0
  1. package fiftyone.generate.lists;
  2.  
  3. import fiftyone.mobile.detection.Provider;
  4. import fiftyone.mobile.detection.entities.Signature;
  5. import fiftyone.mobile.detection.factories.MemoryFactory;
  6. import java.io.IOException;
  7. import java.util.ArrayList;
  8. import java.util.Collections;
  9. import java.util.Comparator;
  10. import java.util.logging.Level;
  11. import java.util.logging.Logger;
  12.  
  13. /* *********************************************************************
  14.  * This Source Code Form is copyright of 51Degrees Mobile Experts Limited.
  15.  * Copyright 2014 51Degrees Mobile Experts Limited, 5 Charlotte Close,
  16.  * Caversham, Reading, Berkshire, United Kingdom RG4 7BY
  17.  *
  18.  * This Source Code Form is the subject of the following patent
  19.  * applications, owned by 51Degrees Mobile Experts Limited of 5 Charlotte
  20.  * Close, Caversham, Reading, Berkshire, United Kingdom RG4 7BY:
  21.  * European Patent Application No. 13192291.6; and
  22.  * United States Patent Application Nos. 14/085,223 and 14/085,301.
  23.  *
  24.  * This Source Code Form is subject to the terms of the Mozilla Public
  25.  * License, v. 2.0.
  26.  *
  27.  * If a copy of the MPL was not distributed with this file, You can obtain
  28.  * one at http://mozilla.org/MPL/2.0/.
  29.  *
  30.  * This Source Code Form is "Incompatible With Secondary Licenses", as
  31.  * defined by the Mozilla Public License, v. 2.0.
  32.  * ********************************************************************* */
  33. /**
  34.  * Class provides methods to create sequential lists based on device properties
  35.  * derived from the 51Degrees data file.
  36.  *
  37.  * Tested with V3.2 51Degrees java API.
  38.  */
  39. public class SequentialListGenerator {
  40.     //51Degrees Provider - allows access to the dataset, used for matching.
  41.     Provider provider;
  42.     //The original list of all the Signatures.
  43.     ArrayList<Signature> sortedSignatures;
  44.     //This list will be modified as filtering takes place.
  45.     ArrayList<Signature> filterSet;
  46.    
  47.     /**
  48.      * Default constructor.
  49.      * @param fiftyOneDataFile path to the 51Degrees data file.
  50.      */
  51.     public SequentialListGenerator(String fiftyOneDataFile) {
  52.         try {
  53.             //Use memory mode for this as Stream will take considerably longer.
  54.             long startTime = System.nanoTime();
  55.             this.provider = new Provider(
  56.                                 MemoryFactory.create(fiftyOneDataFile, false)
  57.                                         );
  58.             long endTime = System.nanoTime();
  59.             System.out.println("Provider initialised. Time elapsed: "
  60.                                 +((endTime - startTime)/1000000)
  61.                                 +"ms");
  62.         } catch (IOException ex) {
  63.             Logger.getLogger(SequentialListGenerator.class
  64.                     .getName()).log(Level.SEVERE, null, ex);
  65.         }
  66.     }
  67.    
  68.     /**
  69.      * Test run that produces a list of Browser versions running on Android
  70.      * Samsung IsSmartPhone devices.
  71.      */
  72.     public void testRunSamsungAndroidVersions() {
  73.        
  74.         long startTime, endTime;
  75.        
  76.         startTime = System.nanoTime();
  77.         System.out.print("Creating a copy of the Signatures list. ");
  78.         readSignaturesToRanked();
  79.         endTime = System.nanoTime();
  80.         System.out.println("Done. Time elapsed: "
  81.                             +((endTime - startTime)/1000000)
  82.                             +"ms");
  83.        
  84.         startTime = System.nanoTime();
  85.         System.out.print("Creating a copy of the Original list. ");
  86.         this.filterSet = new ArrayList<Signature>(this.sortedSignatures);
  87.         endTime = System.nanoTime();
  88.         System.out.println("Done. Time elapsed: "
  89.                             +((endTime - startTime)/1000000)
  90.                             +"ms");
  91.        
  92.         try {
  93.             startTime = System.nanoTime();
  94.             System.out.print("Filtering by Samsung vendor. ");
  95.             filterBy("HardwareVendor", "Samsung");
  96.             endTime = System.nanoTime();
  97.             System.out.println("Done. Time elapsed: "
  98.                             +((endTime - startTime)/1000000)
  99.                             +"ms");
  100.            
  101.             startTime = System.nanoTime();
  102.             System.out.print("Filtering by IsSmartPhone. ");
  103.             filterBy("IsSmartPhone", "True");
  104.             endTime = System.nanoTime();
  105.             System.out.println("Done. Time elapsed: "
  106.                             +((endTime - startTime)/1000000)
  107.                             +"ms");
  108.            
  109.             startTime = System.nanoTime();
  110.             System.out.print("Filtering by PlatformName. ");
  111.             filterBy("PlatformName", "Android");
  112.             endTime = System.nanoTime();
  113.             System.out.println("Done. Time elapsed: "
  114.                             +((endTime - startTime)/1000000)
  115.                             +"ms");
  116.            
  117.             printValuesForProperty("BrowserVersion");
  118.            
  119.         } catch (IOException ex) {
  120.             Logger.getLogger(SequentialListGenerator.class
  121.                     .getName()).log(Level.SEVERE, null, ex);
  122.         }
  123.     }
  124.    
  125.     /**
  126.      * Print all unique values for a given property.
  127.      * @param propertyName
  128.      */
  129.     public void printValuesForProperty(String propertyName) throws IOException {
  130.         ArrayList<String> uniqueValues = new ArrayList<String>();
  131.         //Set up the list of all possible values.
  132.         for (Signature s : this.filterSet) {
  133.             String value = s.getValues(propertyName).toString();
  134.             if (!uniqueValues.contains(value)) {
  135.                 uniqueValues.add(value);
  136.             }
  137.         }
  138.         //Print the list.
  139.         for (String val : uniqueValues) {
  140.             System.out.println(val);
  141.         }
  142.     }
  143.    
  144.     /**
  145.      * Runs an example test with pre-defined filtering parameters.
  146.      */
  147.     public void testRunIsMobileIsTablet() {
  148.         System.out.println("Total signatures in the data file: "
  149.                 +provider.dataSet.getSignatures().size());
  150.        
  151.         //Copy signatures in to master list.
  152.         System.out.print("Signatures read into array: ");
  153.         readSignaturesToRanked();
  154.         System.out.println(this.sortedSignatures.size());
  155.        
  156.         //Create a working copy. To keep the master list intact.
  157.         System.out.print("Signatures copied: ");
  158.         this.filterSet = new ArrayList<Signature>(this.sortedSignatures);
  159.         System.out.println(this.filterSet.size());
  160.        
  161.         //Filter by property:value
  162.         System.out.print("Size after filtered by IsMobile:true ");
  163.         try {
  164.             //Get all signatures relating where IsMobile is True.
  165.             filterBy("IsMobile", "True");
  166.         } catch (IOException ex) {
  167.             Logger.getLogger(SequentialListGenerator.class
  168.                     .getName()).log(Level.SEVERE, null, ex);
  169.         }
  170.         System.out.println(this.filterSet.size());
  171.        
  172.         //From the subset of signatures derived above now only leave those where
  173.         //the IsTablet property is set to True.
  174.         System.out.print("Size after filtered by IsTablet:true ");
  175.         try {
  176.             filterBy("IsTablet", "True");
  177.         } catch (IOException ex) {
  178.             Logger.getLogger(SequentialListGenerator.class
  179.                     .getName()).log(Level.SEVERE, null, ex);
  180.         }
  181.         System.out.println(this.filterSet.size());
  182.        
  183.         //Now cut off half the most unpopular signatures.
  184.         System.out.print("Signatures after removing low ranked signatures: ");
  185.         trimRank(50);
  186.         System.out.println(this.filterSet.size());
  187.        
  188.         //Print the result.
  189.         try {
  190.             report();
  191.         } catch (IOException ex) {
  192.             Logger.getLogger(SequentialListGenerator.class
  193.                     .getName()).log(Level.SEVERE, null, ex);
  194.         }
  195.     }
  196.    
  197.     /**
  198.      * Prints the content of the filtered signatures list.
  199.      * @throws IOException
  200.      */
  201.     public void report() throws IOException {
  202.         Collections.sort(filterSet, new RankComparator());
  203.         for (Signature s : this.filterSet) {
  204.             System.out.println("Device rank: "+s.getRank());
  205.             System.out.println("Device Name: "+s.getValues("HardwareVendor")
  206.                     +" : "+s.getValues("HardwareFamily")
  207.                     +" : "+s.getValues("HardwareModel"));
  208.             System.out.println("");
  209.             System.out.println("");
  210.             System.out.println("");
  211.         }
  212.     }
  213.    
  214.     /**
  215.      * Cuts off X percent of the signatures based on signature rank.
  216.      * @param thresholdPercentage
  217.      */
  218.     public void trimRank(int thresholdPercentage) {
  219.         //Initially first rank is both highest and lowest.
  220.         int smallest = this.filterSet.get(0).getRank();
  221.         int largest = this.filterSet.get(0).getRank();
  222.         //First pass.
  223.         //Find min and max.
  224.         for (int i = 0; i < this.filterSet.size(); i++) {
  225.             if (smallest > this.filterSet.get(i).getRank()) {
  226.                 smallest = this.filterSet.get(i).getRank();
  227.             }
  228.             if (largest < this.filterSet.get(i).getRank()) {
  229.                 largest = this.filterSet.get(i).getRank();
  230.             }
  231.         }
  232.         //Chop off the signatures that are below the threshold.
  233.         int threshold = (largest - smallest) / 100 * thresholdPercentage;
  234.         //Second pass.
  235.         //only leave signatures with rank below the threshold.
  236.         //the lower the rank the more popular the device.
  237.         ArrayList<Signature> temp = new ArrayList<Signature>();
  238.         for (Signature s : this.filterSet) {
  239.             if (s.getRank() < threshold) {
  240.                 temp.add(s);
  241.             }
  242.         }
  243.         this.filterSet = temp;
  244.     }
  245.    
  246.     /**
  247.      * Filter list of signatures by the property name and value. I.e. if you
  248.      * want to see all IsMobile devices. Use several times to narrow down the
  249.      * resulting set.
  250.      * @param propertyName
  251.      * @param propertyValue
  252.      * @throws IOException
  253.      */
  254.     public void filterBy(String propertyName, String propertyValue)
  255.                                                         throws IOException {
  256.         ArrayList<Signature> temp = new ArrayList<Signature>();
  257.         for (Signature s : this.filterSet) {
  258.             if (s.getValues(propertyName).toString().equals(propertyValue)) {
  259.                 temp.add(s);
  260.             }
  261.         }
  262.         this.filterSet = temp;
  263.     }
  264.    
  265.     /**
  266.      * Copies Signatures in to a list.
  267.      */
  268.     public final void readSignaturesToRanked() {
  269.         this.sortedSignatures = new ArrayList<Signature>();
  270.         for (Signature s : provider.dataSet.getSignatures()) {
  271.             this.sortedSignatures.add(s);
  272.         }
  273.     }
  274.    
  275.     /**
  276.      * Class used when sorting the list by Signature rank.
  277.      */
  278.     public class RankComparator implements Comparator<Signature> {
  279.         @Override
  280.         public int compare(Signature o1, Signature o2) {
  281.             int s1 = o1.getRank();
  282.             int s2 = o2.getRank();
  283.             return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;
  284.         }
  285.     }
  286. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement