Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 46917 invoked from network); 21 Apr 2010 20:03:34 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 21 Apr 2010 20:03:34 -0000 Received: (qmail 25677 invoked by uid 500); 21 Apr 2010 20:03:33 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 25654 invoked by uid 500); 21 Apr 2010 20:03:33 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 25647 invoked by uid 99); 21 Apr 2010 20:03:33 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Apr 2010 20:03:33 +0000 X-ASF-Spam-Status: No, hits=-1393.7 required=10.0 tests=ALL_TRUSTED,AWL X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Apr 2010 20:03:30 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id AA4B42388A43; Wed, 21 Apr 2010 20:02:48 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r936472 [3/3] - in /db/derby/code/trunk: ./ java/build/org/apache/derbyBuild/ tools/release/ Date: Wed, 21 Apr 2010 20:02:48 -0000 To: derby-commits@db.apache.org From: rhillegas@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100421200248.AA4B42388A43@eris.apache.org> Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/ChangesFileGenerator.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/ChangesFileGenerator.java?rev=936472&r1=936471&r2=936472&view=diff ============================================================================== --- db/derby/code/trunk/java/build/org/apache/derbyBuild/ChangesFileGenerator.java (original) +++ db/derby/code/trunk/java/build/org/apache/derbyBuild/ChangesFileGenerator.java Wed Apr 21 20:02:48 2010 @@ -86,6 +86,8 @@ public class ChangesFileGenerator extend // major sections private static final String BUG_FIXES_SECTION = "CHANGES"; + private ReportParser reportParser = ReportParser.makeReportParser(); + /** * Only different from the default no-args constructor in that it has a * throws clause. @@ -195,8 +197,8 @@ public class ChangesFileGenerator extend (bugListSection, DEFAULT_TABLE_BORDER_WIDTH, new String[] { ISSUE_ID_HEADLINE, DESCRIPTION_HEADLINE }); - for (Iterator i = JiraIssue.createJiraIssueList(bugListDoc, - excludeReleaseIDList).iterator(); i.hasNext();) { + for (Iterator i = JiraIssue.createJiraIssueList( bugListDoc, excludeReleaseIDList, reportParser ).iterator(); i.hasNext(); ) + { JiraIssue issue = (JiraIssue) i.next(); println(issue.getKey()); Element row = insertRow(table); Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/GeneratorBase.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/GeneratorBase.java?rev=936472&r1=936471&r2=936472&view=diff ============================================================================== --- db/derby/code/trunk/java/build/org/apache/derbyBuild/GeneratorBase.java (original) +++ db/derby/code/trunk/java/build/org/apache/derbyBuild/GeneratorBase.java Wed Apr 21 20:02:48 2010 @@ -86,7 +86,7 @@ public class GeneratorBase extends Task protected ElementFacade summary; // Bug list file protected String bugListFileName; - protected Document bugListDoc; + protected TagReader bugListDoc; // Output file private String outputFileName; @@ -149,7 +149,7 @@ public class GeneratorBase extends Task */ public void setBugListFileName(String bugListFileName) throws Exception { this.bugListFileName = bugListFileName; - bugListDoc = docBldr.parse(new File(bugListFileName)); + bugListDoc = new TagReader( new FileInputStream(bugListFileName) ); } /** Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/JiraIssue.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/JiraIssue.java?rev=936472&r1=936471&r2=936472&view=diff ============================================================================== --- db/derby/code/trunk/java/build/org/apache/derbyBuild/JiraIssue.java (original) +++ db/derby/code/trunk/java/build/org/apache/derbyBuild/JiraIssue.java Wed Apr 21 20:02:48 2010 @@ -15,152 +15,69 @@ limitations under the License. package org.apache.derbyBuild; import org.w3c.dom.*; +import java.io.InputStream; import java.util.*; /** * - * An issue from a JIRA report. + * An issue from a JIRA report. The constructor of this class parses text produced by + * a JIRA report. This parsing logic probably has to be rewritten for every release because + * the format of the JIRA reports is not stable. * */ class JiraIssue { - private static final long NO_RELEASE_NOTE = -1; - private static final String JIRA_ITEM = "h3"; - private static final String JIRA_ID = "id"; - private static final String JIRA_NAME = "name"; - private static final String JIRA_TITLE = "a"; - private static final String JIRA_KEY = "key"; - private static final String JIRA_ATTACHMENT = "attachment"; - private static final String JIRA_FIXVERSION = "fixVersion"; private static final String RELEASE_NOTE_NAME = "releaseNote.html"; private String key; private String title; - private long releaseNoteAttachmentID = NO_RELEASE_NOTE; - private HashSet fixVersionSet = new HashSet(); + private long releaseNoteAttachmentID = ReportParser.NO_RELEASE_NOTE; + private HashSet fixVersionSet; /** - * Create an object instance from an XML document Element. The Element given - * as argument is assumed to be an 'item' sub-tree from the XML file - * representation of a Jira filter/query. - * @param itemElement the 'item' subtree representing a Jira issue - * @throws java.lang.Exception - */ - public JiraIssue(Element itemElement) throws Exception { - ElementFacade ef = new ElementFacade(itemElement); - title = ef.getTextByTagName(JIRA_TITLE); - //key = ef.getTextByTagName(JIRA_KEY); - key = parseKey( title ); - - releaseNoteAttachmentID = getReleaseNoteAttachmentID( key, itemElement ); - - // - // A JIRA title has the following form: - // - // "[DERBY-2598] new upgrade test failures after change 528033" - // - // We strip off the leading JIRA id because that information already - // lives in the key. - // - title = title.substring(title.indexOf(']') + 2); - - for (Iterator i = ef.getTextListByTagName(JIRA_FIXVERSION).iterator(); - i.hasNext();) { - - String nextVersion = (String) i.next(); - - fixVersionSet.add( nextVersion ); - } - } - - /** - * Look up the attachment id for the release note attached to - * an issue. - */ - private long getReleaseNoteAttachmentID - ( String key, Element itemElement ) - throws Exception - { - long result = NO_RELEASE_NOTE; - - // - // The following code used to work before the time of Derby 10.6. - // With that release, the list of attachments stopped appearing in - // the xml reports. - // - // NodeList attachmentsList = - // itemElement.getElementsByTagName(JIRA_ATTACHMENT); - // - // for (int i = 0; i < attachmentsList.getLength(); i++) { - // Element attachment = (Element) attachmentsList.item(i); - // String name = attachment.getAttribute(JIRA_NAME); - // if (RELEASE_NOTE_NAME.equals(name)) { - // result = - // Math.max(result, - // Long.parseLong(attachment.getAttribute(JIRA_ID))); - // } - // } - - // - // As a consequence, we now hardcode the attachment ids. - // The attachment id is in the link of the latest release note - // attached to the issue. - // - if ( key.equals( "DERBY-4602" ) ) { result = 12440335L; } - else if ( key.equals( "DERBY-4483" ) ) { result = 12439775L; } - else if ( key.equals( "DERBY-4432" ) ) { result = 12424709L; } - else if ( key.equals( "DERBY-4380" ) ) { result = 12434514L; } - else if ( key.equals( "DERBY-4355" ) ) { result = 12419298L; } - else if ( key.equals( "DERBY-4312" ) ) { result = 12442288L; } - else if ( key.equals( "DERBY-4230" ) ) { result = 12409466L; } - else if ( key.equals( "DERBY-4191" ) ) { result = 12442312L; } - else if ( key.equals( "DERBY-3991" ) ) { result = 12409798L; } - else if ( key.equals( "DERBY-3844" ) ) { result = 12436979L; } - else if ( key.equals( "DERBY-2769" ) ) { result = 12418474L; } - - return result; - } - - /** - * Extract the JIRA key (DERBY-XXXX) from the raw title. - * A JIRA raw title has the following form: - * - * "[DERBY-2598] new upgrade test failures after change 528033" + * Create an object instance from a TagReader. */ - private String parseKey( String rawTitle ) throws Exception + public JiraIssue( ReportParser rp, TagReader tr ) throws Exception { - String result = rawTitle.substring(1, title.indexOf(']') ); - - return result; + key = rp.parseKey( tr ); + title = rp.parseTitle( tr ); + fixVersionSet = rp.parseFixedVersions( tr ); + releaseNoteAttachmentID = rp.getReleaseNoteAttachmentID( tr ); } /** * Factory method which extracts a list of JiraIssue objects from a Jira * report (supplied as an XML Document). Issues with a fixVersion contained * in the exclude list will be omitted from the list. - * @param report the Jira report to extract issues from (as a Document object) + * @param masterReport a TagReader holding the JIRA report of all the fixed bugs * @param excludeReleaseIDList list of fixVersions that disqualifies an issue + * @param parser a class to parse content in the master report * @return a List of JiraIssue objects * @throws java.lang.Exception */ - public static List createJiraIssueList(Document report, - List excludeReleaseIDList) throws Exception { - Element reportRoot = report.getDocumentElement(); - NodeList itemList = reportRoot.getElementsByTagName(JIRA_ITEM); - int count = itemList.getLength(); + public static List createJiraIssueList + ( TagReader masterReport, List excludeReleaseIDList, ReportParser parser ) throws Exception + { + int issueCount = 0; + ArrayList jiraIssues = new ArrayList(); - boolean skip; - for (int i = 0; i < count; i++) { - skip=false; - JiraIssue candidate = new JiraIssue((Element) itemList.item(i)); - for (Iterator ex = excludeReleaseIDList.iterator(); ex.hasNext();) { + while( true ) + { + TagReader nextIssue = parser.parseNextIssue( masterReport ); + if ( nextIssue == null ) { break; } + + JiraIssue candidate = new JiraIssue( parser, nextIssue ); + + boolean skip = false; + for (Iterator ex = excludeReleaseIDList.iterator(); ex.hasNext();) + { String rid = (String) ex.next(); - if (candidate.isFixedIn(rid)) { - System.out.println("Already fixed: "+candidate.getKey()+ - " (in "+rid+")"); + if (candidate.isFixedIn(rid)) + { + //System.out.println("Already fixed: "+candidate.getKey()+ " (in "+rid+")"); skip=true; - continue; + break; } } if (!skip) @@ -169,11 +86,12 @@ class JiraIssue { jiraIssues.add(candidate); } } + return jiraIssues; } /** - * @return the issue's key (jira number DERBY-xxx) + * @return the issue's key (jira number, e.g., 1234) */ public String getKey() { return key; @@ -197,7 +115,7 @@ class JiraIssue { * @return true iff this issue has a release note attached */ public boolean hasReleaseNote() { - return (releaseNoteAttachmentID > NO_RELEASE_NOTE); + return (releaseNoteAttachmentID > ReportParser.NO_RELEASE_NOTE); } /** @@ -213,7 +131,7 @@ class JiraIssue { * @return URL for this Jira issue */ public String getJiraAddress() { - return "https://issues.apache.org/jira/browse/" + key; + return "https://issues.apache.org/jira/browse/DERBY-" + key; } /** Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java?rev=936472&r1=936471&r2=936472&view=diff ============================================================================== --- db/derby/code/trunk/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java (original) +++ db/derby/code/trunk/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java Wed Apr 21 20:02:48 2010 @@ -132,9 +132,9 @@ public class ReleaseNotesGenerator exten ///////////////////////////////////////////////////////////////////////// private ReleaseNoteReader releaseNoteReader = new ReleaseNoteReader(docBldr); + private ReportParser reportParser = ReportParser.makeReportParser(); // set on the command line or by ant - private String releaseNotesListFileName; - private Document releaseNotesDoc; + private ArrayList missingReleaseNotes = new ArrayList(); @@ -163,20 +163,6 @@ public class ReleaseNotesGenerator exten ///////////////////////////////////////////////////////////////////////// /** - * Ant accessor to set the name of the JIRA-generated list of bugs which - * have release notes - * @param releaseNotesListFileName name of the xml file from the release - * note Jira filter/query - * @throws Exception - */ - public void setReleaseNotesListFileName(String releaseNotesListFileName) - throws Exception { - this.releaseNotesListFileName = releaseNotesListFileName; - releaseNotesDoc = docBldr.parse(new File(releaseNotesListFileName)); - } - - - /** * This is Ant's entry point into this task. * @throws BuildException */ @@ -298,15 +284,17 @@ public class ReleaseNotesGenerator exten (bugListSection, DEFAULT_TABLE_BORDER_WIDTH, new String[] { ISSUE_ID_HEADLINE, DESCRIPTION_HEADLINE }); - for (Iterator i = JiraIssue.createJiraIssueList(bugListDoc, - excludeReleaseIDList).iterator(); i.hasNext();) { + bugListDoc.reset(); + + for ( Iterator i = JiraIssue.createJiraIssueList( bugListDoc, excludeReleaseIDList, reportParser ).iterator(); i.hasNext(); ) + { JiraIssue issue = (JiraIssue) i.next(); //println("Fixed: "+ issue.getKey()); Element row = insertRow(table); Element linkColumn = insertColumn(row); Element descriptionColumn = insertColumn(row); Element hotlink = createLink(outputDoc, issue.getJiraAddress(), - issue.getKey()); + "DERBY-" + issue.getKey()); Text title = outputDoc.createTextNode(issue.getTitle()); linkColumn.appendChild(hotlink); @@ -336,8 +324,10 @@ public class ReleaseNotesGenerator exten addParagraph(issuesSection, deltaStatement); Element toc = createList(issuesSection); - for (Iterator i = JiraIssue.createJiraIssueList(releaseNotesDoc, - excludeReleaseIDList).iterator(); i.hasNext();) { + bugListDoc.reset(); + + for ( Iterator i = JiraIssue.createJiraIssueList( bugListDoc, excludeReleaseIDList, reportParser ).iterator(); i.hasNext(); ) + { JiraIssue issue = (JiraIssue) i.next(); if (issue.hasReleaseNote()) { Node summaryText = null; @@ -352,13 +342,13 @@ public class ReleaseNotesGenerator exten getReleaseNoteDetails(releaseNote); } catch (Throwable t) { errors.add(formatError("Unable to read or parse " + - "release note for " + + "release note for DERBY-" + issue.getKey(), t)); missingReleaseNotes.add(issue); continue; } - String key = "Note for " + issue.getKey(); + String key = "Note for DERBY-" + issue.getKey(); //println("Release note: "+issue.getKey()+" - "+issue.getTitle()); Element paragraph = outputDoc.createElement(PARAGRAPH); paragraph.appendChild(outputDoc.createTextNode(key + ": ")); @@ -455,7 +445,6 @@ public class ReleaseNotesGenerator exten setSummaryFileName( args[ idx++ ] ); setBugListFileName( args[ idx++ ] ); - setReleaseNotesListFileName( args[ idx++ ] ); setOutputFileName( args[ idx++ ] ); return true; Added: db/derby/code/trunk/java/build/org/apache/derbyBuild/ReportParser.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/ReportParser.java?rev=936472&view=auto ============================================================================== --- db/derby/code/trunk/java/build/org/apache/derbyBuild/ReportParser.java (added) +++ db/derby/code/trunk/java/build/org/apache/derbyBuild/ReportParser.java Wed Apr 21 20:02:48 2010 @@ -0,0 +1,247 @@ +/* + + Derby - Class org.apache.derbyBuild.ReportParser + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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 org.apache.derbyBuild; + +import java.util.HashSet; +import java.text.ParseException; + +/** + *

+ * This is the machine which parses a JIRA report, extracting information needed to generate + * release notes. You will probably have to create a separate implementation of + * this class for each release. That is because the JIRA reports change shape between releases. + *

+ * + *

+ * When you need to generate release notes for a new release, edit this file as follows: + *

+ * + *
    + *
  • Create a new inner subclass, modelled on April_2010. Your new inner subclass will + * provide the parsing logic specific to the shape of JIRA reports at that time.
  • + *
  • Change makeReportParser() to return an instance of your new inner subclass.
  • + *
+ */ +public abstract class ReportParser +{ + ///////////////////////////////////////////////////////////////////////// + // + // CONSTANTS + // + ///////////////////////////////////////////////////////////////////////// + + public static final long NO_RELEASE_NOTE = -1; + + ///////////////////////////////////////////////////////////////////////// + // + // STATE + // + /////////////////////////////////////////////////////////////////////////f + + ///////////////////////////////////////////////////////////////////////// + // + // CONSTRUCTORS + // + ///////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////// + // + // STATIC BEHAVIOR + // + ///////////////////////////////////////////////////////////////////////// + + /** + *

+ * Create a ReportParser which understands the current shape of JIRA reports. + *

+ */ + public static ReportParser makeReportParser() + { + return new April_2010(); + } + + ///////////////////////////////////////////////////////////////////////// + // + // ABSTRACT BEHAVIOR TO BE RE-IMPLEMENTED FOR EACH RELEASE + // + ///////////////////////////////////////////////////////////////////////// + + /** + *

+ * Return a TagReader wrapped around the next JIRA issue in the report. + *

+ * + * @param masterReport A TagReader wrapped around the JIRA report. + * + * @return A TagReader wrapped around the next issue in the report. Returns null if there are no more issues. + */ + public abstract TagReader parseNextIssue( TagReader masterReport ) throws Exception; + + /** + *

+ * Parse the numeric Derby JIRA id out of an issue description. For instance, + * for DERBY-1234, this method returns the string "1234". + *

+ * + * @param tr A TagReader positioned on the JIRA issue which is to be parsed. + * + * @return The numeric id of the Derby JIRA issue as a string. + */ + public abstract String parseKey( TagReader tr ) throws Exception; + + /** + *

+ * Parse the title (one line summary) out of a Derby JIRA description. + *

+ * + * @param tr A TagReader positioned on the JIRA issue which is to be parsed. + * + * @return The one line summary of the issue. + */ + public abstract String parseTitle( TagReader tr ) throws Exception; + + /** + *

+ * Parse the set of Fixed-in versions out of a Derby JIRA description. + * These are the ids of all of the Derby versions in which the bug is fixed. + * For instance, this could be the set { "10.5.3.0", "10.6.0.0" }. + *

+ * + * @param tr A TagReader positioned on the JIRA issue which is to be parsed. + * + * @return The set of versions in which the bug is fixed. + */ + public abstract HashSet parseFixedVersions( TagReader tr ) throws Exception; + + /** + *

+ * Get the attachment id of the latest release note attached to an issue. + *

+ * + * @param tr A TagReader positioned on the JIRA issue which is to be parsed. + * + * @return The attachment id of the latest release note, or NO_RELEASE_NOTE if the issue has no release note. + */ + public abstract long getReleaseNoteAttachmentID( TagReader tr ) throws Exception; + + ///////////////////////////////////////////////////////////////////////// + // + // INNER CLASSES + // + ///////////////////////////////////////////////////////////////////////// + + /** + *

+ * A ReportParser which understands the format of Apache JIRA reports + * in April 2010. This ReportParser assumes that the report includes the following + * columns and was produced by selecting "Full Content" option under "Content View" + * and then saved to disk. For the 10.6.1 release, I produced the report using the JIRA filter called + * "10.6.1 Fixed Bugs List": + *

+ * + *
    + *
  • Key
  • + *
  • Summary
  • + *
  • Fix Version/s
  • + *
+ */ + public static final class April_2010 extends ReportParser + { + public TagReader parseNextIssue( TagReader masterReport ) throws Exception + { + int newIssueIdx = masterReport.position( "", true ); + + return new TagReader( issueContent ); + } + + public String parseKey( TagReader tr ) throws Exception + { + tr.reset(); + + tr.position( "issues.apache.org/jira/browse/DERBY-", true ); + String keyString = tr.getUpTill( "\">", true ); + + return keyString; + } + + public String parseTitle( TagReader tr ) throws Exception + { + tr.reset(); + + tr.position( "nav summary\">", true ); + tr.position( ">", true ); + String title = tr.getUpTill( "", true ); + + return title; + } + + public HashSet parseFixedVersions( TagReader tr ) throws Exception + { + tr.reset(); + + HashSet retval = new HashSet(); + + while ( tr.position( "fixforversion", false ) >= 0 ) + { + tr.position( ">", true ); + String version = tr.getUpTill( "<", true ); + + retval.add( version ); + } + + return retval; + } + + /** + *

+ * The attachment ids don't turn up in the html reports produced by the Apache + * JIRA site. So, lamely, we hardcode attachment ids here. For this ReportParser, + * we hardcode the attachment ids of the 10.6.1 release notes. + *

+ */ + public long getReleaseNoteAttachmentID( TagReader tr ) throws Exception + { + tr.reset(); + + long result = NO_RELEASE_NOTE; + String key = parseKey( tr ); + + if ( key.equals( "4602" ) ) { result = 12440335L; } + else if ( key.equals( "4483" ) ) { result = 12439775L; } + else if ( key.equals( "4432" ) ) { result = 12424709L; } + else if ( key.equals( "4380" ) ) { result = 12434514L; } + else if ( key.equals( "4355" ) ) { result = 12419298L; } + else if ( key.equals( "4312" ) ) { result = 12442288L; } + else if ( key.equals( "4230" ) ) { result = 12409466L; } + else if ( key.equals( "4191" ) ) { result = 12442312L; } + else if ( key.equals( "3991" ) ) { result = 12409798L; } + else if ( key.equals( "3844" ) ) { result = 12436979L; } + else if ( key.equals( "2769" ) ) { result = 12418474L; } + + return result; + } + } + +} Propchange: db/derby/code/trunk/java/build/org/apache/derbyBuild/ReportParser.java ------------------------------------------------------------------------------ svn:eol-style = native Added: db/derby/code/trunk/java/build/org/apache/derbyBuild/TagReader.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/TagReader.java?rev=936472&view=auto ============================================================================== --- db/derby/code/trunk/java/build/org/apache/derbyBuild/TagReader.java (added) +++ db/derby/code/trunk/java/build/org/apache/derbyBuild/TagReader.java Wed Apr 21 20:02:48 2010 @@ -0,0 +1,173 @@ +/* + + Derby - Class org.apache.derbyBuild.TagReader + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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 org.apache.derbyBuild; + +import java.io.*; +import java.text.ParseException; + +/** + *

+ * This little machine is constructed from an xml/html document/element and is used to parse + * content inside that element. This machine advances through the element, + * letting the operator look for substrings. This machine was created to read + * elements in JIRA's html reports, which are not well-formed xml documents. + *

+ * + *

+ * To operate the TagReader, keep positioning on substrings, following some + * pattern which allows you to navigate to the content you need. + *

+ */ +public class TagReader +{ + ///////////////////////////////////////////////////////////////////////// + // + // CONSTANTS + // + ///////////////////////////////////////////////////////////////////////// + + private static final int NOT_FOUND = -1; + + ///////////////////////////////////////////////////////////////////////// + // + // STATE + // + /////////////////////////////////////////////////////////////////////////f + + private String _content; + private int _cursor; + + ///////////////////////////////////////////////////////////////////////// + // + // CONSTRUCTORS + // + ///////////////////////////////////////////////////////////////////////// + + /** Wrap a TagReader around a piece of content */ + public TagReader( String content ) + { + if ( content == null ) { content = ""; } + + _content = content; + + init(); + } + + /** Wrap a TagReader around the content siphoned out of a stream */ + public TagReader( InputStream is ) throws IOException + { + StringWriter buffer = new StringWriter(); + + while( true ) + { + int nextChar = is.read(); + if ( nextChar < 0 ) { break; } + + buffer.write( nextChar ); + } + + _content = buffer.toString(); + + is.close(); + + init(); + } + + /** Initialization common to all constructors */ + private void init() + { + reset(); + } + + ///////////////////////////////////////////////////////////////////////// + // + // PUBLIC BEHAVIOR + // + ///////////////////////////////////////////////////////////////////////// + + /** + *

+ * Resets the reader to the beginning of the content. + *

+ */ + public void reset() + { + _cursor = 0; + } + + /** + *

+ * Starting at the current position, search for a substring in the content. If the substring is found, positions + * the reader AFTER the substring and returns that new cursor position. If the + * substring is not found, does not advance the cursor, but returns -1. + *

+ */ + public int position( String tag, boolean failIfNotFound ) throws ParseException + { + int retval = NOT_FOUND; + + if ( _cursor < _content.length() ) + { + retval = _content.indexOf( tag, _cursor ); + + if ( retval < 0 ) { retval = NOT_FOUND; } + else + { + retval += tag.length(); + _cursor = retval; + } + } + + if ( failIfNotFound && ( retval == NOT_FOUND ) ) + { + throw new ParseException( "Could not find substring '" + tag + "'", _cursor ); + } + + return retval; + } + + /** + *

+ * Starting at the current position, search for a substring in the content. If the + * substring is found, return everything from the cursor up to the start of the substring + * and position the reader AFTER the substring. If the substring is not found, return null + * and do not alter the cursor. + *

+ */ + public String getUpTill( String tag, boolean failIfNotFound ) throws ParseException + { + int oldCursor = _cursor; + int endIdx = position( tag, failIfNotFound ); + + if ( endIdx < 0 ) { return null; } + + return _content.substring( oldCursor, endIdx - tag.length() ); + } + + ///////////////////////////////////////////////////////////////////////// + // + // MINIONS + // + ///////////////////////////////////////////////////////////////////////// + + +} Propchange: db/derby/code/trunk/java/build/org/apache/derbyBuild/TagReader.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/tools/release/build.xml URL: http://svn.apache.org/viewvc/db/derby/code/trunk/tools/release/build.xml?rev=936472&r1=936471&r2=936472&view=diff ============================================================================== --- db/derby/code/trunk/tools/release/build.xml (original) +++ db/derby/code/trunk/tools/release/build.xml Wed Apr 21 20:02:48 2010 @@ -55,7 +55,6 @@ - @@ -109,18 +108,15 @@ Generate the Release Notes The ${relnotes.src.reports} property must point at a - directory containing the two JIRA reports: + directory containing a JIRA report: fixedBugsList.xml - This is a JIRA xml report of issues fixed in the release. - - releaseNotesList.xml - This is a JIRA xml report of issues having detailed release notes. -->