@Nullable @Override public Element getSerializedState( @NotNull Boolean storageData, Object component, @NotNull String componentName, boolean archive) { if (storageData) { return null; } Element element = new Element("component"); ModifiableRootModel model = null; AccessToken token = ReadAction.start(); try { model = ((ModuleRootManagerImpl) component).getModifiableModel(); // IDEA-137969 Eclipse integration: external remove of classpathentry is not synchronized model.clear(); try { myConverter.readClasspath(model); } catch (IOException e) { throw new RuntimeException(e); } ((RootModelImpl) model).writeExternal(element); } catch (WriteExternalException e) { LOG.error(e); } finally { try { token.finish(); } finally { if (model != null) { model.dispose(); } } } if (myPathMacroSubstitutor != null) { myPathMacroSubstitutor.expandPaths(element); myPathMacroSubstitutor.addUnknownMacros( "NewModuleRootManager", PathMacrosCollector.getMacroNames(element)); } getStorageDataRef().set(true); return element; }
public ClasspathStorage( @NotNull final Module module, @NotNull StateStorageManager storageManager) { String storageType = module.getOptionValue(JpsProjectLoader.CLASSPATH_ATTRIBUTE); if (storageType == null) { throw new IllegalStateException("Classpath storage requires non-default storage type"); } ClasspathStorageProvider provider = getProvider(storageType); if (provider == null) { if (module.getUserData(ERROR_NOTIFIED_KEY) == null) { Notification n = new Notification( StorageUtil.NOTIFICATION_GROUP_ID, "Cannot load module '" + module.getName() + "'", "Support for " + storageType + " format is not installed.", NotificationType.ERROR); n.notify(module.getProject()); module.putUserData(ERROR_NOTIFIED_KEY, Boolean.TRUE); LOG.info("Classpath storage provider " + storageType + " not found"); } myConverter = new MissingClasspathConverter(); } else { myConverter = provider.createConverter(module); } myPathMacroSubstitutor = storageManager.getMacroSubstitutor(); final List<String> paths = myConverter.getFilePaths(); MessageBusConnection busConnection = module.getMessageBus().connect(); busConnection.subscribe( VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@NotNull List<? extends VFileEvent> events) { for (VFileEvent event : events) { if (!event.isFromRefresh() || !(event instanceof VFileContentChangeEvent)) { continue; } for (String path : paths) { if (path.equals(event.getPath())) { module .getMessageBus() .syncPublisher(StateStorageManager.STORAGE_TOPIC) .storageFileChanged(event, ClasspathStorage.this, module); return; } } } } }); busConnection.subscribe( StateStorageManager.STORAGE_TOPIC, new StorageManagerListener() { private String fileNameToModuleName(@NotNull String fileName) { return fileName.substring( 0, fileName.length() - ModuleFileType.DOT_DEFAULT_EXTENSION.length()); } @Override public void storageFileChanged( @NotNull VFileEvent event, @NotNull StateStorage storage, @NotNull ComponentManager componentManager) { assert componentManager == module; if (!(event instanceof VFilePropertyChangeEvent)) { return; } VFilePropertyChangeEvent propertyEvent = (VFilePropertyChangeEvent) event; if (propertyEvent.getPropertyName().equals(VirtualFile.PROP_NAME)) { String oldFileName = (String) propertyEvent.getOldValue(); if (oldFileName.endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) { ClasspathStorageProvider provider = getProvider(ClassPathStorageUtil.getStorageType(module)); if (provider != null) { provider.moduleRenamed( module, fileNameToModuleName(oldFileName), fileNameToModuleName((String) propertyEvent.getNewValue())); } } } } }); }
@Override @NotNull public ExternalizationSession startExternalization() { return myConverter.startExternalization(); }