/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.wc;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.internal.util.SVNHashMap;
import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
/**
* The <b>SVNCommitPacket</b> is a storage for <b>SVNCommitItem</b>
* objects which represent information on versioned items intended
* for being committed to a repository.
*
* <p>
* Used by {@link SVNCommitClient} to collect and hold information on paths that are to be committed.
* Each <code>SVNCommitPacket</code> is committed in a single transaction.
*
* @version 1.3
* @author TMate Software Ltd.
* @since 1.2
* @see SVNCommitItem
*/
public class SVNCommitPacket {
/**
* This constant denotes an empty commit items storage (contains no
* {@link SVNCommitItem} objects).
*/
public static final SVNCommitPacket EMPTY = new SVNCommitPacket((SVNWCAccess)null, new SVNCommitItem[0], null);
private SVNCommitItem[] myCommitItems;
private Map myLockTokens;
private boolean[] myIsSkipped;
private boolean myIsDisposed;
public SVNCommitPacket(SVNWCAccess wcAccess, SVNCommitItem[] items, Map lockTokens) {
myCommitItems = items;
myLockTokens = lockTokens;
myIsSkipped = new boolean[items == null ? 0 : items.length];
myIsDisposed = false;
if (wcAccess != null) {
for (int i = 0; i < items.length; i++) {
if (items[i].getWCAccess() == null) {
items[i].setWCAccess(wcAccess);
}
}
}
}
/**
* Gets an array of <b>SVNCommitItem</b> objects stored in this
* object.
*
* @return an array of <b>SVNCommitItem</b> objects containing
* info of versioned items to be committed
*/
public SVNCommitItem[] getCommitItems() {
return myCommitItems;
}
/**
* Sets or unsets a versioned item to be skipped -
* whether or not it should be committed.
*
*
* @param item an item that should be marked skipped
* @param skipped if <span class="javakeyword">true</span> the item is
* set to be skipped (a commit operation should skip
* the item), otherwise - unskipped if it was
* previously marked skipped
* @see #isCommitItemSkipped(SVNCommitItem)
*
*/
public void setCommitItemSkipped(SVNCommitItem item, boolean skipped) {
int index = getItemIndex(item);
if (index >= 0 && index < myIsSkipped.length) {
myIsSkipped[index] = skipped;
}
}
/**
* Determines if an item intended for a commit is set to
* be skipped - that is not to be committed.
*
* @param item an item to check
* @return <span class="javakeyword">true</span> if the item
* is set to be skipped, otherwise <span class="javakeyword">false</span>
* @see #setCommitItemSkipped(SVNCommitItem, boolean)
*/
public boolean isCommitItemSkipped(SVNCommitItem item) {
int index = getItemIndex(item);
if (index >= 0 && index < myIsSkipped.length) {
return myIsSkipped[index];
}
return true;
}
/**
* Determines if this object is disposed.
*
* @return <span class="javakeyword">true</span> if disposed
* otherwise <span class="javakeyword">false</span>
*/
public boolean isDisposed() {
return myIsDisposed;
}
/**
* Disposes the current object.
*
* @throws SVNException
*/
public void dispose() throws SVNException {
try {
for (int i = 0; i < myCommitItems.length; i++) {
if (myCommitItems[i] != null && myCommitItems[i].getWCAccess() != null) {
myCommitItems[i].getWCAccess().close();
}
}
} finally {
myIsDisposed = true;
}
}
private int getItemIndex(SVNCommitItem item) {
for (int i = 0; myCommitItems != null && i < myCommitItems.length; i++) {
SVNCommitItem commitItem = myCommitItems[i];
if (commitItem == item) {
return i;
}
}
return -1;
}
public Map getLockTokens() {
return myLockTokens;
}
public SVNCommitPacket removeSkippedItems() {
if (this == EMPTY) {
return EMPTY;
}
Collection items = new ArrayList();
Map lockTokens = getLockTokens() == null ? null : new SVNHashMap(getLockTokens());
SVNCommitItem[] filteredItems = filterSkippedItemsAndLockTokens(items, lockTokens);
return new SVNCommitPacket(null, filteredItems, lockTokens);
}
/**
* Gives a string representation of this object.
*
* @return a string representing this object.
*/
public String toString() {
if (EMPTY == this) {
return "[EMPTY]";
}
StringBuffer result = new StringBuffer();
result.append("SVNCommitPacket: ");
for (int i = 0; i < myCommitItems.length; i++) {
SVNCommitItem commitItem = myCommitItems[i];
result.append("\n");
if (commitItem.isAdded()) {
result.append("A");
} else if (commitItem.isDeleted()) {
result.append("D");
} else if (commitItem.isContentsModified()) {
result.append("M");
} else {
result.append("_");
}
if (commitItem.isPropertiesModified()) {
result.append("M");
} else {
result.append(" ");
}
result.append(" ");
if (commitItem.getPath() != null) {
result.append(commitItem.getPath());
result.append(" ");
}
result.append(commitItem.getFile().getAbsolutePath());
result.append("\n");
result.append(commitItem.getRevision());
result.append(" ");
result.append(commitItem.getURL());
if (commitItem.isCopied()) {
result.append("\n");
result.append("+");
result.append(commitItem.getCopyFromURL());
}
if (commitItem.isLocked()) {
result.append("\n");
result.append("LOCKED");
}
}
return result.toString();
}
protected SVNCommitItem[] filterSkippedItemsAndLockTokens(Collection<SVNCommitItem> items, Map<String, ?> lockTokens) {
for (int i = 0; myCommitItems != null && i < myCommitItems.length; i++) {
SVNCommitItem commitItem = myCommitItems[i];
if (!myIsSkipped[i]) {
items.add(commitItem);
} else if (lockTokens != null) {
lockTokens.remove(commitItem.getURL().toString());
}
}
return (SVNCommitItem[]) items.toArray(new SVNCommitItem[items.size()]);
}
}