protected final void collectModels( IFile dir, String package_, String relativePath, Map<String, String> options, Collection<SModel> models) { if (FileSystem.getInstance().isFileIgnored(dir.getName())) return; if (!dir.isDirectory()) return; List<IFile> files = dir.getChildren(); options.put(ModelFactory.OPTION_PACKAGE, package_); for (IFile file : files) { String fileName = file.getName(); String extension = FileUtil.getExtension(fileName); if (extension == null) continue; ModelFactory modelFactory = PersistenceFacade.getInstance().getModelFactory(extension); if (modelFactory == null || file.isDirectory()) continue; FileDataSource source = new FileDataSource(file, this); options.put(ModelFactory.OPTION_RELPATH, combinePath(relativePath, fileName)); String fileNameWE = FileUtil.getNameWithoutExtension(fileName); options.put( ModelFactory.OPTION_MODELNAME, package_ != null ? (package_.isEmpty() ? fileNameWE : package_ + "." + fileNameWE) : null); try { SModel model = modelFactory.load(source, Collections.unmodifiableMap(options)); ((SModelBase) model).setModelRoot(this); models.add(model); } catch (UnsupportedDataSourceException ex) { /* model factory registration problem: ignore */ } } options.put(ModelFactory.OPTION_RELPATH, relativePath); for (FolderModelFactory factory : PersistenceRegistry.getInstance().getFolderModelFactories()) { for (DataSource dataSource : factory.createDataSources(this, dir)) { SModel model = factory.load(dataSource, Collections.unmodifiableMap(options)); ((SModelBase) model).setModelRoot(this); models.add(model); } } for (IFile childDir : files) { if (childDir.isDirectory()) { String name = childDir.getName(); String innerPackage = package_ != null && JavaNameUtil.isJavaIdentifier(name) ? (package_.isEmpty() ? name : package_ + "." + name) : null; String innerPath = combinePath(relativePath, name); collectModels(childDir, innerPackage, innerPath, options, models); } } }
protected static String makeRelative(String contentHome, String fullPath) { if ((fullPath == null || fullPath.length() == 0 || fullPath.equals(contentHome))) { return ""; } String normalized = FileUtil.getAbsolutePath(fullPath).replace("\\", "/"); try { return FileUtil.getRelativePath(normalized, contentHome, "/"); } catch (Exception ex) { return null; } }
public boolean isEnabled(AnActionEvent e) { PsiElement psiElement = e.getData(LangDataKeys.PSI_ELEMENT); if (psiElement == null || !(psiElement instanceof PsiDirectory)) { // Can be used only on package return false; } VirtualFile targetDir = ((PsiDirectory) psiElement).getVirtualFile(); boolean isUnderSourceRoot = false; if (psiElement instanceof MPSPsiModel) { isUnderSourceRoot = true; } else { Module m = e.getData(LangDataKeys.MODULE); VirtualFile[] sourceRoots = ModuleRootManager.getInstance(m).getSourceRoots(true); for (VirtualFile root : sourceRoots) { if (targetDir.getPath().equals(root.getPath())) { // Can't be source or test folder return false; } isUnderSourceRoot = isUnderSourceRoot || FileUtil.isSubPath(root.getPath(), targetDir.getPath()); } } return isUnderSourceRoot && myOperationContext != null && (myModelDescriptor != null || myNewModel) && myProject != null; }
@Override public void rename(String newModelName, boolean changeFile) { assertCanChange(); SModelReference oldName = getReference(); fireBeforeModelRenamed(new SModelRenamedEvent(this, oldName.getModelName(), newModelName)); // TODO update SModelId (if it contains modelName) // if(getReference().getModelId().getModelName() != null) { } SModelReference newModelReference = PersistenceFacade.getInstance() .createModelReference( getReference().getModuleReference(), getReference().getModelId(), newModelName); fireBeforeModelRenamed(newModelReference); changeModelReference(newModelReference); if (!changeFile) { save(); } else { if (changeFile && !(getSource() instanceof FileDataSource)) { throw new UnsupportedOperationException("cannot change model file on non-file data source"); } IFile oldFile = ((FileDataSource) getSource()).getFile(); ModelRoot root = ModelRootUtil.getModelRoot(this); if (root instanceof DefaultModelRoot) { DefaultModelRoot defaultModelRoot = (DefaultModelRoot) root; String sourceRoot = null; for (String sr : defaultModelRoot.getFiles(FileBasedModelRoot.SOURCE_ROOTS)) { if (oldFile.getPath().startsWith(sr)) { // using the same sourceRoot sourceRoot = sr; break; } } try { IFile newFile = defaultModelRoot .createSource( newModelName, FileUtil.getExtension(oldFile.getName()), sourceRoot, new HashMap<String, String>()) .getFile(); newFile.getParent().mkdirs(); newFile.createNewFile(); changeModelFile(newFile); save(); oldFile.delete(); } catch (IOException e) { LOG.error("cannot rename " + getModelName() + ": " + e.getMessage()); save(); } } } fireModelRenamed(new SModelRenamedEvent(this, oldName.getModelName(), newModelName)); fireModelRenamed(oldName); }
public static SModel doModelParsing(FileContent inputData) { SModel model = inputData.getUserData(PARSED_MODEL); if (model == null) { String ext = FileUtil.getExtension(inputData.getFileName()); if (MPSFileTypeFactory.MPS_ROOT_FILE_TYPE.equals(inputData.getFile().getFileType())) { ext = MPSFileTypeFactory.MPS_HEADER_FILE_TYPE.getDefaultExtension(); } ModelFactory factory = PersistenceFacade.getInstance().getModelFactory(ext); if (factory == null) { return null; } if (factory instanceof FolderModelFactory) { model = PersistenceUtil.loadModel( VirtualFileUtils.toIFile( MPSFileTypeFactory.MPS_ROOT_FILE_TYPE.equals(inputData.getFile().getFileType()) ? inputData.getFile().getParent().findChild(MPSExtentions.DOT_MODEL_HEADER) : inputData.getFile())); } else { model = factory.isBinary() ? PersistenceUtil.loadModel(inputData.getContent(), ext) : PersistenceUtil.loadModel(inputData.getContentAsText().toString(), ext); } if (model == null) { return null; } inputData.putUserData(PARSED_MODEL, model); } return model; }
@Override public void findTargets( TargetKind kind, Collection<SModel> scope, Consumer<NavigationTarget> consumer, Consumer<SModel> processedConsumer) { final ID<Integer, List<SNodeDescriptor>> indexName = RootNodeNameIndex.NAME; final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); for (SModel sm : scope) { if (sm instanceof EditableSModel && ((EditableSModel) sm).isChanged()) { continue; } DataSource source = sm.getSource(); if (!(source instanceof FileDataSource)) { continue; } IFile modelFile = ((FileDataSource) source).getFile(); String ext = FileUtil.getExtension(modelFile.getName()); if (ext == null || modelFile.isDirectory() || !(supportedExtensions.contains(ext.toLowerCase()))) { continue; } VirtualFile vf = VirtualFileUtils.getVirtualFile(modelFile); if (vf == null) continue; // e.g. model was deleted int fileId = FileBasedIndex.getFileId(vf); ConcreteFilesGlobalSearchScope fileScope = new ConcreteFilesGlobalSearchScope(Collections.singleton(vf)); List<List<SNodeDescriptor>> descriptors = fileBasedIndex.getValues(indexName, fileId, fileScope); if (descriptors.isEmpty()) continue; boolean needToLoad = false; for (NavigationTarget snd : descriptors.get(0)) { PropertyConstraintsDescriptor descriptor = ConceptRegistry.getInstance() .getConstraintsDescriptor(snd.getConcept().getQualifiedName()) .getProperty(SNodeUtil.property_INamedConcept_name); if (descriptor instanceof BasePropertyConstraintsDescriptor && !((BasePropertyConstraintsDescriptor) descriptor).isGetterDefault()) { needToLoad = true; break; } } if (!needToLoad) { for (SNodeDescriptor desc : descriptors.get(0)) { consumer.consume(desc); } processedConsumer.consume(sm); } } }
/** * Convert path from sources module descriptor for using on distribution /classes && /classes_gen * converts to bundle home path * * @param originalPath Original path from sources module descriptor * @return Converted path, null if path meaningless on packaged module */ @Nullable private String convertPath( String originalPath, IFile bundleHome, IFile sourcesDescriptorFile, ModuleDescriptor descriptor) { MacroHelper macroHelper = MacrosFactory.forModuleFile(sourcesDescriptorFile); String canonicalPath = FileUtil.getCanonicalPath(originalPath).toLowerCase(); // /classes && /classes_gen hack String suffix = descriptor.getCompileInMPS() ? CLASSES_GEN : CLASSES; if (canonicalPath.endsWith(suffix)) { // MacrosFactory based on original descriptor file because we use original descriptor file for // ModuleDescriptor reading, so all paths expanded to original descriptor file String classes = macroHelper.expandPath("${module}/" + suffix); if (FileUtil.getCanonicalPath(classes).equalsIgnoreCase(canonicalPath)) { return bundleHome.getPath(); } } else if (FileUtil.getCanonicalPath(bundleHome.getPath()).equalsIgnoreCase(canonicalPath)) { return bundleHome.getPath(); } // ${mps_home}/lib String mpsHomeLibPath = FileUtil.getCanonicalPath(PathManager.getHomePath() + File.separator + "lib").toLowerCase(); if (canonicalPath.startsWith(mpsHomeLibPath)) { return canonicalPath; } // we used to keep originalPath if it has a macro not known to MPS here. // However, the check has been deprecated in 2012 and thus removed. I'm not 100% sure what // 'meaningless' in the contract of the method means. Of course, unknown macros make no sense // for us // and thus null is legitimate answer, OTOH, custom macros might have a lot of meaning to // someone else. // // ignore paths starts from ${module}/${project} etc return null; }
@Override protected void customizeCellRenderer( JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { setPaintFocusBorder(false); setFocusBorderAroundIcon(true); setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); if (value != null) { String path = FileUtil.getCanonicalPath((String) value); if (!(new File(path)).exists()) { append(path, SimpleTextAttributes.ERROR_ATTRIBUTES); } else { append(path); } } }
public void clean(final Set<? extends SModule> modules, @NotNull final ProgressMonitor monitor) { monitor.start("Cleaning...", modules.size()); try { for (SModule module : modules) { if (isExcluded(module)) { monitor.advance(1); continue; } if (monitor.isCanceled()) break; monitor.step(module.getModuleName()); JavaModuleFacet facet = module.getFacet(JavaModuleFacet.class); assert facet != null && facet.getClassesGen() != null; String path = facet.getClassesGen().getPath(); FileUtil.delete(new File(path)); ClassPathFactory.getInstance().invalidate(Collections.singleton(path)); monitor.advance(1); } } finally { monitor.done(); } }
public void rename(@NotNull String newName) { SModuleReference oldRef = getModuleReference(); renameModels(getModuleName(), newName, true); save(); // see MPS-18743, need to save before setting descriptor ModuleDescriptor descriptor = getModuleDescriptor(); if (myDescriptorFile != null) { // fixme AP: this looks awful -- I agree; the right way is to have IFile something immutable // fixme or just work in <code>WatchedRoots</code> by IFile (not by String) and listen for // rename myFileSystem.removeListener(this); myDescriptorFile.rename(newName + "." + FileUtil.getExtension(myDescriptorFile.getName())); myFileSystem.addListener(this); } if (descriptor != null) { descriptor.setNamespace(newName); setModuleDescriptor(descriptor); } fireModuleRenamed(oldRef); }
/*package*/ void onOk() { if (myThis.getSourcesPath().length() == 0) { myThis.getDialog().setErrorText("Enter the sources path"); return; } File sourcesDir = new File(myThis.getSourcesPath()); if (!(sourcesDir.exists())) { myThis.getDialog().setErrorText("Specified sources dir doesn't exist"); return; } String moduleName = myThis.myModuleNameField.getText(); // RE-3532 if (!SolutionUtils.isValidModuleName(moduleName)) { myThis.getDialog().setErrorText("Invalid module name"); return; } if (moduleName.isEmpty()) { myThis.getDialog().setErrorText("Enter the module name"); return; } final String libraryName = moduleName; if (!checkLibraryName(libraryName)) { return; } String projectPath = FileUtil.getCanonicalPath(myThis.getProject().getProjectFile().getParentFile()); String solutionDirPath = projectPath + File.separator + "modules" + File.separator + libraryName; String message = NewModuleCheckUtil.checkModuleDirectory( new File(solutionDirPath), MPSExtentions.DOT_SOLUTION, "Module"); if (message != null) { myThis.getDialog().setErrorText(message); return; } final String descriptorPath = solutionDirPath + File.separator + libraryName + MPSExtentions.DOT_SOLUTION; myThis.getDialog().dispose(); SolutionUtils.refreshModuleFiles(descriptorPath); final List<SModelDescriptor> modelDescriptors = new ArrayList<SModelDescriptor>(); execute(descriptorPath, modelDescriptors); // RE-3181 ModelAccess.instance() .runWriteActionInCommand( new Runnable() { @Override public void run() { try { SWCStubsRegistry.setAvoidIndexing(true); SModelOperations.validateLanguagesAndImportsNew(modelDescriptors, myResult); } finally { SWCStubsRegistry.setAvoidIndexing(false); StubSolutionUtils.invalidateStubSolutionCaches(myResult); } } }, getProject().getProject()); }
public static boolean testOnProjectCopy( final File source, final File destinationDir, final String projectName, ProjectRunnable pr, final String... plugins) { IdeMain.setTestMode(TestMode.CORE_TEST); Logger.setThreshold("WARN"); org.apache.log4j.BasicConfigurator.configure(); TestMain.configureMPS(plugins); if (destinationDir.exists()) { FileUtil.delete(destinationDir); } if (source.isDirectory()) { FileUtil.copyDir(source, destinationDir); } else { // it is allowed to have zipped directory here try { destinationDir.mkdir(); UnzipUtil.unzip(source, destinationDir); } catch (IOException e) { e.printStackTrace(); return false; } } final Project[] project = new MPSProject[] {null}; try { // load a project ThreadUtils.runInUIThreadAndWait( new Runnable() { public void run() { try { project[0] = loadProject(new File(destinationDir, projectName)); VirtualFile projectVirtualDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destinationDir); assert projectVirtualDir != null; projectVirtualDir.refresh(false, true); } catch (Throwable t) { t.printStackTrace(); } } }); waitUntilAllEventsFlushed(); // execute test return pr.execute(project[0]); } catch (Throwable t) { t.printStackTrace(); return false; } finally { waitUntilAllEventsFlushed(); // clean up ThreadUtils.runInUIThreadAndWait( new Runnable() { public void run() { if (project[0] != null) { project[0].dispose(); } FileUtil.delete(destinationDir); } }); } }
private <T> MultiMap<SModel, T> findCandidates( Collection<SModel> models, Set<T> elems, Consumer<SModel> processedModels, Function<T, UsageEntry> id) { // get all files in scope final ManyToManyMap<SModel, VirtualFile> scopeFiles = new ManyToManyMap<SModel, VirtualFile>(); for (final SModel sm : models) { if (sm instanceof EditableSModel && ((EditableSModel) sm).isChanged()) { continue; } DataSource source = sm.getSource(); // these are data sources this participant knows about if (!(source instanceof FileDataSource || source instanceof FilePerRootDataSource)) { continue; } /* This is a tmp fix for MPS-24151. See the issue to learn about the correct fix */ if (!(sm instanceof DefaultSModelDescriptor)) { continue; } Collection<IFile> modelFiles = getDataSourceFiles(source); for (IFile modelFile : modelFiles) { String ext = FileUtil.getExtension(modelFile.getName()); if (ext == null || modelFile.isDirectory()) { continue; } VirtualFile vf = VirtualFileUtils.getOrCreateVirtualFile(modelFile); if (vf == null) { LogManager.getLogger(MPSModelsFastFindSupport.class) .warn( String.format( "Model %s: virtual file not found for model file. Model file: %s", sm.getName(), modelFile.getPath())); continue; } processedModels.consume(sm); scopeFiles.addLink(sm, vf); } } // filter files with usages ConcreteFilesGlobalSearchScope allFiles = new ConcreteFilesGlobalSearchScope(scopeFiles.getSecond()); // process indexes MultiMap<SModel, T> result = new SetBasedMultiMap<SModel, T>(); for (T elem : elems) { UsageEntry entry = id.apply(elem); Collection<VirtualFile> matchingFiles; try { matchingFiles = MPSModelsIndexer.getContainingFiles(entry, allFiles); } catch (ProcessCanceledException ce) { matchingFiles = Collections.emptyList(); } // back-transform for (VirtualFile file : matchingFiles) { for (SModel m : scopeFiles.getBySecond(file)) { result.putValue(m, elem); } } } return result; }
private MPSCompilationResult compile(Set<SModule> modules, JavaCompilerOptions compilerOptions) { boolean hasAnythingToCompile = false; List<IMessage> messages = new ArrayList<IMessage>(); for (SModule m : modules) { if (isExcluded(m)) continue; hasAnythingToCompile = true; } if (!hasAnythingToCompile) { return new MPSCompilationResult(0, 0, false, Collections.<SModule>emptySet()); } JavaCompiler compiler = new JavaCompiler(); boolean hasJavaToCompile = false; boolean hasFilesToCopyOrDelete = false; myTracer.push("preparing to compile", false); Set<SModule> modulesWithRemovals = new HashSet<SModule>(); for (SModule m : modules) { if (areClassesUpToDate(m)) continue; if (!getJavaFacet(m).isCompileInMps()) { String text = "Module which compiled in IDEA depends on module which has to be compiled in MPS:" + m.getModuleName(); messages.add(createMessage(MessageKind.WARNING, text, m)); myHandler.handle(createMessage(MessageKind.INFORMATION, text, m)); continue; } ModuleSources sources = getModuleSources(m); hasFilesToCopyOrDelete |= !sources.isResourcesUpToDate(); hasJavaToCompile |= !sources.isJavaUpToDate(); for (File f : sources.getFilesToDelete()) { //noinspection ResultOfMethodCallIgnored f.delete(); modulesWithRemovals.add(m); } for (JavaFile f : sources.getFilesToCompile()) { compiler.addSource(f.getClassName(), f.getContents()); myContainingModules.put(f.getClassName(), m); } } myTracer.pop(); if (!hasJavaToCompile && !hasFilesToCopyOrDelete) { return new MPSCompilationResult(0, 0, false, Collections.<SModule>emptySet(), messages); } myTracer.push("invalidating classpath", false); for (SModule module : modulesWithRemovals) { invalidateCompiledClasses(module); } myTracer.pop(); Set<SModule> changedModules = new HashSet<SModule>(); MyCompilationResultAdapter listener = null; if (hasJavaToCompile) { myTracer.push("compiling java", false); IClassPathItem classPathItems = computeDependenciesClassPath(modules); listener = new MyCompilationResultAdapter(modules, classPathItems, messages); compiler.addCompilationResultListener(listener); myTracer.push("eclipse compiler", true); if (compilerOptions == null) { compiler.compile(classPathItems); } else { compiler.compile(classPathItems, compilerOptions); } myTracer.pop(); changedModules.addAll(listener.myChangedModules); compiler.removeCompilationResultListener(listener); myTracer.pop(); } myTracer.push("copying resources", false); for (SModule module : modules) { ModuleSources sources = getModuleSources(module); IFile classesGen = getJavaFacet(module).getClassesGen(); if (classesGen == null) { continue; } for (ResourceFile toCopy : sources.getResourcesToCopy()) { String fqName = toCopy.getPath(); fqName = fqName.substring(0, fqName.length() - toCopy.getFile().getName().length()); String path = fqName.replace('/', File.separatorChar) + toCopy.getFile().getName(); if (new File(toCopy.getFile().getAbsolutePath()).exists()) { FileUtil.copyFile( new File(toCopy.getFile().getAbsolutePath()), new File(classesGen.getDescendant(path).getPath())); } } } myTracer.pop(); myTracer.push("updating classpath", false); for (SModule module : changedModules) { invalidateCompiledClasses(module); } myTracer.pop(); for (SModule module : modulesWithRemovals) { if (!changedModules.contains(module)) { myHandler.handle( createMessage( MessageKind.WARNING, "Module with removals not in changed modules: " + module, module)); } } // todo: check possibility of this statements if (hasJavaToCompile && changedModules.isEmpty()) { myHandler.handle( createMessage( MessageKind.ERROR, "has java to compile but changed modules is empty", null)); } if (!hasJavaToCompile && !changedModules.isEmpty()) { myHandler.handle( createMessage( MessageKind.ERROR, "has not java to compile but changed modules is not empty", null)); } return new MPSCompilationResult( listener == null ? 0 : listener.getErrorCount(), 0, false, changedModules, messages); }