OperatingSystem.java

  1. /*******************************************************************************
  2.  * Copyright 2012 André Rouél
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *   http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  ******************************************************************************/
  16. package net.sf.uadetector.internal.data.domain;

  17. import java.io.Serializable;
  18. import java.util.Collections;
  19. import java.util.Set;
  20. import java.util.SortedSet;
  21. import java.util.TreeSet;

  22. import javax.annotation.Nonnegative;
  23. import javax.annotation.Nonnull;
  24. import javax.annotation.concurrent.Immutable;
  25. import javax.annotation.concurrent.NotThreadSafe;

  26. import net.sf.qualitycheck.Check;
  27. import net.sf.uadetector.OperatingSystemFamily;
  28. import net.sf.uadetector.UserAgent;
  29. import net.sf.uadetector.VersionNumber;

  30. @Immutable
  31. public final class OperatingSystem implements Identifiable, Serializable {

  32.     @NotThreadSafe
  33.     public static final class Builder {

  34.         @Nonnull
  35.         private String family = "";

  36.         @Nonnull
  37.         private String icon = "";

  38.         private int id = Integer.MIN_VALUE;

  39.         @Nonnull
  40.         private String infoUrl = "";

  41.         @Nonnull
  42.         private String name = "";

  43.         @Nonnull
  44.         private SortedSet<OperatingSystemPattern> patterns = new TreeSet<OperatingSystemPattern>();

  45.         @Nonnull
  46.         private String producer = "";

  47.         @Nonnull
  48.         private String producerUrl = "";

  49.         @Nonnull
  50.         private String url = "";

  51.         public Builder() {
  52.             // default constructor
  53.         }

  54.         /**
  55.          * Creates a new instance of a builder with the data of the passed builder.
  56.          *
  57.          * @param builder
  58.          *            builder containing the data to be copied
  59.          * @throws net.sf.qualitycheck.exception.IllegalNullArgumentException
  60.          *             if the given argument is {@code null}
  61.          */
  62.         protected Builder(@Nonnull final Builder builder) {
  63.             Check.notNull(builder, "builder");

  64.             family = builder.family;
  65.             icon = builder.icon;
  66.             id = builder.id;
  67.             infoUrl = builder.infoUrl;
  68.             name = builder.name;
  69.             patterns.addAll(builder.patterns);
  70.             producer = builder.producer;
  71.             producerUrl = builder.producerUrl;
  72.             url = builder.url;
  73.         }

  74.         public Builder(@Nonnull final OperatingSystem operatingSystem) {
  75.             Check.notNull(operatingSystem, "operatingSystem");
  76.             id = Check.notNegative(operatingSystem.getId(), "operatingSystem.getId()");
  77.             name = Check.notNull(operatingSystem.getName(), "operatingSystem.getName()");
  78.             family = Check.notNull(operatingSystem.getFamily(), "operatingSystem.getFamily()");
  79.             infoUrl = Check.notNull(operatingSystem.getInfoUrl(), "operatingSystem.getInfoUrl()");
  80.             patterns = new TreeSet<OperatingSystemPattern>(Check.notNull(operatingSystem.getPatterns(), "operatingSystem.getPatterns()"));
  81.             producer = Check.notNull(operatingSystem.getProducer(), "operatingSystem.getProducer()");
  82.             producerUrl = Check.notNull(operatingSystem.getProducerUrl(), "operatingSystem.getProducerUrl()");
  83.             url = Check.notNull(operatingSystem.getUrl(), "operatingSystem.getUrl()");
  84.             icon = Check.notNull(operatingSystem.getIcon(), "operatingSystem.getIcon()");
  85.         }

  86.         @Nonnull
  87.         public Builder addPatterns(@Nonnull final Set<OperatingSystemPattern> patterns) {
  88.             Check.notNull(patterns, "patterns");

  89.             this.patterns.addAll(patterns);
  90.             return this;
  91.         }

  92.         @Nonnull
  93.         public OperatingSystem build() {
  94.             return new OperatingSystem(id, name, family, infoUrl, patterns, producer, producerUrl, url, icon);
  95.         }

  96.         /**
  97.          * Creates a copy (with all its data) of the current builder.
  98.          *
  99.          * @return a new instance of the current builder, never {@code null}
  100.          */
  101.         @Nonnull
  102.         public OperatingSystem.Builder copy() {
  103.             return new Builder(this);
  104.         }

  105.         @Nonnull
  106.         public String getFamily() {
  107.             return family;
  108.         }

  109.         @Nonnull
  110.         public String getIcon() {
  111.             return icon;
  112.         }

  113.         public int getId() {
  114.             return id;
  115.         }

  116.         @Nonnull
  117.         public String getInfoUrl() {
  118.             return infoUrl;
  119.         }

  120.         @Nonnull
  121.         public String getName() {
  122.             return name;
  123.         }

  124.         @Nonnull
  125.         public SortedSet<OperatingSystemPattern> getPatterns() {
  126.             return patterns;
  127.         }

  128.         @Nonnull
  129.         public String getProducer() {
  130.             return producer;
  131.         }

  132.         @Nonnull
  133.         public String getProducerUrl() {
  134.             return producerUrl;
  135.         }

  136.         @Nonnull
  137.         public String getUrl() {
  138.             return url;
  139.         }

  140.         @Nonnull
  141.         public Builder setFamily(@Nonnull final String family) {
  142.             this.family = Check.notNull(family, "family");
  143.             return this;
  144.         }

  145.         @Nonnull
  146.         public Builder setIcon(@Nonnull final String icon) {
  147.             this.icon = Check.notNull(icon, "icon");
  148.             return this;
  149.         }

  150.         @Nonnull
  151.         public Builder setId(@Nonnegative final int id) {
  152.             this.id = Check.notNegative(id, "id");
  153.             return this;
  154.         }

  155.         @Nonnull
  156.         public Builder setId(@Nonnull final String id) {
  157.             Check.notEmpty(id, "id");

  158.             this.setId(Integer.parseInt(id.trim()));
  159.             return this;
  160.         }

  161.         @Nonnull
  162.         public Builder setInfoUrl(@Nonnull final String infoUrl) {
  163.             this.infoUrl = Check.notNull(infoUrl, "infoUrl");
  164.             return this;
  165.         }

  166.         @Nonnull
  167.         public Builder setName(@Nonnull final String name) {
  168.             this.name = Check.notNull(name, "name");
  169.             return this;
  170.         }

  171.         @Nonnull
  172.         public Builder setPatterns(@Nonnull final SortedSet<OperatingSystemPattern> patterns) {
  173.             this.patterns = new TreeSet<OperatingSystemPattern>(Check.notNull(patterns, "patterns"));
  174.             return this;
  175.         }

  176.         @Nonnull
  177.         public Builder setProducer(@Nonnull final String producer) {
  178.             this.producer = Check.notNull(producer, "producer");
  179.             return this;
  180.         }

  181.         @Nonnull
  182.         public Builder setProducerUrl(@Nonnull final String producerUrl) {
  183.             this.producerUrl = Check.notNull(producerUrl, "producerUrl");
  184.             return this;
  185.         }

  186.         @Nonnull
  187.         public Builder setUrl(@Nonnull final String url) {
  188.             this.url = Check.notNull(url, "url");
  189.             return this;
  190.         }

  191.     }

  192.     private static final long serialVersionUID = -5330180544816352323L;

  193.     private static int buildHashCode(@Nonnegative final int id, @Nonnull final String name, @Nonnull final String family,
  194.             @Nonnull final String infoUrl, @Nonnull final SortedSet<OperatingSystemPattern> patterns, @Nonnull final String producer,
  195.             @Nonnull final String producerUrl, @Nonnull final String url, @Nonnull final String icon) {
  196.         final int prime = 31;
  197.         int result = 1;
  198.         result = prime * result + id;
  199.         result = prime * result + name.hashCode();
  200.         result = prime * result + family.hashCode();
  201.         result = prime * result + infoUrl.hashCode();
  202.         result = prime * result + patterns.hashCode();
  203.         result = prime * result + producer.hashCode();
  204.         result = prime * result + producerUrl.hashCode();
  205.         result = prime * result + url.hashCode();
  206.         result = prime * result + icon.hashCode();
  207.         return result;
  208.     }

  209.     @Nonnull
  210.     private final String family;

  211.     private final int hash;

  212.     @Nonnull
  213.     private final String icon;

  214.     @Nonnegative
  215.     private final int id;

  216.     @Nonnull
  217.     private final String infoUrl;

  218.     @Nonnull
  219.     private final String name;

  220.     @Nonnull
  221.     private final SortedSet<OperatingSystemPattern> patterns;

  222.     @Nonnull
  223.     private final String producer;

  224.     @Nonnull
  225.     private final String producerUrl;

  226.     @Nonnull
  227.     private final String url;

  228.     public OperatingSystem(@Nonnegative final int id, @Nonnull final String name, @Nonnull final String family,
  229.             @Nonnull final String infoUrl, @Nonnull final SortedSet<OperatingSystemPattern> patterns, @Nonnull final String producer,
  230.             @Nonnull final String producerUrl, @Nonnull final String url, @Nonnull final String icon) {
  231.         this.id = Check.notNegative(id, "id");
  232.         this.name = Check.notNull(name, "name");
  233.         this.family = Check.notNull(family, "family");
  234.         this.infoUrl = Check.notNull(infoUrl, "infoUrl");
  235.         this.patterns = Collections.unmodifiableSortedSet(new TreeSet<OperatingSystemPattern>(Check.notNull(patterns, "patterns")));
  236.         this.producer = Check.notNull(producer, "producer");
  237.         this.producerUrl = Check.notNull(producerUrl, "producerUrl");
  238.         this.url = Check.notNull(url, "url");
  239.         this.icon = Check.notNull(icon, "icon");
  240.         hash = buildHashCode(id, name, family, infoUrl, patterns, producer, producerUrl, url, icon);
  241.     }

  242.     /**
  243.      * Copies all information of the current operating system entry to the given user agent builder.
  244.      *
  245.      * @param builder
  246.      *            user agent builder
  247.      */
  248.     public void copyTo(@Nonnull final UserAgent.Builder builder) {
  249.         final OperatingSystemFamily f = OperatingSystemFamily.evaluate(family);
  250.         final VersionNumber version = VersionNumber.parseOperatingSystemVersion(f, builder.getUserAgentString());
  251.         builder.setOperatingSystem(new net.sf.uadetector.OperatingSystem(f, family, icon, name, producer, producerUrl, url, version));
  252.     }

  253.     @Override
  254.     public boolean equals(final Object obj) {
  255.         if (this == obj) {
  256.             return true;
  257.         }
  258.         if (obj == null) {
  259.             return false;
  260.         }
  261.         if (getClass() != obj.getClass()) {
  262.             return false;
  263.         }
  264.         final OperatingSystem other = (OperatingSystem) obj;
  265.         if (id != other.id) {
  266.             return false;
  267.         }
  268.         if (!name.equals(other.name)) {
  269.             return false;
  270.         }
  271.         if (!family.equals(other.family)) {
  272.             return false;
  273.         }
  274.         if (!infoUrl.equals(other.infoUrl)) {
  275.             return false;
  276.         }
  277.         if (!patterns.equals(other.patterns)) {
  278.             return false;
  279.         }
  280.         if (!producer.equals(other.producer)) {
  281.             return false;
  282.         }
  283.         if (!producerUrl.equals(other.producerUrl)) {
  284.             return false;
  285.         }
  286.         if (!url.equals(other.url)) {
  287.             return false;
  288.         }
  289.         if (!icon.equals(other.icon)) {
  290.             return false;
  291.         }
  292.         return true;
  293.     }

  294.     @Nonnull
  295.     public String getFamily() {
  296.         return family;
  297.     }

  298.     @Nonnull
  299.     public String getIcon() {
  300.         return icon;
  301.     }

  302.     @Override
  303.     @Nonnegative
  304.     public int getId() {
  305.         return id;
  306.     }

  307.     @Nonnull
  308.     public String getInfoUrl() {
  309.         return infoUrl;
  310.     }

  311.     @Nonnull
  312.     public String getName() {
  313.         return name;
  314.     }

  315.     @Nonnull
  316.     public SortedSet<OperatingSystemPattern> getPatterns() {
  317.         return patterns;
  318.     }

  319.     @Nonnull
  320.     public String getProducer() {
  321.         return producer;
  322.     }

  323.     @Nonnull
  324.     public String getProducerUrl() {
  325.         return producerUrl;
  326.     }

  327.     @Nonnull
  328.     public String getUrl() {
  329.         return url;
  330.     }

  331.     @Override
  332.     public int hashCode() {
  333.         return hash;
  334.     }

  335.     @Override
  336.     public String toString() {
  337.         final StringBuilder builder = new StringBuilder();
  338.         builder.append("OperatingSystem [id=");
  339.         builder.append(id);
  340.         builder.append(", name=");
  341.         builder.append(name);
  342.         builder.append(", family=");
  343.         builder.append(family);
  344.         builder.append(", infoUrl=");
  345.         builder.append(infoUrl);
  346.         builder.append(", patterns=");
  347.         builder.append(patterns);
  348.         builder.append(", producer=");
  349.         builder.append(producer);
  350.         builder.append(", producerUrl=");
  351.         builder.append(producerUrl);
  352.         builder.append(", url=");
  353.         builder.append(url);
  354.         builder.append(", icon=");
  355.         builder.append(icon);
  356.         builder.append("]");
  357.         return builder.toString();
  358.     }

  359. }