Java tutorial
/* * Copyright 2015-2016 * * This file is part of Spoofax for IntelliJ. * * 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 org.metaborg.intellij.idea.projects; import com.google.common.base.Preconditions; import com.google.inject.Inject; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.metaborg.core.project.IProject; import org.metaborg.core.project.IProjectService; import org.metaborg.intellij.logging.InjectLogger; import org.metaborg.intellij.resources.FileNameUtils; import org.metaborg.util.log.ILogger; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; // TODO: Move to Spoofax core? /** * Project service for language artifacts. */ public final class ArtifactProjectService implements IProjectService { private final IArtifactProjectFactory artifactProjectFactory; private final Map<FileName, ArtifactProject> projects = new HashMap<>(); @InjectLogger private ILogger logger; @Inject public ArtifactProjectService(final IArtifactProjectFactory artifactProjectFactory) { this.artifactProjectFactory = artifactProjectFactory; } /** * {@inheritDoc} */ @Nullable @Override public IProject get(final FileObject resource) { Preconditions.checkNotNull(resource); @Nullable final FileObject artifactRoot = getArtifactRoot(resource); if (artifactRoot == null) return null; final FileName artifactName = artifactRoot.getName(); @Nullable ArtifactProject project = this.projects.get(artifactName); if (project == null) { project = this.artifactProjectFactory.create(artifactRoot, null); this.projects.put(artifactName, project); } return project; } /** * Determines the language artifact root of the specified file. * * @param file The file. * @return The language artifact root; or <code>null</code> when there is none. */ @Nullable private FileObject getArtifactRoot(final FileObject file) { @Nullable FileObject current = getRoot(file); while (current != null && !isArtifactRoot(current.getName())) { current = getParentRoot(current); } return current; } /** * Gets the root file of the specified layer. * * @param layer The layer; or <code>null</code>. * @return The root file; or <code>null</code>. */ @Nullable private FileObject getRoot(@Nullable final FileObject layer) { if (layer == null) return null; try { return layer.getFileSystem().getRoot(); } catch (final FileSystemException e) { this.logger.error("Ignored exception.", e); return null; } } /** * Determines whether the specified file name points to a language artifact root. * <p> * For example, <code>zip:file:///dir/archive.spoofax-language!/</code> is a language artifact root. * * @param fileName The file name to check. * @return <code>true</code> when the file is a language artifact root; * otherwise, <code>false</code>. */ private boolean isArtifactRoot(final FileName fileName) { @Nullable final FileName outerFileName = FileNameUtils.getOuterFileName(fileName); if (outerFileName == null) return false; return "spoofax-language".equals(outerFileName.getExtension()); } /** * Gets the parent root of the specified file. * * @param file The file. * @return The parent root; or <code>null</code>. */ @Nullable private FileObject getParentRoot(final FileObject file) { try { return getRoot(file.getFileSystem().getParentLayer()); } catch (final FileSystemException e) { this.logger.error("Ignored exception.", e); return null; } } }