From: <jbo...@li...> - 2006-05-20 12:55:47
|
Author: aron.gombas Date: 2006-05-20 08:55:37 -0400 (Sat, 20 May 2006) New Revision: 4332 Modified: labs/kosmos/trunk/src/java/hu/midori/kosmos/server/jira/JiraWebCrawlingServiceImpl.java Log: No exception, but log.warn() when facing an unknown status or priority code in JIRA Modified: labs/kosmos/trunk/src/java/hu/midori/kosmos/server/jira/JiraWebCrawlingServiceImpl.java =================================================================== --- labs/kosmos/trunk/src/java/hu/midori/kosmos/server/jira/JiraWebCrawlingServiceImpl.java 2006-05-20 04:52:04 UTC (rev 4331) +++ labs/kosmos/trunk/src/java/hu/midori/kosmos/server/jira/JiraWebCrawlingServiceImpl.java 2006-05-20 12:55:37 UTC (rev 4332) @@ -38,200 +38,200 @@ * @version $Id$ */ public class JiraWebCrawlingServiceImpl extends AbstractJiraServiceImpl implements JiraService { - private final static Log log = LogFactory.getLog(JiraWebCrawlingServiceImpl.class); + private final static Log log = LogFactory.getLog(JiraWebCrawlingServiceImpl.class); - @SuppressWarnings("unchecked") - public List<JiraProject> getProjects(String url) { - log.debug("Returning projects..."); + @SuppressWarnings("unchecked") + public List<JiraProject> getProjects(String url) { + log.debug("Returning projects..."); - List<JiraProject> projects = new ArrayList<JiraProject>(); - updateTimestamp(); + List<JiraProject> projects = new ArrayList<JiraProject>(); + updateTimestamp(); - beginStoreSession(); + beginStoreSession(); - try { - // download database info - connect(url); + try { + // download database info + connect(url); - Document dom = WebCrawlingUtils.downloadHtmlDom(new URL(UrlUtils.removeUserInfoFromUrl(url))); + Document dom = WebCrawlingUtils.downloadHtmlDom(new URL(UrlUtils.removeUserInfoFromUrl(url))); - disconnect(url); + disconnect(url); - // run XQueries - String queryProjects = - "for " + - "$d in //table " + - "where " + - "contains($d/child::tr/child::td/child::h3/child::a/@href, '/secure/BrowseProjects.jspa') " + - "return " + - "<dummy>" + - "{ data(fn:substring-after(fn:normalize-space($d/child::tr/child::td/child::h3/text()), ' ')) }|" + - "{ data(fn:substring-after(fn:substring-before($d/child::tr/child::td/child::h3/font/text(), ')'), ' ')) }|" + - "{ data($d/following-sibling::table/child::tr/child::td/child::p[1]/child::a[2]) }|" + - "{ data(fn:normalize-space(fn:string-join($d/following-sibling::table/child::tr/child::td/child::p[1]/text(), ''))) }|" + - "{ data($d/following-sibling::table/child::tr/child::td/child::p[1]/child::a[1]) }" + - "</dummy>"; - List resultProjects = WebCrawlingUtils.runXQuery(dom, queryProjects); - if(resultProjects.size() < 1) - throw new IllegalStateException(String.format("Couldn't find JIRA project properties (%d) at \"%s\"", resultProjects.size(), url)); + // run XQueries + String queryProjects = + "for " + + "$d in //table " + + "where " + + "contains($d/child::tr/child::td/child::h3/child::a/@href, '/secure/BrowseProjects.jspa') " + + "return " + + "<dummy>" + + "{ data(fn:substring-after(fn:normalize-space($d/child::tr/child::td/child::h3/text()), ' ')) }|" + + "{ data(fn:substring-after(fn:substring-before($d/child::tr/child::td/child::h3/font/text(), ')'), ' ')) }|" + + "{ data($d/following-sibling::table/child::tr/child::td/child::p[1]/child::a[2]) }|" + + "{ data(fn:normalize-space(fn:string-join($d/following-sibling::table/child::tr/child::td/child::p[1]/text(), ''))) }|" + + "{ data($d/following-sibling::table/child::tr/child::td/child::p[1]/child::a[1]) }" + + "</dummy>"; + List resultProjects = WebCrawlingUtils.runXQuery(dom, queryProjects); + if(resultProjects.size() < 1) + throw new IllegalStateException(String.format("Couldn't find JIRA project properties (%d) at \"%s\"", resultProjects.size(), url)); - String queryIssueStatuses = - "for " + - "$d in //tr " + - "where " + - "count($d/child::td) = 4 and " + - "contains($d/child::td[2]/child::a[1]/@href, '/secure/IssueNavigator.jspa') and " + - "contains($d/child::td[2]/child::a[1]/@href, 'status') " + // can be "status" or "statusIds" - "return " + - "<dummy>" + - "{ data(fn:substring-after(fn:substring-after($d/child::td[2]/child::a[1]/@href, 'status'), '=')) }|" +// TODO should grab the next number after "status" - "{ data(fn:normalize-space(fn:string-join($d/child::td[3]/text(), ''))) }" + - "</dummy>"; - List resultIssueStatuses = WebCrawlingUtils.runXQuery(dom, queryIssueStatuses); + String queryIssueStatuses = + "for " + + "$d in //tr " + + "where " + + "count($d/child::td) = 4 and " + + "contains($d/child::td[2]/child::a[1]/@href, '/secure/IssueNavigator.jspa') and " + + "contains($d/child::td[2]/child::a[1]/@href, 'status') " + // can be "status" or "statusIds" + "return " + + "<dummy>" + + "{ data(fn:substring-after(fn:substring-after($d/child::td[2]/child::a[1]/@href, 'status'), '=')) }|" +// TODO should grab the next number after "status" + "{ data(fn:normalize-space(fn:string-join($d/child::td[3]/text(), ''))) }" + + "</dummy>"; + List resultIssueStatuses = WebCrawlingUtils.runXQuery(dom, queryIssueStatuses); - String queryIssuePriorities = - "for " + - "$d in //tr " + - "where " + - "count($d/child::td) = 4 and " + - "contains($d/child::td[2]/child::a[1]/@href, '/secure/IssueNavigator.jspa') and " + - "contains($d/child::td[2]/child::a[1]/@href, 'priority') " + - "return " + - "<dummy>" + - "{ data(fn:substring(fn:substring-after(fn:substring-after($d/child::td[2]/child::a[1]/@href, 'priority'), '='), 1, 1)) }|" +// TODO not appropriate, because priority is hardwired to a single character - "{ data(fn:normalize-space(fn:string-join($d/child::td[3]/text(), ''))) }" + - "</dummy>"; - List resultIssuePriorities = WebCrawlingUtils.runXQuery(dom, queryIssuePriorities); + String queryIssuePriorities = + "for " + + "$d in //tr " + + "where " + + "count($d/child::td) = 4 and " + + "contains($d/child::td[2]/child::a[1]/@href, '/secure/IssueNavigator.jspa') and " + + "contains($d/child::td[2]/child::a[1]/@href, 'priority') " + + "return " + + "<dummy>" + + "{ data(fn:substring(fn:substring-after(fn:substring-after($d/child::td[2]/child::a[1]/@href, 'priority'), '='), 1, 1)) }|" +// TODO not appropriate, because priority is hardwired to a single character + "{ data(fn:normalize-space(fn:string-join($d/child::td[3]/text(), ''))) }" + + "</dummy>"; + List resultIssuePriorities = WebCrawlingUtils.runXQuery(dom, queryIssuePriorities); - String queryIssueAssignees = - "for " + - "$d in //tr " + - "where " + - "count($d/child::td) = 3 and " + - "contains($d/child::td[1]/child::a[1]/@href, '/secure/IssueNavigator.jspa') and " + - "contains($d/child::td[1]/child::a[1]/@href, 'assignee') " + - "return " + - "<dummy>" + - "{ data(fn:normalize-space($d/child::td[1]/child::a[1]/text())) }|" + - "{ data(fn:normalize-space(fn:string-join($d/child::td[2]/text(), ''))) }" + - "</dummy>"; - List resultIssueAssignees = WebCrawlingUtils.runXQuery(dom, queryIssueAssignees); + String queryIssueAssignees = + "for " + + "$d in //tr " + + "where " + + "count($d/child::td) = 3 and " + + "contains($d/child::td[1]/child::a[1]/@href, '/secure/IssueNavigator.jspa') and " + + "contains($d/child::td[1]/child::a[1]/@href, 'assignee') " + + "return " + + "<dummy>" + + "{ data(fn:normalize-space($d/child::td[1]/child::a[1]/text())) }|" + + "{ data(fn:normalize-space(fn:string-join($d/child::td[2]/text(), ''))) }" + + "</dummy>"; + List resultIssueAssignees = WebCrawlingUtils.runXQuery(dom, queryIssueAssignees); - // scrape - for(Iterator itProject = resultProjects.iterator(); itProject.hasNext();) { - String valueProject = WebCrawlingUtils.eliminateEmptyValues(((NodeInfo)itProject.next()).getStringValue()); - log.debug(String.format("Scraped project: \"%s\"", valueProject)); + // scrape + for(Iterator itProject = resultProjects.iterator(); itProject.hasNext();) { + String valueProject = WebCrawlingUtils.eliminateEmptyValues(((NodeInfo)itProject.next()).getStringValue()); + log.debug(String.format("Scraped project: \"%s\"", valueProject)); - StringTokenizer tokenizerProject = new StringTokenizer(valueProject, "|"); - String name = tokenizerProject.nextToken(); - String projectKey = tokenizerProject.nextToken(); - String projectUrl = tokenizerProject.nextToken(); - String description = tokenizerProject.nextToken(); - String lead = tokenizerProject.nextToken(); + StringTokenizer tokenizerProject = new StringTokenizer(valueProject, "|"); + String name = tokenizerProject.nextToken(); + String projectKey = tokenizerProject.nextToken(); + String projectUrl = tokenizerProject.nextToken(); + String description = tokenizerProject.nextToken(); + String lead = tokenizerProject.nextToken(); - // scrape issue statuses - int openIssues = 0; - int codingInProgressIssues = 0; - int reopenedIssues = 0; - int resolvedIssues = 0; - int closedIssues = 0; - for(Iterator itIssueStatus = resultIssueStatuses.iterator(); itIssueStatus.hasNext();) { - String valueIssueStatus = ((NodeInfo)itIssueStatus.next()).getStringValue(); - log.debug(String.format("Scraped issue status: \"%s\"", valueIssueStatus)); + // scrape issue statuses + int openIssues = 0; + int codingInProgressIssues = 0; + int reopenedIssues = 0; + int resolvedIssues = 0; + int closedIssues = 0; + for(Iterator itIssueStatus = resultIssueStatuses.iterator(); itIssueStatus.hasNext();) { + String valueIssueStatus = ((NodeInfo)itIssueStatus.next()).getStringValue(); + log.debug(String.format("Scraped issue status: \"%s\"", valueIssueStatus)); - StringTokenizer tokenizerIssueStatus = new StringTokenizer(valueIssueStatus, "|"); - int status = Integer.parseInt(tokenizerIssueStatus.nextToken()); - int count = Integer.parseInt(tokenizerIssueStatus.nextToken()); - switch(status) { - case 1: openIssues = count; break; - // TODO what is 2? - case 3: codingInProgressIssues = count; break; - case 4: reopenedIssues = count; break; - case 5: resolvedIssues = count; break; - case 6: closedIssues = count; break; - default: throw new IllegalArgumentException(String.format("Unknown issue status: %d", status)); - } - } + StringTokenizer tokenizerIssueStatus = new StringTokenizer(valueIssueStatus, "|"); + int status = Integer.parseInt(tokenizerIssueStatus.nextToken()); + int count = Integer.parseInt(tokenizerIssueStatus.nextToken()); + switch(status) { + case 1: openIssues = count; break; + // TODO what is 2? + case 3: codingInProgressIssues = count; break; + case 4: reopenedIssues = count; break; + case 5: resolvedIssues = count; break; + case 6: closedIssues = count; break; + default: log.warn(String.format("Unknown issue status: %d", status)); + } + } - // scrape issue priorities - int blockerOpenIssues = 0; - int criticalOpenIssues = 0; - int majorOpenIssues = 0; - int minorOpenIssues = 0; - int trivialOpenIssues = 0; - int optionalOpenIssues = 0; - for(Iterator itIssuePriority = resultIssuePriorities.iterator(); itIssuePriority.hasNext();) { - String valueIssuePriority = ((NodeInfo)itIssuePriority.next()).getStringValue(); - log.debug(String.format("Scraped issue priority: \"%s\"", valueIssuePriority)); + // scrape issue priorities + int blockerOpenIssues = 0; + int criticalOpenIssues = 0; + int majorOpenIssues = 0; + int minorOpenIssues = 0; + int trivialOpenIssues = 0; + int optionalOpenIssues = 0; + for(Iterator itIssuePriority = resultIssuePriorities.iterator(); itIssuePriority.hasNext();) { + String valueIssuePriority = ((NodeInfo)itIssuePriority.next()).getStringValue(); + log.debug(String.format("Scraped issue priority: \"%s\"", valueIssuePriority)); - StringTokenizer tokenizerIssuePriority = new StringTokenizer(valueIssuePriority, "|"); - int priority = Integer.parseInt(tokenizerIssuePriority.nextToken()); - int count = Integer.parseInt(tokenizerIssuePriority.nextToken()); - switch(priority) { - case 1: blockerOpenIssues = count; break; - case 2: criticalOpenIssues = count; break; - case 3: majorOpenIssues = count; break; - case 4: minorOpenIssues = count; break; - case 5: trivialOpenIssues = count; break; - // TODO what is 6? - case 7: optionalOpenIssues = count; break; - default: throw new IllegalArgumentException(String.format("Unknown issue priority: %d", priority)); - } - } + StringTokenizer tokenizerIssuePriority = new StringTokenizer(valueIssuePriority, "|"); + int priority = Integer.parseInt(tokenizerIssuePriority.nextToken()); + int count = Integer.parseInt(tokenizerIssuePriority.nextToken()); + switch(priority) { + case 1: blockerOpenIssues = count; break; + case 2: criticalOpenIssues = count; break; + case 3: majorOpenIssues = count; break; + case 4: minorOpenIssues = count; break; + case 5: trivialOpenIssues = count; break; + // TODO what is 6? + case 7: optionalOpenIssues = count; break; + default: log.warn(String.format("Unknown issue priority: %d", priority)); + } + } - // scrape issue assignees - Map<String, Integer> openIssuesPerAssigneeMap = new HashMap<String, Integer>(); - for(Iterator itIssueAssignee = resultIssueAssignees.iterator(); itIssueAssignee.hasNext();) { - String valueIssueAssignee = ((NodeInfo)itIssueAssignee.next()).getStringValue(); - log.debug(String.format("Scraped issue assignee: \"%s\"", valueIssueAssignee)); + // scrape issue assignees + Map<String, Integer> openIssuesPerAssigneeMap = new HashMap<String, Integer>(); + for(Iterator itIssueAssignee = resultIssueAssignees.iterator(); itIssueAssignee.hasNext();) { + String valueIssueAssignee = ((NodeInfo)itIssueAssignee.next()).getStringValue(); + log.debug(String.format("Scraped issue assignee: \"%s\"", valueIssueAssignee)); - StringTokenizer tokenizerIssueAssignee = new StringTokenizer(valueIssueAssignee, "|"); - String assignee = tokenizerIssueAssignee.nextToken(); - int count = Integer.parseInt(tokenizerIssueAssignee.nextToken()); - openIssuesPerAssigneeMap.put(assignee, count); - } + StringTokenizer tokenizerIssueAssignee = new StringTokenizer(valueIssueAssignee, "|"); + String assignee = tokenizerIssueAssignee.nextToken(); + int count = Integer.parseInt(tokenizerIssueAssignee.nextToken()); + openIssuesPerAssigneeMap.put(assignee, count); + } - // generate charts - String prefix = UrlUtils.removeUserInfoFromUrl(url); - List<Map.Entry<String, Integer>> openIssuesPerAssignee = (List<Map.Entry<String, Integer>>)ChartUtils.countMapToSortedList(openIssuesPerAssigneeMap); + // generate charts + String prefix = UrlUtils.removeUserInfoFromUrl(url); + List<Map.Entry<String, Integer>> openIssuesPerAssignee = (List<Map.Entry<String, Integer>>)ChartUtils.countMapToSortedList(openIssuesPerAssigneeMap); - ZoomableImageLocator openIssuesPerAssigneeChartLocator = generateOpenIssuesPerAssigneeChart(prefix, openIssuesPerAssignee); - ZoomableImageLocator issuesPerStatusChartLocator = generateIssuePerStatusChart(prefix, openIssues, codingInProgressIssues, reopenedIssues, resolvedIssues, closedIssues); - ZoomableImageLocator openIssuesPerPriorityChartLocator = generateIssuePerPriorityChart(prefix, blockerOpenIssues, criticalOpenIssues, majorOpenIssues, minorOpenIssues, trivialOpenIssues, optionalOpenIssues); + ZoomableImageLocator openIssuesPerAssigneeChartLocator = generateOpenIssuesPerAssigneeChart(prefix, openIssuesPerAssignee); + ZoomableImageLocator issuesPerStatusChartLocator = generateIssuePerStatusChart(prefix, openIssues, codingInProgressIssues, reopenedIssues, resolvedIssues, closedIssues); + ZoomableImageLocator openIssuesPerPriorityChartLocator = generateIssuePerPriorityChart(prefix, blockerOpenIssues, criticalOpenIssues, majorOpenIssues, minorOpenIssues, trivialOpenIssues, optionalOpenIssues); - // save - JiraProject project = new JiraProject(name, prefix, projectKey, projectUrl, description, lead, - openIssues, codingInProgressIssues, reopenedIssues, resolvedIssues, closedIssues, - blockerOpenIssues, criticalOpenIssues, majorOpenIssues, minorOpenIssues, trivialOpenIssues, optionalOpenIssues, - (List<Map.Entry<String, Integer>>)trimList(openIssuesPerAssignee), - issuesPerStatusChartLocator, openIssuesPerPriorityChartLocator, openIssuesPerAssigneeChartLocator); - log.debug(String.format("Adding project \"%s\"...", project)); - projects.add(project); - } - } catch(Exception ex) { - log.error("Unable to scrape", ex); - } + // save + JiraProject project = new JiraProject(name, prefix, projectKey, projectUrl, description, lead, + openIssues, codingInProgressIssues, reopenedIssues, resolvedIssues, closedIssues, + blockerOpenIssues, criticalOpenIssues, majorOpenIssues, minorOpenIssues, trivialOpenIssues, optionalOpenIssues, + (List<Map.Entry<String, Integer>>)trimList(openIssuesPerAssignee), + issuesPerStatusChartLocator, openIssuesPerPriorityChartLocator, openIssuesPerAssigneeChartLocator); + log.debug(String.format("Adding project \"%s\"...", project)); + projects.add(project); + } + } catch(Exception ex) { + log.error("Unable to scrape", ex); + } - endStoreSession(); + endStoreSession(); - return projects; - } + return projects; + } - /** Connects to the given public or secure JIRA URL. */ - protected void connect(String url) throws MalformedURLException { - // authenticate if project is secured - String userInfo[] = UrlUtils.parseUserInfoFromUrl(url); - if(userInfo != null) { - String userName = userInfo[0]; - String password = userInfo[1]; + /** Connects to the given public or secure JIRA URL. */ + protected void connect(String url) throws MalformedURLException { + // authenticate if project is secured + String userInfo[] = UrlUtils.parseUserInfoFromUrl(url); + if(userInfo != null) { + String userName = userInfo[0]; + String password = userInfo[1]; - log.debug(String.format("Signing in as \"%s\" \"%s\"...", userName, password)); - // do nothing - } - } + log.debug(String.format("Signing in as \"%s\" \"%s\"...", userName, password)); + // do nothing + } + } - /** Disconnects from the given URL. */ - protected void disconnect(String url) { - // do nothing - } + /** Disconnects from the given URL. */ + protected void disconnect(String url) { + // do nothing + } } |