package com.ciandt.techgallery.service.impl;
import com.google.api.server.spi.response.BadRequestException;
import com.google.api.server.spi.response.InternalServerErrorException;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.oauth.OAuthRequestException;
import com.google.appengine.api.users.User;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Ref;
import com.ciandt.techgallery.persistence.dao.SkillDAO;
import com.ciandt.techgallery.persistence.dao.impl.SkillDAOImpl;
import com.ciandt.techgallery.persistence.model.Skill;
import com.ciandt.techgallery.persistence.model.TechGalleryUser;
import com.ciandt.techgallery.persistence.model.Technology;
import com.ciandt.techgallery.service.SkillService;
import com.ciandt.techgallery.service.TechnologyService;
import com.ciandt.techgallery.service.UserServiceTG;
import com.ciandt.techgallery.service.enums.ValidationMessageEnums;
import com.ciandt.techgallery.service.impl.profile.UserProfileServiceImpl;
import com.ciandt.techgallery.service.model.UserSkillTO;
import com.ciandt.techgallery.utils.TechGalleryUtil;
import com.ciandt.techgallery.utils.i18n.I18n;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Services for Skill Endpoint requests.
*
* @author Felipe Goncalves de Castro
*
*/
public class SkillServiceImpl implements SkillService {
/*
* Constants --------------------------------------------
*/
private static final Logger log = Logger.getLogger(SkillServiceImpl.class.getName());
private static final I18n i18n = I18n.getInstance();
/*
* Attributes --------------------------------------------
*/
private static SkillServiceImpl instance;
SkillDAO skillDao = SkillDAOImpl.getInstance();
/** Technology service. */
TechnologyService techService = TechnologyServiceImpl.getInstance();
/** tech gallery user service. */
UserServiceTG userService = UserServiceTGImpl.getInstance();
/*
* Constructors --------------------------------------------
*/
private SkillServiceImpl() {}
/**
* Singleton method for the service.
*
* @author <a href="mailto:joaom@ciandt.com"> João Felipe de Medeiros Moreira </a>
* @since 07/10/2015
*
* @return SkillServiceImpl instance.
*/
public static SkillServiceImpl getInstance() {
if (instance == null) {
instance = new SkillServiceImpl();
}
return instance;
}
/*
* Methods --------------------------------------------
*/
@Override
public Skill addOrUpdateSkill(Skill skill, User user)
throws InternalServerErrorException, BadRequestException, NotFoundException {
log.info("Starting creating or updating skill");
validateInputs(skill, user);
Technology technology = skill.getTechnology().get();
TechGalleryUser techUser = userService.getUserByGoogleId(user.getUserId());
Skill skillEntity = skillDao.findByUserAndTechnology(techUser, technology);
// if there is a skillEntity, it is needed to inactivate it and create a new
// one
inactivateSkill(skillEntity);
final Skill newSkill = addNewSkill(skill, techUser, technology);
UserProfileServiceImpl.getInstance().handleSkillChanges(newSkill);
return newSkill;
}
private void inactivateSkill(Skill skillEntity) {
if (skillEntity != null) {
log.info("Inactivating skill: " + skillEntity.getId());
skillEntity.setInactivatedDate(new Date());
skillEntity.setActive(Boolean.FALSE);
skillDao.update(skillEntity);
}
}
@Override
public void deleteUserSkill(String techId, User user) throws InternalServerErrorException, BadRequestException, NotFoundException, OAuthRequestException {
Skill skillEntity = getUserSkill(techId, user);
inactivateSkill(skillEntity);
UserProfileServiceImpl.getInstance().handleSkillChanges(skillEntity);
}
/**
* Validate inputs of SkillResponse.
*
* @param skill inputs to be validate
* @param user info about user from google
*
* @throws BadRequestException for the validations.
* @throws InternalServerErrorException in case something goes wrong
* @throws NotFoundException in case the information are not founded
*/
private void validateInputs(Skill skill, User user)
throws BadRequestException, NotFoundException, InternalServerErrorException {
log.info("Validating inputs of skill");
if (user == null || user.getUserId() == null || user.getUserId().isEmpty()) {
throw new BadRequestException(ValidationMessageEnums.USER_GOOGLE_ENDPOINT_NULL.message());
}
final TechGalleryUser techUser = userService.getUserByGoogleId(user.getUserId());
if (techUser == null) {
throw new BadRequestException(ValidationMessageEnums.USER_NOT_EXIST.message());
}
if (skill == null) {
throw new BadRequestException(ValidationMessageEnums.SKILL_CANNOT_BLANK.message());
}
if (skill.getValue() == null || skill.getValue() < 0 || skill.getValue() > 5) {
throw new BadRequestException(ValidationMessageEnums.SKILL_RANGE.message());
}
if (skill.getTechnology() == null) {
throw new BadRequestException(ValidationMessageEnums.TECHNOLOGY_ID_CANNOT_BLANK.message());
}
}
private Skill addNewSkill(Skill skill, TechGalleryUser techUser, Technology technology) {
log.info("Adding new skill...");
final Skill newSkill = new Skill();
newSkill.setTechGalleryUser(Ref.create(techUser));
newSkill.setTechnology(Ref.create(technology));
newSkill.setValue(skill.getValue());
newSkill.setActive(Boolean.TRUE);
newSkill.setCreationDate(new Date());
final Key<Skill> newSkillKey = skillDao.add(newSkill);
newSkill.setId(newSkillKey.getId());
log.info("New skill added: " + newSkill.getId());
return newSkill;
}
@Override
public Skill getUserSkill(String techId, User user) throws BadRequestException,
OAuthRequestException, NotFoundException, InternalServerErrorException {
// user google id
String googleId;
// user from techgallery datastore
TechGalleryUser tgUser;
// User from endpoint can't be null
if (user == null) {
throw new OAuthRequestException(i18n.t("OAuth error, null user reference!"));
} else {
googleId = user.getUserId();
}
// TechGalleryUser can't be null and must exists on datastore
if (googleId == null || googleId.equals("")) {
throw new BadRequestException(i18n.t("Current user was not found!"));
} else {
// get the TechGalleryUser from datastore or PEOPLE API
tgUser = userService.getUserByGoogleId(googleId);
if (tgUser == null) {
throw new BadRequestException(i18n.t("Endorser user do not exists on datastore!"));
}
}
// Technology can't be null
final Technology technology = techService.getTechnologyById(techId, user);
if (technology == null) {
throw new BadRequestException(i18n.t("Technology do not exists!"));
}
final Skill userSkill = skillDao.findByUserAndTechnology(tgUser, technology);
if (userSkill == null) {
throw new NotFoundException(i18n.t("User skill do not exist!"));
} else {
return userSkill;
}
}
@Override
public Skill getUserSkill(String techId, TechGalleryUser user) throws BadRequestException,
OAuthRequestException, NotFoundException, InternalServerErrorException {
// User can't be null
if (user == null) {
throw new OAuthRequestException(i18n.t("Null user reference!"));
}
// Technology can't be null
final Technology technology = techService.getTechnologyById(techId, null);
if (technology == null) {
throw new NotFoundException(i18n.t("Technology do not exists!"));
}
final Skill userSkill = skillDao.findByUserAndTechnology(user, technology);
if (userSkill == null) {
return null;
} else {
return userSkill;
}
}
@Override
public List<Skill> getSkillsByTech(Technology technology) throws BadRequestException {
if (technology == null) {
throw new BadRequestException(ValidationMessageEnums.TECHNOLOGY_NOT_EXIST.message());
}
return skillDao.findByTechnology(technology);
}
@Override
public String importUserSkill(UserSkillTO userSkills, User user)
throws InternalServerErrorException, BadRequestException {
String email = userSkills.getEmail();
TechGalleryUser techGalleryUser;
try {
techGalleryUser = userService.getUserSyncedWithProvider(email.split("@")[0]);
for (String techSkill : userSkills.getTechSkill()) {
String[] splitedTechSkill = techSkill.split(";");
Technology technology = recoverTechnologyById(splitedTechSkill[0]);
if (technology != null) {
Skill skillEntity = skillDao.findByUserAndTechnology(techGalleryUser, technology);
if (skillEntity != null) {
log.warning("Inactivating skill: " + skillEntity.getId());
skillEntity.setInactivatedDate(new Date());
skillEntity.setActive(Boolean.FALSE);
skillDao.update(skillEntity);
}
Skill skill = new Skill();
skill.setValue(Integer.parseInt(splitedTechSkill[1]));
Skill newSkill = addNewSkill(skill, techGalleryUser, technology);
UserProfileServiceImpl.getInstance().handleSkillChanges(newSkill);
}
}
} catch (NotFoundException e) {
log.log(Level.INFO,
"User " + userSkills.getEmail() + " not found during import. Row ignored.", e);
}
return null;
}
private Technology recoverTechnologyById(String techCompleteName) {
Technology technology = null;
try {
String techName = techCompleteName.substring(techCompleteName.indexOf('[') + 1,
techCompleteName.indexOf(']'));
techName = TechGalleryUtil.slugify(techName);
technology = techService.getTechnologyById(techName, null);
} catch (Exception e) {
log.info("Technology " + techCompleteName + " does not exist!");
} catch (Throwable e) {
log.info("Technology " + techCompleteName + " does not exist!");
}
return technology;
}
}