code: /**
   * This file is part of Eclipse Steady.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   * SPDX-License-Identifier: Apache-2.0
   * SPDX-FileCopyrightText: Copyright (c) 2018-2020 SAP SE or an SAP affiliate company and Eclipse Steady contributors
   */
  package org.eclipse.steady.shared.json.model.mavenCentral;
  
  import java.util.Collection;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  import com.fasterxml.jackson.annotation.JsonIgnore;
  import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  
  import org.apache.logging.log4j.Logger;
  import org.eclipse.steady.shared.enums.ProgrammingLanguage;
  import org.eclipse.steady.shared.json.model.Artifact;
  import org.eclipse.steady.shared.json.model.LibraryId;
  
  /**
   * Corresponds to the JSON object structure returned by the RESTful search of the Maven Central.
   * This class is used to de-serialize requests from Maven central and to represent artifacts to be
   * downloaded from Maven central.
   */
  @JsonIgnoreProperties(
      ignoreUnknown = true,
      value = {"c"})
  public class ResponseDoc implements Comparable {
  
    static final Pattern VERSION_PATTERN = Pattern.compile("([\\d\\.]*)(.*)", Pattern.DOTALL);
  
    private static Logger log = org.apache.logging.log4j.LogManager.getLogger(ResponseDoc.class);
  
    private String id;
  
    private String g;
  
    private String a;
  
    private String v;
  
    private String c;
  
    private String p;
  
    private long timestamp;
  
    private Collection<String> ec = null;
  
    private Collection<String> tags = null;
  
    /**
     * <p>Constructor for ResponseDoc.</p>
     */
    public ResponseDoc() {}
  
    /**
     * <p>Getter for the field <code>id</code>.</p>
     *
     * @return a {@link java.lang.String} object.
     */
    public String getId() {
      return id;
    }
    /**
     * <p>Setter for the field <code>id</code>.</p>
     *
     * @param id a {@link java.lang.String} object.
     */
    public void setId(String id) {
      this.id = id;
    }
  
    /**
     * <p>Getter for the field <code>g</code>.</p>
     *
     * @return a {@link java.lang.String} object.
     */
    public String getG() {
      return g;
    }
    /**
     * <p>Setter for the field <code>g</code>.</p>
     *
     * @param g a {@link java.lang.String} object.
     */
    public void setG(String g) {
      this.g = g;
    }
  
    /**
     * <p>Getter for the field <code>a</code>.</p>
     *
     * @return a {@link java.lang.String} object.
     */
    public String getA() {
      return a;
    }
    /**
     * <p>Setter for the field <code>a</code>.</p>
     *
     * @param a a {@link java.lang.String} object.
     */
    public void setA(String a) {
      this.a = a;
    }
  
    /**
     * <p>Getter for the field <code>v</code>.</p>
     *
     * @return a {@link java.lang.String} object.
     */
    public String getV() {
      return v;
    }
    /**
     * <p>Setter for the field <code>v</code>.</p>
     *
     * @param v a {@link java.lang.String} object.
     */
    public void setV(String v) {
      this.v = v;
    }
  
    /**
     * <p>Getter for the field <code>c</code>.</p>
     *
     * @return a {@link java.lang.String} object.
     */
    public String getC() {
      return c;
    }
    /**
     * <p>Setter for the field <code>c</code>.</p>
     *
     * @param c a {@link java.lang.String} object.
     */
    public void setC(String c) {
      // TODO check that c is among ec
      this.c = c;
    }
  
    /**
     * <p>Getter for the field <code>p</code>.</p>
     *
     * @return a {@link java.lang.String} object.
     */
    public String getP() {
      return p;
    }
    /**
     * <p>Setter for the field <code>p</code>.</p>
     *
     * @param p a {@link java.lang.String} object.
     */
    public void setP(String p) {
      this.p = p;
    }
  
    /**
     * <p>Getter for the field <code>timestamp</code>.</p>
     *
     * @return a long.
     */
    public long getTimestamp() {
      return timestamp;
    }
    /**
     * <p>Setter for the field <code>timestamp</code>.</p>
     *
     * @param timestamp a long.
     */
    public void setTimestamp(long timestamp) {
      this.timestamp = timestamp;
    }
  
    /**
     * <p>Getter for the field <code>ec</code>.</p>
     *
     * @return a {@link java.util.Collection} object.
     */
    public Collection<String> getEc() {
      return ec;
    }
    /**
     * <p>Setter for the field <code>ec</code>.</p>
     *
     * @param ec a {@link java.util.Collection} object.
     */
    public void setEc(Collection<String> ec) {
      this.ec = ec;
    }
  
    /**
     * <p>Getter for the field <code>tags</code>.</p>
     *
     * @return a {@link java.util.Collection} object.
     */
    public Collection<String> getTags() {
      return tags;
    }
  
    /**
     * <p>Setter for the field <code>tags</code>.</p>
     *
     * @param tags a {@link java.util.Collection} object.
     */
    public void setTags(Collection<String> tags) {
      this.tags = tags;
    }
  
    /**
     * <p>availableWith.</p>
     *
     * @param _classifier a {@link java.lang.String} object.
     * @param _packaging a {@link java.lang.String} object.
     * @return a boolean.
     */
    @JsonIgnore
    public boolean availableWith(String _classifier, String _packaging) {
      // final String filter_ec = (_classifier!=null && !_classifier.equals("") ? _classifier + "-" :
      // "") + "." + _packaging;
      for (String ec : this.getEc()) {
  
        if (_classifier != null && _packaging != null) {
          if (ec.equals("-" + _classifier + "." + _packaging)) return true;
        } else if (_classifier == null && _packaging != null) {
          if (ec.endsWith("." + _packaging)) return true;
        } else if (_classifier != null && _packaging == null) {
          if (ec.startsWith("-" + _classifier)) return true;
        } else return true;
      }
      return false;
    }
  
    /**
     * {@inheritDoc}
     *
     * Compares the respective timestamps.
     */
    @Override
    public int compareTo(Object other) {
      if (other instanceof ResponseDoc) {
        final ResponseDoc other_doc = (ResponseDoc) other;
        int c = Long.compare(this.timestamp, other_doc.getTimestamp());
        if (c == 0) {
          // c = this.v.compareTo(other_doc.v);
  
          Matcher this_m = VERSION_PATTERN.matcher(this.v);
          Matcher other_m = VERSION_PATTERN.matcher(other_doc.v);
  
          String this_v = (this_m.matches() ? this_m.group(1) : this.v);
          String other_v = (other_m.matches() ? other_m.group(1) : other_doc.v);
  
          ResponseDoc.log.debug(
              "Compare artifact versions: Original ["
                  + this.v
                  + ", "
                  + other_doc.v
                  + "], modified for comparison ["
                  + this_v
                  + ", "
                  + other_v
                  + "]");
          c = this_v.compareTo(other_v);
  
          if (c == 0) {
            String this_v_tag = (this_m.matches() ? this_m.group(2) : this.v);
            String other_v_tag = (other_m.matches() ? other_m.group(2) : other_doc.v);
  
            if (this_v_tag.equals("") && !other_v_tag.equals("")) return 1;
            else if (!this_v_tag.equals("") && other_v_tag.equals("")) return -1;
            else {
              ResponseDoc.log.debug(
                  "Compare artifact versions: Original ["
                      + this.v
                      + ", "
                      + other_doc.v
                      + "], modified for comparison based on tag (if any)["
                      + this_v_tag
                      + ", "
                      + other_v_tag
                      + "]");
              // comparison in order to obtain X.X > X.X-RC > X.X-beta
              c = this_v_tag.compareToIgnoreCase(other_v_tag);
            }
          }
        }
        return c;
      } else {
        throw new IllegalArgumentException(
            "Expected ResponseDoc, got [" + other.getClass().getName() + "]");
      }
    }
  
    /** {@inheritDoc} */
    @Override
    public String toString() {
      final StringBuilder b = new StringBuilder();
      b.append("[").append(id);
      if (this.c != null && !this.c.equals("")) b.append(":").append(this.getC());
      b.append(":").append(p).append("]");
      return b.toString();
    }
  
    //	/**
    //	 * Returns the path of the directory where the artifact is stored, relative to the local M2
    // repository.
    //	 * E.g, com/jolira/guice/3.0.0.
    //	 * @return
    //	 */
    //	@JsonIgnore
    //	private Path getRelM2Dir() {
    //		final StringBuilder b = new StringBuilder();
    //		b.append(this.getG().replace('.',  '/')).append("/");
    //		b.append(this.getA()).append("/");
    //		b.append(this.getV());
    //		return Paths.get(b.toString());
    //	}
    //
    //	/**
    //     * Returns the artifact's filename root, e.g., guice-3.0.0
    //     * To be completed with one of the available postfix in this.ec
    //	 * @return
    //	 */
    //	@JsonIgnore
    //	public String getM2Filename() {
    //		final StringBuilder b = new StringBuilder();
    //		b.append(this.getA()).append("-").append(this.getV());
    //		if(this.c!=null && !this.c.equals(""))
    //			b.append("-").append(this.getC());
    //		b.append(".").append(this.getP());
    //		return b.toString();
    //	}
  
    //	/**
    //	 * http://search.maven.org/remotecontent?filepath=com/jolira/guice/3.0.0/guice-3.0.0.pom
    //	 * @return
    //	 */
    //	@JsonIgnore
    //	public Path getRelM2Path() {
    //		return Paths.get(this.getRelM2Dir().toString(), this.getM2Filename());
    //	}
  
    /**
     * Returns a {@link LibraryId} corresponding to this {@link ResponseDoc}.
     *
     * @return a {@link org.eclipse.steady.shared.json.model.Artifact} object.
     */
    public Artifact toArtifact() {
      Artifact r = new Artifact(g, a, v);
      r.setTimestamp(timestamp);
      r.setProgrammingLanguage(ProgrammingLanguage.JAVA);
      return r;
    }
  }
  