| /* |
| * Copyright 2000-2011 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.cvsSupport2; |
| |
| import com.intellij.CvsBundle; |
| import com.intellij.codeStyle.CodeStyleFacade; |
| import com.intellij.cvsSupport2.application.CvsEntriesManager; |
| import com.intellij.cvsSupport2.application.CvsInfo; |
| import com.intellij.cvsSupport2.config.CvsApplicationLevelConfiguration; |
| import com.intellij.cvsSupport2.connections.CvsConnectionSettings; |
| import com.intellij.cvsSupport2.connections.CvsRootParser; |
| import com.intellij.cvsSupport2.cvsstatuses.CvsStatusProvider; |
| import com.intellij.cvsSupport2.util.CvsFileUtil; |
| import com.intellij.cvsSupport2.util.CvsVfsUtil; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.ui.Messages; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.util.registry.Registry; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.openapi.vcs.FilePath; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.util.text.SyncDateFormat; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.netbeans.lib.cvsclient.admin.Entries; |
| import org.netbeans.lib.cvsclient.admin.EntriesHandler; |
| import org.netbeans.lib.cvsclient.admin.Entry; |
| |
| import javax.swing.*; |
| import java.io.File; |
| import java.io.FilenameFilter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.text.SimpleDateFormat; |
| import java.util.*; |
| import java.util.regex.Pattern; |
| |
| /** |
| * author: lesya |
| */ |
| public class CvsUtil { |
| |
| private final static SyncDateFormat DATE_FORMATTER = new SyncDateFormat(new SimpleDateFormat(Entry.getLastModifiedDateFormatter().toPattern(), Locale.US)); |
| |
| static { |
| //noinspection HardCodedStringLiteral |
| DATE_FORMATTER.setTimeZone(TimeZone.getTimeZone("GMT+0000")); |
| } |
| |
| @NonNls public static final String CVS_IGNORE_FILE = ".cvsignore"; |
| @NonNls public static final String CVS_ROOT_FILE = "Root"; |
| private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.CvsUtil"); |
| @NonNls private static final String REPOSITORY = "Repository"; |
| @NonNls private static final String TAG = "Tag"; |
| @NonNls public static final String CVS = "CVS"; |
| @NonNls public static final String ENTRIES = "Entries"; |
| @NonNls private static final String CONFLICTS = "Conflicts"; |
| @NonNls private static final String BASE_REVISIONS_DIR = "BaseRevisions"; |
| @NonNls public static final String STICKY_DATE_PREFIX = "D"; |
| @NonNls private static final String TEMPLATE = "Template"; |
| @NonNls public static final String STICKY_BRANCH_TAG_PREFIX = "T"; |
| @NonNls public static final String STICKY_NON_BRANCH_TAG_PREFIX = "N"; |
| @NonNls public static final String HEAD = "HEAD"; |
| @NonNls public static final String BASE = "Base"; |
| @NonNls public static final String REVISION_PATTERN = "\\d+(\\.\\d+)*"; |
| |
| public static void skip(InputStream inputStream, int length) throws IOException { |
| int skipped = 0; |
| while (skipped < length) { |
| skipped += inputStream.skip(length - skipped); |
| } |
| } |
| |
| public static String getModuleName(VirtualFile file) { |
| if (file.isDirectory()) { |
| return CvsEntriesManager.getInstance().getRepositoryFor(file); |
| } else { |
| return CvsEntriesManager.getInstance().getRepositoryFor(file.getParent()) + "/" + file.getName(); |
| } |
| } |
| |
| public static String getModuleName(FilePath path) { |
| if (path.isDirectory()) { |
| return CvsEntriesManager.getInstance().getRepositoryFor(path.getVirtualFile()); |
| } else { |
| return CvsEntriesManager.getInstance().getRepositoryFor(path.getVirtualFileParent()) + "/" + path.getName(); |
| } |
| } |
| |
| public static boolean fileIsUnderCvsMaybeWithVfs(VirtualFile vFile) { |
| try { |
| if (Registry.is("cvs.roots.refresh.uses.vfs")) { |
| if (vFile.isDirectory()) { |
| return directoryIsUnderCVS(vFile); |
| } |
| return fileIsUnderCvs(getEntryFor(vFile)); |
| } else { |
| return fileIsUnderCvs(vFile); |
| } |
| } |
| catch (Exception e1) { |
| return false; |
| } |
| } |
| |
| public static boolean fileIsUnderCvs(VirtualFile vFile) { |
| return fileIsUnderCvs(CvsVfsUtil.getFileFor(vFile)); |
| } |
| |
| public static boolean fileIsUnderCvs(File ioFile) { |
| try { |
| if (ioFile.isDirectory()) { |
| return directoryIsUnderCVS(ioFile); |
| } |
| return fileIsUnderCvs(getEntryFor(ioFile)); |
| } |
| catch (Exception e1) { |
| return false; |
| } |
| } |
| |
| private static boolean directoryIsUnderCVS(File directory) { |
| if (!getAdminDir(directory).isDirectory()) return false; |
| if (!getFileInTheAdminDir(directory, ENTRIES).isFile()) return false; |
| if (!getFileInTheAdminDir(directory, CVS_ROOT_FILE).isFile()) return false; |
| if (!getFileInTheAdminDir(directory, REPOSITORY).isFile()) return false; |
| return true; |
| } |
| |
| private static boolean directoryIsUnderCVS(VirtualFile vDir) { |
| VirtualFile dir = getAdminDir(vDir); |
| if (dir == null) return false; |
| |
| if (!hasPlainFileInTheAdminDir(dir, ENTRIES)) return false; |
| if (!hasPlainFileInTheAdminDir(dir, CVS_ROOT_FILE)) return false; |
| if (!hasPlainFileInTheAdminDir(dir, REPOSITORY)) return false; |
| |
| return true; |
| } |
| |
| private static boolean hasPlainFileInTheAdminDir(VirtualFile dir, String filename) { |
| VirtualFile child = dir.findChild(filename); |
| return child != null && !child.isDirectory(); |
| } |
| |
| public static Entry getEntryFor(@NotNull VirtualFile file) { |
| return CvsEntriesManager.getInstance().getEntryFor(file.getParent(), file.getName()); |
| } |
| |
| public static Entry getEntryFor(File ioFile) { |
| File parentFile = ioFile.getParentFile(); |
| if (parentFile == null) return null; |
| return CvsEntriesManager.getInstance().getEntryFor(CvsVfsUtil.findFileByIoFile(parentFile), |
| ioFile.getName()); |
| } |
| |
| private static boolean fileIsUnderCvs(Entry entry) { |
| return entry != null; |
| } |
| |
| public static boolean filesAreUnderCvs(File[] selectedFiles) { |
| return allSatisfy(selectedFiles, fileIsUnderCvsCondition()); |
| } |
| |
| public static boolean filesArentUnderCvs(File[] selectedFiles) { |
| return !anySatisfy(selectedFiles, fileIsUnderCvsCondition()); |
| } |
| |
| private static FileCondition fileIsUnderCvsCondition() { |
| return new FileCondition() { |
| public boolean verify(File file) { |
| return fileIsUnderCvs(file); |
| } |
| }; |
| } |
| |
| private static boolean allSatisfy(File[] files, FileCondition condition) { |
| for (File file : files) { |
| if (!condition.verify(file)) return false; |
| } |
| return true; |
| } |
| |
| private static boolean anySatisfy(File[] files, FileCondition condition) { |
| return !allSatisfy(files, new ReverseFileCondition(condition)); |
| } |
| |
| public static boolean filesHaveParentUnderCvs(File[] files) { |
| return allSatisfy(files, new FileCondition() { |
| public boolean verify(File file) { |
| return fileHasParentUnderCvs(file); |
| } |
| }); |
| } |
| |
| private static boolean fileHasParentUnderCvs(File file) { |
| return fileIsUnderCvs(file.getParentFile()); |
| } |
| |
| public static boolean fileIsLocallyAdded(File file) { |
| Entry entry = getEntryFor(file); |
| return entry != null && entry.isAddedFile(); |
| } |
| |
| public static boolean fileIsLocallyDeleted(File file) { |
| Entry entry = getEntryFor(file); |
| return entry != null && entry.isRemoved(); |
| } |
| |
| public static boolean fileIsLocallyAdded(VirtualFile file) { |
| return fileIsLocallyAdded(CvsVfsUtil.getFileFor(file)); |
| } |
| |
| public static Entries getEntriesIn(File dir) { |
| return getEntriesHandlerIn(dir).getEntries(); |
| } |
| |
| private static EntriesHandler getEntriesHandlerIn(final File dir) { |
| EntriesHandler entriesHandler = new EntriesHandler(dir); |
| try { |
| entriesHandler.read(CvsApplicationLevelConfiguration.getCharset()); |
| return entriesHandler; |
| } |
| catch (Exception ex) { |
| final String entries = loadFrom(dir, ENTRIES, true); |
| if (entries != null) { |
| ApplicationManager.getApplication().invokeLater(new Runnable() { |
| public void run() { |
| final String entriesFileRelativePath = CVS + File.separatorChar + ENTRIES; |
| Messages.showErrorDialog( |
| CvsBundle.message("message.error.invalid.entries", entriesFileRelativePath, dir.getAbsolutePath(), entries), |
| CvsBundle.message("message.error.invalid.entries.title")); |
| } |
| }); |
| } |
| return entriesHandler; |
| } |
| } |
| |
| public static void removeEntryFor(File file) { |
| File entriesFile = file.getParentFile(); |
| EntriesHandler handler = new EntriesHandler(entriesFile); |
| String charset = CvsApplicationLevelConfiguration.getCharset(); |
| try { |
| handler.read(charset); |
| } |
| catch (IOException e) { |
| return; |
| } |
| Entries entries = handler.getEntries(); |
| entries.removeEntry(file.getName()); |
| |
| try { |
| handler.write(getLineSeparator(), charset); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| } |
| CvsEntriesManager.getInstance().removeEntryForFile(file.getParentFile(), file.getName()); |
| } |
| |
| private static String getLineSeparator() { |
| return CodeStyleFacade.getInstance().getLineSeparator(); |
| } |
| |
| public static boolean fileIsLocallyRemoved(File file) { |
| Entry entry = getEntryFor(file); |
| if (entry == null) return false; |
| return entry.isRemoved(); |
| } |
| |
| public static boolean fileIsLocallyRemoved(VirtualFile file) { |
| return fileIsLocallyRemoved(CvsVfsUtil.getFileFor(file)); |
| } |
| |
| public static String formatDate(Date date) { |
| return DATE_FORMATTER.format(date); |
| } |
| |
| public static void saveEntryForFile(File file, Entry entry) throws IOException { |
| EntriesHandler entriesHandler = new EntriesHandler(file.getParentFile()); |
| entriesHandler.read(CvsApplicationLevelConfiguration.getCharset()); |
| entriesHandler.getEntries().addEntry(entry); |
| entriesHandler.write(getLineSeparator(), CvsApplicationLevelConfiguration.getCharset()); |
| } |
| |
| public static String loadRepositoryFrom(File file) { |
| return loadFrom(file, REPOSITORY, true); |
| } |
| |
| public static String loadRootFrom(File file) { |
| return loadFrom(file, CVS_ROOT_FILE, true); |
| } |
| |
| @Nullable |
| private static String loadFrom(File directory, String fileName, boolean trimContent) { |
| if (directory == null) return null; |
| File file = getFileInTheAdminDir(directory, fileName); |
| if (!file.isFile()) return null; |
| try { |
| String result = FileUtil.loadFile(file); |
| if (trimContent) { |
| return result.trim(); |
| } |
| else { |
| return result; |
| } |
| } |
| catch (IOException e) { |
| return null; |
| } |
| } |
| |
| private static File getFileInTheAdminDir(File file, String fileName) { |
| return new File(getAdminDir(file), fileName); |
| } |
| |
| private static File getAdminDir(File file) { |
| return new File(file, CVS); |
| } |
| |
| private static VirtualFile getAdminDir(VirtualFile file) { |
| VirtualFile child = file.findChild(CVS); |
| return child != null && child.isDirectory() ? child:null; |
| } |
| |
| @Nullable |
| public static String getStickyDateForDirectory(VirtualFile parentFile) { |
| File file = CvsVfsUtil.getFileFor(parentFile); |
| return getStickyDateForDirectory(file); |
| } |
| |
| @Nullable |
| public static String getStickyDateForDirectory(final File file) { |
| String tag = loadStickyTagFrom(file); |
| if (tag == null) return null; |
| if (tag.startsWith(STICKY_DATE_PREFIX)) { |
| return tag.substring(STICKY_DATE_PREFIX.length()); |
| } |
| if (tag.startsWith(STICKY_BRANCH_TAG_PREFIX)) { |
| return tag.substring(STICKY_BRANCH_TAG_PREFIX.length()); |
| } |
| |
| return tag; |
| } |
| |
| public static String loadStickyTagFrom(File file) { |
| return loadFrom(file, TAG, true); |
| } |
| |
| @Nullable |
| public static String getStickyTagForDirectory(VirtualFile parentFile) { |
| return getStickyTagForDirectory(CvsVfsUtil.getFileFor(parentFile)); |
| } |
| |
| @Nullable |
| public static String getStickyTagForDirectory(File ioFile) { |
| String tag = loadFrom(ioFile, TAG, true); |
| if (tag == null) return null; |
| if (tag.length() == 0) return null; |
| if (tag.startsWith(STICKY_DATE_PREFIX)) return null; |
| if (tag.startsWith(STICKY_BRANCH_TAG_PREFIX)) return tag.substring(1); |
| if (tag.startsWith(STICKY_NON_BRANCH_TAG_PREFIX)) return tag.substring(1); |
| return null; |
| } |
| |
| public static void ignoreFile(@NotNull final VirtualFile file) throws IOException { |
| VirtualFile directory = file.getParent(); |
| File cvsignoreFile = cvsignoreFileFor(directory == null ? "" : directory.getPath()); |
| CvsFileUtil.appendLineToFile(file.getName(), cvsignoreFile); |
| CvsEntriesManager.getInstance().clearCachedFiltersFor(directory); |
| } |
| |
| public static File cvsignoreFileFor(String path) { |
| return new File(new File(path), CVS_IGNORE_FILE); |
| } |
| |
| public static File cvsignoreFileFor(File file) { |
| return new File(file, CVS_IGNORE_FILE); |
| } |
| |
| public static void addConflict(File file) { |
| File conflictsFile = getConflictsFile(file); |
| try { |
| Conflicts conflicts = Conflicts.readFrom(conflictsFile); |
| conflicts.addConflictForFile(file.getName()); |
| conflicts.saveTo(conflictsFile); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| } |
| } |
| |
| private static File getConflictsFile(File file) { |
| return getFileInTheAdminDir(file.getParentFile(), CONFLICTS); |
| } |
| |
| public static void removeConflict(File file) { |
| File conflictsFile = getConflictsFile(file); |
| if (!conflictsFile.exists()) return; |
| try { |
| Conflicts conflicts = Conflicts.readFrom(conflictsFile); |
| conflicts.removeConflictForFile(file.getName()); |
| conflicts.saveTo(conflictsFile); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| } |
| } |
| |
| public static boolean isLocallyRemoved(File file) { |
| Entry entry = getEntryFor(file); |
| if (entry == null) return false; |
| return entry.isRemoved(); |
| } |
| |
| public static String getRevisionFor(File file) { |
| final Entry entry = getEntryFor(file); |
| if (entry == null) return null; |
| return entry.getRevision(); |
| } |
| |
| public static boolean filesExistInCvs(File[] files) { |
| return allSatisfy(files, new FileCondition() { |
| public boolean verify(File file) { |
| return fileIsUnderCvs(file) && !fileIsLocallyAdded(file); |
| } |
| }); |
| } |
| |
| public static boolean filesAreNotDeleted(File[] files) { |
| return allSatisfy(files, new FileCondition() { |
| public boolean verify(File file) { |
| return fileIsUnderCvs(file) |
| && !fileIsLocallyAdded(file) |
| && !fileIsLocallyDeleted(file); |
| } |
| }); |
| } |
| |
| public static void saveRevisionForMergedFile(@NotNull VirtualFile parent, |
| @NotNull final Entry previousEntry, |
| List<String> revisions) { |
| File conflictsFile = getConflictsFile(new File(CvsVfsUtil.getFileFor(parent), previousEntry.getFileName())); |
| try { |
| Conflicts conflicts = Conflicts.readFrom(conflictsFile); |
| Date lastModified = previousEntry.getLastModified(); |
| conflicts.setRevisionAndDateForFile(previousEntry.getFileName(), |
| previousEntry.getRevision(), |
| revisions, |
| lastModified == null ? new Date().getTime() : lastModified.getTime()); |
| conflicts.saveTo(conflictsFile); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| } |
| } |
| |
| public static byte[] getStoredContentForFile(VirtualFile file, final String originalRevision) { |
| File ioFile = CvsVfsUtil.getFileFor(file); |
| try { |
| File storedRevisionFile = new File(ioFile.getParentFile(), ".#" + ioFile.getName() + "." + originalRevision); |
| if (!storedRevisionFile.isFile()) return null; |
| return FileUtil.loadFileBytes(storedRevisionFile); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return null; |
| } |
| } |
| |
| public static boolean haveCachedContent(final VirtualFile file, final String revision) { |
| final File storedRevisionFile = createFromRevisionAndPath(file, revision); |
| return (storedRevisionFile != null) && storedRevisionFile.isFile(); |
| } |
| |
| @Nullable |
| private static File createFromRevisionAndPath(final VirtualFile file, final String revision) { |
| File ioFile = CvsVfsUtil.getFileFor(file); |
| final File parent = new File(getAdminDir(ioFile.getParentFile()), BASE_REVISIONS_DIR); |
| if (! parent.exists()) { |
| if (! parent.mkdirs()) { |
| return null; |
| } |
| } else if (parent.isFile()) { |
| return null; |
| } |
| return new File(parent, ".#" + ioFile.getName() + "." + revision); |
| } |
| |
| private static File getCachedContentFile(final VirtualFile parent, String name, String revision) { |
| final File parentFile = new File(getAdminDir(new File(parent.getPath())), BASE_REVISIONS_DIR); |
| final File storedRevisionFile; |
| if (revision.startsWith("-")) { |
| storedRevisionFile = new File(parentFile, ".#" + name + '.' + revision.substring(1)); |
| } else { |
| storedRevisionFile = new File(parentFile, ".#" + name + '.' + revision); |
| } |
| if ((! storedRevisionFile.exists()) || (! storedRevisionFile.isFile())) return null; |
| return storedRevisionFile; |
| } |
| |
| @Nullable |
| public static byte[] getCachedStoredContent(final VirtualFile parent, final String name, final String revision) { |
| try { |
| File storedRevisionFile = getCachedContentFile(parent, name, revision); |
| if (storedRevisionFile == null) return null; |
| return FileUtil.loadFileBytes(storedRevisionFile); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return null; |
| } |
| } |
| |
| public static boolean restoreFileFromCachedContent(final VirtualFile parent, |
| final String name, |
| final String revision, |
| boolean makeReadOnly) { |
| try { |
| final File cachedContentFile = getCachedContentFile(parent, name, revision); |
| if (cachedContentFile == null) return false; |
| final byte[] content = FileUtil.loadFileBytes(cachedContentFile); |
| final File file = new File(parent.getPath(), name); |
| FileUtil.createIfDoesntExist(file); |
| if (!file.canWrite() && !file.setWritable(true)) return false; |
| FileUtil.writeToFile(file, content); |
| if (makeReadOnly && !file.setWritable(false)) return false; |
| return file.setLastModified(cachedContentFile.lastModified()); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return false; |
| } |
| } |
| |
| public static void storeContentForRevision(final VirtualFile file, final String revision, final byte[] bytes) { |
| final File storedRevisionFile = createFromRevisionAndPath(file, revision); |
| if (storedRevisionFile == null) { |
| return; |
| } |
| // already exists |
| if (storedRevisionFile.isFile()) return; |
| try { |
| FileUtil.writeToFile(storedRevisionFile, bytes); |
| storedRevisionFile.setLastModified(file.getTimeStamp()); |
| } |
| catch (IOException e) { |
| LOG.info(e); |
| } |
| deleteAllOtherRevisions(file, storedRevisionFile.getName()); |
| } |
| |
| private static void deleteAllOtherRevisions(final VirtualFile file, final String storedFilename) { |
| File ioFile = new File(file.getPath()); |
| final Pattern pattern = Pattern.compile("\\\u002E#" + ioFile.getName().replace(".", "\\\u002E") + "\u002E" + REVISION_PATTERN); |
| final File dir = new File(getAdminDir(ioFile.getParentFile()), BASE_REVISIONS_DIR); |
| File[] files = dir.listFiles(new FilenameFilter() { |
| public boolean accept(final File dir, final String name) { |
| return (!storedFilename.equals(name)) && pattern.matcher(name).matches(); |
| } |
| }); |
| if (files != null) { |
| for (File oldFile : files) { |
| oldFile.delete(); |
| } |
| } |
| } |
| |
| public static byte[] getStoredContentForFile(VirtualFile file) { |
| File ioFile = CvsVfsUtil.getFileFor(file); |
| try { |
| File storedRevisionFile = new File(ioFile.getParentFile(), ".#" + ioFile.getName() + "." + getAllRevisionsForFile(file).get(0)); |
| if (!storedRevisionFile.isFile()) return null; |
| return FileUtil.loadFileBytes(storedRevisionFile); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return null; |
| } |
| } |
| |
| public static long getUpToDateDateForFile(VirtualFile file) { |
| try { |
| return Conflicts.readFrom(getConflictsFile(CvsVfsUtil.getFileFor(file))).getPreviousEntryTime(file.getName()); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return -1; |
| } |
| } |
| |
| public static String getOriginalRevisionForFile(VirtualFile file) { |
| try { |
| return Conflicts.readFrom(getConflictsFile(CvsVfsUtil.getFileFor(file))).getOriginalRevisionFor(file.getName()); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return null; |
| } |
| } |
| |
| public static void resolveConflict(VirtualFile vFile) { |
| File file = CvsVfsUtil.getFileFor(vFile); |
| removeConflict(file); |
| |
| EntriesHandler handler = getEntriesHandlerIn(file.getParentFile()); |
| Entries entries = handler.getEntries(); |
| Entry entry = entries.getEntry(file.getName()); |
| if (entry == null) return; |
| long timeStamp = vFile.getTimeStamp(); |
| final Date date = CvsStatusProvider.createDateDiffersTo(timeStamp); |
| entry.parseConflictString(Entry.getLastModifiedDateFormatter().format(date)); |
| entries.addEntry(entry); |
| try { |
| handler.write(getLineSeparator(), CvsApplicationLevelConfiguration.getCharset()); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| } |
| |
| } |
| |
| @Nullable |
| public static String getTemplateFor(FilePath file) { |
| return loadFrom(file.isDirectory() ? file.getIOFile().getParentFile() : file.getIOFile(), TEMPLATE, false); |
| } |
| |
| public static String getRepositoryFor(File file) { |
| String result = loadRepositoryFrom(file); |
| |
| if (result == null) return null; |
| |
| String root = loadRootFrom(file); |
| |
| if (root != null) { |
| final CvsRootParser cvsRootParser = CvsRootParser.valueOf(root, false); |
| String serverRoot = cvsRootParser.REPOSITORY; |
| if (serverRoot != null) { |
| result = getRelativeRepositoryPath(result, serverRoot); |
| } |
| } |
| |
| return result; |
| |
| } |
| |
| public static String getRelativeRepositoryPath(String repository, String serverRoot) { |
| repository = repository.replace(File.separatorChar, '/'); |
| serverRoot = serverRoot.replace(File.separatorChar, '/'); |
| |
| if (repository.startsWith(serverRoot)) { |
| repository = repository.substring(serverRoot.length()); |
| |
| if (repository.startsWith("/")) { |
| repository = repository.substring(1); |
| } |
| |
| } |
| |
| if (repository.startsWith("./")) { |
| repository = repository.substring(2); |
| } |
| |
| return repository; |
| } |
| |
| public static File getCvsLightweightFileForFile(File file) { |
| return new File(getRepositoryFor(file.getParentFile()), file.getName()); |
| } |
| |
| public static List<String> getAllRevisionsForFile(VirtualFile file) { |
| try { |
| return Conflicts.readFrom(getConflictsFile(CvsVfsUtil.getFileFor(file))).getRevisionsFor(file.getName()); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| return null; |
| } |
| |
| } |
| |
| public static void restoreFile(final VirtualFile file) { |
| CvsEntriesManager cvsEntriesManager = CvsEntriesManager.getInstance(); |
| VirtualFile directory = file == null ? null : file.getParent(); |
| LOG.assertTrue(directory != null); |
| CvsInfo cvsInfo = cvsEntriesManager.getCvsInfoFor(directory); |
| Entry entry = cvsInfo.getEntryNamed(file.getName()); |
| LOG.assertTrue(entry != null); |
| String revision = entry.getRevision(); |
| LOG.assertTrue(StringUtil.startsWithChar(revision, '-')); |
| String originalRevision = revision.substring(1); |
| String date = Entry.formatLastModifiedDate(CvsStatusProvider.createDateDiffersTo(file.getTimeStamp())); |
| String kwdSubstitution = entry.getOptions() == null ? "" : entry.getOptions(); |
| String stickyDataString = entry.getStickyData(); |
| Entry newEntry = Entry.createEntryForLine("/" + file.getName() + "/" + originalRevision + "/" + date + "/" + kwdSubstitution + "/" + stickyDataString); |
| try { |
| saveEntryForFile(CvsVfsUtil.getFileFor(file), newEntry); |
| cvsEntriesManager.clearCachedEntriesFor(directory); |
| } |
| |
| catch (final IOException e) { |
| SwingUtilities.invokeLater(new Runnable() { |
| public void run() { |
| Messages.showErrorDialog(CvsBundle.message("message.error.restore.entry", file.getPresentableUrl(), e.getLocalizedMessage()), |
| CvsBundle.message("message.error.restore.entry.title")); |
| } |
| }); |
| } |
| } |
| |
| public static boolean fileExistsInCvs(VirtualFile file) { |
| if (file.isDirectory()) { |
| final VirtualFile child = file.findChild(CVS); |
| if (child != null && child.isDirectory()) return true; |
| } |
| |
| Entry entry = CvsEntriesManager.getInstance().getEntryFor(file); |
| if (entry == null) return false; |
| return !entry.isAddedFile(); |
| } |
| |
| public static boolean fileExistsInCvs(FilePath file) { |
| if (file.isDirectory() && new File(file.getIOFile(), CVS).isDirectory()) return true; |
| Entry entry = CvsEntriesManager.getInstance().getEntryFor(file.getVirtualFileParent(), file.getName()); |
| if (entry == null) return false; |
| return !entry.isAddedFile(); |
| } |
| |
| |
| public static boolean storedVersionExists(final String original, final VirtualFile file) { |
| File ioFile = CvsVfsUtil.getFileFor(file); |
| File storedRevisionFile = new File(ioFile.getParentFile(), ".#" + ioFile.getName() + "." + original); |
| return storedRevisionFile.isFile(); |
| } |
| |
| public static boolean isNonDateTag(final String dirTag) { |
| return dirTag.startsWith(STICKY_BRANCH_TAG_PREFIX) || dirTag.startsWith(STICKY_NON_BRANCH_TAG_PREFIX); |
| } |
| |
| private static interface FileCondition { |
| boolean verify(File file); |
| } |
| |
| private static class ReverseFileCondition implements FileCondition { |
| private final FileCondition myCondition; |
| |
| public ReverseFileCondition(FileCondition condition) { |
| myCondition = condition; |
| } |
| |
| public boolean verify(File file) { |
| return !myCondition.verify(file); |
| } |
| } |
| |
| private static class Conflict { |
| private final String myName; |
| private final List<String> myRevisions; |
| private final long myPreviousTime; |
| private static final String DELIM = ";"; |
| |
| private Conflict(String name, String originalRevision, List<String> revisions, long time) { |
| myName = name; |
| myRevisions = new ArrayList<String>(); |
| myRevisions.add(originalRevision); |
| myRevisions.addAll(revisions); |
| myPreviousTime = time; |
| } |
| |
| private Conflict(String name, List<String> revisions, long time) { |
| myName = name; |
| myRevisions = new ArrayList<String>(); |
| myRevisions.addAll(revisions); |
| myPreviousTime = time; |
| } |
| |
| public String toString() { |
| StringBuffer result = new StringBuffer(); |
| result.append(myName); |
| result.append(DELIM); |
| result.append(String.valueOf(myPreviousTime)); |
| result.append(DELIM); |
| for (int i = 0; i < myRevisions.size(); i++) { |
| if (i > 0) { |
| result.append(DELIM); |
| } |
| result.append(myRevisions.get(i)); |
| } |
| return result.toString(); |
| } |
| |
| public static Conflict readFrom(String line) { |
| try { |
| String[] strings = line.split(DELIM); |
| if (strings.length == 0) return null; |
| String name = strings[0]; |
| long time = strings.length > 1 ? Long.parseLong(strings[1]) : -1; |
| |
| int revisionsSize = strings.length > 2 ? strings.length - 2 : 0; |
| String[] revisions = new String[revisionsSize]; |
| if (revisions.length > 0) { |
| System.arraycopy(strings, 2, revisions, 0, revisions.length); |
| } |
| |
| return new Conflict(name, Arrays.asList(revisions), time); |
| } |
| catch (NumberFormatException e) { |
| return null; |
| } |
| } |
| |
| public String getFileName() { |
| return myName; |
| } |
| |
| public long getPreviousEntryTime() { |
| return myPreviousTime; |
| } |
| |
| public List<String> getRevisions() { |
| return new ArrayList<String>(myRevisions); |
| } |
| |
| public void setOriginalRevision(final String originalRevision) { |
| if (!myRevisions.isEmpty()) myRevisions.remove(0); |
| myRevisions.add(0, originalRevision); |
| } |
| |
| public void setRevisions(final List<String> revisions) { |
| if (myRevisions.isEmpty()) { |
| |
| } else { |
| final String originalRevision = myRevisions.remove(0); |
| myRevisions.clear(); |
| myRevisions.add(originalRevision); |
| myRevisions.addAll(revisions); |
| } |
| } |
| } |
| |
| private static class Conflicts { |
| private final Map<String, Conflict> myNameToConflict = new com.intellij.util.containers.HashMap<String, Conflict>(); |
| |
| @NotNull |
| public static Conflicts readFrom(File file) throws IOException { |
| Conflicts result = new Conflicts(); |
| if (!file.exists()) return result; |
| List<String> lines = CvsFileUtil.readLinesFrom(file); |
| for (final String line : lines) { |
| Conflict conflict = Conflict.readFrom(line); |
| if (conflict != null) { |
| result.addConflict(conflict); |
| } |
| } |
| return result; |
| } |
| |
| |
| public void saveTo(File file) throws IOException { |
| CvsFileUtil.storeLines(getConflictLines(), file); |
| } |
| |
| private List<String> getConflictLines() { |
| ArrayList<String> result = new ArrayList<String>(); |
| for (final Conflict conflict : myNameToConflict.values()) { |
| result.add((conflict).toString()); |
| } |
| return result; |
| } |
| |
| private void addConflict(Conflict conflict) { |
| myNameToConflict.put(conflict.getFileName(), conflict); |
| } |
| |
| public void setRevisionAndDateForFile(String fileName, |
| String originalRevision, |
| List<String> revisions, |
| long time) { |
| if (!myNameToConflict.containsKey(fileName)) { |
| myNameToConflict.put(fileName, new Conflict(fileName, originalRevision, revisions, time)); |
| } |
| myNameToConflict.get(fileName).setOriginalRevision(originalRevision); |
| myNameToConflict.get(fileName).setRevisions(revisions); |
| } |
| |
| public void addConflictForFile(String name) { |
| if (!myNameToConflict.containsKey(name)) { |
| myNameToConflict.put(name, new Conflict(name, "", new ArrayList<String>(), -1)); |
| } |
| } |
| |
| public void removeConflictForFile(String name) { |
| myNameToConflict.remove(name); |
| } |
| |
| public List<String> getRevisionsFor(String name) { |
| if (!myNameToConflict.containsKey(name)) return new ArrayList<String>(); |
| return (myNameToConflict.get(name)).getRevisions(); |
| } |
| |
| public long getPreviousEntryTime(String fileName) { |
| if (!myNameToConflict.containsKey(fileName)) return -1; |
| return (myNameToConflict.get(fileName)).getPreviousEntryTime(); |
| } |
| |
| public String getOriginalRevisionFor(final String name) { |
| if (!myNameToConflict.containsKey(name)) return ""; |
| final List<String> revisions = (myNameToConflict.get(name)).getRevisions(); |
| return revisions.isEmpty() ? "" : revisions.get(0); |
| } |
| } |
| |
| public static CvsConnectionSettings getCvsConnectionSettings(FilePath path){ |
| VirtualFile virtualFile = path.getVirtualFile(); |
| if (virtualFile == null || !path.isDirectory()){ |
| return CvsEntriesManager.getInstance().getCvsConnectionSettingsFor(path.getVirtualFileParent()); |
| } else { |
| return CvsEntriesManager.getInstance().getCvsConnectionSettingsFor(virtualFile); |
| } |
| } |
| |
| } |