diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java')
-rw-r--r-- | platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java | 134 |
1 files changed, 53 insertions, 81 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java index 923072d4fb1d..54fd9d65cb92 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java @@ -22,19 +22,14 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.components.StateStorageException; -import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.components.TrackingPathMacroSubstitutor; +import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.tracker.VirtualFileTracker; -import com.intellij.util.io.fs.FileSystem; -import com.intellij.util.io.fs.IFile; import com.intellij.util.messages.MessageBus; -import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NonNls; @@ -44,46 +39,40 @@ import org.picocontainer.PicoContainer; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.util.Collection; import java.util.Collections; import java.util.List; public class FileBasedStorage extends XmlElementStorage { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.FileBasedStorage"); + private static final Logger LOG = Logger.getInstance(FileBasedStorage.class); private static boolean ourConfigDirectoryRefreshed = false; private final String myFilePath; - private final IFile myFile; - private final String myRootElementName; + private final File myFile; private volatile VirtualFile myCachedVirtualFile; - public FileBasedStorage(@Nullable TrackingPathMacroSubstitutor pathMacroManager, - StreamProvider streamProvider, - String filePath, - String fileSpec, - String rootElementName, + public FileBasedStorage(@NotNull String filePath, + @NotNull String fileSpec, + @Nullable RoamingType roamingType, + @Nullable TrackingPathMacroSubstitutor pathMacroManager, + @NotNull String rootElementName, @NotNull Disposable parentDisposable, PicoContainer picoContainer, - ComponentRoamingManager componentRoamingManager, + @Nullable StreamProvider streamProvider, ComponentVersionProvider componentVersionProvider) { - super(pathMacroManager, parentDisposable, rootElementName, streamProvider, fileSpec, componentRoamingManager, componentVersionProvider); + super(fileSpec, roamingType, pathMacroManager, parentDisposable, rootElementName, streamProvider, componentVersionProvider); refreshConfigDirectoryOnce(); - myRootElementName = rootElementName; myFilePath = filePath; - myFile = FileSystem.FILE_SYSTEM.createFile(myFilePath); + myFile = new File(filePath); VirtualFileTracker virtualFileTracker = ServiceManager.getService(VirtualFileTracker.class); MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class); if (virtualFileTracker != null && messageBus != null) { - final String path = myFile.getAbsolutePath(); - final String fileUrl = LocalFileSystem.PROTOCOL_PREFIX + path.replace(File.separatorChar, '/'); - final Listener listener = messageBus.syncPublisher(STORAGE_TOPIC); - virtualFileTracker.addTracker(fileUrl, new VirtualFileAdapter() { + virtualFileTracker.addTracker(LocalFileSystem.PROTOCOL_PREFIX + myFile.getAbsolutePath().replace(File.separatorChar, '/'), new VirtualFileAdapter() { @Override public void fileMoved(@NotNull VirtualFileMoveEvent event) { myCachedVirtualFile = null; @@ -95,6 +84,11 @@ public class FileBasedStorage extends XmlElementStorage { } @Override + public void fileCreated(@NotNull VirtualFileEvent event) { + myCachedVirtualFile = event.getFile(); + } + + @Override public void contentsChanged(@NotNull final VirtualFileEvent event) { if (!isDisposed()) { listener.storageFileChanged(event, FileBasedStorage.this); @@ -130,13 +124,6 @@ public class FileBasedStorage extends XmlElementStorage { return new FileSaveSession(externalizationSession); } - public void resetProviderCache() { - myProviderUpToDateHash = -1; - if (myRemoteVersionProvider != null) { - myRemoteVersionProvider.myProviderVersions = null; - } - } - private class FileSaveSession extends MySaveSession { protected FileSaveSession(MyExternalizationSession externalizationSession) { super(externalizationSession); @@ -145,9 +132,11 @@ public class FileBasedStorage extends XmlElementStorage { @Override protected boolean physicalContentNeedsSave() { VirtualFile file = getVirtualFile(); - if (file == null || !file.exists()) + if (file == null || !file.exists()) { return !myStorageData.isEmpty(); - return !StorageUtil.contentEquals(getDocumentToSave(), file); + } + Element element = getElementToSave(); + return element == null || !StorageUtil.contentEquals(element, file); } @Override @@ -169,14 +158,13 @@ public class FileBasedStorage extends XmlElementStorage { } LOG.assertTrue(myFile != null); - myCachedVirtualFile = StorageUtil.save(myFile, getDocumentToSave(), this); + myCachedVirtualFile = StorageUtil.save(myFile, getElementToSave(), this, true, myCachedVirtualFile); } @NotNull @Override - public Collection<IFile> getStorageFilesToSave() throws StateStorageException { - boolean needsSave = needsSave(); - if (needsSave) { + public Collection<File> getStorageFilesToSave() { + if (needsSave()) { if (LOG.isDebugEnabled()) { LOG.info("File " + myFileSpec + " needs save; hash=" + myUpToDateHash + "; currentHash=" + calcHash() + "; " + "content needs save=" + physicalContentNeedsSave()); @@ -190,21 +178,17 @@ public class FileBasedStorage extends XmlElementStorage { @NotNull @Override - public List<IFile> getAllStorageFiles() { + public List<File> getAllStorageFiles() { return Collections.singletonList(myFile); } } @Override - protected void loadState(final StorageData result, final Element element) throws StateStorageException { - ((FileStorageData)result).myFilePath = myFile.getAbsolutePath(); - super.loadState(result, element); - } - - @Override @NotNull protected StorageData createStorageData() { - return new FileStorageData(myRootElementName); + FileStorageData data = new FileStorageData(myRootElementName); + data.myFilePath = myFilePath; + return data; } public static class FileStorageData extends StorageData { @@ -234,18 +218,24 @@ public class FileBasedStorage extends XmlElementStorage { public VirtualFile getVirtualFile() { VirtualFile virtualFile = myCachedVirtualFile; if (virtualFile == null) { - myCachedVirtualFile = virtualFile = StorageUtil.getVirtualFile(myFile); + myCachedVirtualFile = virtualFile = LocalFileSystem.getInstance().findFileByIoFile(myFile); } return virtualFile; } + @NotNull public File getFile() { - return new File(myFile.getPath()); + return myFile; + } + + @NotNull + public String getFilePath() { + return myFilePath; } @Override @Nullable - protected Document loadDocument() throws StateStorageException { + protected Element loadLocalData() { myBlockSavingTheContent = false; try { VirtualFile file = getVirtualFile(); @@ -256,7 +246,7 @@ public class FileBasedStorage extends XmlElementStorage { if (file.getLength() == 0) { return processReadException(null); } - return loadDocumentImpl(file); + return StorageData.load(file); } catch (final JDOMException e) { return processReadException(e); @@ -267,7 +257,7 @@ public class FileBasedStorage extends XmlElementStorage { } @Nullable - private Document processReadException(@Nullable final Exception e) { + private Element processReadException(@Nullable final Exception e) { boolean contentTruncated = e == null; myBlockSavingTheContent = isProjectOrModuleOrWorkspaceFile() && !contentTruncated; if (!ApplicationManager.getApplication().isUnitTestMode() && !ApplicationManager.getApplication().isHeadlessEnvironment()) { @@ -291,45 +281,27 @@ public class FileBasedStorage extends XmlElementStorage { return isProjectOrModuleOrWorkspaceFile() && !contentTruncated ? "Please correct the file content" : "File content will be recreated"; } - private static Document loadDocumentImpl(final VirtualFile file) throws IOException, JDOMException { - InputStream stream = file.getInputStream(); - try { - return JDOMUtil.loadDocument(stream); - } - finally { - stream.close(); - } - } - - public String getFileName() { - return myFile.getName(); - } - - public String getFilePath() { - return myFilePath; - } - @Override public void setDefaultState(final Element element) { element.setName(myRootElementName); super.setDefaultState(element); } - protected boolean physicalContentNeedsSave(final Document doc) { - VirtualFile file = getVirtualFile(); - return file == null || !file.exists() || !StorageUtil.contentEquals(doc, file); - } - @Nullable public File updateFileExternallyFromStreamProviders() throws IOException { - StorageData loadedData = loadData(true); - Document document = getDocument(loadedData); - if (physicalContentNeedsSave(document)) { - File file = new File(myFile.getAbsolutePath()); - JDOMUtil.writeDocument(document, file, "\n"); - return file; + Element element = getElement(loadData(true)); + if (element == null) { + FileUtil.delete(myFile); + return null; } - return null; + BufferExposingByteArrayOutputStream out = StorageUtil.newContentIfDiffers(element, getVirtualFile()); + if (out == null) { + return null; + } + + File file = new File(myFile.getAbsolutePath()); + FileUtil.writeToFile(file, out.getInternalBuffer(), 0, out.size()); + return file; } } |