Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.anotheria.anosite.wizard.api.BaseWizardAPIImpl Maven / Gradle / Ivy
package net.anotheria.anosite.wizard.api;
import net.anotheria.anoplass.api.APIInitException;
import net.anotheria.anoplass.api.AbstractAPIImpl;
import net.anotheria.anoplass.api.session.APISession;
import net.anotheria.anoprise.metafactory.MetaFactory;
import net.anotheria.anoprise.metafactory.MetaFactoryException;
import net.anotheria.anosite.gen.aswizarddata.data.WizardDef;
import net.anotheria.anosite.gen.aswizarddata.service.ASWizardDataServiceException;
import net.anotheria.anosite.gen.aswizarddata.service.IASWizardDataService;
import net.anotheria.anosite.gen.aswizarddata.service.WizardDefNotFoundInASWizardDataServiceException;
import net.anotheria.anosite.wizard.WizardCommand;
import net.anotheria.anosite.wizard.api.exception.WizardAPIException;
import net.anotheria.anosite.wizard.api.exception.WizardAPIFirstStepException;
import net.anotheria.anosite.wizard.api.exception.WizardAPILastStepException;
import net.anotheria.anosite.wizard.api.exception.WizardNotFoundException;
import net.anotheria.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static net.anotheria.anosite.wizard.WizardCommand.CANCEL;
import static net.anotheria.anosite.wizard.WizardCommand.FINISH;
import static net.anotheria.anosite.wizard.WizardCommand.NAVIGATE_TO;
import static net.anotheria.anosite.wizard.WizardCommand.NEXT;
import static net.anotheria.anosite.wizard.WizardCommand.PREVIOUS;
/**
* Base implementation of WizardAPI.
*
* @author h3ll
*/
public class BaseWizardAPIImpl extends AbstractAPIImpl implements WizardAPI {
/**
* {@link Logger} instance.
*/
private static final Logger LOG = LoggerFactory.getLogger(BaseWizardAPIImpl.class);
/**
* BaseWizardAPIImpl WIZARD_ATTRIBUTE_SUFFIX.
*/
public static final String WIZARD_ATTRIBUTE_SUFFIX = "_wizardData";
/**
* Attribute which holds allowed wizard step commands.
*/
public static final String ALLOWED_WIZARD_STEP_COMMANDS_ATTRIBUTE = "allowedWizardStepCommands";
/**
* Wizard service.
*/
private IASWizardDataService wizardDataService;
@Override
public void init() throws APIInitException {
super.init();
try {
this.wizardDataService = MetaFactory.get(IASWizardDataService.class);
} catch (MetaFactoryException e) {
throw new APIInitException("WizardAPI init failed", e);
}
}
@Override
public WizardAO getWizardByName(String wizardName) throws WizardAPIException {
if (StringUtils.isEmpty(wizardName))
throw new IllegalArgumentException("Wizard name is illegal");
try {
List wizards = wizardDataService.getWizardDefsByProperty(WizardDef.PROP_NAME, wizardName);
if (wizards == null || wizards.isEmpty())
throw new WizardNotFoundException(wizardName);
return toWizardAO(wizards.get(0));
} catch (ASWizardDataServiceException e) {
LOG.error("getWizardByName(" + wizardName + ")", e);
throw new WizardAPIException("Backend failure", e);
}
}
@Override
public WizardAO getWizard(String wizardId) throws WizardAPIException {
if (StringUtils.isEmpty(wizardId))
throw new IllegalArgumentException("WizardId is illegal");
try {
return toWizardAO(wizardDataService.getWizardDef(wizardId));
} catch (WizardDefNotFoundInASWizardDataServiceException wDnfe) {
throw new WizardNotFoundException(wizardId);
} catch (ASWizardDataServiceException e) {
LOG.error("getWizard(" + wizardId + ")", e);
throw new WizardAPIException("Backend failure", e);
}
}
@Override
public String getCurrentStepPageId(String wizardId) throws WizardAPIException {
return getCurrentStep(wizardId).getPagexId();
}
@Override
public WizardStepAO getCurrentStep(String wizardId) throws WizardAPIException {
WizardAO wizard = getWizard(wizardId);
if (wizard.getWizardSteps().isEmpty()) {
LOG.warn(" getCurrentStep(" + wizardId + ") - Steps are not properly configured");
throw new WizardAPIException(" getCurrentStep(" + wizardId + ") - Steps are not properly configured");
}
WizardData data = getDataFromSession(wizardId);
if (data == null) {
data = createWizardData(wizard);
}
return data.getCurrentStep();
}
@Override
public List getCompletedSteps(String wizardId) throws WizardAPIException {
WizardData data = getDataFromSession(wizardId);
if (data == null) {
LOG.warn("getCompletedSteps(" + wizardId + ") . There is no data found. Suppose it was just removed!");
throw new WizardAPIException("getCompletedSteps(" + wizardId + ") . There is no data found. Suppose it was just removed!");
}
return data.getCompletedSteps();
}
@Override
public WizardStepAO adjustToNextStep(String wizardId) throws WizardAPIException {
WizardData data = getDataFromSession(wizardId);
if (data == null) {
LOG.warn("adjustToNextStep(" + wizardId + ") . There is no data found.");
throw new WizardAPIException("adjustToNextStep(" + wizardId + ") . There is no data found.");
}
WizardAO wizard = getWizard(wizardId);
WizardStepAO currentStep = getCurrentStep(wizardId);
if (isLastStep(wizard, currentStep))
throw new WizardAPILastStepException(wizardId, currentStep.getPagexId(), currentStep.getStepIndex());
try {
//check if next is allowed!
if (!isCommandAllowed(wizard.getId(), currentStep.getPagexId(), NEXT)) {
LOG.debug("Next step is not allowed! Stay on current!");
return currentStep;
}
final int nextStepIndex = currentStep.getStepIndex() + 1;
//mark step completed
data.addCompletedStep(data.getCurrentStep());
WizardStepAO nextStep = wizard.getWizardSteps().get(nextStepIndex);
data.setCurrentStep(nextStep);
//returning nextStep data
return nextStep;
} finally {
cleanAllowedCommands(wizard.getId(), currentStep.getPagexId());
}
}
@Override
public WizardStepAO adjustToPreviousStep(String wizardId) throws WizardAPIException {
WizardData data = getDataFromSession(wizardId);
if (data == null) {
LOG.warn("adjustToPreviousStep(" + wizardId + ") . There is no data found.");
throw new WizardAPIException("adjustToPreviousStep(" + wizardId + ") . There is no data found.");
}
WizardStepAO currentStep = getCurrentStep(wizardId);
WizardAO wizard = getWizard(wizardId);
if (isFirstStep(wizard, currentStep))
throw new WizardAPIFirstStepException(wizardId, currentStep.getPagexId(), currentStep.getStepIndex());
try {
if (!isCommandAllowed(wizard.getId(), currentStep.getPagexId(), PREVIOUS)) {
LOG.debug("Previous step is not allowed! Stay on current!");
return currentStep;
}
final int prevStepIndex = currentStep.getStepIndex() - 1;
//we should not mark step as completed
WizardStepAO prevStep = wizard.getWizardSteps().get(prevStepIndex);
data.setCurrentStep(prevStep);
//returning prevStep data
return prevStep;
} finally {
cleanAllowedCommands(wizard.getId(), currentStep.getPagexId());
}
}
@Override
public WizardStepAO adjustToStep(String wizardId, int stepIndex) throws WizardAPIException {
WizardAO wizard = getWizard(wizardId);
WizardStepAO currentStep = getCurrentStep(wizardId);
if (!navigateToAllowed(wizard, stepIndex)) {
LOG.debug("Navigate to step is not allowed! Stay on current!");
return currentStep;
}
if (currentStep.getStepIndex() == stepIndex)
return currentStep;
WizardData data = getDataFromSession(wizardId);
if (data == null) {
LOG.warn("adjustToStep(" + wizardId + ", " + stepIndex + ") . There is no data found.");
throw new WizardAPIException("adjustToStep(" + wizardId + ", " + stepIndex + ") . There is no data found.");
}
//we should not mark step as completed
WizardStepAO step = wizard.getWizardSteps().get(stepIndex);
data.setCurrentStep(step);
//returning step data
return step;
}
/**
* Checking possibility of navigation to selected step.
*
* @param wizard {@link WizardAO}
* @param stepIndex index
* @return boolean value
* @throws net.anotheria.anosite.wizard.api.exception.WizardAPIException
* on errors
*/
private boolean navigateToAllowed(WizardAO wizard, int stepIndex) throws WizardAPIException {
if (stepIndex < 0 || stepIndex >= wizard.getWizardSteps().size())
throw new IllegalArgumentException("Step index is illegal " + stepIndex);
WizardStepAO stepAO = wizard.getWizardSteps().get(stepIndex);
List passed = getCompletedSteps(wizard.getId());
if (!passed.contains(stepAO) && !isCommandAllowed(wizard.getId(), stepAO.getPagexId(), NAVIGATE_TO)) {
log.debug(stepAO + "is not passed! Navigation is not allowed!");
return false;
}
log.debug("Navigating to allowed " + stepAO);
return true;
}
@Override
public boolean finishWizard(WizardAO wizard) throws WizardAPIException {
if (wizard == null)
throw new IllegalArgumentException("Incorrect incoming param");
WizardStepAO current = getCurrentStep(wizard.getId());
try {
if (isLastStep(wizard, current) && isCommandAllowed(wizard.getId(), current.getPagexId(), FINISH)) {
removeWizardData(wizard.getId());
LOG.debug(wizard + " finished");
return true;
}
LOG.debug("Wizard Finish is not allowed " + wizard + "isLastStep [" + isLastStep(wizard, current) +
"] commandAllowed[" + isCommandAllowed(wizard.getId(), current.getPagexId(), FINISH) + "]");
return false;
} finally {
cleanAllowedCommands(wizard.getId(), current.getPagexId());
}
}
@Override
public boolean cancelWizard(WizardAO wizard) throws WizardAPIException {
if (wizard == null)
throw new IllegalArgumentException("Incorrect incoming param");
WizardStepAO current = getCurrentStep(wizard.getId());
try {
if (isCommandAllowed(wizard.getId(), current.getPagexId(), CANCEL)) {
removeWizardData(wizard.getId());
LOG.debug(wizard + " canceled on step :[" + current + "]");
return true;
}
LOG.debug(wizard + " cancel not allowed on step :[" + current + "]");
return false;
} finally {
cleanAllowedCommands(wizard.getId(), current.getWizardId());
}
}
@Override
public void allowNextStepNavigation(WizardAO wizard, WizardStepAO wizardStep) {
allowCommand(wizard.getId(), wizardStep.getPagexId(), NEXT);
}
@Override
public void allowPreviousStepNavigation(WizardAO wizard, WizardStepAO wizardStep) {
allowCommand(wizard.getId(), wizardStep.getPagexId(), PREVIOUS);
}
@Override
public void allowWizardCancel(WizardAO wizard, WizardStepAO wizardStep) {
allowCommand(wizard.getId(), wizardStep.getPagexId(), CANCEL);
}
@Override
public void allowWizardFinish(WizardAO wizard, WizardStepAO wizardStep) {
allowCommand(wizard.getId(), wizardStep.getPagexId(), FINISH);
}
public void allowWizardNavigateTo(WizardAO wizard, WizardStepAO wizardStep) {
allowCommand(wizard.getId(), wizardStep.getPagexId(), NAVIGATE_TO);
}
/**
* Allow selected {@link WizardCommand} execution for wizard with selected id, on selected step.
*
* @param wizardId id of wizard
* @param wizardStepId id of wizard step
* @param command {@link WizardCommand}
*/
private void allowCommand(String wizardId, String wizardStepId, WizardCommand command) {
Map> allowedWizardCommands = getAllowedCommands();
Set stepCommands = allowedWizardCommands.get(wizardId + "_" + wizardStepId);
if (stepCommands == null) {
stepCommands = new HashSet();
allowedWizardCommands.put(wizardId + "_" + wizardStepId, stepCommands);
}
stepCommands.add(command);
}
/**
* Return true - if selected {@link WizardCommand} allowed for selected wizard with wizardId, on step with wizardStepId.
*
* @param wizardId wizard id
* @param wizardStepId page id / step id
* @param command {@link WizardCommand}
* @return boolean value
*/
private boolean isCommandAllowed(String wizardId, String wizardStepId, WizardCommand command) {
Map> allowedWizardCommands = getAllowedCommands();
Set stepCommands = allowedWizardCommands.get(wizardId + "_" + wizardStepId);
return stepCommands != null && stepCommands.contains(command);
}
/**
* Remove all commands.
*
* @param wizardId id of wizard
* @param wizardStepId page id/ step id
*/
private void cleanAllowedCommands(String wizardId, String wizardStepId) {
Map> allowedWizardCommands = getAllowedCommands();
if (allowedWizardCommands.isEmpty())
return;
allowedWizardCommands.remove(wizardId + "_" + wizardStepId);
}
/**
* Get allowed commands from APISession.
* Command map contains all allowed {@link WizardCommand} which can be performed on current step.
*
* @return {@link Map>}
*/
private Map> getAllowedCommands() {
Object cached = getAttributeFromSession(ALLOWED_WIZARD_STEP_COMMANDS_ATTRIBUTE);
if (cached instanceof Map)
//noinspection unchecked
return (Map>) cached;
Map> allowedWizardCommands = new ConcurrentHashMap>();
setAttributeInSession(ALLOWED_WIZARD_STEP_COMMANDS_ATTRIBUTE, allowedWizardCommands);
return allowedWizardCommands;
}
private boolean isFirstStep(WizardAO wizard, WizardStepAO wizardStep) throws WizardAPIException {
if (wizard.getWizardSteps().isEmpty()) {
LOG.warn(" isFirstStep(" + wizard + "," + wizardStep + ") - Steps are not properly configured");
throw new WizardAPIException(" isFirstStep(" + wizard + "," + wizardStep + ")- Steps are not properly configured");
}
return wizard.getWizardSteps().get(0).equals(wizardStep);
}
private boolean isLastStep(WizardAO wizard, WizardStepAO wizardStep) throws WizardAPIException {
if (wizard.getWizardSteps().isEmpty()) {
LOG.warn(" isFirstStep(" + wizard + "," + wizardStep + ") - Steps are not properly configured");
throw new WizardAPIException(" isFirstStep(" + wizard + "," + wizardStep + ")- Steps are not properly configured");
}
int lastStepIndex = wizard.getWizardSteps().size() - 1;
return wizard.getWizardSteps().get(lastStepIndex).equals(wizardStep);
}
/**
* Return {@link WizardData} from {@link APISession} if such exists. Null otherwise.
*
* @param wizardId id of wizard.
* @return {@link WizardData} or null
*/
private WizardData getDataFromSession(String wizardId) {
Object attribute = getAttributeFromSession(wizardId + WIZARD_ATTRIBUTE_SUFFIX);
if (attribute instanceof WizardData)
return WizardData.class.cast(attribute);
return null;
}
/**
* Creates new {@link WizardData} and store it to {@link APISession}.
*
* @param wizard {@link WizardAO}
* @return {@link WizardData}
*/
private WizardData createWizardData(WizardAO wizard) {
final int firstStepIndex = 0;
WizardData data = new WizardData(wizard.getId());
data.setCurrentStep(wizard.getWizardSteps().get(firstStepIndex));
//storing to APISession
setAttributeInSession(wizard.getId() + WIZARD_ATTRIBUTE_SUFFIX, data);
return data;
}
/**
* Creates {@link WizardAO} based on {@link WizardDef}.
*
* @param wizardDef {@link WizardDef}
* @return {@link WizardAO}
* @throws net.anotheria.anosite.wizard.api.exception.WizardAPIException
* on errors
*/
private WizardAO toWizardAO(WizardDef wizardDef) throws WizardAPIException {
WizardAO result = new WizardAO(wizardDef.getId());
result.setName(wizardDef.getName());
result.setCancelRedirectUrl(wizardDef.getWizardCancelRedirectUrl());
result.setFinishRedirectUrl(wizardDef.getWizardFinishRedirectUrl());
result.setHandlerId(wizardDef.getHandler());
result.setWizardSteps(toWizardSteps(wizardDef.getId(), wizardDef.getWizardSteps()));
return result;
}
/**
* Create wizard steps collection based on configured via cms steps ids.
*
* @param wizardId id of wizard
* @param wizardSteps {@link List}
* @return {@link WizardStepAO}
*/
private List toWizardSteps(String wizardId, List wizardSteps) {
List resultSteps = new ArrayList(wizardSteps.size());
for (String pagexId : wizardSteps) {
int position = wizardSteps.indexOf(pagexId);
resultSteps.add(position, new WizardStepAO(wizardId, position, pagexId));
}
return resultSteps;
}
/**
* Remove WizardData session attribute.
*
* @param wizardId id of wizard
*/
private void removeWizardData(String wizardId) {
removeAttributeFromSession(wizardId + WIZARD_ATTRIBUTE_SUFFIX);
}
/**
* WizardData object which represents APISessionAttribute for storing WizardStepAO.
*/
protected class WizardData implements Serializable {
/**
* Basic serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* WizardData 'wizardId'.
*/
private String wizardId;
/**
* WizardData 'currentStep'.
*/
private WizardStepAO currentStep;
/**
* WizardData 'completedSteps'.
*/
private List completedSteps = new ArrayList();
/**
* Constructor.
*
* @param aWizardId id
*/
public WizardData(String aWizardId) {
this.wizardId = aWizardId;
}
public String getWizardId() {
return wizardId;
}
public WizardStepAO getCurrentStep() {
return currentStep;
}
public void setCurrentStep(WizardStepAO currentStep) {
this.currentStep = currentStep;
}
public List getCompletedSteps() {
return completedSteps;
}
/**
* Add {@link WizardStepAO} to completed step collection if such still does not exists there.
*
* @param completed {@link WizardStepAO}
*/
public void addCompletedStep(WizardStepAO completed) {
if (!completedSteps.contains(completed))
completedSteps.add(completed);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("WizardData");
sb.append("{completedSteps=").append(completedSteps.size());
sb.append(", wizardId='").append(wizardId).append('\'');
sb.append(", currentStep=").append(currentStep);
sb.append('}');
return sb.toString();
}
}
}