/******************************************************************************* * Copyright (c) 2007 - 2007 IT Solutions, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Robert Munteanu *******************************************************************************/ package com.itsolut.mantis.core; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.itsolut.mantis.core.exception.MantisException; import com.itsolut.mantis.core.model.*; import com.itsolut.mantis.core.model.MantisTicket.Key; /** * Holds the cached information for a complete Mantis installations. * * @author Robert Munteanu * */ public class MantisCache { public static final int BUILT_IN_PROJECT_TASKS_FILTER_ID = -1; static final String BUILT_IN_PROJECT_TASKS_FILTER_FORMAT = "[Built-in] Latest %s tasks"; private MantisCacheData cacheData = new MantisCacheData(); public void setProjects(List<MantisProject> projects) { this.cacheData.setProjects( projects ); } public List<MantisProject> getProjects() { return cacheData.getProjects(); } public void cacheTimeTrackingEnabled(String stringValue) { cacheData.timeTrackingEnabled = parseMantisBoolean(stringValue); } private boolean parseMantisBoolean(String stringValue) { return "1".equals(stringValue); } public void cacheDueDateUpdateThreshold(int threshold) { cacheData.dueDateUpdateThreshold = threshold; } public void cacheDueDateViewThreshold(int threshold) { cacheData.dueDateViewThreshold = threshold; } public void cacheAssignedStatus(int status) { cacheData.bugAssignedStatus = status; } public void cacheSubmitStatus(int status) { cacheData.bugSubmitStatus = status; } public void cacheProjectVersions(int value, List<MantisVersion> projectVersions) { cacheData.getVersionsByProjectId().replaceValues(value, projectVersions); } public void cacheProjectReporters(int projectId, List<MantisUser> projectUsers) { cacheUsers0(projectUsers); cacheData.getReportersByProjectId().replaceValues(projectId, projectUsers); } private void cacheUsers0(List<MantisUser> projectUsers) { for (MantisUser user : projectUsers) cacheData.allUsers.put(user.getKey(), user); } public void cacheProjectDevelopers(int projectId, List<MantisUser> projectDevelopers) { cacheUsers0(projectDevelopers); cacheData.getDevelopersByProjectId().replaceValues(projectId, projectDevelopers); } public void cacheReporterThreshold(int threshold) { cacheData.setReporterThreshold(threshold); } public void cacheDeveloperThreshold(int threshold) { cacheData.setDeveloperThreshold(threshold); } public void cacheProjectCategories(int projectId, String[] projectCategories) { List<MantisProjectCategory> categories = new ArrayList<MantisProjectCategory>(); // the SOAP API returns just the names, so we assign arbitrary ids int id = 0; for (String categoryName : projectCategories) categories.add(new MantisProjectCategory(categoryName, ++id)); this.cacheData.categoriesByProjectId.put(projectId, categories); } public void cacheViewStates(List<MantisViewState> viewStates) { this.cacheData.viewStates = Lists.newArrayList(viewStates); } public void cacheEtas(List<MantisETA> etas) { this.cacheData.etas = Lists.newArrayList(etas); } public void cacheProjections(List<MantisProjection> projects) { this.cacheData.projections = Lists.newArrayList(projects); } public void cacheReproducibilites(List<MantisReproducibility> reproducibilities) { this.cacheData.reproducibilities = Lists.newArrayList(reproducibilities); } public void cacheResolutions(List<MantisResolution> resolutions) { this.cacheData.resolutions = Lists.newArrayList(resolutions); } public void cacheSeverities(List<MantisSeverity> severities) { this.cacheData.severities = Lists.newArrayList(severities); } public void cacheStatuses(List<MantisTicketStatus> statuses) { this.cacheData.statuses = Lists.newArrayList(statuses); } public void cachePriorities(List<MantisPriority> prios) { cacheData.priorities = Lists.newArrayList(prios); } public void cacheResolvedStatus(String resolvedStatus) { this.cacheData.resolvedStatus = Integer.parseInt(resolvedStatus); } public void cacheProjects(List<MantisProject> projectData) { cacheData.setProjects(Lists.newArrayList(projectData)); } public void cacheFilters(int projectId, List<MantisProjectFilter> projectFilters) throws MantisException { List<MantisProjectFilter> filters = new ArrayList<MantisProjectFilter>(); filters.add(addDefaultFilter(projectId)); filters.addAll(projectFilters); cacheData.getProjectFiltersById().replaceValues(projectId, filters); } private MantisProjectFilter addDefaultFilter(int projectId) throws MantisException { String projectDisplayName = getProjectById(projectId).getName(); String filterDisplayName = String.format(BUILT_IN_PROJECT_TASKS_FILTER_FORMAT, projectDisplayName); return new MantisProjectFilter(filterDisplayName, BUILT_IN_PROJECT_TASKS_FILTER_ID, null, projectId); } public void cacheProjectCustomFields(int projectId, List<MantisCustomField> customFieldData) { cacheData.getCustomFieldsByProjectId().replaceValues(projectId, customFieldData); } public void cacheRepositoryVersion(String version) throws MantisException { this.cacheData.repositoryVersion = RepositoryVersion.fromVersionString(version); } public void cacheDefaultAttributeValue(Key attribute, int readValue) { cacheData.putDefaultValueForAttribute(attribute, readValue); } public RepositoryVersion getRepositoryVersion() { return cacheData.repositoryVersion; } public int getProjectId(String projectName) throws MantisException { if ( MantisProject.ALL_PROJECTS.getName().equals(projectName) ) return MantisProject.ALL_PROJECTS.getValue(); for (MantisProject mantisProject : cacheData.getProjects()) if (mantisProject.getName().equals(projectName)) return mantisProject.getValue(); throw new MantisException("No project with the name " + projectName + " ."); } public int getProjectFilterId(int projectId, String filterName) throws MantisException { for (MantisProjectFilter filter : getProjectFilters(projectId)) if (filter.getName().equals(filterName)) return filter.getValue(); throw new MantisException("No filter with name " + filterName + " for project with id " + projectId + " ."); } public MantisResolution getResolution(int intValue) throws MantisException { for (MantisResolution resolution : cacheData.resolutions) if (resolution.getValue() == intValue) return resolution; throw new MantisException("No resolution with id " + intValue + " ."); } public MantisPriority getPriority(int intValue) throws MantisException { for (MantisPriority priority : cacheData.priorities) if (priority.getValue() == intValue) return priority; throw new MantisException("No priority with id " + intValue + " ."); } public MantisSeverity getSeverity(int intValue) throws MantisException { for (MantisSeverity severity : cacheData.severities) if (severity.getValue() == intValue) return severity; throw new MantisException("No severity with id " + intValue + " ."); } public MantisTicketStatus getStatus(int intValue) throws MantisException { for (MantisTicketStatus status : cacheData.statuses) if (status.getValue() == intValue) return status; throw new MantisException("No status with id " + intValue + " ."); } public MantisReproducibility getReproducibility(int reproducibilityId) throws MantisException { for (MantisReproducibility reproducibility : cacheData.reproducibilities) if (reproducibility.getValue() == reproducibilityId ) return reproducibility; throw new MantisException("No reproducibility with id " + reproducibilityId + " ."); } public MantisProjection getProjection(int projectionId) throws MantisException { for (MantisProjection projection : cacheData.projections) if (projection.getValue() == projectionId ) return projection; throw new MantisException("No projection with id " + projectionId + " ."); } public MantisETA getETA(int etaId) throws MantisException { for (MantisETA eta : cacheData.etas) if (eta.getValue() == etaId ) return eta; throw new MantisException("No eta with id " + etaId + " ."); } public MantisViewState getViewState(int viewStateId) throws MantisException { for (MantisViewState viewState : cacheData.viewStates) if (viewState.getValue() == viewStateId) return viewState; throw new MantisException("No viewState with name " + viewStateId + " ."); } public MantisCustomField getCustomFieldByProjectIdAndFieldName(int projectId, String customFieldName) throws MantisException { for (MantisCustomField customField : getCustomFieldsByProjectId(projectId)) if (customField.getName().equals(customFieldName)) return customField; throw new MantisException("No custom field with name " + customFieldName + " for the project with id " + projectId + " ."); } private List<MantisCustomField> getCustomFieldsByProjectId(int projectId) throws MantisException { return cacheData.getCustomFieldsByProjectId().get(projectId); } public int getResolvedStatus() { return cacheData.resolvedStatus; } public MantisTicketStatus getStatusByName(String statusName) throws MantisException { for (MantisTicketStatus status : cacheData.statuses) if (status.getName().equals(statusName)) return status; throw new MantisException("No status with name " + statusName + " ."); } public List<MantisCustomField> getCustomFieldsByProjectName(String projectName) throws MantisException { return getCustomFieldsByProjectId(getProjectId(projectName)); } public MantisSeverity[] getSeverities() { return cacheData.severities.toArray(new MantisSeverity[cacheData.severities.size()]); } public MantisResolution[] getTicketResolutions() { return cacheData.resolutions.toArray(new MantisResolution[cacheData.resolutions.size()]); } public MantisTicketStatus[] getTicketStatus() { return cacheData.statuses.toArray(new MantisTicketStatus[cacheData.statuses.size()]); } public MantisPriority[] getPriorities() { return cacheData.priorities.toArray(new MantisPriority[cacheData.priorities.size()]); } public MantisReproducibility[] getReproducibility() { return cacheData.reproducibilities.toArray(new MantisReproducibility[cacheData.reproducibilities.size()]); } public MantisProjection[] getProjection() { return cacheData.projections.toArray(new MantisProjection[cacheData.projections.size()]); } public MantisETA[] getETA() { return cacheData.etas.toArray(new MantisETA[cacheData.etas.size()]); } public MantisViewState[] getViewState() { return cacheData.viewStates.toArray(new MantisViewState[cacheData.viewStates.size()]); } public MantisProject getProjectByName(String projectName) throws MantisException { if ( MantisProject.ALL_PROJECTS.getName().equals(projectName) ) return MantisProject.ALL_PROJECTS; for (MantisProject project : cacheData.getProjects()) if (project.getName().equals(projectName)) return project; throw new MantisException("No project with name " + projectName + " ."); } public MantisProject getProjectById(int projectId) throws MantisException { for (MantisProject project : cacheData.getProjects()) if (project.getValue() == projectId) return project; throw new MantisException("No project with id " + projectId + " ."); } /** * @param projectId the project id or {@link MantisProject#ALL_PROJECTS} */ public List<MantisProjectFilter> getProjectFilters(int projectId) throws MantisException { if ( projectId == MantisProject.ALL_PROJECTS.getValue() ) return getProjectFiltersForAllProject(); return cacheData.getProjectFiltersById().get(projectId); } private List<MantisProjectFilter> getProjectFiltersForAllProject() { Map<Integer, MantisProjectFilter> filters = new LinkedHashMap<Integer, MantisProjectFilter>(); for ( MantisProjectFilter filter : cacheData.getProjectFiltersById().values() ) if ( filter.getProjectId() == MantisProject.ALL_PROJECTS.getValue() && filter.getValue() != BUILT_IN_PROJECT_TASKS_FILTER_ID ) filters.put(filter.getValue(), filter); return Lists.newArrayList(filters.values()); } public List<MantisProjectCategory> getProjectCategories(String projectName) throws MantisException { int projectId = getProjectId(projectName); List<MantisProjectCategory> categories = cacheData.categoriesByProjectId.get(projectId); if (categories == null) throw new MantisException("No categories for project with id " + projectId + " ."); return categories; } public MantisUser[] getDevelopersByProjectName(String projectName, IProgressMonitor monitor) throws MantisException { int projectId = getProjectId(projectName); List<MantisUser> developers = cacheData.getDevelopersByProjectId().get(projectId); return developers.toArray(new MantisUser[developers.size()]); } public MantisUser[] getUsersByProjectName(String projectName, IProgressMonitor monitor) throws MantisException { int projectId = getProjectId(projectName); List<MantisUser> reporters = cacheData.getReportersByProjectId().get(projectId); if (reporters == null) throw new MantisException("No reporters for project with id " + projectId + " "); return reporters.toArray(new MantisUser[reporters.size()]); } /** * Returns a user by the specified <tt>userName</tt> * * @param userName * @return the matching user, possibly <code>null</code> */ public MantisUser getUserByUsername(String userName) { return cacheData.allUsers.get(userName); } public MantisVersion[] getVersionsByProjectName(String projectName) throws MantisException { int projectId = getProjectId(projectName); List<MantisVersion> versions = cacheData.getVersionsByProjectId().get(projectId); if (versions == null) throw new MantisException("No versions for project with id " + projectId + " "); return versions.toArray(new MantisVersion[versions.size()]); } public MantisTicketStatus getSubmitStatus() throws MantisException { return getStatus(cacheData.bugSubmitStatus); } public MantisTicketStatus getAssignedStatus() throws MantisException { return getStatus(cacheData.bugAssignedStatus); } public String getResolvedStatusName() throws MantisException { for ( MantisTicketStatus status : cacheData.statuses) if ( status.getValue() == cacheData.resolvedStatus) return status.getName(); throw new MantisException("No status with id " + cacheData.resolvedStatus + " ."); } public MantisSeverity getDefaultSeverity() throws MantisException { try { return getSeverity(cacheData.getDefaultValueForAttribute(Key.SEVERITY)); } catch (MantisException e) { if ( cacheData.severities.size() > 0 ) return cacheData.severities.get(0); return null; } } public MantisPriority getDefaultPriority() throws MantisException { try { return getPriority(cacheData.getDefaultValueForAttribute(Key.PRIORITY)); } catch (MantisException e) { if ( cacheData.priorities.size() > 0 ) return cacheData.priorities.get(0); return null; } } public MantisETA getDefaultEta() throws MantisException { try { return getETA(cacheData.getDefaultValueForAttribute(Key.ETA)); } catch (MantisException e) { if ( cacheData.etas.size() > 0 ) return cacheData.etas.get(0); return null; } } public MantisProjection getDefaultProjection() throws MantisException { try { return getProjection(cacheData.getDefaultValueForAttribute(Key.PROJECTION)); } catch (MantisException e) { if ( cacheData.projections.size() > 0 ) return cacheData.projections.get(0); return null; } } public MantisResolution getDefaultResolution() throws MantisException { try { return getResolution(cacheData.getDefaultValueForAttribute(Key.RESOLUTION)); } catch (MantisException e) { if ( cacheData.resolutions.size() > 0 ) return cacheData.resolutions.get(0); return null; } } public MantisReproducibility getDefaultReproducibility() throws MantisException { try { return getReproducibility(cacheData.getDefaultValueForAttribute(Key.REPRODUCIBILITY)); } catch (MantisException e) { if ( cacheData.reproducibilities.size() > 0 ) return cacheData.reproducibilities.get(0); return null; } } public MantisViewState getDefaultViewState() throws MantisException { try { return getViewState(cacheData.getDefaultValueForAttribute(Key.VIEW_STATE)); } catch (MantisException e) { if ( cacheData.viewStates.size() > 0 ) return cacheData.viewStates.get(0); return null; } } public String getDefaultStepsToReproduce() { return cacheData.getDefaultValueForStringAttribute(Key.STEPS_TO_REPRODUCE); } public String getDefaultAdditionalInfo() { return cacheData.getDefaultValueForStringAttribute(Key.ADDITIONAL_INFO); } public MantisResolution getBugResolutionFixedThreshold() throws MantisException { return getResolution(cacheData.getBugResolutionFixedThreshold()); } public boolean isEtaEnabled() { return cacheData.isEtaEnabled(); } public boolean isProjectionEnabled() { return cacheData.isProjectionEnabled(); } public MantisCacheData getCacheData() { return cacheData; } public void setCacheData(MantisCacheData cacheData) { this.cacheData = cacheData; } /** * Since for large user counts the reporter retrieval fails, we provide a hook for registering * additional reporter users as they are discovered, e.g. in IssueData * * @param projectId * the project id * @param accountData * the name of the reporter */ public void registerAdditionalReporter(int projectId, MantisUser user) { // empty account if ( user.getValue() == 0 ) return; cacheData.allUsers.put(user.getKey(), user); if ( cacheData.getReportersByProjectId().containsEntry(projectId, user) ) return; cacheData.getReportersByProjectId().put(projectId, user); } public boolean dueDateIsEnabled() { return cacheData.dueDateViewThreshold < DefaultConstantValues.Role.NOBODY.getValue() && cacheData.dueDateUpdateThreshold < DefaultConstantValues.Role.NOBODY.getValue(); } public void copyReportersFromDevelopers(int projectId) { cacheData.getReportersByProjectId().replaceValues(projectId, cacheData.getDevelopersByProjectId().get(projectId)); } /** * @param userId * @return the matching username, possibly <code>null</code> */ public String getUserNameById(int userId) { for ( MantisUser user : cacheData.allUsers.values() ) if ( user.getValue() == userId ) return user.getKey(); return null; } public void cacheTags(List<MantisTag> tags) { Map<Integer, MantisTag> tagsById = Maps.newHashMapWithExpectedSize(tags.size()); for ( MantisTag tag : tags ) tagsById.put(tag.getValue(), tag); cacheData.setTagsById(tagsById); } public List<MantisTag> getTags() { return Lists.newArrayList(cacheData.getTagsById().values()); } public void cacheEnableProfiles(boolean enableProfiles) { cacheData.setEnableProfiles(enableProfiles); } public boolean isEnableProfiles() { return cacheData.isEnableProfiles(); } }