![JAR search and dependency download from the Maven repository](/logo.png)
ru.blizzed.openlastfm.methods.ApiMethod Maven / Gradle / Ivy
Show all versions of openlastfm Show documentation
/*
* Copyright (c) 2017 BlizzedRu (Ivan Vlasov)
*
* 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.
*/
package ru.blizzed.openlastfm.methods;
import ru.blizzed.openlastfm.models.ModelParser;
import ru.blizzed.openlastfm.params.Param;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/**
* This class represents method that may be converted to {@link ApiRequest} for call the LastFM API
* with set of {@link ApiParams}
*
* May contain description for each method param.
* Contains self and section names
* Contains {@link ModelParser} to parse a model of response
*
* ApiMethod instance can be got only with using of {@link Builder}
*
*
* @param type of expected response model
* @author BlizzedRu (Ivan Vlasov)
* @see Builder
*/
public final class ApiMethod {
/**
* An exception that can be thrown if you have not pass required params for chosen method
*/
public static class NoRequiredParamsException extends IllegalArgumentException {
public NoRequiredParamsException(String message) {
super(message);
}
}
private String alias;
private String sectionAlias;
private List paramsDescriptions;
private ModelParser modelParser;
/**
* @param sectionAlias section name (e.g. author, track, etc)
* @param alias self method name (e.g. getInfo, getTracks)
*/
private ApiMethod(String sectionAlias, String alias) {
this.alias = alias;
this.sectionAlias = sectionAlias;
paramsDescriptions = new ArrayList<>();
}
/**
* Returns a self method name (alias)
*
* @return method alias
*/
public String getAlias() {
return alias;
}
/**
* Returns amount of all contained {@link ApiParamDescription}
*
* @return method params count
*/
public int getParamsCount() {
return paramsDescriptions.size();
}
/**
* Returns {@link ApiParamDescription} at concrete position
*
* @param index a position of needed {@link ApiParamDescription}
* @return {@link ApiParamDescription} at specified position
* @throws IllegalArgumentException if index is not in range
*/
public ApiParamDescription getParamDescriptionAt(int index) {
if (index >= getParamsCount() | index < 0)
throw new IllegalArgumentException("Illegal index " + index + ". Expected 0 to " + (getParamsCount() - 1) + ".");
return paramsDescriptions.get(index);
}
/**
* Returns full alias of the method formatted as LastFM claims (%sectionName.%methodName)
* e.g. artist.getInfo, album.getTags, etc
*
* @return full alias of the method
*/
public String getFullAlias() {
return String.format(Locale.US, "%s.%s", getSectionAlias().toLowerCase(), getAlias());
}
/**
* Returns the section name
*
e.g. artist, album, etc
*
* @return name of the method section
*/
public String getSectionAlias() {
return sectionAlias;
}
/**
* @see #withParams(Param... params)
* @see ApiParams#from(Param[])
* @see ApiParams#from(List)
*
* @param params {@link ApiParams} that contains all required params at least
* @return {@link ApiRequest} that may be executed for calling to LastFM
* @throws NoRequiredParamsException if you have not pass required params for chosen method
*/
public ApiRequest withParams(ApiParams params) throws NoRequiredParamsException {
if (!checkForAllRequiredParams(params))
throw new NoRequiredParamsException(
paramsDescriptions.stream().filter(ApiParamDescription::isRequired).count()
+ " required params expected."
);
return new ApiRequest<>(this, params);
}
/**
* Generates a new {@link ApiRequest} with specified set of {@link Param} which can be executed for calling to LastFM
*
* There is no need to pass here your api key, it will be got from {@link ru.blizzed.openlastfm.OpenLastFMContext} by default
*
* By default params contain a "US" {@link ru.blizzed.openlastfm.params.LangParam} if you have
* initialized {@link ru.blizzed.openlastfm.OpenLastFMContext} without lang param
*
If you have initialized it with your custom lang param it will be used by default
*
* You can pass here another {@link ru.blizzed.openlastfm.params.LangParam} if it differs from specified in {@link ru.blizzed.openlastfm.OpenLastFMContext}
*
* @param params a single {@link Param} or array of {@link Param} that contains all required params at least
* @return {@link ApiRequest} that may be executed for calling to LastFM
* @throws NoRequiredParamsException if you have not pass required params for chosen method
*/
public ApiRequest withParams(Param... params) throws NoRequiredParamsException {
return withParams(ApiParams.from(params));
}
/**
* Returns used {@link ModelParser} for response parsing
*
* @return used {@link ModelParser}
*/
public ModelParser getModelParser() {
return modelParser;
}
private boolean checkForAllRequiredParams(ApiParams params) {
return paramsDescriptions.stream()
.filter(ApiParamDescription::isRequired)
.filter(p -> !params.asList().contains(p.getParam()))
.filter(p -> !params.asList().containsAll(p.getReplacements()))
.count() == 0;
}
/**
* Builder class for {@link ApiMethod}
*
* @see ApiMethod
* @param type of expected response model
*/
public static class Builder {
private ApiMethod method;
/**
* @param sectionAlias section name (e.g. author, track, etc)
* @param alias self method name (e.g. getInfo, getTracks)
*/
public Builder(String sectionAlias, String alias) {
method = new ApiMethod<>(sectionAlias, alias);
}
/**
* Adds a {@link ApiParamDescription} to the method
*
* @param paramsDescriptions single or set of {@link ApiParamDescription} to add to the method
* @return {@link Builder}
*/
public Builder addParamsDescriptions(ApiParamDescription... paramsDescriptions) {
method.paramsDescriptions.addAll(Arrays.asList(paramsDescriptions));
return this;
}
/**
* Set the name of the method section
* e.g. author, track, etc
*
* @param sectionAlias name (alias) of the method section
* @return {@link Builder}
*/
public Builder setSectionAlias(String sectionAlias) {
method.sectionAlias = sectionAlias;
return this;
}
/**
* Set the name of the method itself
* e.g. getInfo, getTracks, etc
*
* @param alias name (alias) of the method itself
* @return {@link Builder}
*/
public Builder setAlias(String alias) {
method.alias = alias;
return this;
}
/**
* Builds a new ApiMethod with specified section name {@link #setSectionAlias(String)}, self name {@link #setAlias(String)}
* and {@link ModelParser}
*
* @param resultModelParser A {@link ModelParser} used for parse a response model
* @return full built {@link ApiMethod}
*/
public ApiMethod buildWithResultModelParser(ModelParser resultModelParser) {
method.modelParser = resultModelParser;
return method;
}
}
}