/* * 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()); } } }