ApiSchemaTypeRestriction.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.utils.rest.api;

  21. import java.io.Serializable;
  22. import java.math.BigDecimal;
  23. import java.util.ArrayList;
  24. import java.util.List;

  25. import org.openspcoop2.utils.UtilsException;
  26. import org.openspcoop2.utils.beans.BaseBean;

  27. /**
  28.  * ApiSchemaTypeRestriction
  29.  *
  30.  *
  31.  * @author Poli Andrea (apoli@link.it)
  32.  * @author $Author$
  33.  * @version $Rev$, $Date$
  34.  */
  35. public class ApiSchemaTypeRestriction extends BaseBean implements Serializable {
  36.    
  37.     /**
  38.      *
  39.      */
  40.     private static final long serialVersionUID = 1L;
  41.    
  42.     private Object schema;
  43.    
  44.     private String format;
  45.     private String type;
  46.    
  47.    
  48.     // ** STYLE e EXPLODE **
  49.    
  50.     private Boolean arrayParameter;
  51.     private String style;
  52.     private String explode;
  53.    
  54.    
  55.     // ** NUMBER **
  56.    
  57.     // minimum ≤ value ≤ maximum
  58.     private BigDecimal minimum;
  59.     private BigDecimal maximum;
  60.     /*
  61.      * exclusiveMinimum: false or not included  value ≥ minimum
  62.      * exclusiveMinimum: true   value > minimum
  63.      * exclusiveMaximum: false or not included  value ≤ maximum
  64.      * exclusiveMaximum: true   value < maximum
  65.      */
  66.     private Boolean exclusiveMinimum;
  67.     private Boolean exclusiveMaximum;
  68.    
  69.     // The example 10 above matches 10, 20, 30, 0, -10, -20, and so on.
  70.     // The value of multipleOf must be a positive number, that is, you cannot use multipleOf: -5.
  71.     private BigDecimal multipleOf;
  72.        

  73.     // ** STRING **
  74.    
  75.     private Long minLength;
  76.     private Long maxLength;
  77.    
  78.     /*
  79.      * Note that the regular expression is enclosed in the ^…$ tokens, where ^ means the beginning of the string, and $ means the end of the string.
  80.      * Without ^…$, pattern works as a partial match, that is, matches any string that contains the specified regular expression.
  81.      * For example, pattern: pet matches pet, petstore and carpet. The ^…$ token forces an exact match.
  82.      **/
  83.     private String pattern;
  84.    
  85.    
  86.     // ** ENUM **
  87.    
  88.     private List<?> enumValues;
  89.    
  90.    
  91.     private static final String TYPE = "type";
  92.     private static final String TYPE_OBJECT = "object";
  93.     private static final String TYPE_ARRAY = "array";
  94.     private static final String FORMAT = "format";
  95.     private static final String MINIMUM = "minimum";
  96.     private static final String EXCLUSIVE_MINIMUM = "exclusiveMinimum";
  97.     private static final String MAXIMUM = "maximum";
  98.     private static final String EXCLUSIVE_MAXIMUM = "exclusiveMaximum";
  99.     private static final String MULTIPLE_OF = "multipleOf";
  100.     private static final String MIN_LENGTH = "minLength";
  101.     private static final String MAX_LENGTH = "maxLength";
  102.     private static final String PATTERN = "pattern";
  103.     private static final String ENUM_VALUES = "enumValues";
  104.    
  105.     private static final String ARRAY_PARAMETER = "arrayParameter";
  106.     private static final String STYLE = "style";
  107.     private static final String STYLE_PATH_SIMPLE = "simple";
  108.     private static final String STYLE_PATH_LABEL = "label";
  109.     private static final String STYLE_PATH_MATRIX = "matrix";
  110.     private static final String STYLE_QUERY_FORM = "form";
  111.     private static final String STYLE_QUERY_SPACE_DELIMITED = "spaceDelimited";
  112.     private static final String STYLE_QUERY_PIPE_DELIMITED = "pipeDelimited";
  113.     private static final String STYLE_QUERY_DEEP_OBJECT = "deepObject";
  114.     private static final String STYLE_HEADER_SIMPLE = "simple";
  115.     private static final String STYLE_COOKIE_FORM = "form";
  116.     private static final String EXPLODE = "explode";
  117.    
  118.     public static ApiSchemaTypeRestriction toApiSchemaTypeRestriction(String restriction) throws UtilsException {
  119.         if(restriction!=null) {
  120.             restriction = restriction.trim();  
  121.         }
  122.         if(restriction==null || "".equals(restriction) || !restriction.contains("=")) {
  123.             throw new UtilsException("Formato non valido");
  124.         }
  125.         ApiSchemaTypeRestriction schema = new ApiSchemaTypeRestriction();
  126.        
  127.         String [] tmp = restriction.split(";");
  128.         if(tmp==null || tmp.length<=0) {
  129.             throw new UtilsException("Formato non valido");
  130.         }
  131.         for (int i = 0; i < tmp.length; i++) {
  132.            
  133.             String regola = tmp[i];
  134.             if(regola!=null) {
  135.                 regola = regola.trim();
  136.             }
  137.             if(regola==null || "".equals(regola) || !regola.contains("=")) {
  138.                 throw new UtilsException("Formato non valido (trovata regola '"+regola+"' senza '=')");
  139.             }
  140.            
  141.             String [] nomeValore = regola.split("=");
  142.             if(nomeValore==null || nomeValore.length!=2) {
  143.                 throw new UtilsException("Formato non valido (regola '"+regola+"'); atteso tipo=restrizione");
  144.             }
  145.            
  146.             String tipo = nomeValore[0];
  147.             if(tipo!=null) {
  148.                 tipo = tipo.trim();
  149.             }
  150.             if(tipo==null || "".equals(tipo)) {
  151.                 throw new UtilsException("Formato non valido (regola '"+regola+"'); atteso tipo=restrizione");
  152.             }
  153.            
  154.             String restrizione = nomeValore[1];
  155.             if(restrizione!=null) {
  156.                 restrizione = restrizione.trim();  
  157.             }
  158.             if(restrizione==null || "".equals(restrizione)) {
  159.                 throw new UtilsException("Formato non valido (regola '"+regola+"'); atteso tipo=restrizione");
  160.             }
  161.            
  162.             try {
  163.                 if(TYPE.equalsIgnoreCase(tipo)) {
  164.                     schema.setType(restrizione);
  165.                 }
  166.                 else if(FORMAT.equalsIgnoreCase(tipo)) {
  167.                     schema.setFormat(restrizione);
  168.                 }
  169.                 else if(MINIMUM.equalsIgnoreCase(tipo)) {
  170.                     schema.setMinimum(new BigDecimal(restrizione));
  171.                 }
  172.                 else if(EXCLUSIVE_MINIMUM.equalsIgnoreCase(tipo)) {
  173.                     schema.setExclusiveMinimum(Boolean.parseBoolean(restrizione));
  174.                 }
  175.                 else if(MAXIMUM.equalsIgnoreCase(tipo)) {
  176.                     schema.setMaximum(new BigDecimal(restrizione));
  177.                 }
  178.                 else if(EXCLUSIVE_MAXIMUM.equalsIgnoreCase(tipo)) {
  179.                     schema.setExclusiveMaximum(Boolean.parseBoolean(restrizione));
  180.                 }
  181.                 else if(MULTIPLE_OF.equalsIgnoreCase(tipo)) {
  182.                     schema.setMultipleOf(new BigDecimal(restrizione));
  183.                 }
  184.                 else if(MIN_LENGTH.equalsIgnoreCase(tipo)) {
  185.                     schema.setMinLength(Long.valueOf(restrizione));
  186.                 }
  187.                 else if(MAX_LENGTH.equalsIgnoreCase(tipo)) {
  188.                     schema.setMaxLength(Long.valueOf(restrizione));
  189.                 }
  190.                 else if(PATTERN.equalsIgnoreCase(tipo)) {
  191.                     schema.setPattern(restrizione);
  192.                 }
  193.                 else if(ENUM_VALUES.equalsIgnoreCase(tipo)) {
  194.                     String [] values = restrizione.split(",");
  195.                     if(values!=null && values.length>0) {
  196.                         List<String> l = new ArrayList<>();
  197.                         for (String v : values) {
  198.                             if(v!=null) {
  199.                                 v = v.trim();
  200.                                 l.add(v);
  201.                             }
  202.                         }
  203.                         if(!l.isEmpty()) {
  204.                             schema.setEnumValues(l);
  205.                         }
  206.                     }
  207.                 }
  208.                 else if(ARRAY_PARAMETER.equalsIgnoreCase(tipo)) {
  209.                     schema.setArrayParameter(Boolean.parseBoolean(restrizione));
  210.                 }
  211.                 else if(STYLE.equalsIgnoreCase(tipo)) {
  212.                     schema.setStyle(restrizione);
  213.                 }
  214.                 else if(EXPLODE.equalsIgnoreCase(tipo)) {
  215.                     schema.setExplode(restrizione);
  216.                 }
  217.                 else {
  218.                     throw new UtilsException("Trovata regola '"+regola+"' con un tipo '"+tipo+"' sconosciuto");
  219.                 }
  220.             }
  221.             catch(UtilsException u) {
  222.                 throw u;
  223.             }
  224.             catch(Exception e) {
  225.                 throw new UtilsException("Trovata regola '"+regola+"' con una restrizione non valida: "+e.getMessage());
  226.             }
  227.            
  228.         }
  229.        
  230.         return schema;
  231.     }
  232.     public static String toString(ApiSchemaTypeRestriction restriction) throws UtilsException {
  233.         return restriction.toString();
  234.     }

  235.     @Override
  236.     public String toString() {
  237.         StringBuilder sb = new StringBuilder();
  238.        
  239.         if(this.type!=null) {
  240.             sb.append(TYPE).append("=").append(this.type);
  241.         }
  242.         if(this.format!=null) {
  243.             if(sb.length()>0) {
  244.                 sb.append("; ");
  245.             }
  246.             sb.append(FORMAT).append("=").append(this.format);
  247.         }
  248.        
  249.         if(this.minimum!=null) {
  250.             if(sb.length()>0) {
  251.                 sb.append("; ");
  252.             }
  253.             sb.append(MINIMUM).append("=").append(this.minimum);
  254.         }
  255.         if(this.exclusiveMinimum!=null) {
  256.             if(sb.length()>0) {
  257.                 sb.append("; ");
  258.             }
  259.             sb.append(EXCLUSIVE_MINIMUM).append("=").append(this.exclusiveMinimum);
  260.         }
  261.         if(this.maximum!=null) {
  262.             if(sb.length()>0) {
  263.                 sb.append("; ");
  264.             }
  265.             sb.append(MAXIMUM).append("=").append(this.maximum);
  266.         }
  267.         if(this.exclusiveMaximum!=null) {
  268.             if(sb.length()>0) {
  269.                 sb.append("; ");
  270.             }
  271.             sb.append(EXCLUSIVE_MAXIMUM).append("=").append(this.exclusiveMaximum);
  272.         }
  273.        
  274.         if(this.multipleOf!=null) {
  275.             if(sb.length()>0) {
  276.                 sb.append("; ");
  277.             }
  278.             sb.append(MULTIPLE_OF).append("=").append(this.multipleOf);
  279.         }
  280.        
  281.         if(this.minLength!=null) {
  282.             if(sb.length()>0) {
  283.                 sb.append("; ");
  284.             }
  285.             sb.append(MIN_LENGTH).append("=").append(this.minLength);
  286.         }
  287.         if(this.maxLength!=null) {
  288.             if(sb.length()>0) {
  289.                 sb.append("; ");
  290.             }
  291.             sb.append(MAX_LENGTH).append("=").append(this.maxLength);
  292.         }
  293.        
  294.         if(this.pattern!=null) {
  295.             if(sb.length()>0) {
  296.                 sb.append("; ");
  297.             }
  298.             sb.append(PATTERN).append("=").append(this.pattern);
  299.         }
  300.        
  301.         if(this.enumValues!=null && !this.enumValues.isEmpty()) {
  302.             if(sb.length()>0) {
  303.                 sb.append("; ");
  304.             }
  305.             StringBuilder sbList = new StringBuilder();
  306.             for (Object object : this.enumValues) {
  307.                 if(sbList.length()>0) {
  308.                     sbList.append(",");
  309.                 }
  310.                 sbList.append(object);
  311.             }
  312.             sb.append(ENUM_VALUES).append("=").append(sbList.toString());
  313.         }
  314.        
  315.         if(this.arrayParameter!=null) {
  316.             if(sb.length()>0) {
  317.                 sb.append("; ");
  318.             }
  319.             sb.append(ARRAY_PARAMETER).append("=").append(this.arrayParameter);
  320.         }
  321.        
  322.         if(this.style!=null) {
  323.             if(sb.length()>0) {
  324.                 sb.append("; ");
  325.             }
  326.             sb.append(STYLE).append("=").append(this.style);
  327.         }
  328.        
  329.         if(this.explode!=null) {
  330.             if(sb.length()>0) {
  331.                 sb.append("; ");
  332.             }
  333.             sb.append(EXPLODE).append("=").append(this.explode);
  334.         }
  335.        
  336.         return sb.toString();
  337.     }
  338.    
  339.    
  340.    
  341.     public Object getSchema() {
  342.         return this.schema;
  343.     }

  344.     public void setSchema(Object schema) {
  345.         this.schema = schema;
  346.     }

  347.     public String getFormat() {
  348.         return this.format;
  349.     }

  350.     public void setFormat(String format) {
  351.         this.format = format;
  352.     }

  353.     public String getType() {
  354.         return this.type;
  355.     }

  356.     public void setType(String type) {
  357.         this.type = type;
  358.     }
  359.    
  360.     public boolean isTypeObject() {
  361.         return TYPE_OBJECT.equals(this.type);
  362.     }
  363.     public boolean isTypeArray() {
  364.         return TYPE_ARRAY.equals(this.type);
  365.     }

  366.     public BigDecimal getMinimum() {
  367.         return this.minimum;
  368.     }

  369.     public void setMinimum(BigDecimal minimum) {
  370.         this.minimum = minimum;
  371.     }

  372.     public BigDecimal getMaximum() {
  373.         return this.maximum;
  374.     }

  375.     public void setMaximum(BigDecimal maximum) {
  376.         this.maximum = maximum;
  377.     }

  378.     public Boolean getExclusiveMinimum() {
  379.         return this.exclusiveMinimum;
  380.     }

  381.     public void setExclusiveMinimum(Boolean exclusiveMinimum) {
  382.         this.exclusiveMinimum = exclusiveMinimum;
  383.     }

  384.     public Boolean getExclusiveMaximum() {
  385.         return this.exclusiveMaximum;
  386.     }

  387.     public void setExclusiveMaximum(Boolean exclusiveMaximum) {
  388.         this.exclusiveMaximum = exclusiveMaximum;
  389.     }

  390.     public BigDecimal getMultipleOf() {
  391.         return this.multipleOf;
  392.     }

  393.     public void setMultipleOf(BigDecimal multipleOf) {
  394.         this.multipleOf = multipleOf;
  395.     }

  396.     public Long getMinLength() {
  397.         return this.minLength;
  398.     }

  399.     public void setMinLength(Long minLength) {
  400.         this.minLength = minLength;
  401.     }

  402.     public Long getMaxLength() {
  403.         return this.maxLength;
  404.     }

  405.     public void setMaxLength(Long maxLength) {
  406.         this.maxLength = maxLength;
  407.     }

  408.     public String getPattern() {
  409.         return this.pattern;
  410.     }

  411.     public void setPattern(String pattern) {
  412.         this.pattern = pattern;
  413.     }
  414.    
  415.     public List<?> getEnumValues() {
  416.         return this.enumValues;
  417.     }

  418.     public void setEnumValues(List<?> enumValues) {
  419.         this.enumValues = enumValues;
  420.     }
  421.    
  422.     public Boolean getArrayParameter() {
  423.         return this.arrayParameter;
  424.     }
  425.     public boolean isArrayParameter() {
  426.         return this.arrayParameter!=null && this.arrayParameter;
  427.     }
  428.     public void setArrayParameter(Boolean arrayParameter) {
  429.         this.arrayParameter = arrayParameter;
  430.     }
  431.    
  432.     public String getStyle() {
  433.         return this.style;
  434.     }
  435.     public void setStyle(String style) {
  436.         this.style = style;
  437.     }
  438.     public boolean isStylePathSimple() {
  439.         return STYLE_PATH_SIMPLE.equals(this.style);
  440.     }
  441.     public boolean isStylePathLabel() {
  442.         return STYLE_PATH_LABEL.equals(this.style);
  443.     }
  444.     public boolean isStylePathMatrix() {
  445.         return STYLE_PATH_MATRIX.equals(this.style);
  446.     }
  447.     public boolean isStyleQueryForm() {
  448.         return STYLE_QUERY_FORM.equals(this.style);
  449.     }
  450.     public boolean isStyleQuerySpaceDelimited() {
  451.         return STYLE_QUERY_SPACE_DELIMITED.equals(this.style);
  452.     }
  453.     public boolean isStyleQueryPipeDelimited() {
  454.         return STYLE_QUERY_PIPE_DELIMITED.equals(this.style);
  455.     }
  456.     public boolean isStyleQueryDeepObject() {
  457.         return STYLE_QUERY_DEEP_OBJECT.equals(this.style);
  458.     }
  459.     public boolean isStyleHeaderSimple() {
  460.         return STYLE_HEADER_SIMPLE.equals(this.style);
  461.     }
  462.     public boolean isStyleCookieForm() {
  463.         return STYLE_COOKIE_FORM.equals(this.style);
  464.     }
  465.    
  466.     public String getExplode() {
  467.         return this.explode;
  468.     }
  469.     public void setExplode(String explode) {
  470.         this.explode = explode;
  471.     }
  472.     public boolean isExplodeEnabled() {
  473.         return "true".equals(this.explode);
  474.     }
  475.     public boolean isExplodeDisabled() {
  476.         return "false".equals(this.explode);
  477.     }
  478.    
  479. }