./codecover/src/org/codecover/eclipse/tscmanager/TSContainerInfo.java

package org.codecover.eclipse.tscmanager;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.codecover.model.TestCase;
import org.codecover.model.utils.CollectionUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;

/**
 * Represents a known test session container to save memory, only the location of its file, its ID, and its
 * date are saved.
 * 

* In the documentation of this class the term represented test session * container is used for a * TestSessionContainer which is represented by an object of this class. */ public class TSContainerInfo implements TSContainerHandle { /** * File of the TestSessionContainer represented by this object. Its path is used as the * unique identifier for this object and the corresponding TestSessionContainer. */ private IFile file; /** * The ID of the represented test session container. */ private final String id; /** * The date of the represented test session container. */ private final Date date; /** * The name of this represented test session container, which is unique during a session of Eclipse. */ private final String name; /** * List of active TestCases as TestCaseInfos. */ private List activeTestCases; private List redundantTestCases; /** * true if the represented test session container is synchronized with its IFile, * false if there are unsaved changes */ private boolean sync; private final TSContainerInfoListenerHandler listenerHandler; private final Object lockTestCases; private final Object lockFile; /** * Constructs a TSContainerInfo-representation of a test session container with the given * ID, date and name and which is contained in the given file. * * @param file the file the represented test session container is stored in * @param id the ID of the represented test session container * @param date the date of the represented test session container * @param name the name of the represented test session container */ TSContainerInfo(IFile file, String id, Date date, String name) { if (file == null) { throw new NullPointerException("file mustn't be null");//$NON-NLS-1$ } if (id == null) { throw new NullPointerException("id mustn't be null"); //$NON-NLS-1$ } if (date == null) { throw new NullPointerException("date mustn't be null");//$NON-NLS-1$ } if (name == null) { throw new NullPointerException("name mustn't be null");//$NON-NLS-1$ } this.lockTestCases = new Object(); this.lockFile = new Object(); this.file = file; this.id = new String(id); this.date = (Date) date.clone(); this.name = name; this.activeTestCases = new LinkedList(); this.sync = true; this.listenerHandler = new TSContainerInfoListenerHandler(this); } void setFile(IFile file) { if (file == null) { throw new NullPointerException("file mustn't be null");//$NON-NLS-1$ } synchronized (this.lockFile) { if (!file.getFullPath().equals(this.file.getFullPath())) { throw new IllegalArgumentException("file must have the same path"); //$NON-NLS-1$ } this.file = file; } } /** * Stores the given (active) test cases represented as a list of TestCaseInfos. * * @param testCases the test cases to save */ void setActiveTestCases(Set testCases) { this.setActiveTestCases(TestCaseInfo.generateTestCaseInfos(testCases)); } void setActiveTestCases(List testCaseInfos) { if (testCaseInfos == null) { throw new NullPointerException("testCaseInfos mustn't be null"); //$NON-NLS-1$ } synchronized (this.lockTestCases) { this.activeTestCases = new LinkedList(testCaseInfos); } } /** * Stores the given (redundant) test cases represented as a list of TestCaseInfos. * * @param testCases the test cases to save */ void setRedundantTestCases(Set RedundantTestCases) { this.setRedundantTestCases(TestCaseInfo.generateTestCaseInfos(RedundantTestCases)); } void setRedundantTestCases(List testCaseInfos) { if (testCaseInfos == null) { throw new NullPointerException("testCaseInfos mustn't be null"); //$NON-NLS-1$ } synchronized (this.lockTestCases) { this.activeTestCases = new LinkedList(testCaseInfos); } } /** * Removes/Deactivates the given active test case. If the given test case isn't active, nothing is changed. * * @param tcInfo the TestCaseInfo-representation of the active test cases to * remove/deactivate */ void removeActiveTestCase(TestCaseInfo tcInfo) { synchronized (this.lockTestCases) { this.activeTestCases.remove(tcInfo); } } /** * Removes/Deactivates the given redundant test case. If the given test case isn't active, nothing is * changed. * * @param tcInfo the TestCaseInfo-representation of the redundant test cases to * remove/deactivate */ void removeRedundantTestCase(TestCaseInfo tcInfo) { synchronized (this.lockTestCases) { this.redundantTestCases.remove(tcInfo); } } /** * Sets whether the represented test session container is in sync with its file in the workspace. * * @param sync true if the represented test session container is synchronized with its * IFile, false if there are unsaved changes */ void setSynchronized(boolean sync) { this.sync = sync; this.listenerHandler.fireSynchronizedStateChanged(sync); } /** * Adds the given listener to receive events from the associated TSContainerInfo. * * @param listener the listener * @throws NullPointerException if the specified listener is null */ void addListener(TSContainerInfoListener listener) { this.listenerHandler.addListener(listener); } /** * Removes the given listener so that it no longer receives events from the associated * TSContainerInfo. * * @param listener the listener */ void removeListener(TSContainerInfoListener listener) { this.listenerHandler.removeListener(listener); } /** * Returns the file of the represented test session container. * * @return the file of the represented test session container */ public IFile getFile() { synchronized (this.lockFile) { return this.file; } } /** * Returns the ID of the represented test session container, do not use this ID as a unique * identifier for this representation of a test session container or for the represented test session * container itself, because the same test session container can appear twice in the workspace (e.g., if the * user imported it two times). * * @return the ID of the represented test session container */ public String getId() { return this.id; } /** * Returns the date of the represented test session container. * * @return the date of the represented test session container */ public Date getDate() { return this.date; } /** * Returns the path of the file of the represented test session container relative to the containing * workspace. This path is used as the unique identifier of this representation of a test session container * and the represented test session container itself. * * @return the path of the file of the represented test session container. */ public IPath getPath() { synchronized (this.lockFile) { return this.file.getFullPath(); } } /** * Returns the name of the represented test session container. This name doesn't have to be unique. Use the * path of the file ({@link #getPath()}), if you need a unique identifier for the represented test session * container or this representation of a test session container. * * @return the name of the represented test session container */ public String getName() { return this.name; } /** * Returns the project the represented test session container belongs to. * * @return the project the represented test session container belongs to. */ public IProject getProject() { synchronized (this.lockFile) { return this.file.getProject(); } } /** * Returns the active test cases represented by an immutable copy of the list of TestCaseInfos. * * @return the active test cases represented by a list of TestCaseInfos. */ List getActiveTestCases() { synchronized (this.lockTestCases) { return CollectionUtil.copy(this.activeTestCases); } } /** * Returns the redundant test cases represented by an immutable copy of the list of * TestCaseInfos. * * @return the redundant test cases represented by a list of TestCaseInfos. */ List getRedundantTestCases() { synchronized (this.lockTestCases) { return CollectionUtil.copy(this.redundantTestCases); } } @Override public String toString() { return String.format("%s (%2$td.%2$tm.%2$tY %2$tH:%2$tM:%2$tS)", //$NON-NLS-1$ this.getId(), this.getDate()); } /** * Returns whether the represented test session container is in sync with its file in the workspace. * * @return true if the represented test session container is synchronized with its * IFile, false if there are unsaved changes */ public boolean isSynchronized() { return this.sync; } /** * Returns whether this TSContainerInfo equals the given object. *

* This TSContainerInfo is equal to the given object if the given object is a * TSContainerHandle and both have the same path ({@link #getPath()}). See * {@link IPath#equals(Object)} for equality of paths. * * @param o the object to compare to * @return the comparison result */ @Override public boolean equals(Object o) { if (o != null && o instanceof TSContainerHandle && ((TSContainerHandle) o).getPath().equals(this.getPath())) { return true; } else { return false; } } @Override public int hashCode() { return this.getPath().toString().hashCode(); } /** * Compares this object with the given represented test session container by the name of the project they * belong to, by their dates and by their names. */ public int compareTo(TSContainerHandle tscHandle) { int cProjectName, cDate; if ((cProjectName = this.getProject().getName().compareTo(tscHandle.getProject().getName())) != 0) { return cProjectName; } else if ((cDate = this.getDate().compareTo(tscHandle.getDate())) != 0) { return cDate; } else { return this.getName().compareTo(tscHandle.getName()); } } }