ParseType.java

  1. /*
  2.  * Copyright © 2017, Salesforce.com, Inc
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are met:
  7.  *     * Redistributions of source code must retain the above copyright
  8.  *       notice, this list of conditions and the following disclaimer.
  9.  *     * Redistributions in binary form must reproduce the above copyright
  10.  *       notice, this list of conditions and the following disclaimer in the
  11.  *       documentation and/or other materials provided with the distribution.
  12.  *     * Neither the name of the <organization> nor the
  13.  *       names of its contributors may be used to endorse or promote products
  14.  *       derived from this software without specific prior written permission.
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19.  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  20.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26.  */
  27. package com.salesforce.apt.graph.types.impl;

  28. import java.util.ArrayList;
  29. import java.util.Arrays;
  30. import java.util.Iterator;
  31. import java.util.LinkedList;
  32. import java.util.List;
  33. import java.util.Queue;
  34. import java.util.stream.Collectors;

  35. public class ParseType {

  36.   private final String type;
  37.   private final List<ParseType> parameters = new ArrayList<>();

  38.   public ParseType(String type) {
  39.     this.type = type;
  40.   }
  41.  
  42.   public ParseType(String type, ParseType... parameters) {
  43.     this.type = type;
  44.     this.parameters.addAll(Arrays.asList(parameters));
  45.   }
  46.  
  47.   public String getType() {
  48.     return type;
  49.   }

  50.   public List<ParseType> getParameters() {
  51.     return parameters;
  52.   }
  53.  
  54.   public static ParseType parse(String type) {
  55.     final String parseToken = "*";
  56.     String[] tokens = type
  57.         .replaceAll("<", parseToken + "<" + parseToken)
  58.         .replaceAll(">", parseToken + ">" + parseToken)
  59.         .replaceAll(",", parseToken + "," + parseToken).split("\\" + parseToken);
  60.     Queue<String> tokenQueue = new LinkedList<>(Arrays.asList(tokens).stream().map(t -> t.trim()).collect(Collectors.toList()));
  61.     return parseParameters(tokenQueue);
  62.   }

  63.   @Override
  64.   public int hashCode() {
  65.     final int prime = 31;
  66.     int result = 1;
  67.     result = prime * result + parameters.hashCode();
  68.     result = prime * result + ((type == null) ? 0 : type.hashCode());
  69.     return result;
  70.   }

  71.   @Override
  72.   public boolean equals(Object obj) {
  73.     if (this == obj) {
  74.       return true;
  75.     }
  76.     if (obj == null) {
  77.       return false;
  78.     }
  79.     if (getClass() != obj.getClass()) {
  80.       return false;
  81.     }
  82.     ParseType other = (ParseType)obj;
  83.     if (!parameters.equals(other.parameters)) {
  84.       return false;
  85.     }
  86.     if (type == null) {
  87.       if (other.type != null) {
  88.         return false;
  89.       }
  90.     } else {
  91.       if (!type.equals(other.type)) {
  92.         return false;
  93.       }
  94.     }
  95.     return true;
  96.   }

  97.   @Override
  98.   public String toString() {
  99.     StringBuilder builder = new StringBuilder(getType());
  100.     if (!getParameters().isEmpty()) {
  101.       builder.append('<');
  102.       Iterator<ParseType> iter = getParameters().iterator();
  103.       while (iter.hasNext()) {
  104.         builder.append(iter.next().toString());
  105.         if (iter.hasNext()) {
  106.           builder.append(',');
  107.         }
  108.       }
  109.       builder.append('>');
  110.     }
  111.     return builder.toString();
  112.   }

  113.   private static ParseType parseParameters(Queue<String> tokens) {
  114.     ParseType child = new ParseType(tokens.remove());
  115.     if (tokens.isEmpty()) {
  116.       return child;
  117.     }
  118.     if (",".equals(tokens.peek())) {
  119.       return child;
  120.     }
  121.     if ("<".equals(tokens.peek())) {
  122.       tokens.remove();
  123.       child.parameters.add(parseParameters(tokens));
  124.       while (",".equals(tokens.peek())) {
  125.         tokens.remove();
  126.         child.parameters.add(parseParameters(tokens));
  127.       }
  128.       if (">".equals(tokens.peek())) {
  129.         tokens.remove();
  130.       }
  131.     }
  132.     return child;
  133.   }
  134.    
  135. }