/******************************************************************************* * 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.workspace.server.dao.Workspace; import org.eclipse.che.api.workspace.server.dao.WorkspaceDao; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.regex.Pattern; @Singleton public class LocalWorkspaceDaoImpl implements WorkspaceDao { private static final Pattern WS_NAME = Pattern.compile("[\\w][\\w\\.\\-]{1,18}[\\w]"); private final List<Workspace> workspaces; private final ReadWriteLock lock; @Inject public LocalWorkspaceDaoImpl(@Named("codenvy.local.infrastructure.workspaces") Set<Workspace> workspaces) { this.workspaces = new LinkedList<>(); lock = new ReentrantReadWriteLock(); try { for (Workspace workspace : workspaces) { create(workspace); } } catch (Exception e) { // fail if can't validate this instance properly throw new RuntimeException(e); } } @Override public void create(Workspace workspace) throws ConflictException { validateWorkspaceName(workspace.getName()); lock.writeLock().lock(); try { for (Workspace w : workspaces) { if (w.getId().equals(workspace.getId())) { throw new ConflictException(String.format("Workspace with id %s already exists.", workspace.getId())); } if (w.getName().equals(workspace.getName())) { throw new ConflictException(String.format("Workspace with name %s already exists.", workspace.getName())); } } workspaces.add(new Workspace().withId(workspace.getId()).withName(workspace.getName()).withAccountId(workspace.getAccountId()) .withAttributes(new LinkedHashMap<>(workspace.getAttributes())) .withTemporary(workspace.isTemporary())); } finally { lock.writeLock().unlock(); } } @Override public void update(Workspace workspace) throws NotFoundException, ConflictException { validateWorkspaceName(workspace.getName()); lock.writeLock().lock(); try { Workspace myWorkspace = null; for (int i = 0, size = workspaces.size(); i < size && myWorkspace == null; i++) { if (workspaces.get(i).getId().equals(workspace.getId())) { myWorkspace = workspaces.get(i); } } if (myWorkspace == null) { throw new NotFoundException(String.format("Workspace not found %s", workspace.getId())); } myWorkspace.setName(workspace.getName()); myWorkspace.getAttributes().clear(); myWorkspace.getAttributes().putAll(workspace.getAttributes()); } finally { lock.writeLock().unlock(); } } @Override public void remove(String id) throws NotFoundException { lock.writeLock().lock(); try { Workspace myWorkspace = null; for (int i = 0, size = workspaces.size(); i < size && myWorkspace == null; i++) { if (workspaces.get(i).getId().equals(id)) { myWorkspace = workspaces.get(i); } } if (myWorkspace == null) { throw new NotFoundException(String.format("Workspace not found %s", id)); } workspaces.remove(myWorkspace); } finally { lock.writeLock().unlock(); } } @Override public Workspace getById(String id) throws NotFoundException { lock.readLock().lock(); try { for (Workspace workspace : workspaces) { if (workspace.getId().equals(id)) { return new Workspace().withId(workspace.getId()).withName(workspace.getName()).withAccountId(workspace.getAccountId()) .withAttributes(new LinkedHashMap<>(workspace.getAttributes())) .withTemporary(workspace.isTemporary()); } } } finally { lock.readLock().unlock(); } throw new NotFoundException(String.format("Workspace not found %s", id)); } @Override public Workspace getByName(String name) throws NotFoundException { lock.readLock().lock(); try { for (Workspace workspace : workspaces) { if (workspace.getName().equals(name)) { return new Workspace().withId(workspace.getId()).withName(workspace.getName()).withAccountId(workspace.getAccountId()) .withAttributes(new LinkedHashMap<>(workspace.getAttributes())) .withTemporary(workspace.isTemporary()); } } } finally { lock.readLock().unlock(); } throw new NotFoundException(String.format("Workspace not found %s", name)); } @Override public List<Workspace> getByAccount(String accountId) { final List<Workspace> result = new LinkedList<>(); lock.readLock().lock(); try { for (Workspace workspace : workspaces) { if (workspace.getAccountId().equals(accountId)) { result.add(new Workspace().withId(workspace.getId()).withName(workspace.getName()) .withAccountId(workspace.getAccountId()) .withAttributes(new LinkedHashMap<>(workspace.getAttributes())) .withTemporary(workspace.isTemporary())); } } } finally { lock.readLock().unlock(); } return result; } private void validateWorkspaceName(String workspaceName) throws ConflictException { if (workspaceName == null) { throw new ConflictException("Workspace name required"); } if (!WS_NAME.matcher(workspaceName).matches()) { throw new ConflictException("Incorrect workspace name"); } } }