RestServiceKey.java
/*
** Module : RestServiceKey.java
** Abstract : Key to identify a REST service, by its resource/operation and verb.
**
** Copyright (c) 2019-2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
** 001 CA 20190614 First version.
** 002 CA 20200514 Refactoring to allow common code for SOAP services support.
** 003 CA 20200910 The 'address' at the service signature is included in the key.
** CA 20210227 Each specific 'address' must have its own handler, so the context path can be reported
** and managed properly.
** SBI 20221215 Added parametersTypes to distinguish methods having the same name but different parameters types.
** SBI 20221216 Added utility method buildContextPath to build the rest service context path.
** SBI 20221229 Cached a context path of a rest service.
** 004 SBI 20231206 Added the path entries mask.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.rest;
import java.util.*;
/**
* A key to identify a REST operation by its PATH and VERB.
*/
class RestServiceKey
extends ServiceKey
{
/** The basepath address. */
final String address;
/** The defined path. */
final String path;
/** The defined verb. */
final String verb;
/** The path elements. */
final String[] paths;
/** Types of parameters */
final String[] parametersTypes;
/** The context path */
final String context;
/** The mask of path elements */
final BitSet mask;
/**
* Create a new key.
*
* @param address
* The basepath address.
* @param path
* The defined path.
* @param verb
* The defined verb.
*/
public RestServiceKey(String basePath, String address, String path, String verb, List<String> types)
{
if (!address.isEmpty() && !address.endsWith("/"))
{
address = address + "/";
}
this.address = address;
this.path = path;
this.verb = verb;
this.paths = RestHandler.getPaths(path);
this.mask = RestHandler.getMask(this.paths);
this.parametersTypes = types.toArray(new String[types.size()]);
this.context = buildContextPath(basePath, address);
}
/**
* Build the rest service context path based on the given rest service base path and address.
*
* @param basePath
* The rest service bath path
* @param address
* The base path of the given rest method
*
* @return The context path
*/
public static String buildContextPath(String basePath, String address)
{
StringBuilder contextPath = new StringBuilder(basePath);
if (basePath.charAt(basePath.length() - 1) != '/')
{
contextPath.append("/");
}
int begIndex = 0;
if (address.charAt(0) == '/')
{
begIndex = 1;
}
int endIndex = address.length();
int endCharPos = endIndex - 1;
if (address.charAt(endCharPos) == '/')
{
endIndex = endCharPos;
}
contextPath.append(address.substring(begIndex, endIndex));
return contextPath.toString();
}
/**
* Check if the given object is the same as this one.
*
* @param obj
* The object to check for equality.
*
* @return See above.
*/
@Override
public boolean equals(Object obj)
{
if (!(obj instanceof RestServiceKey))
{
return false;
}
RestServiceKey srv = (RestServiceKey) obj;
return Objects.equals(path, srv.path) && Objects.equals(verb, srv.verb) && Arrays.equals(parametersTypes, srv.parametersTypes);
}
/**
* Calculate the key's hashcode.
*
* @return See above.
*/
@Override
public int hashCode()
{
int result = 17;
result = result * 37 + address.hashCode();
result = result * 37 + path.hashCode();
result = result * 37 + verb.hashCode();
result = result * 37 + Arrays.hashCode(parametersTypes);
return result;
}
/**
* The string representation of this key (the path and verb).
*
* @return See above.
*/
@Override
public String toString()
{
return address + path + Arrays.toString(parametersTypes) + " " + verb;
}
}