Java tutorial
/* * Copyright (c) 2014. * * BaasBox - info@baasbox.com * * 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 com.baasbox.commands; import java.io.IOException; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import com.baasbox.commands.exceptions.CommandException; import com.baasbox.commands.exceptions.CommandExecutionException; import com.baasbox.commands.exceptions.CommandNotImplementedException; import com.baasbox.commands.exceptions.CommandParsingException; import com.baasbox.dao.UserDao; import com.baasbox.dao.exception.EmailAlreadyUsedException; import com.baasbox.dao.exception.SqlInjectionException; import com.baasbox.dao.exception.UserAlreadyExistsException; import com.baasbox.db.DbHelper; import com.baasbox.enumerations.DefaultRoles; import com.baasbox.exception.AlreadyFriendsException; import com.baasbox.exception.InvalidJsonException; import com.baasbox.exception.OpenTransactionException; import com.baasbox.exception.UserNotFoundException; import com.baasbox.service.push.PushService; import com.baasbox.service.scripting.base.JsonCallback; import com.baasbox.service.scripting.js.Json; import com.baasbox.service.storage.BaasBoxPrivateFields; import com.baasbox.service.user.FriendShipService; import com.baasbox.service.user.RoleService; import com.baasbox.service.user.UserService; import com.baasbox.util.JSONFormats; import com.baasbox.util.QueryParams; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.BooleanNode; import com.fasterxml.jackson.databind.node.NullNode; import com.google.common.collect.ImmutableMap; import com.orientechnologies.orient.core.db.record.OIdentifiable; import com.orientechnologies.orient.core.record.impl.ODocument; import com.orientechnologies.orient.core.type.tree.OMVRBTreeRIDSet; import scala.util.parsing.combinator.testing.Str; /** * Created by Andrea Tortorella on 02/07/14. */ class UsersResource extends BaseRestResource { public static final Resource INSTANCE = new UsersResource(); @Override protected ImmutableMap.Builder<String, ScriptCommand> baseCommands() { return super.baseCommands().put("suspend", new ScriptCommand() { @Override public JsonNode execute(JsonNode command, JsonCallback callback) throws CommandException { return suspend(command); } }).put("reactivate", new ScriptCommand() { @Override public JsonNode execute(JsonNode command, JsonCallback callback) throws CommandException { return reactivate(command); } }).put("follow", this::friendshipUpdate).put("followers", getFriends(false)) .put("following", getFriends(true)).put("changeUsername", this::changeUsername) .put("changePassword", this::changePassword); } private ScriptCommand getFriends(boolean following) { return (command, unused) -> { JsonNode params = command.get(ScriptCommand.PARAMS); if (params == null) throw new CommandParsingException(command, "missing required parameters"); JsonNode user = params.path("user"); JsonNode query = params.get("query"); if (!user.isTextual()) throw new CommandParsingException(command, "missing required paramter user as string"); if (query != null && !query.isObject()) throw new CommandParsingException(command, "query must be a json object"); QueryParams qparams = QueryParams.getParamsFromJson(query); try { List<ODocument> res = following ? FriendShipService.getFollowing(user.asText(), qparams) : FriendShipService.getFriendsOf(user.asText(), qparams); String s = JSONFormats.prepareDocToJson(res, JSONFormats.Formats.USER); return Json.mapper().readTreeOrMissing(s); } catch (SqlInjectionException e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } }; } // private JsonNode followers(JsonNode command, JsonCallback unused) throws CommandException{ // try { // List<ODocument> friendsOf = FriendShipService.getFriendsOf(user.asText(), QueryParams.getParamsFromJson(query)); // String s = JSONFormats.prepareResponseToJson(friendsOf, JSONFormats.Formats.USER); // return Json.mapper().readTreeOrMissing(s); // } catch (SqlInjectionException | IOException e) { // throw new CommandExecutionException(command,ExceptionUtils.getMessage(e),e); // } // } protected JsonNode friendshipUpdate(JsonNode command, JsonCallback unused) throws CommandException { JsonNode params = command.get(ScriptCommand.PARAMS); if (params == null) throw new CommandParsingException(command, "missing required parameters"); JsonNode from = params.get("from"); JsonNode to = params.get("to"); JsonNode remove = params.get("remove"); if (from == null || !from.isTextual() || to == null || !to.isTextual()) throw new CommandParsingException(command, "missing required user"); boolean unfollow; if (remove == null) { unfollow = false; } else if (remove.isBoolean()) { unfollow = remove.asBoolean(); } else { throw new CommandParsingException(command, "wrong parameter remove"); } if (unfollow) { return doUnfollow(command, from.asText(), to.asText()); } else { return doFollow(command, from.asText(), to.asText()); } } private JsonNode doUnfollow(JsonNode command, String from, String to) throws CommandExecutionException { try { return BooleanNode.valueOf(FriendShipService.unfollow(from, to)); } catch (Exception e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } } private JsonNode doFollow(JsonNode command, String from, String to) throws CommandExecutionException { try { ODocument followed = FriendShipService.follow(from, to); String s = JSONFormats.prepareDocToJson(followed, JSONFormats.Formats.USER); return Json.mapper().readTree(s); } catch (UserNotFoundException e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } catch (AlreadyFriendsException e) { return NullNode.getInstance(); } catch (SqlInjectionException e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } catch (Exception e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } } protected JsonNode suspend(JsonNode command) throws CommandException { String username = getUsername(command); try { boolean inTransaction = DbHelper.isInTransaction(); if (inTransaction) { return BooleanNode.getFalse(); } UserService.disableUser(username); } catch (UserNotFoundException e) { throw new CommandExecutionException(command, "User " + username + " does not exists"); } catch (OpenTransactionException e) { return BooleanNode.getFalse(); //throw new CommandExecutionException(command,"Transaction still open during suspend"); } return BooleanNode.getTrue(); } protected JsonNode changeUsername(JsonNode command, JsonCallback unused) throws CommandException { String username = getUsername(command); JsonNode newUsernameJson = getParamField(command, "newUsername"); if (newUsernameJson == null || !newUsernameJson.isTextual()) throw new CommandExecutionException(command, "invalid new username: " + newUsernameJson); String newUsername = newUsernameJson.asText(); try { UserService.changeUsername(username, newUsername); } catch (UserNotFoundException | OpenTransactionException | SqlInjectionException e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } return NullNode.getInstance(); } protected JsonNode changePassword(JsonNode command, JsonCallback unused) throws CommandException { String username = getUsername(command); JsonNode newPasswordJson = getParamField(command, "newPassword"); if (newPasswordJson == null || !newPasswordJson.isTextual()) throw new CommandExecutionException(command, "invalid new password: " + newPasswordJson); String newPassword = newPasswordJson.asText(); try { UserService.changePassword(username, newPassword); } catch (UserNotFoundException | OpenTransactionException | SqlInjectionException e) { throw new CommandExecutionException(command, ExceptionUtils.getMessage(e), e); } return NullNode.getInstance(); } private String getUsername(JsonNode command) throws CommandException { JsonNode params = command.get(ScriptCommand.PARAMS); JsonNode id = params.get("username"); if (id == null || !id.isTextual()) { throw new CommandParsingException(command, "missing user username"); } String username = id.asText(); boolean internalUsername = UserService.isInternalUsername(username); if (internalUsername) { throw new CommandExecutionException(command, "invalid user: " + username); } return username; } protected JsonNode reactivate(JsonNode command) throws CommandException { String username = getUsername(command); try { if (DbHelper.isInTransaction()) return BooleanNode.getFalse(); UserService.enableUser(username); } catch (UserNotFoundException e) { throw new CommandExecutionException(command, "user " + username + " does not exists"); } catch (OpenTransactionException e) { return BooleanNode.getFalse(); //throw new CommandExecutionException(command,"transaction still open while altering user status"); } return BooleanNode.getTrue(); } @Override protected JsonNode delete(JsonNode command) throws CommandException { throw new CommandNotImplementedException(command, "not implemented"); } @Override protected JsonNode put(JsonNode command) throws CommandException { String username = getUsername(command); JsonNode params = command.get(ScriptCommand.PARAMS); String role = params.get("role") != null ? params.get("role").asText() : null; JsonNode userVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_ONLY_BY_THE_USER); JsonNode friendsVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_BY_FRIENDS_USER); JsonNode registeredVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_BY_REGISTERED_USER); JsonNode anonymousVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_BY_ANONYMOUS_USER); try { ODocument doc; if (!params.has("id")) { doc = UserService.updateProfile(username, role, anonymousVisible, userVisible, friendsVisible, registeredVisible); } else { String id = params.get("id") != null ? params.get("id").asText() : null; doc = UserService.updateProfile(username, role, anonymousVisible, userVisible, friendsVisible, registeredVisible, id); } String s = JSONFormats.prepareDocToJson(doc, JSONFormats.Formats.USER); return Json.mapper().readTree(s); } catch (Exception e) { throw new CommandExecutionException(command, "Error updating user: " + ExceptionUtils.getMessage(e)); } } @Override protected JsonNode post(JsonNode command) throws CommandException { try { JsonNode params = command.get(ScriptCommand.PARAMS); if (params == null || !params.isObject()) throw new CommandParsingException(command, "missing parameters"); String username = getUsername(command); JsonNode password = params.get("password"); if (password == null || !password.isTextual()) throw new CommandParsingException(command, "missing required password"); JsonNode id = params.get(BaasBoxPrivateFields.ID.toString()); String idString = null; if (!(id instanceof NullNode) && id != null && !id.isTextual()) throw new CommandParsingException(command, "ID must be a string"); if (!(id instanceof NullNode) && id != null && id.isTextual() && StringUtils.isBlank(id.asText())) throw new CommandParsingException(command, "ID cannot be empty or cannot contains only whitespaces"); if (!(id instanceof NullNode) && id != null && id.isTextual()) idString = id.asText(); JsonNode roleNode = params.get("role"); String role; if (roleNode == null) { role = DefaultRoles.REGISTERED_USER.getORole().getName(); } else if (roleNode.isTextual()) { role = roleNode.asText(); } else { throw new CommandParsingException(command, "role parameter is not valid"); } if (!RoleService.exists(role)) { throw new CommandExecutionException(command, "required role does not exists: " + role); } JsonNode userVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_ONLY_BY_THE_USER); JsonNode friendsVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_BY_FRIENDS_USER); JsonNode registeredVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_BY_REGISTERED_USER); JsonNode anonymousVisible = params.get(UserDao.ATTRIBUTES_VISIBLE_BY_ANONYMOUS_USER); ODocument user = UserService.signUp(username, password.asText(), new Date(), role, anonymousVisible, userVisible, friendsVisible, registeredVisible, false, idString); String userNode = JSONFormats.prepareDocToJson(user, JSONFormats.Formats.USER); return Json.mapper().readTree(userNode); } catch (InvalidJsonException | IOException e) { throw new CommandExecutionException(command, "invalid json", e); } catch (UserAlreadyExistsException | EmailAlreadyUsedException e) { return NullNode.getInstance(); } } @Override protected JsonNode list(JsonNode command) throws CommandException { JsonNode paramsNode = command.get(ScriptCommand.PARAMS); QueryParams qp = QueryParams.getParamsFromJson(paramsNode); try { List<ODocument> users = UserService.getUsers(qp, true); String response = prepareResponseToJson(users); return Json.mapper().readTree(response); } catch (SqlInjectionException e) { throw new CommandExecutionException(command, "error executing command: " + ExceptionUtils.getMessage(e)); } catch (IOException e) { throw new CommandExecutionException(command, "error parsing response: " + ExceptionUtils.getMessage(e)); } } @Override protected JsonNode get(JsonNode command) throws CommandException { String user = getUsername(command); try { if (UserService.isInternalUsername(user)) return NullNode.getInstance(); ODocument doc = UserService.getUserProfilebyUsername(user); if (doc == null) { return NullNode.getInstance(); } String resp = JSONFormats.prepareResponseToJson(doc, JSONFormats.Formats.USER); return Json.mapper().readTree(resp); } catch (SqlInjectionException e) { throw new CommandExecutionException(command, "error executing command: " + ExceptionUtils.getMessage(e)); } catch (IOException e) { throw new CommandExecutionException(command, "error parsing response: " + ExceptionUtils.getMessage(e)); } } @Override public String name() { return "users"; } private String prepareResponseToJson(List<ODocument> listOfDoc) { try { for (ODocument doc : listOfDoc) { doc.detach(); if (doc.field("user") instanceof ODocument) { OMVRBTreeRIDSet roles = ((ODocument) doc.field("user")).field("roles"); if (roles.size() > 1) { Iterator<OIdentifiable> it = roles.iterator(); while (it.hasNext()) { if (((ODocument) it.next().getRecord()).field("name").toString() .startsWith(FriendShipService.FRIEND_ROLE_NAME)) { it.remove(); } } } } } return JSONFormats.prepareResponseToJson(listOfDoc, JSONFormats.Formats.USER); } catch (IOException e) { throw new RuntimeException(e); } } }