/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * 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 hr.fer.zemris.vhdllab.platform.manager.workspace; import hr.fer.zemris.vhdllab.entity.File; import hr.fer.zemris.vhdllab.entity.FileType; import hr.fer.zemris.vhdllab.entity.Project; import hr.fer.zemris.vhdllab.platform.i18n.LocalizationSource; import hr.fer.zemris.vhdllab.platform.listener.AbstractEventPublisher; import hr.fer.zemris.vhdllab.platform.manager.editor.EditorManager; import hr.fer.zemris.vhdllab.platform.manager.editor.EditorManagerFactory; import hr.fer.zemris.vhdllab.service.WorkspaceService; import hr.fer.zemris.vhdllab.service.hierarchy.Hierarchy; import hr.fer.zemris.vhdllab.service.workspace.FileReport; import hr.fer.zemris.vhdllab.service.workspace.Workspace; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.map.CaseInsensitiveMap; import org.apache.commons.lang.Validate; import org.springframework.beans.factory.annotation.Autowired; public class DefaultWorkspaceManager extends AbstractEventPublisher<WorkspaceListener> implements WorkspaceManager, IdentifierToInfoObjectMapper { private static final String FILE_CREATED_MESSAGE = "notification.file.created"; private static final String FILE_SAVED_MESSAGE = "notification.file.saved"; private static final String SIMULATION_SAVED_MESSAGE = "notification.simulation.saved"; private static final String SIMULATION_SAVE_FAILED_MESSAGE = "notification.simulation.save.failed"; private static final String FILE_DELETED_MESSAGE = "notification.file.deleted"; private static final String PROJECT_CREATED_MESSAGE = "notification.project.created"; private static final String PROJECT_DELETED_MESSAGE = "notification.project.deleted"; @Autowired private WorkspaceService workspaceService; @Autowired private EditorManagerFactory editorManagerFactory; @Resource(name = "standaloneLocalizationSource") private LocalizationSource localizationSource; private Workspace workspace; public DefaultWorkspaceManager() { super(WorkspaceListener.class); } private Map<Integer, Project> projectIds; private Map<String, Project> projectIdentifiers; private Map<String, File> fileIdentifiers; private Map<Integer, File> fileIds; @Override public Project getProject(String name) { Validate.notNull(name, "Project name can't be null"); return getProjectIdentifiers().get(name); } @Override public Project getProject(Integer projectId) { Validate.notNull(projectId, "Project id can't be null"); return getProjectIds().get(projectId); } @Override public File getFile(String projectName, final String fileName) { Validate.notNull(projectName, "Project name can't be null"); Validate.notNull(fileName, "File name can't be null"); String key = makeKey(projectName, fileName); if (getFileIdentifiers().containsKey(key)) { return getFileIdentifiers().get(key); } Set<File> predefinedFiles = getWorkspace().getPredefinedFiles(); File found = (File) CollectionUtils.find(predefinedFiles, new Predicate() { @Override public boolean evaluate(Object object) { File predefined = (File) object; return predefined.getName().equalsIgnoreCase(fileName); } }); return new File(found, getProject(projectName)); } @Override public File getFile(File file) { Validate.notNull(file, "File can't be null"); if (!file.isNew()) { return getFileIds().get(file.getId()); } File clone = new File(file); Set<File> predefinedFiles = workspace.getPredefinedFiles(); for (File predefined : predefinedFiles) { if (predefined.equals(clone)) { return new File(predefined); } } throw new IllegalStateException("No such file: " + file.toString()); } private String makeKey(String projectName, String fileName) { return projectName + "-" + fileName; } private Map<Integer, Project> getProjectIds() { if (projectIds == null) { initializeIdentifiers(); } return projectIds; } private Map<String, Project> getProjectIdentifiers() { if (projectIdentifiers == null) { initializeIdentifiers(); } return projectIdentifiers; } private Map<String, File> getFileIdentifiers() { if (fileIdentifiers == null) { initializeIdentifiers(); } return fileIdentifiers; } private Map<Integer, File> getFileIds() { if (fileIds == null) { initializeIdentifiers(); } return fileIds; } @SuppressWarnings("unchecked") private void initializeIdentifiers() { int projectCount = getWorkspace().getProjectCount(); projectIds = new HashMap<Integer, Project>(projectCount); projectIdentifiers = new CaseInsensitiveMap(); fileIdentifiers = new CaseInsensitiveMap(); fileIds = new HashMap<Integer, File>(); for (Project project : getWorkspace().getProjects()) { addProject(project); for (File file : getWorkspace().getFiles(project)) { addFile(file); } } } private void addProject(Project project) { getProjectIds().put(project.getId(), project); getProjectIdentifiers().put(project.getName(), project); } private void addFile(File file) { Project project = file.getProject(); getFileIdentifiers().put(makeKey(project.getName(), file.getName()), file); getFileIds().put(file.getId(), file); } private void removeProject(Project project) { getProjectIds().remove(project.getId()); getProjectIdentifiers().remove(project.getName()); } private void removeFile(File file) { Project project = file.getProject(); getFileIdentifiers().remove(makeKey(project.getName(), file.getName())); getFileIds().remove(file.getId()); } // ************************************************************************* // Implementation of Workspace Manager // ************************************************************************* @Override public void create(File file) throws FileAlreadyExistsException { checkIfNull(file); if (exist(file)) { throw new FileAlreadyExistsException(file.toString()); } FileReport report = workspaceService.createFile(file.getProject() .getId(), file.getName(), file.getType(), file.getData()); getWorkspace().addFile(report.getFile(), report.getHierarchy()); addFile(report.getFile()); fireFileCreated(report); openEditor(report.getFile()); log(report, FILE_CREATED_MESSAGE); } @Override public void save(File file) { checkIfNull(file); FileReport report = workspaceService.saveFile(file.getId(), file .getData()); getWorkspace().addFile(report.getFile(), report.getHierarchy()); addFile(report.getFile()); fireFileSaved(report); log(report, FILE_SAVED_MESSAGE); } @Override public void saveSimulation(File file, String name) { checkIfNull(file); FileReport report = workspaceService.saveSimulation(file.getId(), name); if (report == null) { logger.info(localizationSource.getMessage(SIMULATION_SAVE_FAILED_MESSAGE)); } else { getWorkspace().addFile(report.getFile(), report.getHierarchy()); addFile(report.getFile()); fireFileCreated(report); log(report, SIMULATION_SAVED_MESSAGE); openEditor(report.getFile()); } } @Override public void delete(File file) { checkIfNull(file); if (!file.getType().equals(FileType.PREDEFINED)) { closeEditor(file); FileReport report = workspaceService.deleteFile(file.getId()); getWorkspace().removeFile(report.getFile(), report.getHierarchy()); removeFile(file); fireFileDeleted(report); log(report, FILE_DELETED_MESSAGE); } } private void fireFileCreated(FileReport report) { for (WorkspaceListener l : getListeners()) { l.fileCreated(report); } } private void fireFileSaved(FileReport report) { for (WorkspaceListener l : getListeners()) { l.fileSaved(report); } } private void fireFileDeleted(FileReport report) { for (WorkspaceListener l : getListeners()) { l.fileDeleted(report); } } private void openEditor(File file) { editorManagerFactory.get(file).open(); } private void closeEditor(Project project) { EditorManager em = editorManagerFactory .getAllAssociatedWithProject(project); em.close(false); } private void closeEditor(File file) { EditorManager em = editorManagerFactory.get(file); if (em.isOpened()) { em.close(false); } } private void log(FileReport report, String code) { File file = report.getFile(); String fileName = file.getName(); String projectName = file.getProject().getName(); logger.info(localizationSource.getMessage(code, new Object[] { fileName, projectName })); } private void checkIfNull(File file) { Validate.notNull(file, "File can't be null"); } @Override public void create(Project project) throws ProjectAlreadyExistsException { checkIfNull(project); if (exist(project)) { throw new ProjectAlreadyExistsException(project.toString()); } Project created = workspaceService.persist(project.getName()); getWorkspace().addProject(created); addProject(created); fireProjectCreated(created); log(project, PROJECT_CREATED_MESSAGE); } @Override public void delete(Project project) { checkIfNull(project); closeEditor(project); workspaceService.deleteProject(project.getId()); getWorkspace().removeProject(project); removeProject(project); fireProjectDeleted(project); log(project, PROJECT_DELETED_MESSAGE); } private void fireProjectCreated(Project project) { for (WorkspaceListener l : getListeners()) { l.projectCreated(project); } } private void fireProjectDeleted(Project project) { for (WorkspaceListener l : getListeners()) { l.projectDeleted(project); } } private void log(Project project, String code) { logger.info(localizationSource.getMessage(code, new Object[] { project .getName() })); } private void checkIfNull(Project project) { Validate.notNull(project, "Project can't be null"); } @Override public List<Project> getProjects() { return getWorkspace().getProjects(); } @Override public List<Project> getProjects(Predicate filter, Transformer transformer) { List<Project> projects = new ArrayList<Project>(getProjects()); CollectionUtils.filter(projects, filter); CollectionUtils.transform(projects, transformer); return projects; } @Override public Set<File> getFilesForProject(Project project) { return getWorkspace().getFiles(project); } @Override public Set<File> getFilesForProject(Project project, Predicate filter, Transformer transformer) { Set<File> files = new HashSet<File>(getFilesForProject(project)); CollectionUtils.filter(files, filter); CollectionUtils.transform(files, transformer); return files; } @Override public boolean isEmpty(Project project, Predicate filter) { return getFilesForProject(project, filter, null).isEmpty(); } @Override public Hierarchy getHierarchy(Project project) { return getWorkspace().getHierarchy(project); } @Override public boolean exist(Project project) { return getProjects().contains(project); } @Override public boolean exist(File file) { return getFilesForProject(file.getProject()).contains(file); } @Override public Workspace getWorkspace() { if (workspace == null) { workspace = workspaceService.getWorkspace(); } return workspace; } }