package org.metaborg.core.project; import java.util.Map.Entry; import java.util.concurrent.ConcurrentMap; import javax.annotation.Nullable; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileObject; import org.metaborg.core.MetaborgException; import org.metaborg.core.config.ConfigRequest; import org.metaborg.core.config.IProjectConfig; import org.metaborg.core.config.IProjectConfigService; import org.metaborg.core.messages.StreamMessagePrinter; import org.metaborg.core.source.ISourceTextService; import org.metaborg.util.log.ILogger; import org.metaborg.util.log.LoggerUtils; import com.google.common.collect.Maps; import com.google.inject.Inject; public class SimpleProjectService implements ISimpleProjectService { private static final ILogger logger = LoggerUtils.logger(SimpleProjectService.class); private final ISourceTextService sourceTextService; private final IProjectConfigService projectConfigService; private final ConcurrentMap<FileName, IProject> projects = Maps.newConcurrentMap(); @Inject public SimpleProjectService(ISourceTextService sourceTextService, IProjectConfigService projectConfigService) { this.sourceTextService = sourceTextService; this.projectConfigService = projectConfigService; } @Override public @Nullable IProject get(FileObject resource) { final FileName name = resource.getName(); for(Entry<FileName, IProject> entry : projects.entrySet()) { final FileName projectName = entry.getKey(); if(name.equals(projectName) || name.isAncestor(projectName)) { return entry.getValue(); } } return null; } @Override public IProject create(FileObject location) throws MetaborgException { final FileName name = location.getName(); for(FileName projectName : projects.keySet()) { if(name.equals(projectName) || name.isAncestor(projectName)) { final String message = String.format("Location %s is equal to or nested in project %s", name, projectName); throw new MetaborgException(message); } } final ConfigRequest<? extends IProjectConfig> configRequest = projectConfigService.get(location); if(!configRequest.valid()) { logger.error("Errors occurred when retrieving project configuration from project directory {}", location); configRequest.reportErrors(new StreamMessagePrinter(sourceTextService, false, false, logger)); } final IProjectConfig config; if(configRequest.config() != null) { config = configRequest.config(); } else { logger.debug("Using default configuration for project at {}", location); config = projectConfigService.defaultConfig(location); } final IProject project = new Project(location, config); if(projects.putIfAbsent(name, project) != null) { final String message = String.format("Project with location %s already exists", name); throw new MetaborgException(message); } return project; } @Override public void remove(IProject project) throws MetaborgException { final FileName name = project.location().getName(); if(projects.remove(name) == null) { final String message = String.format("Project with location %s does not exists", name); throw new MetaborgException(message); } } }