/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun * Microsystems, Inc. All Rights Reserved. * Portions Copyright 2008 Alexander Coles (Ikonoklastik Productions). * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. */ package org.nbgit; import java.io.File; import java.io.Serializable; import java.util.ResourceBundle; import org.openide.util.NbBundle; /** * Immutable class encapsulating status of a file. * * @author Maros Sandor */ public class StatusInfo implements Serializable { private static final long serialVersionUID = 1L; /** * There is nothing known about the file, it may not even exist. */ public static final int STATUS_UNKNOWN = 0; /** * The file is not managed by the module, i.e. the user does not wish it to be under control of this * versioning system module. All files except files under versioned roots have this status. */ public static final int STATUS_NOTVERSIONED_NOTMANAGED = 1; /** * The file exists locally but is NOT under version control because it should not be (i.e. is has * the Ignore property set or resides under an excluded folder). The file itself IS under a versioned root. */ public static final int STATUS_NOTVERSIONED_EXCLUDED = 2; /** * The file exists locally but is NOT under version control, mostly because it has not been added * to the repository yet. */ public static final int STATUS_NOTVERSIONED_NEWLOCALLY = 4; /** * The file is under version control and is in sync with repository. */ public static final int STATUS_VERSIONED_UPTODATE = 8; /** * The file is modified locally and was not yet modified in repository. */ public static final int STATUS_VERSIONED_MODIFIEDLOCALLY = 16; /** * The file was not modified locally but an updated version exists in repository. */ public static final int STATUS_VERSIONED_MODIFIEDINREPOSITORY = 32; /** * Merging during update resulted in merge conflict. Conflicts in the local copy must be resolved before * the file can be commited. */ public static final int STATUS_VERSIONED_CONFLICT = 64; /** * The file was modified both locally and remotely and these changes may or may not result in * merge conflict. */ public static final int STATUS_VERSIONED_MERGE = 128; /** * The file does NOT exist locally and exists in repository, it has beed removed locally, waits * for commit. */ public static final int STATUS_VERSIONED_REMOVEDLOCALLY = 256; /** * The file does NOT exist locally but exists in repository and has not yet been downloaded. */ public static final int STATUS_VERSIONED_NEWINREPOSITORY = 512; /** * The file has been removed from repository. */ public static final int STATUS_VERSIONED_REMOVEDINREPOSITORY = 1024; /** * The file does NOT exist locally and exists in repository, it has beed removed locally. */ public static final int STATUS_VERSIONED_DELETEDLOCALLY = 2048; /** * The file exists locally and has beed scheduled for addition to repository. This status represents * state after the 'add' command. */ public static final int STATUS_VERSIONED_ADDEDLOCALLY = 4096; public static final int STATUS_VERSIONED_COPIEDLOCALLY = 8192; public static final int STATUS_ALL = ~0; /** * All statuses except <tt>STATUS_NOTVERSIONED_NOTMANAGED</tt> * * <p>Note: it covers ignored files. */ public static final int STATUS_MANAGED = StatusInfo.STATUS_ALL & ~StatusInfo.STATUS_NOTVERSIONED_NOTMANAGED; public static final int STATUS_VERSIONED = StatusInfo.STATUS_VERSIONED_UPTODATE | StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY | StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY | StatusInfo.STATUS_VERSIONED_CONFLICT | StatusInfo.STATUS_VERSIONED_MERGE | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY | StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY | StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY | StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY; public static final int STATUS_IN_REPOSITORY = StatusInfo.STATUS_VERSIONED_UPTODATE | StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY | StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY | StatusInfo.STATUS_VERSIONED_CONFLICT | StatusInfo.STATUS_VERSIONED_MERGE | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY | StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY | StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY | StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY; public static final int STATUS_LOCAL_CHANGE = StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY | StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY | StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY | StatusInfo.STATUS_VERSIONED_CONFLICT | StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_MERGE | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY | StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY; /** * Modified, in conflict, scheduled for removal or addition; * or deleted but with existing entry record. */ public static final int STATUS_REVERTIBLE_CHANGE = StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY | StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY | StatusInfo.STATUS_VERSIONED_CONFLICT | StatusInfo.STATUS_VERSIONED_MERGE | StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY | StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY | StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY; public static final int STATUS_REMOTE_CHANGE = StatusInfo.STATUS_VERSIONED_MERGE | StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY | StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY | StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY; /** * Status constant. */ private final int status; /** * More detailed information about a file, you may disregard the field if not needed. */ private transient File entry; /** * Directory indicator, mainly because of files that may have been deleted so file.isDirectory() won't work. */ private final boolean isDirectory; /** * For deserialization purposes only. */ public StatusInfo() { status = 0; isDirectory = false; } public StatusInfo(int status, File entry, boolean isDirectory) { this.status = status; this.entry = entry; this.isDirectory = isDirectory; } StatusInfo(int status, boolean isDirectory) { this(status, null, isDirectory); } /** * Retrieves the status constant representing status of the file. * * @return one of status constants */ public int getStatus() { return status; } public boolean isDirectory() { return isDirectory; } /** * Retrieves file's Status. * * @param file file this information belongs to or null if you do not want the entry to be read from disk * in case it is not loaded yet * @return Status parsed entry form the .svn/entries file or null if the file does not exist, * is not versioned or its entry is invalid */ public File getStatus(File file) { if (entry == null && file != null) { readEntry(file); } return entry; } private void readEntry(File file) { // Fetches File info from .svn directory: // entry = Subversion.getInstance().getClient(true).getSingleStatus(file); entry = null; // TODO: read your detailed information about the file here, or disregard the entry field } /** * Returns localized text representation of status. * * @return status name, for multistatuses prefers local * status name. */ public String getStatusText() { return getStatusText(~0); } /** * Returns localized text representation of status. * * @param displayStatuses statuses bitmask * * @return status name, for multistatuses prefers local * status name, for masked <tt>""</tt>. // NOI18N */ public String getStatusText(int displayStatuses) { int stat = this.status & displayStatuses; ResourceBundle loc = NbBundle.getBundle(StatusInfo.class); if (stat == StatusInfo.STATUS_UNKNOWN) { return loc.getString("CTL_FileInfoStatus_Unknown"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)) { return loc.getString("CTL_FileInfoStatus_Excluded"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY)) { return loc.getString("CTL_FileInfoStatus_NewLocally"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) /* FIXME if (entry != null && entry.isCopied()) return loc.getString("CTL_FileInfoStatus_AddedLocallyCopied"); */ { return loc.getString("CTL_FileInfoStatus_AddedLocally"); // NOI18N } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY)) { return loc.getString("CTL_FileInfoStatus_AddedLocallyCopied"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_UPTODATE)) { return loc.getString("CTL_FileInfoStatus_UpToDate"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_CONFLICT)) { return loc.getString("CTL_FileInfoStatus_Conflict"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MERGE)) { return loc.getString("CTL_FileInfoStatus_Merge"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY)) { return loc.getString("CTL_FileInfoStatus_DeletedLocally"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY)) { return loc.getString("CTL_FileInfoStatus_RemovedLocally"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY)) { return loc.getString("CTL_FileInfoStatus_ModifiedLocally"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_NEWINREPOSITORY)) { return loc.getString("CTL_FileInfoStatus_NewInRepository"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_MODIFIEDINREPOSITORY)) { return loc.getString("CTL_FileInfoStatus_ModifiedInRepository"); } else if (StatusInfo.match(stat, StatusInfo.STATUS_VERSIONED_REMOVEDINREPOSITORY)) { return loc.getString("CTL_FileInfoStatus_RemovedInRepository"); } else { return ""; } } /** * @return short status name for local changes, for remote * changes returns <tt>""</tt> // NOI18N */ public String getShortStatusText() { ResourceBundle loc = NbBundle.getBundle(StatusInfo.class); if (StatusInfo.match(status, StatusInfo.STATUS_NOTVERSIONED_EXCLUDED)) { return loc.getString("CTL_FileInfoStatus_Excluded_Short"); } else if (StatusInfo.match(status, StatusInfo.STATUS_NOTVERSIONED_NEWLOCALLY)) { return loc.getString("CTL_FileInfoStatus_NewLocally_Short"); } else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_ADDEDLOCALLY)) /* { if (entry != null && entry.isCopied()) return loc.getString("CTL_FileInfoStatus_AddedLocallyCopied_Short"); */ { return loc.getString("CTL_FileInfoStatus_AddedLocally_Short"); // NOI18N } else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_COPIEDLOCALLY)) { return loc.getString("CTL_FileInfoStatus_AddedLocallyCopied_Short"); } else if (status == StatusInfo.STATUS_VERSIONED_REMOVEDLOCALLY) { return loc.getString("CTL_FileInfoStatus_RemovedLocally_Short"); } else if (status == StatusInfo.STATUS_VERSIONED_DELETEDLOCALLY) { return loc.getString("CTL_FileInfoStatus_DeletedLocally_Short"); } else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_MODIFIEDLOCALLY)) { return loc.getString("CTL_FileInfoStatus_ModifiedLocally_Short"); } else if (StatusInfo.match(status, StatusInfo.STATUS_VERSIONED_CONFLICT)) { return loc.getString("CTL_FileInfoStatus_Conflict_Short"); } else { return ""; } } private static boolean match(int status, int mask) { return (status & mask) != 0; } /** * Two StatusInfo objects are equivalent if their status contants are equal AND they both reperesent a file (or * both represent a directory) AND Entries they cache, if they can be compared, are equal. * * @param other object to compare to * @return true if status constants of both object are equal, false otherwise */ public static boolean equivalent(StatusInfo main, StatusInfo other) { if (other == null || main.getStatus() != other.getStatus() || main.isDirectory() != other.isDirectory()) { return false; } File e1 = main.getStatus(null); File e2 = other.getStatus(null); return e1 == e2 || e1 == null || e2 == null || equal(e1, e2); } /** * Replacement for missing Entry.equals(). It is implemented as a separate method to maintain compatibility. * * @param e1 first entry to compare * @param e2 second Entry to compare * @return true if supplied entries contain equivalent information */ private static boolean equal(File e1, File e2) { // TODO: use your own logic here return true; } @Override public String toString() { return "Text: " + status + " " + getStatusText(status); // NOI18N } }