/* * Copyright 2000-2009 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 com.intellij.openapi.vcs.changes.shelf; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.components.RoamingType; import com.intellij.openapi.components.impl.stores.StorageUtil; import com.intellij.openapi.components.impl.stores.StreamProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vcs.changes.CommitContext; import com.intellij.openapi.vfs.CharsetToolkit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public class CompoundShelfFileProcessor { private final String mySubdirName; private final StreamProvider myServerStreamProvider; private final String FILE_SPEC; private final String myShelfPath; private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.shelf.CompoundShelfFileProcessor"); public CompoundShelfFileProcessor(final String subdirName) { mySubdirName = subdirName; myServerStreamProvider = ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider(); FILE_SPEC = "$ROOT_CONFIG$/" + subdirName + "/"; myShelfPath = PathManager.getConfigPath() + File.separator + mySubdirName; } public CompoundShelfFileProcessor(@Nullable StreamProvider serverStreamProvider, String shelfPath) { myServerStreamProvider = serverStreamProvider; myShelfPath = shelfPath; mySubdirName = new File(myShelfPath).getName(); FILE_SPEC = "$ROOT_CONFIG$/" + mySubdirName + "/"; } /* public void onWriteExternal() { if (myShelfPath != null) { File[] shelfFiles = new File(myShelfPath).listFiles(); if (shelfFiles != null) { for (File shelfFile : shelfFiles) { try { for (StreamProvider serverStreamProvider : myServerStreamProviders) { FileInputStream input = new FileInputStream(shelfFile); try { serverStreamProvider.saveContent(FILE_SPEC + shelfFile.getName(), input, shelfFile.length(), PER_USER); } finally { input.close(); } } } catch (IOException e) { //ignore } } } } } */ public List getLocalFiles() { ArrayList result = new ArrayList(); File[] files = new File(myShelfPath).listFiles(); if (files != null) { for (File file : files) { result.add(file.getName()); } } return result; } public Collection getServerFiles() { if (myServerStreamProvider == null || !myServerStreamProvider.isEnabled()) { return Collections.emptyList(); } return myServerStreamProvider.listSubFiles(FILE_SPEC, RoamingType.PER_USER); } public String copyFileFromServer(final String serverFileName, final List localFileNames) { if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) { try { File file = new File(new File(myShelfPath), serverFileName); if (!file.exists()) { InputStream stream = myServerStreamProvider.loadContent(FILE_SPEC + serverFileName, RoamingType.PER_USER); if (stream != null) { //noinspection ResultOfMethodCallIgnored file.getParentFile().mkdirs(); FileOutputStream out = new FileOutputStream(file); try { FileUtil.copy(stream, out); } finally { out.close(); stream.close(); } } } } catch (IOException ignored) { } } localFileNames.add(serverFileName); return serverFileName; } public String renameFileOnServer(final String serverFileName, final Collection serverFileNames, final Collection localFileNames) { String newName = getNewFileName(serverFileName, serverFileNames, localFileNames); if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) { renameFileOnProvider(newName, FILE_SPEC + serverFileName, FILE_SPEC + newName, myServerStreamProvider); } return newName; } private void renameFileOnProvider(@NotNull String newName, @NotNull String oldFilePath, @NotNull String newFilePath, @NotNull StreamProvider serverStreamProvider) { if (!serverStreamProvider.isEnabled()) { return; } try { InputStream stream = serverStreamProvider.loadContent(oldFilePath, RoamingType.PER_USER); if (stream != null) { File file = new File(myShelfPath + "/" + newName); copyFileToStream(stream, file); serverStreamProvider.deleteFile(oldFilePath, RoamingType.PER_USER); copyFileContentToProviders(newFilePath, serverStreamProvider, file); } } catch (IOException e) { LOG.info(e); } } private static void copyFileContentToProviders(final String newFilePath, final StreamProvider serverStreamProvider, final File file) throws IOException { if (serverStreamProvider.isEnabled() && serverStreamProvider.isApplicable(newFilePath, RoamingType.PER_USER)) { byte[] content = FileUtil.loadFileBytes(file); serverStreamProvider.saveContent(newFilePath, content, content.length, RoamingType.PER_USER, true); } } private static void copyFileToStream(final InputStream stream, final File file) throws IOException { FileOutputStream out = new FileOutputStream(file); try { FileUtil.copy(stream, out); } finally { out.close(); } } private static String getNewFileName(final String serverFileName, final Collection serverFileNames, Collection localFileNames) { String name = FileUtil.getNameWithoutExtension(serverFileName); String ext = FileUtilRt.getExtension(serverFileName); for (int i = 1; ;i++) { String suggestedName = name + i + "." + ext; if (!serverFileNames.contains(suggestedName) && !localFileNames.contains(suggestedName)) { serverFileNames.add(suggestedName); localFileNames.add(suggestedName); return suggestedName; } } } public interface ContentProvider { void writeContentTo(Writer writer, CommitContext commitContext) throws IOException; } public void savePathFile(ContentProvider contentProvider, final File patchPath, CommitContext commitContext) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(patchPath), CharsetToolkit.UTF8_CHARSET); try { contentProvider.writeContentTo(writer, commitContext); } finally { writer.close(); } if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) { copyFileContentToProviders(FILE_SPEC + patchPath.getName(), myServerStreamProvider, patchPath); } } public File getBaseIODir() { return new File(myShelfPath); } public void saveFile(final File from, final File to) throws IOException { if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) { copyFileContentToProviders(FILE_SPEC + to.getName(), myServerStreamProvider, from); } FileUtil.copy(from, to); } public void delete(final String name) { FileUtil.delete(new File(getBaseIODir(), name)); if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) { StorageUtil.deleteContent(myServerStreamProvider, FILE_SPEC + name, RoamingType.PER_USER); } } }