/*
* Copyright 2003-2016 JetBrains s.r.o.
*
* 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 jetbrains.mps.generator.impl;
import jetbrains.mps.extapi.model.GeneratableSModel;
import jetbrains.mps.extapi.persistence.FileDataSource;
import jetbrains.mps.extapi.persistence.FolderDataSource;
import jetbrains.mps.smodel.SModelOperations;
import jetbrains.mps.vfs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.SModelReference;
import org.jetbrains.mps.openapi.persistence.DataSource;
import org.jetbrains.mps.openapi.persistence.MultiStreamDataSource;
/**
* {@link jetbrains.mps.generator.impl.ModelStreamManager} implementation to capture present conventions regarding
* location of output artifacts and generated caches.
*
* FIXME likely, shall get a different name (to better distinguish from DeployedStreamManager), e.g. WorkspaceStreamManager
*
* FIXME move FileGenerationUtil logic in here; move this class out from generator and expose to any model client; replace used of FGU with this class, drop the FGU class.
*
* FIXME align with {@link jetbrains.mps.project.facets.GenerationTargetFacet} output location management
*
* @author Artem Tikhomirov
*/
public class DefaultStreamManager implements ModelStreamManager {
private final SModelReference myModelReference;
private final FolderDataSource myOutputDir;
private final FolderDataSource myCachesDir;
/*package*/ DefaultStreamManager(@NotNull SModelReference modelReference, @NotNull IFile outputDir, @NotNull IFile cachesDir) {
myModelReference = modelReference;
// expect directories, if exist
assert !outputDir.exists() || outputDir.isDirectory();
assert !cachesDir.exists() || cachesDir.isDirectory();
myOutputDir = new FolderDataSource(outputDir);
myCachesDir = new FolderDataSource(cachesDir);
}
@Override
public SModelReference getModel() {
return myModelReference;
}
@NotNull
@Override
public MultiStreamDataSource getOutputLocation() {
return myOutputDir;
}
@Override
public MultiStreamDataSource getCachesLocation() {
return myCachesDir;
}
/**
* @deprecated use {@link ModelStreamProviderImpl} instead
*/
@Deprecated
public static class Provider extends ModelStreamProviderImpl {
/**
* FIXME public until TextGenUtil and TextGen_Facet are refactored to use ModelStreamManager
*/
public static IFile getOutputDir(SModel model) {
IFile forced = getOverriddenOutputDir(model);
if (forced != null) {
return forced;
}
IFile loc = SModelOperations.getOutputLocation(model);
if (loc == null) {
throw new IllegalArgumentException(String.format("No output location for %s", model.getName()));
}
return loc;
}
/**
* FIXME public until TextGenUtil and TextGen_Facet are refactored to use ModelStreamManager
*/
public static IFile getCachesDir(SModel model) {
// seems to be intentional that we don't look into overridden output dir when constriction location for caches
// as we might direct output to a public location but still keep caches in our own space
IFile loc = SModelOperations.getOutputCacheLocation(model);
if (loc == null) {
throw new IllegalArgumentException(String.format("No output location for %s", model.getName()));
}
return loc;
}
private static IFile getOverriddenOutputDir(SModel md) {
if (md instanceof GeneratableSModel) {
boolean useModelFolder = ((GeneratableSModel) md).isGenerateIntoModelFolder();
DataSource source = md.getSource();
if (useModelFolder && source instanceof FileDataSource) {
IFile file = ((FileDataSource) source).getFile();
return file.getParent();
}
}
return null;
}
}
}