/*
* Copyright 2003-2014 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.jps.persistence;
import jetbrains.mps.extapi.persistence.FileDataSource;
import jetbrains.mps.idea.core.module.CachedModelData;
import jetbrains.mps.idea.core.module.CachedModuleData;
import jetbrains.mps.idea.core.module.CachedRepositoryData;
import jetbrains.mps.persistence.BinaryModelFactory;
import jetbrains.mps.persistence.DefaultModelRoot;
import jetbrains.mps.persistence.DefaultModelPersistence;
import jetbrains.mps.smodel.Generator;
import jetbrains.mps.smodel.SModelHeader;
import jetbrains.mps.util.FileUtil;
import jetbrains.mps.util.JavaNameUtil;
import jetbrains.mps.vfs.IFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.persistence.ModelFactory;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import java.io.IOException;
import java.util.*;
/**
* evgeny, 12/11/12
*/
public class CachedDefaultModelRoot extends DefaultModelRoot {
private CachedRepositoryData myCachedRepository;
public CachedDefaultModelRoot(CachedRepositoryData repo) {
myCachedRepository = repo;
}
@NotNull
@Override
public Iterable<SModel> loadModels() {
SModule module = getModule();
if (module instanceof Generator) {
module = ((Generator) module).getSourceLanguage();
}
if (module == null) {
return super.loadModels();
}
CachedModuleData moduleData = myCachedRepository.getModuleData(module.getModuleReference());
if (moduleData == null) {
return super.loadModels();
}
List<CachedModelData> models = moduleData.getModels(this);
if (models == null) {
return super.loadModels();
}
List<SModel> result = new ArrayList<SModel>();
Map<String, String> options = new HashMap<String, String>();
options.put(ModelFactory.OPTION_MODULEREF, module.getModuleReference().toString());
for (CachedModelData mdata : models) {
IFile file = getFileSystem().getFile(mdata.getFile());
FileDataSource source = new FileDataSource(file, this);
Object header = mdata.getHeader();
if (mdata.getCacheKind() == CachedModelData.Kind.Binary) {
result.add(BinaryModelFactory.createFromHeader(((SModelHeader) header), source));
} else if (mdata.getCacheKind() == CachedModelData.Kind.Regular) {
result.add(DefaultModelPersistence.createFromHeader((SModelHeader) header, source));
} else {
String fileName = file.getName();
String extension = FileUtil.getExtension(fileName);
if (extension == null) continue;
ModelFactory modelFactory = PersistenceFacade.getInstance().getModelFactory(extension);
if (modelFactory == null) continue;
fillOptions(file, options);
try {
SModel model = modelFactory.load(source, Collections.unmodifiableMap(options));
result.add(model);
} catch (IOException e) {
// TODO handle errors
}
}
}
return result;
}
private void fillOptions(IFile file, Map<String, String> options) {
String relPath = null;
String filePath = file.getPath().replace("\\", "/");
for (String path : getFiles(SOURCE_ROOTS)) {
String normalized = FileUtil.getAbsolutePath(path).replace("\\", "/");
if (!normalized.endsWith("/")) {
normalized = normalized + "/";
}
if (filePath.startsWith(normalized)) {
relPath = filePath.substring(normalized.length());
break;
}
}
options.put(ModelFactory.OPTION_RELPATH, relativize(filePath, getContentDirectory()));
options.remove(ModelFactory.OPTION_PACKAGE);
options.remove(ModelFactory.OPTION_MODELNAME);
if (relPath != null) {
StringBuilder p = new StringBuilder();
int slash = relPath.indexOf('/');
int start = 0;
while (slash >= 0) {
String part = relPath.substring(0, slash);
if (JavaNameUtil.isJavaIdentifier(part)) {
return;
}
start = slash + 1;
slash = relPath.indexOf('/', start);
if (p.length() != 0) {
p.append(".");
}
p.append(part);
}
options.put(ModelFactory.OPTION_PACKAGE, p.toString());
String fileNameWE = FileUtil.getNameWithoutExtension(relPath.substring(start));
if (p.length() != 0) {
p.append(".");
}
p.append(fileNameWE);
options.put(ModelFactory.OPTION_MODELNAME, p.toString());
}
}
}