package org.nightlabs.jfire.personrelation.issuetracking.trade.ui.tree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jdo.FetchPlan;
import javax.jdo.JDOHelper;
import org.apache.log4j.Logger;
import org.nightlabs.jdo.NLJDOHelper;
import org.nightlabs.jdo.ObjectID;
import org.nightlabs.jfire.issue.Issue;
import org.nightlabs.jfire.issue.IssueComment;
import org.nightlabs.jfire.issue.IssueDescription;
import org.nightlabs.jfire.issue.IssueLink;
import org.nightlabs.jfire.issue.dao.IssueCommentDAO;
import org.nightlabs.jfire.issue.dao.IssueDAO;
import org.nightlabs.jfire.issue.dao.IssueLinkDAO;
import org.nightlabs.jfire.issue.id.IssueCommentID;
import org.nightlabs.jfire.issue.id.IssueDescriptionID;
import org.nightlabs.jfire.issue.id.IssueID;
import org.nightlabs.jfire.issue.id.IssueLinkID;
import org.nightlabs.jfire.jdo.notification.TreeNodeMultiParentResolver;
import org.nightlabs.jfire.personrelation.PersonRelation;
import org.nightlabs.jfire.personrelation.dao.PersonRelationDAO;
import org.nightlabs.jfire.personrelation.id.PersonRelationID;
import org.nightlabs.jfire.personrelation.issuetracking.PersonRelationIssueParentResolver;
import org.nightlabs.jfire.personrelation.issuetracking.trade.ui.resource.Messages;
import org.nightlabs.jfire.personrelation.ui.tree.AbstractPersonRelationTreeControllerDelegate;
import org.nightlabs.jfire.personrelation.ui.tree.PersonRelationTreeNode;
import org.nightlabs.jfire.prop.id.PropertySetID;
import org.nightlabs.progress.NullProgressMonitor;
import org.nightlabs.progress.ProgressMonitor;
import org.nightlabs.progress.SubProgressMonitor;
public class IssuePersonRelationTreeControllerDelegate extends AbstractPersonRelationTreeControllerDelegate
{
private static final Logger logger = Logger.getLogger(IssuePersonRelationTreeControllerDelegate.class);
public static final String[] FETCH_GROUPS_ISSUE_LINK = {
FetchPlan.DEFAULT,
IssueLink.FETCH_GROUP_LINKED_OBJECT_CLASS,
IssueLink.FETCH_GROUP_ISSUE,
Issue.FETCH_GROUP_SUBJECT,
};
public static final String[] FETCH_GROUPS_ISSUE_COMMENT = {
FetchPlan.DEFAULT,
IssueComment.FETCH_GROUP_USER,
IssueComment.FETCH_GROUP_ISSUE_ID, // used for the TreeNodeMultiParentResolver
};
public static final String[] FETCH_GROUPS_ISSUE_DESCRIPTION_ISSUE = {
FetchPlan.DEFAULT,
Issue.FETCH_GROUP_DESCRIPTION,
};
@Override
public Map<ObjectID, Long> retrieveChildCount(Set<? extends PersonRelationTreeNode> parentNodes, Set<ObjectID> parentIDs, ProgressMonitor monitor) {
if (logger.isDebugEnabled()) {
logger.debug("retrieveChildCount: entered with " + parentIDs.size() + " parentIDs."); //$NON-NLS-1$ //$NON-NLS-2$
if (logger.isTraceEnabled()) {
for (ObjectID parentID : parentIDs) {
logger.trace("retrieveChildCount: * " + parentID); //$NON-NLS-1$
}
}
}
monitor.beginTask(Messages.getString("org.nightlabs.jfire.personrelation.issuetracking.trade.ui.tree.IssuePersonRelationTreeControllerDelegate.task.loadingLinkedIssueCountsForPersons.name"), 150); //$NON-NLS-1$
try {
Set<PropertySetID> personIDs = null;
Set<PersonRelationID> personRelationIDs = null;
Set<IssueLinkID> issueLinkIDs = null;
Map<ObjectID, Long> result = new HashMap<ObjectID, Long>(parentIDs.size());
for (ObjectID objectID : parentIDs) {
if (objectID instanceof PropertySetID) {
if (personIDs == null)
personIDs = new HashSet<PropertySetID>();
personIDs.add((PropertySetID) objectID);
}
else if (objectID instanceof PersonRelationID) {
if (personRelationIDs == null)
personRelationIDs = new HashSet<PersonRelationID>();
personRelationIDs.add((PersonRelationID) objectID);
}
else if (objectID instanceof IssueLinkID) {
if (issueLinkIDs == null)
issueLinkIDs = new HashSet<IssueLinkID>();
issueLinkIDs.add((IssueLinkID) objectID);
}
else if (objectID instanceof IssueDescriptionID) {
result.put(objectID, 0L);
}
else if (objectID instanceof IssueCommentID) {
result.put(objectID, 0L);
}
}
if (issueLinkIDs != null) {
Map<IssueLinkID, Long> counts = IssueCommentDAO.sharedInstance().getIssueCommentCountsOfIssueOfIssueLinks(issueLinkIDs, new SubProgressMonitor(monitor, 50));
for (Map.Entry<IssueLinkID, Long> me : counts.entrySet()) {
result.put(me.getKey(), me.getValue() + 1); // add 1 for the description
}
}
else
monitor.worked(50);
if (personIDs != null) {
Map<ObjectID, Long> issueLinkCounts = IssueLinkDAO.sharedInstance().getIssueLinkCounts(personIDs, new SubProgressMonitor(monitor, 50));
result.putAll(issueLinkCounts);
}
else
monitor.worked(50);
personIDs = null; // not used below => give the gc the possibility to collect it.
if (personRelationIDs != null) {
Set<PropertySetID> pIDs = new HashSet<PropertySetID>();
// TODO maybe we should start a backend project to optimize this?! Marco.
Collection<? extends PersonRelation> personRelations = PersonRelationDAO.sharedInstance().getPersonRelations(
personRelationIDs,
new String[] { FetchPlan.DEFAULT, PersonRelation.FETCH_GROUP_TO_ID },
NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT,
new SubProgressMonitor(monitor, 50)
);
Map<PropertySetID, List<PersonRelationID>> personID2personRelationIDs = new HashMap<PropertySetID, List<PersonRelationID>>();
for (PersonRelation personRelation : personRelations) {
PersonRelationID personRelationID = (PersonRelationID) JDOHelper.getObjectId(personRelation);
PropertySetID personID = personRelation.getToID();
pIDs.add(personID);
List<PersonRelationID> l = personID2personRelationIDs.get(personID);
if (l == null) {
l = new ArrayList<PersonRelationID>();
personID2personRelationIDs.put(personID, l);
}
l.add(personRelationID);
}
Map<ObjectID, Long> issueLinkCounts = IssueLinkDAO.sharedInstance().getIssueLinkCounts(pIDs, new SubProgressMonitor(monitor, 50));
for (Map.Entry<ObjectID, Long> me : issueLinkCounts.entrySet()) {
PropertySetID personID = (PropertySetID) me.getKey();
List<PersonRelationID> prIDs = personID2personRelationIDs.get(personID);
if (prIDs == null)
throw new IllegalStateException("personID2personRelationIDs.get(personID) returned null! " + personID); //$NON-NLS-1$
for (PersonRelationID personRelationID : prIDs) {
result.put(personRelationID, me.getValue());
}
}
}
else
monitor.worked(50);
return result;
} finally {
monitor.done();
}
}
@Override
public Collection<? extends ObjectID> retrieveChildObjectIDs(PersonRelationTreeNode parentNode, ProgressMonitor monitor) {
ObjectID parentID = parentNode != null ? parentNode.getJdoObjectID() : null;
if (logger.isDebugEnabled())
logger.debug("retrieveChildObjectIDs: entered for: " + parentID); //$NON-NLS-1$
monitor.beginTask(Messages.getString("org.nightlabs.jfire.personrelation.issuetracking.trade.ui.tree.IssuePersonRelationTreeControllerDelegate.task.loadingLinkedIssuesForPerson.name"), 100); //$NON-NLS-1$
try {
PropertySetID personID = null;
if (parentID instanceof PropertySetID) {
personID = (PropertySetID) parentID;
monitor.worked(50);
}
else if (parentID instanceof PersonRelationID) {
PersonRelationID personRelationID = (PersonRelationID) parentID;
PersonRelation personRelation = PersonRelationDAO.sharedInstance().getPersonRelation(
personRelationID,
new String[] { FetchPlan.DEFAULT, PersonRelation.FETCH_GROUP_TO_ID },
NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT,
new SubProgressMonitor(monitor, 50)
);
personID = personRelation.getToID();
}
else if (parentID instanceof IssueLinkID) {
IssueLinkID issueLinkID = (IssueLinkID) parentID;
List<IssueCommentID> issueCommentIDs = IssueCommentDAO.sharedInstance().getIssueCommentIDsOfIssueOfIssueLink(issueLinkID, new SubProgressMonitor(monitor, 100));
Collection<ObjectID> result = new ArrayList<ObjectID>(issueCommentIDs.size() + 1); // add one for the description
IssueLink issueLink = IssueLinkDAO.sharedInstance().getIssueLink(issueLinkID, FETCH_GROUPS_ISSUE_LINK, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor());
IssueDescriptionID issueDescriptionID = IssueDescriptionID.create(
issueLink.getIssue().getOrganisationID(),
issueLink.getIssue().getIssueID()
);
result.add(issueDescriptionID);
result.addAll(issueCommentIDs);
return result;
}
if (personID == null)
return null;
Collection<IssueLinkID> issueLinkIDs = IssueLinkDAO.sharedInstance().getIssueLinkIDs(personID, new SubProgressMonitor(monitor, 50));
return issueLinkIDs;
} finally {
monitor.done();
}
}
@Override
public Collection<?> retrieveJDOObjects(Set<ObjectID> objectIDs, ProgressMonitor monitor) {
if (logger.isDebugEnabled()) {
logger.debug("retrieveJDOObjects: entered with " + objectIDs.size() + " objectIDs."); //$NON-NLS-1$ //$NON-NLS-2$
if (logger.isTraceEnabled()) {
for (ObjectID objectID : objectIDs) {
logger.trace("retrieveJDOObjects: * " + objectID); //$NON-NLS-1$
}
}
}
Collection<Object> result = null;
Set<IssueID> issueDescriptionIssueIDs = null;
Set<IssueCommentID> issueCommentIDs = null;
Set<IssueLinkID> issueLinkIDs = null;
for (ObjectID objectID : objectIDs) {
if (objectID instanceof IssueLinkID) {
IssueLinkID issueLinkID = (IssueLinkID) objectID;
if (issueLinkIDs == null)
issueLinkIDs = new HashSet<IssueLinkID>(objectIDs.size());
issueLinkIDs.add(issueLinkID);
}
else if (objectID instanceof IssueCommentID) {
IssueCommentID issueCommentID = (IssueCommentID) objectID;
if (issueCommentIDs == null)
issueCommentIDs = new HashSet<IssueCommentID>(objectIDs.size());
issueCommentIDs.add(issueCommentID);
}
else if (objectID instanceof IssueDescriptionID) {
IssueDescriptionID issueDescriptionID = (IssueDescriptionID) objectID;
if (issueDescriptionIssueIDs == null)
issueDescriptionIssueIDs = new HashSet<IssueID>();
IssueID issueID = IssueID.create(issueDescriptionID.organisationID, issueDescriptionID.issueID);
issueDescriptionIssueIDs.add(issueID);
}
}
if (issueLinkIDs != null) {
if (result == null)
result = new LinkedList<Object>();
result.addAll(
IssueLinkDAO.sharedInstance().getIssueLinks(issueLinkIDs, FETCH_GROUPS_ISSUE_LINK, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, monitor)
);
}
if (issueCommentIDs != null) {
if (result == null)
result = new LinkedList<Object>();
result.addAll(
IssueCommentDAO.sharedInstance().getIssueComments(issueCommentIDs, FETCH_GROUPS_ISSUE_COMMENT, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, monitor)
);
}
if (issueDescriptionIssueIDs != null) {
if (result == null)
result = new LinkedList<Object>();
List<Issue> issues = IssueDAO.sharedInstance().getIssues(issueDescriptionIssueIDs, FETCH_GROUPS_ISSUE_DESCRIPTION_ISSUE, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, monitor);
for (Issue issue : issues) {
result.add(issue.getDescription());
}
}
return result;
}
@Override
public Collection<Class<? extends Object>> getJDOObjectClasses() {
Collection<Class<? extends Object>> result = new ArrayList<Class<? extends Object>>(3);
result.add(IssueLink.class);
result.add(IssueDescription.class);
result.add(IssueComment.class);
return result;
}
private PersonRelationIssueParentResolver personRelationIssueParentResolver;
@Override
public TreeNodeMultiParentResolver getPersonRelationParentResolverDelegate() {
if (personRelationIssueParentResolver == null)
personRelationIssueParentResolver = new PersonRelationIssueParentResolver();
return personRelationIssueParentResolver;
}
}