352 lines
13 KiB
Java
352 lines
13 KiB
Java
package com.nttdata.calender.states;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.stream.Collectors;
|
|
|
|
import com.bmc.arsys.api.ARException;
|
|
import com.bmc.arsys.api.Entry;
|
|
import com.nttdata.calender.api.Query;
|
|
import com.nttdata.calender.api.RemedyJavaAPI;
|
|
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
|
|
|
|
/**
|
|
* The State class is a singleton class responsible for managing and querying
|
|
* state-related information. It handles the retrieval and storage of state
|
|
* names in english and german and possible state transitions.
|
|
* The states get fetched once at the start of the server.
|
|
*/
|
|
public class State {
|
|
private HashMap<Integer, StateInfo> state;
|
|
private static final State INSTANCE = new State();
|
|
|
|
/**
|
|
* Initializes the state with an empty HashMap.
|
|
*/
|
|
private State() {
|
|
this.state = new HashMap<>();
|
|
}
|
|
|
|
/**
|
|
* Returns the Singleton instance of the State.
|
|
*
|
|
* @return the Singleton instance of State
|
|
*/
|
|
public static State getInstance() {
|
|
return INSTANCE;
|
|
}
|
|
|
|
/**
|
|
* Returns the state.
|
|
*
|
|
* @return the state
|
|
*/
|
|
public HashMap<Integer, StateInfo> getState() {
|
|
return state;
|
|
}
|
|
|
|
/**
|
|
* Sets the state.
|
|
*
|
|
* @param state the state to set
|
|
*/
|
|
public void setState(HashMap<Integer, StateInfo> state) {
|
|
this.state = state;
|
|
}
|
|
|
|
/**
|
|
* Query for all the information about the state. First, the possible state
|
|
* transitions are queried by {@code queryPossibleStates()}. The query consists
|
|
* of
|
|
* the actual state, the possible state, and the English state name. Then, the
|
|
* state names in English and German are queried by {@code queryStateNames()}.
|
|
* These pieces of information are then merged and saved into the {@link #state}
|
|
* HashMap.
|
|
*
|
|
* @param api Remedy API object
|
|
* @throws ARException
|
|
*/
|
|
public void queryState(RemedyJavaAPI api) throws ARException, NotFoundError {
|
|
// queryStateNames(api);
|
|
queryPossibleStates(api);
|
|
|
|
if (state.isEmpty()) {
|
|
throw new NotFoundError("No States found in this context");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Query the specified form for the possible states. A state is encoded with an
|
|
* integer and has one or multiple states that it could transition to. The state
|
|
* and possible states are encoded as integers and saved as {@link StateInfo}.
|
|
* Additionally, the English state name is queried and saved into the
|
|
* {@link StateInfo}.
|
|
*
|
|
* @param api Remedy API object
|
|
* @throws ARException if an error occurs during the query
|
|
*/
|
|
public void queryPossibleStates(RemedyJavaAPI api) throws ARException {
|
|
var configurationQuery = new Query.QueryBuilder("ITSM:Configuration")
|
|
.addFieldId("engName", 700003002)
|
|
.addFieldId("gerName", 700003003)
|
|
.addFieldId("cancelFlag", 700003004)
|
|
.addFieldId("actualState", 700003005)
|
|
.addFieldId("restartFlag", 700003010)
|
|
.addFieldId("implementerFlag", 700003012)
|
|
.addFieldId("possibleState", 700003006) // Include possibleState here
|
|
.build();
|
|
|
|
var configurationStatusQuery = new Query.QueryBuilder("ITSM:Configuration")
|
|
.addFieldId("actualState", 700003005)
|
|
.addFieldId("possibleState", 700003006)
|
|
.build();
|
|
|
|
var stateFields = api.queryFieldsById("\'Menu\' = \"CHANGE_CALENDER_STATUS\"",
|
|
configurationQuery.getFieldIds(),
|
|
configurationQuery.getFormName(), null, 0, 0);
|
|
|
|
var stateStatusFields = api.queryFieldsById("\'Menu\' = \"CHANGE_CALENDER_STATUS_TRANSITIONS\"",
|
|
configurationStatusQuery.getFieldIds(),
|
|
configurationStatusQuery.getFormName(), null, 0, 0);
|
|
|
|
populateStateInfo(stateFields, stateStatusFields, configurationQuery, configurationStatusQuery);
|
|
|
|
// Print state information
|
|
// printStateInfo();
|
|
}
|
|
|
|
private void populateStateInfo(List<Entry> stateFields, List<Entry> stateStatusFields,
|
|
Query configurationQuery, Query configurationStatusQuery) throws ARException {
|
|
for (var stateField : stateFields) {
|
|
int actualState = stateField.get(configurationQuery.getFieldId("actualState")).getIntValue();
|
|
|
|
boolean cancelFlag = false;
|
|
boolean restartFlag = false;
|
|
boolean implementerFlag = false;
|
|
|
|
try {
|
|
// Extract additional fields
|
|
cancelFlag = stateField.get(configurationQuery.getFieldId("cancelFlag")).toString()
|
|
.equals("CANCEL_YES");
|
|
restartFlag = stateField.get(configurationQuery.getFieldId("restartFlag")).toString()
|
|
.equals("RESTARTALLOWED_YES");
|
|
implementerFlag = stateField.get(configurationQuery.getFieldId("implementerFlag")).toString()
|
|
.equals("SETIMPLEMENTER_YES");
|
|
} catch (Exception e) {
|
|
// e.printStackTrace();
|
|
}
|
|
|
|
String engName = stateField.get(configurationQuery.getFieldId("engName")).toString();
|
|
String gerName = stateField.get(configurationQuery.getFieldId("gerName")).toString();
|
|
|
|
// Initialize StateInfo with additional fields
|
|
StateInfo stateInfo = new StateInfo(engName, gerName, cancelFlag, restartFlag, implementerFlag);
|
|
|
|
for (var statusField : stateStatusFields) {
|
|
int statusActualState = statusField.get(configurationStatusQuery.getFieldId("actualState"))
|
|
.getIntValue();
|
|
|
|
if (actualState == statusActualState) {
|
|
int possibleState = statusField.get(configurationStatusQuery.getFieldId("possibleState"))
|
|
.getIntValue();
|
|
stateInfo.addPossibleState(possibleState);
|
|
}
|
|
}
|
|
|
|
// Add StateInfo to the state HashMap
|
|
getState().put(actualState, stateInfo);
|
|
}
|
|
}
|
|
|
|
private void printStateInfo() {
|
|
for (var state : get()) {
|
|
// Join possible states into a single string
|
|
String possibleStatesString = String.join(", ",
|
|
state.possibleStates.stream().map(Object::toString).collect(Collectors.toList()));
|
|
|
|
// Print the state information
|
|
System.out.printf("\n\n[%s]\n[%s]\n[%s]\n[%s]\n[%b]\n[%b]\n[%b]\n\n",
|
|
state.actualState, state.stateNameDE, state.stateNameEN,
|
|
possibleStatesString, state.cancelFlag, state.restartFlag, state.implementerFlag);
|
|
|
|
// Print the number of possible states
|
|
System.out.println("Possible States: " + state.possibleStates.size());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Takes the relevant data about possible states out of the {@code List<Entry>}
|
|
* and processes them to be saved into the State.
|
|
*
|
|
* @param stateFields List of Entry to be processed
|
|
* @param configurationQuery Query object of stateFields
|
|
*/
|
|
// public void updatePossibleStates(List<Entry> stateFields, Query
|
|
// configurationQuery) {
|
|
// stateFields.stream().forEach(entry -> {
|
|
// var actualState =
|
|
// entry.get(configurationQuery.getFieldId("actualState")).getIntValue();
|
|
// var possibleState =
|
|
// entry.get(configurationQuery.getFieldId("possibleState")).getIntValue();
|
|
// this.getState().get(actualState).addPossibleState(possibleState);
|
|
// });
|
|
// }
|
|
/**
|
|
* Query the German state name from the specified form. The German name in the
|
|
* form is associated with the English one. For merging the names into the
|
|
* {@link StateInfo}, we return a HashMap that is composed of the English state
|
|
* name as the key and the German state name as the value.
|
|
*
|
|
* @param api Remedy API object
|
|
* @throws ARException if an error occurs during the query
|
|
*/
|
|
// private void queryStateNames(RemedyJavaAPI api) throws ARException {
|
|
// var nameQuery = new Query.QueryBuilder("SYS:Menu Items Locale LkUp")
|
|
// .addFieldId("englishName", 1000004339)
|
|
// .addFieldId("germanName", 1000004338)
|
|
// .addFieldId("Locale", 1000004342)
|
|
// .addFieldId("SelectionCode", 1000004336)
|
|
// .build();
|
|
// var stateNames = api.queryFieldsById("\'Menu Type\' = \"Change Status
|
|
// Values\"",
|
|
// nameQuery.getFieldIds(),
|
|
// nameQuery.getFormName(), null, 0, 0);
|
|
// updateStateNames(stateNames, nameQuery);
|
|
// }
|
|
/**
|
|
* Takes the relevant data about state names out of the {@code List<Entry>} and
|
|
* processes them to be saved into the State.
|
|
*
|
|
* @param stateFields List of Entry to be processed
|
|
* @param nameQuery Query object of stateFields
|
|
*/
|
|
|
|
// public void updateStateNames(List<Entry> stateFields, Query nameQuery) {
|
|
// stateFields.stream()
|
|
// .filter(entry ->
|
|
// Optional.ofNullable(entry.get(nameQuery.getFieldId("Locale")))
|
|
// .map(Object::toString)
|
|
// .orElse("")
|
|
// .equals("de"))
|
|
// .forEach(
|
|
// entry -> {
|
|
// var selectionCode = nameQuery.getFieldId("SelectionCode");
|
|
// var englishName = nameQuery.getFieldId("englishName");
|
|
// var germanName = nameQuery.getFieldId("germanName");
|
|
// this.getState().put(entry.get(selectionCode).getIntValue(),
|
|
// new StateInfo(entry.get(englishName).toString(),
|
|
// entry.get(germanName).toString()));
|
|
// });
|
|
// }
|
|
/**
|
|
* Generate an Array of JSON objects that consists of all the state information.
|
|
* These are the integer representation of the actual state, an Array of integer
|
|
* representations of possible states, the English name of the actual state, and
|
|
* the German name of the actual state.
|
|
*
|
|
* @return Array of JSON objects with integer representation of state and
|
|
* {@link StateInfo}
|
|
*/
|
|
|
|
public ArrayList<StateResponse> get() {
|
|
var response = new ArrayList<StateResponse>();
|
|
this.state.forEach((key, value) -> {
|
|
response.add(new StateResponse(key, value.possibleState, value.stateNameEN, value.stateNameDE,
|
|
value.cancelFlag, value.restartFlag, value.implementerFlag));
|
|
});
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Represents the state info of a state.
|
|
*/
|
|
public class StateInfo {
|
|
String stateNameEN;
|
|
String stateNameDE;
|
|
ArrayList<Integer> possibleState;
|
|
boolean cancelFlag;
|
|
boolean restartFlag;
|
|
boolean implementerFlag;
|
|
|
|
/**
|
|
* Initializes an instance of the {@link StateInfo} class.
|
|
*
|
|
* @param possibleState possible state encoded as an integer
|
|
* @param stateNameEN state name in English
|
|
* @param stateNameDE state name in German
|
|
*/
|
|
public StateInfo(int possibleState, String stateNameEN, String stateNameDE) {
|
|
this.possibleState = new ArrayList<>();
|
|
this.possibleState.add(possibleState);
|
|
this.stateNameDE = stateNameDE;
|
|
this.stateNameEN = stateNameEN;
|
|
}
|
|
|
|
/**
|
|
* Initializes an instance of the {@link StateInfo} class.
|
|
*
|
|
* @param stateNameEN state name in English
|
|
* @param stateNameDE state name in German
|
|
*/
|
|
public StateInfo(String stateNameEN, String stateNameDE, boolean cancelFlag, boolean restartFlag,
|
|
boolean implementerFlag) {
|
|
this.stateNameEN = stateNameEN;
|
|
this.stateNameDE = stateNameDE;
|
|
this.cancelFlag = cancelFlag;
|
|
this.restartFlag = restartFlag;
|
|
this.implementerFlag = implementerFlag;
|
|
this.possibleState = new ArrayList<>();
|
|
}
|
|
|
|
/**
|
|
* Adds a possible state to transition to, encoded as an integer, to the
|
|
* {@link StateInfo}.
|
|
*
|
|
* @param possibleState possible state
|
|
*/
|
|
public void addPossibleState(int possibleState) {
|
|
if (!this.possibleState.contains(possibleState)) {
|
|
this.possibleState.add(possibleState);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the state name in English.
|
|
*
|
|
* @return the state name in English
|
|
*/
|
|
public String getStateNameEN() {
|
|
return stateNameEN;
|
|
}
|
|
|
|
/**
|
|
* Get the state name in German.
|
|
*
|
|
* @return the state name in German
|
|
*/
|
|
public String getStateNameDE() {
|
|
return stateNameDE;
|
|
}
|
|
|
|
/**
|
|
* Set the state name in German.
|
|
*
|
|
* @param stateNameDE the state name in German
|
|
*/
|
|
public void setStateNameDE(String stateNameDE) {
|
|
this.stateNameDE = stateNameDE;
|
|
}
|
|
|
|
/**
|
|
* Set the state name in English.
|
|
*
|
|
* @param stateNameEN the state name in English
|
|
*/
|
|
public void setStateNameEN(String stateNameEN) {
|
|
this.stateNameEN = stateNameEN;
|
|
}
|
|
}
|
|
}
|