/*
* Copyright 2000-2007 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.update;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.ui.SimpleTextAttributes;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class FileGroup implements JDOMExternalizable {
public String myUpdateName;
public String myStatusName;
private final Collection<UpdatedFile> myFiles = new ArrayList<UpdatedFile>();
public boolean mySupportsDeletion;
public boolean myCanBeAbsent;
public String myId;
@NonNls private static final String PATH = "PATH";
@NonNls private static final String VCS_ATTRIBUTE = "vcs";
@NonNls private static final String REVISION_ATTRIBUTE = "revision";
private final List<FileGroup> myChildren = new ArrayList<FileGroup>();
@NonNls private static final String FILE_GROUP_ELEMENT_NAME = "FILE-GROUP";
@NonNls public static final String MODIFIED_ID = "MODIFIED";
@NonNls public static final String MERGED_WITH_CONFLICT_ID = "MERGED_WITH_CONFLICTS";
@NonNls public static final String MERGED_ID = "MERGED";
@NonNls public static final String UNKNOWN_ID = "UNKNOWN";
@NonNls public static final String LOCALLY_ADDED_ID = "LOCALLY_ADDED";
@NonNls public static final String LOCALLY_REMOVED_ID = "LOCALLY_REMOVED";
@NonNls public static final String UPDATED_ID = "UPDATED";
@NonNls public static final String REMOVED_FROM_REPOSITORY_ID = "REMOVED_FROM_REPOSITORY";
@NonNls public static final String CREATED_ID = "CREATED";
@NonNls public static final String RESTORED_ID = "RESTORED";
@NonNls public static final String CHANGED_ON_SERVER_ID = "CHANGED_ON_SERVER";
@NonNls public static final String SKIPPED_ID = "SKIPPED";
/**
* @param updateName - Name for "update" action
* @param statusName - Name for "status action"
* @param supportsDeletion - User can perform delete action for files from the group
* @param id - Using in order to find the group
* @param canBeAbsent - If canBeAbsent == true absent files from the group will not be marked as invalid
*/
public FileGroup(String updateName, String statusName, boolean supportsDeletion, String id, boolean canBeAbsent) {
mySupportsDeletion = supportsDeletion;
myId = id;
myCanBeAbsent = canBeAbsent;
myUpdateName = updateName;
myStatusName = statusName;
}
public FileGroup() {
}
public void addChild(FileGroup child) {
myChildren.add(child);
}
public boolean getSupportsDeletion() {
return mySupportsDeletion;
}
public void add(@NotNull final String path) {
myFiles.add(new UpdatedFile(path));
}
public void add(@NotNull String path, @NotNull AbstractVcs vcs, @NotNull VcsRevisionNumber revision) {
myFiles.add(new UpdatedFile(path, vcs.getName(), revision.asString()));
}
public void remove(String path) {
for(UpdatedFile file: myFiles) {
if (file.getPath().equals(path)) {
myFiles.remove(file);
break;
}
}
}
public Collection<String> getFiles() {
ArrayList<String> files = new ArrayList<String>();
for(UpdatedFile file: myFiles) {
files.add(file.getPath());
}
return files;
}
public List<Pair<String, VcsRevisionNumber>> getFilesAndRevisions(ProjectLevelVcsManager vcsManager) {
ArrayList<Pair<String, VcsRevisionNumber>> files = new ArrayList<Pair<String, VcsRevisionNumber>>();
for(UpdatedFile file: myFiles) {
VcsRevisionNumber number = getRevision(vcsManager, file);
files.add(new Pair<String, VcsRevisionNumber>(file.getPath(), number));
}
return files;
}
public boolean isEmpty() {
if (!myFiles.isEmpty()) return false;
for (FileGroup child : myChildren) {
if (!child.isEmpty()) return false;
}
return true;
}
public SimpleTextAttributes getInvalidAttributes() {
if (myCanBeAbsent) {
return new SimpleTextAttributes(Font.PLAIN, FileStatus.DELETED.getColor());
}
else {
return SimpleTextAttributes.ERROR_ATTRIBUTES;
}
}
public String getId() {
return myId;
}
public void writeExternal(Element element) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, element);
for (final UpdatedFile file : myFiles) {
Element path = new Element(PATH);
path.setText(file.getPath());
if (file.getVcsName() != null) {
path.setAttribute(VCS_ATTRIBUTE, file.getVcsName());
}
if (file.getRevision() != null) {
path.setAttribute(REVISION_ATTRIBUTE, file.getRevision());
}
element.addContent(path);
}
}
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
List pathElements = element.getChildren(PATH);
for (final Object pathElement1 : pathElements) {
Element pathElement = (Element)pathElement1;
final String path = pathElement.getText();
final String vcsName = pathElement.getAttributeValue(VCS_ATTRIBUTE);
final String revision = pathElement.getAttributeValue(REVISION_ATTRIBUTE);
myFiles.add(new UpdatedFile(path, vcsName, revision));
}
}
public List<FileGroup> getChildren() {
return myChildren;
}
public static void writeGroupsToElement(List<FileGroup> groups, Element element) throws WriteExternalException {
for (FileGroup fileGroup : groups) {
Element groupElement = new Element(FILE_GROUP_ELEMENT_NAME);
element.addContent(groupElement);
fileGroup.writeExternal(groupElement);
writeGroupsToElement(fileGroup.getChildren(), groupElement);
}
}
public static void readGroupsFromElement(List<FileGroup> groups, Element element) throws InvalidDataException {
List groupElements = element.getChildren();
for (final Object groupElement1 : groupElements) {
Element groupElement = (Element)groupElement1;
FileGroup fileGroup = new FileGroup();
fileGroup.readExternal(groupElement);
groups.add(fileGroup);
readGroupsFromElement(fileGroup.myChildren, groupElement);
}
}
public String getStatusName() {
return myStatusName;
}
public String getUpdateName() {
return myUpdateName;
}
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return myId + " " + myFiles.size() + " items";
}
@Nullable
public VcsRevisionNumber getRevision(final ProjectLevelVcsManager vcsManager, final String path) {
for(UpdatedFile file: myFiles) {
if (file.getPath().equals(path)) {
return getRevision(vcsManager, file);
}
}
return null;
}
@Nullable
private static VcsRevisionNumber getRevision(final ProjectLevelVcsManager vcsManager, final UpdatedFile file) {
final String vcsName = file.getVcsName();
final String revision = file.getRevision();
if (vcsName != null && revision != null) {
AbstractVcs vcs = vcsManager.findVcsByName(vcsName);
if (vcs != null) {
return vcs.parseRevisionNumber(revision);
}
}
return null;
}
public void setRevisions(final String path, final AbstractVcs vcs, final VcsRevisionNumber revision) {
for(UpdatedFile file: myFiles) {
if (file.getPath().startsWith(path)){
file.setVcsName(vcs.getName());
file.setRevision(revision.asString());
}
}
for(FileGroup group: myChildren) {
group.setRevisions(path, vcs, revision);
}
}
private static class UpdatedFile {
private final String myPath;
private String myVcsName;
private String myRevision;
public UpdatedFile(final String path) {
myPath = path;
}
public UpdatedFile(final String path, final String vcsName, final String revision) {
myPath = path;
myVcsName = vcsName;
myRevision = revision;
}
public String getPath() {
return myPath;
}
public String getVcsName() {
return myVcsName;
}
public void setVcsName(final String vcsName) {
myVcsName = vcsName;
}
public String getRevision() {
return myRevision;
}
public void setRevision(final String revision) {
myRevision = revision;
}
}
}