/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.api.local; import org.eclipse.che.api.core.ConflictException; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.user.server.dao.UserDao; import org.eclipse.che.api.workspace.server.dao.Member; import org.eclipse.che.api.workspace.server.dao.MemberDao; import org.eclipse.che.api.workspace.server.dao.WorkspaceDao; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @Singleton public class LocalMemberDaoImpl implements MemberDao { private final List<Member> members; private final ReadWriteLock lock; private final WorkspaceDao workspaceDao; private final UserDao userDao; @Inject public LocalMemberDaoImpl(@Named("codenvy.local.infrastructure.workspace.members") Set<Member> members, WorkspaceDao workspaceDao, UserDao userDao) { this.workspaceDao = workspaceDao; this.userDao = userDao; this.members = new LinkedList<>(); lock = new ReentrantReadWriteLock(); try { for (Member member : members) { create(member); } } catch (Exception e) { // fail if can't validate this instance properly throw new RuntimeException(e); } } @Override public void create(Member member) throws NotFoundException, ServerException, ConflictException { lock.writeLock().lock(); try { // Check workspace existence workspaceDao.getById(member.getWorkspaceId()); // Check user existence userDao.getById(member.getUserId()); for (Member m : members) { if (m.getWorkspaceId().equals(member.getWorkspaceId()) && m.getUserId().equals(member.getUserId())) { throw new ConflictException( String.format("Membership of user %s in workspace %s already exists. Use update method instead.", member.getUserId(), member.getWorkspaceId())); } } members.add(new Member().withUserId(member.getUserId()).withWorkspaceId(member.getWorkspaceId()) .withRoles(new ArrayList<>(member.getRoles()))); } finally { lock.writeLock().unlock(); } } @Override public void update(Member member) throws NotFoundException, ServerException { lock.writeLock().lock(); try { // Check workspace existence workspaceDao.getById(member.getWorkspaceId()); // Check user existence userDao.getById(member.getUserId()); Member myMember = null; for (int i = 0, size = members.size(); i < size && myMember == null; i++) { Member m = members.get(i); if (m.getWorkspaceId().equals(member.getWorkspaceId()) && m.getUserId().equals(member.getUserId())) { myMember = m; } } if (myMember == null) { throw new NotFoundException(String.format("Unable to update membership: user %s has no memberships in workspace %s.", member.getUserId(), member.getWorkspaceId())); } myMember.getRoles().clear(); myMember.getRoles().addAll(member.getRoles()); } finally { lock.writeLock().unlock(); } } @Override public List<Member> getWorkspaceMembers(String wsId) { final List<Member> result = new LinkedList<>(); lock.readLock().lock(); try { for (Member member : members) { if (member.getWorkspaceId().equals(wsId)) { result.add(new Member().withUserId(member.getUserId()).withWorkspaceId(member.getWorkspaceId()) .withRoles(new ArrayList<>(member.getRoles()))); } } } finally { lock.readLock().unlock(); } return result; } @Override public List<Member> getUserRelationships(String userId) { final List<Member> result = new LinkedList<>(); lock.readLock().lock(); try { for (Member member : members) { if (member.getUserId().equals(userId)) { result.add(new Member().withUserId(member.getUserId()).withWorkspaceId(member.getWorkspaceId()) .withRoles(new ArrayList<>(member.getRoles()))); } } } finally { lock.readLock().unlock(); } return result; } @Override public Member getWorkspaceMember(String wsId, String userId) throws NotFoundException, ServerException { lock.readLock().lock(); try { for (Member member : members) { if (member.getWorkspaceId().equals(member.getWorkspaceId()) && member.getUserId().equals(userId)) { return new Member().withUserId(member.getUserId()).withWorkspaceId(member.getWorkspaceId()) .withRoles(new ArrayList<>(member.getRoles())); } } } finally { lock.readLock().unlock(); } throw new NotFoundException(String.format("User with id %s has no membership in workspace %s", userId, wsId)); } @Override public void remove(Member member) throws NotFoundException { lock.writeLock().lock(); try { Member myMember = null; for (int i = 0, size = members.size(); i < size && myMember == null; i++) { Member m = members.get(i); if (m.getWorkspaceId().equals(member.getWorkspaceId()) && m.getUserId().equals(member.getUserId())) { myMember = m; } } if (myMember == null) { throw new NotFoundException(String.format("Unable to update membership: user %s has no memberships in workspace %s.", member.getUserId(), member.getWorkspaceId())); } members.remove(myMember); } finally { lock.writeLock().unlock(); } } }