001: /*
002: * ====================================================================
003: * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
004: *
005: * This software is licensed as described in the file COPYING, which
006: * you should have received as part of this distribution. The terms
007: * are also available at http://svnkit.com/license.html.
008: * If newer versions of this license are posted there, you may use a
009: * newer version instead, at your option.
010: * ====================================================================
011: */
012: package org.tmatesoft.svn.core.internal.io.fs;
013:
014: import java.io.IOException;
015: import java.io.InputStream;
016: import java.io.OutputStream;
017: import java.util.Collection;
018: import java.util.Collections;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.LinkedList;
022: import java.util.Map;
023:
024: import org.tmatesoft.svn.core.SVNErrorCode;
025: import org.tmatesoft.svn.core.SVNErrorMessage;
026: import org.tmatesoft.svn.core.SVNException;
027: import org.tmatesoft.svn.core.SVNNodeKind;
028: import org.tmatesoft.svn.core.internal.wc.ISVNCommitPathHandler;
029: import org.tmatesoft.svn.core.internal.wc.SVNCommitUtil;
030: import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
031: import org.tmatesoft.svn.core.io.ISVNEditor;
032:
033: /**
034: * @version 1.1.1
035: * @author TMate Software Ltd.
036: */
037: public class FSRepositoryUtil {
038:
039: public static void replay(FSFS fsfs, FSRoot root, String basePath,
040: long lowRevision, boolean sendDeltas, ISVNEditor editor)
041: throws SVNException {
042: Map fsChanges = root.getChangedPaths();
043: basePath = basePath.startsWith("/") ? basePath.substring(1)
044: : basePath;
045: Collection interestingPaths = new LinkedList();
046: Map changedPaths = new HashMap();
047: for (Iterator paths = fsChanges.keySet().iterator(); paths
048: .hasNext();) {
049: String path = (String) paths.next();
050: FSPathChange change = (FSPathChange) fsChanges.get(path);
051:
052: path = path.startsWith("/") ? path.substring(1) : path;
053: if ("".equals(basePath)
054: || (path.startsWith(basePath) && (path
055: .charAt(basePath.length()) == '/' || path
056: .length() == basePath.length()))) {
057: path = path.startsWith("/") ? path.substring(1) : path;
058: interestingPaths.add(path);
059: changedPaths.put(path, change);
060: }
061: }
062: if (FSRepository.isInvalidRevision(lowRevision)) {
063: lowRevision = 0;
064: }
065:
066: FSRoot compareRoot = null;
067: if (sendDeltas) {
068: long revision = -1;
069: if (root instanceof FSRevisionRoot) {
070: FSRevisionRoot revRoot = (FSRevisionRoot) root;
071: revision = revRoot.getRevision() - 1;
072: } else if (root instanceof FSTransactionRoot) {
073: FSTransactionRoot txnRoot = (FSTransactionRoot) root;
074: revision = txnRoot.getTxn().getBaseRevision();
075: }
076: compareRoot = fsfs.createRevisionRoot(revision);
077: }
078:
079: if (root instanceof FSRevisionRoot) {
080: FSRevisionRoot revRoot = (FSRevisionRoot) root;
081: editor.targetRevision(revRoot.getRevision());
082: }
083:
084: ISVNCommitPathHandler handler = new FSReplayPathHandler(fsfs,
085: root, compareRoot, changedPaths, basePath, lowRevision);
086: SVNCommitUtil.driveCommitEditor(handler, interestingPaths,
087: editor, -1);
088: }
089:
090: public static void copy(InputStream src, OutputStream dst)
091: throws SVNException {
092: try {
093: byte[] buffer = new byte[102400];
094: while (true) {
095: int length = src.read(buffer);
096: if (length > 0) {
097: dst.write(buffer, 0, length);
098: }
099: if (length != 102400) {
100: break;
101: }
102: }
103: } catch (IOException ioe) {
104: SVNErrorMessage err = SVNErrorMessage.create(
105: SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
106: SVNErrorManager.error(err, ioe);
107: }
108: }
109:
110: public static boolean arePropertiesEqual(FSRevisionNode revNode1,
111: FSRevisionNode revNode2) {
112: return areRepresentationsEqual(revNode1, revNode2, true);
113: }
114:
115: public static boolean arePropertiesChanged(FSRoot root1,
116: String path1, FSRoot root2, String path2)
117: throws SVNException {
118: FSRevisionNode node1 = root1.getRevisionNode(path1);
119: FSRevisionNode node2 = root2.getRevisionNode(path2);
120: return !areRepresentationsEqual(node1, node2, true);
121: }
122:
123: public static boolean areFileContentsChanged(FSRoot root1,
124: String path1, FSRoot root2, String path2)
125: throws SVNException {
126: if (root1.checkNodeKind(path1) != SVNNodeKind.FILE) {
127: SVNErrorMessage err = SVNErrorMessage.create(
128: SVNErrorCode.FS_GENERAL, "''{0}'' is not a file",
129: path1);
130: SVNErrorManager.error(err);
131: }
132: if (root2.checkNodeKind(path2) != SVNNodeKind.FILE) {
133: SVNErrorMessage err = SVNErrorMessage.create(
134: SVNErrorCode.FS_GENERAL, "''{0}'' is not a file",
135: path2);
136: SVNErrorManager.error(err);
137: }
138: FSRevisionNode revNode1 = root1.getRevisionNode(path1);
139: FSRevisionNode revNode2 = root2.getRevisionNode(path2);
140: return !areRepresentationsEqual(revNode1, revNode2, false);
141: }
142:
143: public static Map getPropsDiffs(Map sourceProps, Map targetProps) {
144: Map result = new HashMap();
145:
146: if (sourceProps == null) {
147: sourceProps = Collections.EMPTY_MAP;
148: }
149:
150: if (targetProps == null) {
151: targetProps = Collections.EMPTY_MAP;
152: }
153:
154: for (Iterator names = sourceProps.keySet().iterator(); names
155: .hasNext();) {
156: String propName = (String) names.next();
157: String srcPropVal = (String) sourceProps.get(propName);
158: String targetPropVal = (String) targetProps.get(propName);
159:
160: if (targetPropVal == null) {
161: result.put(propName, null);
162: } else if (!targetPropVal.equals(srcPropVal)) {
163: result.put(propName, targetPropVal);
164: }
165: }
166:
167: for (Iterator names = targetProps.keySet().iterator(); names
168: .hasNext();) {
169: String propName = (String) names.next();
170: String targetPropVal = (String) targetProps.get(propName);
171: if (sourceProps.get(propName) == null) {
172: result.put(propName, targetPropVal);
173: }
174: }
175:
176: return result;
177: }
178:
179: private static boolean areRepresentationsEqual(
180: FSRevisionNode revNode1, FSRevisionNode revNode2,
181: boolean forProperties) {
182: if (revNode1 == revNode2) {
183: return true;
184: } else if (revNode1 == null || revNode2 == null) {
185: return false;
186: }
187: return FSRepresentation.compareRepresentations(
188: forProperties ? revNode1.getPropsRepresentation()
189: : revNode1.getTextRepresentation(),
190: forProperties ? revNode2.getPropsRepresentation()
191: : revNode2.getTextRepresentation());
192: }
193:
194: }
|