You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by my...@apache.org on 2007/07/27 04:10:22 UTC
svn commit: r560065 - in /db/derby/code/branches/10.3: ./
java/build/org/apache/derbyBuild/ tools/release/
Author: myrnavl
Date: Thu Jul 26 19:10:21 2007
New Revision: 560065
URL: http://svn.apache.org/viewvc?view=rev&rev=560065
Log:
release work: adding ChangesFileGenerator(see revision 560061 from trunk),
generated CHANGES file (with 2789 which is temporarily open while being
backported to 10.2. manually copied back in), and appropriate changes
for building files for 10.3.1.4, although there are no changes that should
go into the release notes at this point.
Added:
db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ChangesFileGenerator.java (with props)
Modified:
db/derby/code/branches/10.3/CHANGES.html
db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/JiraConnector.java
db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java
db/derby/code/branches/10.3/releaseSummary.xml
db/derby/code/branches/10.3/tools/release/build.xml
Modified: db/derby/code/branches/10.3/CHANGES.html
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/CHANGES.html?view=diff&rev=560065&r1=560064&r2=560065
==============================================================================
--- db/derby/code/branches/10.3/CHANGES.html (original)
+++ db/derby/code/branches/10.3/CHANGES.html Thu Jul 26 19:10:21 2007
@@ -1,21 +1,42 @@
<html>
-<title>Changes for Derby 10.3.1.3</title>
+<title>Changes for Derby 10.3.1.4</title>
<body>
<h1>
-<a name="Changes for Derby 10.3.1.3"></a>Changes for Derby 10.3.1.3</h1>
-<blockquote>
-<p>This table lists the issues in JIRA which were fixed between Derby release 10.3.1.3 and the preceding release 10.2.2.0. This includes issues for the product source, documentation and tests.</p>
-</blockquote>
+<a name="Changes for Derby 10.3.1.4"></a>Changes for Derby 10.3.1.4</h1>
+<blockquote></blockquote>
+<ul>
+<li>
+<a href="#CHANGES">CHANGES</a>
+</li>
+</ul>
+<h2>
+<a name="CHANGES"></a>CHANGES</h2>
<blockquote>
+<p>The following table lists issues in JIRA which were fixed between Derby release 10.3.1.4 and the preceding release 10.2.2.0. This includes issues for the product source, documentation and tests</p>
<table border="2">
<tr>
<td><b>Issue Id</b></td><td><b>Description</b></td>
</tr>
<tr>
-<td><a href="http://issues.apache.org/jira/browse/DERBY-2951">DERBY-2951</a></td><td>BatchUpdateTest.testAssociatedParams test fails with collation with exception: Java exception: 'ASSERT FAILED type of inserted column[0] = org.apache.derby.iapi.types.CollatorSQLChartype of template column[0] = org.apache.derby.iapi.types.SQLChar:</td>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2966">DERBY-2966</a></td><td>rs.moveToInsertRow() causes loss of connection with TERRITORY_BASED collation.</td>
+</tr>
+<tr>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2963">DERBY-2963</a></td><td>AccessControlException: Access denied java.net.SocketPermission <client ip> accept,resolve</td>
+</tr>
+<tr>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2960">DERBY-2960</a></td><td>Group by substr() on collated database causes ERROR XJ001: Java exception: 'ASSERT FAILED col1.getClass() (class org.apache.derby.iapi.types.SQLVarchar) expected to be the same as col2.getClass() (class org.apache.derby.iapi.types.CollatorSQLVarchar):</td>
+</tr>
+<tr>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2959">DERBY-2959</a></td><td>create table ... as select ... from systemtable with no data fails even when there is no character string type involved. This happens in a territory based database</td>
</tr>
<tr>
-<td><a href="http://issues.apache.org/jira/browse/DERBY-2941">DERBY-2941</a></td><td>With 10.2, Closing a resultset after retrieving a large > 32665 bytes value with Network Server does not release locks</td>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2955">DERBY-2955</a></td><td>ERROR 42ZA2 creating table with check constraint with literal comparison</td>
+</tr>
+<tr>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2951">DERBY-2951</a></td><td>BatchUpdateTest.testAssociatedParams test fails with collation with exception: Java exception: 'ASSERT FAILED type of inserted column[0] = org.apache.derby.iapi.types.CollatorSQLChartype of template column[0] = org.apache.derby.iapi.types.SQLChar: </td>
+</tr>
+<tr>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2941">DERBY-2941</a></td><td>With 10.2, Closing a resultset after retrieving a large > 32665 bytes value with Network Server does not release locks</td>
</tr>
<tr>
<td><a href="http://issues.apache.org/jira/browse/DERBY-2932">DERBY-2932</a></td><td>Connection.createClob() and Connection.createBlob() throw a procedure not found exception and do not switch to non-locator code upon soft upgrade</td>
@@ -340,6 +361,9 @@
</tr>
<tr>
<td><a href="http://issues.apache.org/jira/browse/DERBY-2657">DERBY-2657</a></td><td>Performance regression after check-in of svn 531971</td>
+</tr>
+<tr>
+<td><a href="http://issues.apache.org/jira/browse/DERBY-2656">DERBY-2656</a></td><td>Run suites.All against a collated database</td>
</tr>
<tr>
<td><a href="http://issues.apache.org/jira/browse/DERBY-2654">DERBY-2654</a></td><td>Document newly-supported (in embedded mode) JDBC methods for autogenerated keys.</td>
Added: db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ChangesFileGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ChangesFileGenerator.java?view=auto&rev=560065
==============================================================================
--- db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ChangesFileGenerator.java (added)
+++ db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ChangesFileGenerator.java Thu Jul 26 19:10:21 2007
@@ -0,0 +1,1236 @@
+/* Derby - Class org.apache.derbyBuild.ReleaseNotesGenerator
+
+ 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.net.URL;
+import java.util.ArrayList;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.*;
+import org.w3c.dom.*;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Echo;
+
+/**
+ * <p>
+ * This tool generates the Changes file for a Derby release. See the USAGE
+ * constant for details on how to run this tool standalone. It is recommended
+ * that you freshly regenerate your BUG_LIST just before you run this tool.
+ * </p>
+ *
+ * <p>
+ * The tool is designed to be run from Derby's ant build scripts. To run under
+ * ant, do the following:
+ * </p>
+ *
+ * <ul>
+ * <li>Define the "relnotes.src.reports" variable in your ant.properties. This
+ * variable points at the directory which holds your xml JIRA reports.</li>
+ * <li>Put your xml JIRA reports in that directory. They should have the
+ * following names:
+ * <ul>
+ * <li>fixedBugsList.xml - This is the list of issues fixed by the release.</li>
+ * </ul>
+ * </li>
+ * <li>You can use java org.apache.derbyBuild.JiraConnector to create this file.
+ * </li>
+ * <li>Then cd to tools/release and run ant thusly: "ant genchanges"</li>
+ * </ul>
+ *
+ * <p>For more information on this tool, please see the JIRA which introduce its companion, ReleaseNotesGenerator:
+ * </p>
+ *
+ * <p>
+ * <a href="http://issues.apache.org/jira/browse/DERBY-2570">DERBY-2570</a>
+ * </p>
+ */
+public class ChangesFileGenerator extends Task
+{
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // CONSTANTS
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ private static final String USAGE =
+ "Usage:\n" +
+ "\n" +
+ " java org.apache.derbyBuild.ChangesFileGenerator SUMMARY BUG_LIST OUTPUT_PAMPHLET\n" +
+ "\n" +
+ " where\n" +
+ " BUG_LIST An xml JIRA report of issues addressed by this release.\n" +
+ " OUTPUT_PAMPHLET The output file to generate, typically CHANGES.html.\n" +
+ "\n" +
+ "The ChangesFileGenerator attempts to connect to issues.apache.org in\n" +
+ "order to find the individual JIRAs. Before running this program, make sure that you can\n" +
+ "ping issues.apache.org.\n" +
+ "\n" +
+ "The ChangesFileGenerator assumes that the two JIRA reports contain\n" +
+ "key, title, and attachments elements for each Derby issue.\n" +
+ "For this reason, it is recommended that you freshly generate BUG_LIST\n" +
+ "just before you run this tool.\n"
+ ;
+
+ // header levels
+ private static final int BANNER_LEVEL = 1;
+ private static final int MAIN_SECTION_LEVEL = BANNER_LEVEL + 1;
+ private static final int ISSUE_DETAIL_LEVEL = MAIN_SECTION_LEVEL + 1;
+
+ // major sections
+ private static final String BUG_FIXES_SECTION = "CHANGES";
+
+ // headlines
+ private static final String BRANCH_HEADLINE = "Branch";
+ private static final String DESCRIPTION_HEADLINE = "Description";
+ private static final String ISSUE_ID_HEADLINE = "Issue Id";
+
+ // formatting tags
+ private static final String ANCHOR = "a";
+ private static final String BODY = "body";
+ private static final String BOLD = "b";
+ private static final String BORDER = "border";
+ private static final String COLUMN = "td";
+ private static final String HORIZONTAL_LINE = "hr";
+ private static final String HTML = "html";
+ private static final String INDENT = "blockquote";
+ private static final String LIST = "ul";
+ private static final String LIST_ELEMENT = "li";
+ private static final String NAME = "name";
+ private static final String PARAGRAPH = "p";
+ private static final String ROW = "tr";
+ private static final String TABLE = "table";
+
+ // tags in summary xml
+ private static final String SUM_BRANCH = "branch";
+ private static final String SUM_OVERVIEW = "overview";
+ private static final String SUM_PREVIOUS_RELEASE_ID = "previousReleaseID";
+ private static final String SUM_RELEASE_ID = "releaseID";
+
+ // tags in JIRA reports
+ private static final String JIRA_ID = "id";
+ private static final String JIRA_ITEM = "item";
+ private static final String JIRA_KEY = "key";
+ private static final String JIRA_NAME = "name";
+ private static final String JIRA_TITLE = "title";
+ private static final String JIRA_FIXIN = "fixVersion";
+
+ // managing releaseNote.html
+ private static final String RN_SUMMARY_OF_CHANGE = "Summary of Change";
+
+ // other JIRA control
+ private static final String RN_H4 = "h4";
+
+ // other html control
+ private static final int DEFAULT_TABLE_BORDER_WIDTH = 2;
+ private static final String XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // STATE
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ // set on the command line or by ant
+ private String _summaryFileName;
+ private String _bugListFileName;
+ private String _pamphletFileName;
+
+ // computed at run time
+ private String _releaseID;
+ private String _previousReleaseID;
+
+ // misc
+ private boolean _invokedByAnt = true;
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // INNER CLASSES
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * State used by the generator
+ * </p>
+ */
+ public static class GeneratorState
+ {
+ private DocumentBuilder _documentBuilder;
+ private Document _pamphlet;
+ private Document _summary;
+ private Document _bugList;
+ private ArrayList _errors;
+
+ public GeneratorState
+ (
+ DocumentBuilder documentBuilder,
+ Document pamphlet,
+ Document summary,
+ Document bugList
+ )
+ {
+ _documentBuilder = documentBuilder;
+ _pamphlet = pamphlet;
+ _summary = summary;
+ _bugList = bugList;
+
+ _errors = new ArrayList();
+ }
+
+ public void addError( String message )
+ {
+ _errors.add( message );
+ }
+
+ public DocumentBuilder getDocumentBuilder() { return _documentBuilder; }
+ public Document getPamphlet() { return _pamphlet; }
+ public Document getSummary() { return _summary; }
+ public Document getBugList() { return _bugList; }
+
+ public String[] getErrors()
+ {
+ String[] squeezed = new String[ _errors.size() ];
+
+ _errors.toArray( squeezed );
+
+ return squeezed;
+ }
+ }
+
+ /**
+ * <p>
+ * An issue from a JIRA report.
+ * </p>
+ */
+ public static class JiraIssue
+ {
+ private String _key;
+ private String _title;
+
+ public JiraIssue
+ (
+ String key,
+ String title
+ )
+ {
+ _key = key;
+ _title = title;
+ }
+
+ public String getKey() { return _key; }
+ public String getTitle() { return _title; }
+
+ public String getJiraAddress()
+ {
+ return "http://issues.apache.org/jira/browse/" + _key;
+ }
+
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // CONSTRUCTORS
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // ENTRY POINT
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Generate the changes file (for details on how to invoke this tool, see
+ * the header comment on this class).
+ * </p>
+ */
+ public static void main( String[] args )
+ throws Exception
+ {
+ ChangesFileGenerator me = new ChangesFileGenerator();
+
+ me._invokedByAnt = false;
+
+ if ( me.parseArgs( args ) ) { me.execute(); }
+ else { me.printUsage(); }
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // ANT Task BEHAVIOR
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ /** Ant accessor to set the name of the summary file prepared by the Release Manager */
+ public void setSummaryFileName( String summaryFileName ) { _summaryFileName = summaryFileName; }
+
+ /** Ant accessor to set the name of the JIRA-generated list of bugs addressed by this release */
+ public void setBugListFileName( String bugListFileName ) { _bugListFileName = bugListFileName; }
+
+ /** Ant accessor to set the name of the generated output file */
+ public void setPamphletFileName( String pamphletFileName ) { _pamphletFileName = pamphletFileName; }
+
+ /**
+ * <p>
+ * This is Ant's entry point into this task.
+ * </p>
+ */
+ public void execute()
+ throws BuildException
+ {
+ try {
+ GeneratorState gs = initialize();
+
+ beginPamphlet( gs );
+ buildBugList( gs );
+ replaceVariables( gs );
+ endPamphlet( gs );
+
+ printPamphlet( gs );
+ printErrors( gs );
+ }
+ catch ( Throwable t )
+ {
+ t.printStackTrace();
+
+ throw new BuildException( "Error running ChangeFileGenerator: " + t.getMessage(), t );
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // OTHER ACCESSORS
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Get the release ID from the summary file.
+ * </p>
+ */
+ private String getReleaseID( GeneratorState gs)
+ throws Exception
+ {
+ if ( _releaseID == null )
+ {
+ Document summary = gs.getSummary();
+ Element summaryRoot = summary.getDocumentElement();
+
+ _releaseID = squeezeText( getFirstChild( summaryRoot, SUM_RELEASE_ID ) );
+ }
+
+ return _releaseID;
+ }
+
+ /**
+ * <p>
+ * Get the previous release ID from the summary file.
+ * </p>
+ */
+ private String getPreviousReleaseID( GeneratorState gs)
+ throws Exception
+ {
+ if ( _previousReleaseID == null )
+ {
+ Document summary = gs.getSummary();
+ Element summaryRoot = summary.getDocumentElement();
+
+ _previousReleaseID = squeezeText( getFirstChild( summaryRoot, SUM_PREVIOUS_RELEASE_ID ) );
+ }
+
+ return _previousReleaseID;
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ //
+ // MINIONS
+ //
+ /////////////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////
+ //
+ // Boilerplate
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Start an html docment. Returns the body element.
+ * </p>
+ */
+ private void beginPamphlet( GeneratorState gs )
+ throws Exception
+ {
+ Document pamphlet = gs.getPamphlet();
+ String releaseID = getReleaseID( gs );
+ String titleText = "Changes for Derby " + releaseID;
+ Element html = pamphlet.createElement( HTML );
+ Element title = createTextElement( pamphlet, "title", titleText );
+ Element body = pamphlet.createElement( BODY );
+
+ pamphlet.appendChild( html );
+ html.appendChild( title );
+ html.appendChild( body );
+
+ Element bannerBlock = createHeader( body, BANNER_LEVEL, titleText );
+ buildDelta( gs, bannerBlock );
+
+ Element toc = createList( body );
+
+ createSection( body, MAIN_SECTION_LEVEL, toc, BUG_FIXES_SECTION, BUG_FIXES_SECTION );
+ }
+
+ /**
+ * <p>
+ * Finish the html document.
+ * </p>
+ */
+ private void endPamphlet( GeneratorState gs )
+ throws Exception
+ {
+ }
+
+ //////////////////////////////////
+ //
+ // Delta SECTION
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Note that this release is a delta from the previous one.
+ * </p>
+ */
+ private void buildDelta( GeneratorState gs, Element parent )
+ throws Exception
+ {
+ String releaseID = getReleaseID( gs );
+ String previousReleaseID = getPreviousReleaseID( gs );
+ String deltaStatement =
+ "These notes describe the difference between Derby release " + releaseID +
+ " and the preceding release " + previousReleaseID + ".";
+
+// addParagraph( parent, deltaStatement );
+ }
+
+ //////////////////////////////////
+ //
+ // Bug List SECTION
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Build the Bug List section.
+ * </p>
+ */
+ private void buildBugList( GeneratorState gs )
+ throws Exception
+ {
+ Document pamphlet = gs.getPamphlet();
+ Element bugListSection = getSection( pamphlet, MAIN_SECTION_LEVEL, BUG_FIXES_SECTION );
+ Document bugList = gs.getBugList();
+ JiraIssue[] bugs = getJiraIssues( bugList );
+ int count = bugs.length;
+ String releaseID = getReleaseID( gs );
+ String previousReleaseID = getPreviousReleaseID( gs );
+ String deltaStatement =
+ "The following table lists issues in JIRA which were fixed between " +
+ "Derby release " + releaseID + " and the preceding release " +
+ previousReleaseID + ". This includes issues for the product " +
+ "source, documentation and tests";
+
+ addParagraph( bugListSection, deltaStatement );
+
+ Element table = createTable
+ ( bugListSection, DEFAULT_TABLE_BORDER_WIDTH, new String[] { ISSUE_ID_HEADLINE, DESCRIPTION_HEADLINE } );
+
+ for ( int i = 0; i < count; i++ )
+ {
+ if (bugs[i] == null)
+ continue;
+ JiraIssue issue = bugs[ i ];
+ Element row = insertRow( table );
+ Element linkColumn = insertColumn( row );
+ Element descriptionColumn = insertColumn( row );
+ Element hotlink = createLink( pamphlet, issue.getJiraAddress(), issue.getKey() );
+ Text title = pamphlet.createTextNode( issue.getTitle() );
+
+ linkColumn.appendChild( hotlink );
+ descriptionColumn.appendChild( title );
+ }
+ }
+
+ //////////////////////////////////
+ //
+ // REPLACE VARIABLES
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Replace the known parameters with their corresponding text values.
+ * </p>
+ */
+ private void replaceVariables( GeneratorState gs )
+ throws Exception
+ {
+ Document pamphlet = gs.getPamphlet();
+
+ replaceTag( pamphlet, SUM_RELEASE_ID, getReleaseID( gs ) );
+ replaceTag( pamphlet, SUM_PREVIOUS_RELEASE_ID, getPreviousReleaseID( gs ) );
+ }
+
+ //////////////////////////////////
+ //
+ // Print the generated document.
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Print pamphlet to output file.
+ * </p>
+ */
+ private void printPamphlet( GeneratorState gs )
+ throws Exception
+ {
+ Document pamphlet = gs.getPamphlet();
+ Source source = new DOMSource( pamphlet );
+ File outputFile = new File( _pamphletFileName );
+ Result result = new StreamResult( outputFile );
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+
+ transformer.transform( source, result );
+ }
+
+ //////////////////////////////////
+ //
+ // Print errors
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Print errors.
+ * </p>
+ */
+ private void printErrors( GeneratorState gs )
+ throws Exception
+ {
+ String[] errors = gs.getErrors();
+ int count = errors.length;
+
+ if ( count > 0 )
+ {
+ println( "The following other errors occurred:" );
+
+ for ( int i = 0; i < count; i++ )
+ {
+ String error = errors[ i ];
+
+ println( "\n" + error );
+ }
+ }
+ }
+
+ //////////////////////////////////
+ //
+ // ARGUMENT MINIONS
+ //
+ //////////////////////////////////
+
+ /**
+ * <p>
+ * Returns true if arguments parse successfully, false otherwise.
+ * </p>
+ */
+ private boolean parseArgs( String[] args )
+ throws Exception
+ {
+ if ( (args == null) || (args.length != 4) ) { return false; }
+
+ int idx = 0;
+
+ setSummaryFileName( args[ idx++ ] );
+ setBugListFileName( args[ idx++ ] );
+ setPamphletFileName( args[ idx++ ] );
+
+ return true;
+ }
+
+ private void printUsage()
+ {
+ println( USAGE );
+ }
+
+ /**
+ * <p>
+ * Make sure that the input files all exist. Returns a state variable for the generator.
+ * </p>
+ */
+ private GeneratorState initialize()
+ throws Exception
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document pamphlet = builder.newDocument();
+ File summaryFile = new File( _summaryFileName );
+ File bugListFile = new File( _bugListFileName );
+ Document summary = builder.parse( summaryFile );
+ Document bugList = builder.parse( bugListFile );
+
+ return new GeneratorState
+ (
+ builder,
+ pamphlet,
+ summary,
+ bugList
+ );
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // HTML MINIONS
+ //
+ ////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Create a section at the end of a parent element and link to it from a
+ * table of contents.
+ * </p>
+ */
+ private Element createSection( Element parent, int sectionLevel, Element toc, String sectionName, String tocEntry )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Text textNode = doc.createTextNode( tocEntry );
+
+ return createSection( parent, sectionLevel, toc, sectionName, textNode );
+ }
+
+ /**
+ * <p>
+ * Create a section at the end of a parent element and link to it from a
+ * table of contents.
+ * </p>
+ */
+ private Element createSection( Element parent, int sectionLevel, Element toc, String sectionName, Node visibleText )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Element link = createLocalLink( doc, sectionName, visibleText );
+
+ addListItem( toc, link );
+
+ return createHeader( parent, sectionLevel, sectionName );
+ }
+
+ /**
+ * <p>
+ * Create a header at the end of the parent node. Return the block created
+ * to hold the text following this header.
+ * </p>
+ */
+ private Element createHeader( Element parent, int headerLevel, String text )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Text textNode = doc.createTextNode( text );
+ Element header = doc.createElement( makeHeaderTag( headerLevel ) );
+ Element anchor = doc.createElement( ANCHOR );
+ Element block =doc.createElement( INDENT );
+
+ parent.appendChild( header );
+ anchor.setAttribute( NAME, text );
+ header.appendChild( anchor );
+ header.appendChild( textNode );
+ parent.appendChild( block );
+
+ return block;
+ }
+
+ /**
+ * <p>
+ * Create an html text element.
+ * </p>
+ */
+ private Element createTextElement( Document doc, String tag, String text )
+ throws Exception
+ {
+ Element retval = doc.createElement( tag );
+ Text textNode = doc.createTextNode( text );
+
+ retval.appendChild( textNode );
+
+ return retval;
+ }
+
+ /**
+ * <p>
+ * Create a standard link to a local label.
+ * </p>
+ */
+ private Element createLocalLink( Document doc, String anchor, String text )
+ throws Exception
+ {
+ Text textNode = doc.createTextNode( text );
+
+ return createLocalLink( doc, anchor, textNode );
+ }
+
+ /**
+ * <p>
+ * Create a standard link to a local label.
+ * </p>
+ */
+ private Element createLocalLink( Document doc, String anchor, Node visibleText )
+ throws Exception
+ {
+ return createLink( doc, "#" + anchor, visibleText );
+ }
+
+ /**
+ * <p>
+ * Create a hotlink.
+ * </p>
+ */
+ private Element createLink( Document doc, String label, String text )
+ throws Exception
+ {
+ Text textNode = doc.createTextNode( text );
+
+ return createLink( doc, label, textNode );
+ }
+
+ /**
+ * <p>
+ * Create a hotlink.
+ * </p>
+ */
+ private Element createLink( Document doc, String label, Node visibleText )
+ throws Exception
+ {
+ Element hotlink = doc.createElement( ANCHOR );
+
+ hotlink.setAttribute( "href", label );
+ hotlink.appendChild( visibleText );
+
+ return hotlink;
+ }
+
+ /**
+ * <p>
+ * Insert a list at the end of the parent element.
+ * </p>
+ */
+ private Element createList( Element parent )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Element list = doc.createElement( LIST );
+
+ parent.appendChild( list );
+
+ return list;
+ }
+
+ /**
+ * <p>
+ * Add an item with a bold name to the end of a list.
+ * </p>
+ */
+ private Element addHeadlinedItem( Element list, String headline, String text )
+ throws Exception
+ {
+ Document doc = list.getOwnerDocument();
+ Element itemElement = doc.createElement( LIST_ELEMENT );
+ Element boldText = boldText( doc, headline );
+ Text textNode = doc.createTextNode( " - " + text );
+
+ list.appendChild( itemElement );
+ itemElement.appendChild( boldText );
+ itemElement.appendChild( textNode );
+
+ return itemElement;
+ }
+
+ /**
+ * <p>
+ * Make some bold text.
+ * </p>
+ */
+ private Element boldText( Document doc, String text)
+ throws Exception
+ {
+ Element bold = createTextElement( doc, BOLD, text );
+
+ return bold;
+ }
+
+ /**
+ * <p>
+ * Add an item to the end of a list.
+ * </p>
+ */
+ private Element addListItem( Element list, Node item )
+ throws Exception
+ {
+ Document doc = list.getOwnerDocument();
+ Element itemElement = doc.createElement( LIST_ELEMENT );
+
+ list.appendChild( itemElement );
+ itemElement.appendChild( item );
+
+ return itemElement;
+ }
+
+ /**
+ * <p>
+ * Retrieve the indented block inside a section
+ * </p>
+ */
+ private Element getSection( Document doc, int sectionLevel, String sectionName )
+ throws Exception
+ {
+ String headerTag = makeHeaderTag( sectionLevel );
+ Element root = doc.getDocumentElement();
+ NodeList sectionList = root.getElementsByTagName( headerTag );
+ int count = sectionList.getLength();
+
+ for ( int i = 0; i < count; i++ )
+ {
+ Element section = (Element) sectionList.item( i );
+ Element sectionAnchor = getFirstChild( section, ANCHOR );
+
+ if ( sectionName.equals( sectionAnchor.getAttribute( NAME ) ) )
+ {
+ // the next item after the section header, is the indented block
+
+ return (Element) section.getNextSibling();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * <p>
+ * Make the tag for a header, given its level
+ * </p>
+ */
+ private String makeHeaderTag( int headerLevel )
+ {
+ return "h" + Integer.toString( headerLevel );
+ }
+
+ /**
+ * <p>
+ * Add a paragraph to the end of a parent element.
+ * </p>
+ */
+ private Element addParagraph( Element parent, String text )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Text textNode = doc.createTextNode( text );
+ Element paragraph = doc.createElement( PARAGRAPH );
+
+ parent.appendChild( paragraph );
+ paragraph.appendChild( textNode );
+
+ return paragraph;
+ }
+
+ /**
+ * <p>
+ * Insert a table at the end of the parent element.
+ * </p>
+ */
+ private Element createTable( Element parent, int borderWidth, String[] columnHeadings )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Element table = doc.createElement( TABLE );
+ Element headingRow = insertRow( table );
+ int count = columnHeadings.length;
+
+ parent.appendChild( table );
+ table.setAttribute( BORDER, Integer.toString( borderWidth ) );
+
+ for ( int i = 0; i < count; i++ )
+ {
+ Element headingColumn = insertColumn( headingRow );
+ Element boldText = boldText( doc, columnHeadings[ i ] );
+
+ headingColumn.appendChild( boldText );
+ }
+
+ return table;
+ }
+
+ /**
+ * <p>
+ * Insert a row at the end of a table
+ * </p>
+ */
+ private Element insertRow( Element table )
+ throws Exception
+ {
+ Document doc = table.getOwnerDocument();
+ Element row = doc.createElement( ROW );
+
+ table.appendChild( row );
+
+ return row;
+ }
+
+ /**
+ * <p>
+ * Insert a column at the end of a row
+ * </p>
+ */
+ private Element insertColumn( Element row )
+ throws Exception
+ {
+ Document doc = row.getOwnerDocument();
+ Element column = doc.createElement( COLUMN );
+
+ row.appendChild( column );
+
+ return column;
+ }
+
+ /**
+ * <p>
+ * Insert a horizontal line at the end of the parent element.
+ * </p>
+ */
+ private Element insertLine( Element parent )
+ throws Exception
+ {
+ Document doc = parent.getOwnerDocument();
+ Element line = doc.createElement( HORIZONTAL_LINE );
+
+ parent.appendChild( line );
+
+ return line;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // XML MINIONS
+ //
+ ////////////////////////////////////////////////////////
+
+ private Element getFirstChild( Element node, String childName )
+ throws Exception
+ {
+ Element retval = getOptionalChild( node, childName );
+
+ if ( retval == null )
+ {
+ throw new BuildException( "Could not find child element '" + childName + "' in parent element '" + node.getNodeName() + "'." );
+ }
+
+ return retval;
+ }
+
+ private Element getNextChild( Element node, String childName, int index )
+ throws Exception
+ {
+ Element retval = (Element) node.getElementsByTagName( childName ).item( index );
+
+ if ( retval == null )
+ {
+ throw new BuildException( "Could not find child element '" + childName + "' in parent element '" + node.getNodeName() + "'." );
+ }
+
+ return retval;
+ }
+
+ private Element getOptionalChild( Element node, String childName )
+ throws Exception
+ {
+ return (Element) node.getElementsByTagName( childName ).item( 0 );
+ }
+
+ /**
+ * <p>
+ * Squeeze the text out of an Element.
+ * </p>
+ */
+ private String squeezeText( Element node )
+ throws Exception
+ {
+ Node textChild = node.getFirstChild();
+ String text = textChild.getNodeValue();
+
+ return text;
+ }
+
+ /**
+ * <p>
+ * Clone all of the children of a source node and add them as children
+ * of a target node.
+ * </p>
+ */
+ private void cloneChildren( Node source, Node target )
+ throws Exception
+ {
+ Document targetDoc = target.getOwnerDocument();
+ NodeList sourceChildren = source.getChildNodes();
+ int count = sourceChildren.getLength();
+
+ for ( int i = 0; i < count; i++ )
+ {
+ Node sourceChild = sourceChildren.item( i );
+ Node targetChild = targetDoc.importNode( sourceChild, true );
+
+ target.appendChild( targetChild );
+ }
+ }
+
+ /**
+ * <p>
+ * Replace all instances of the tag with the indicated text.
+ * </p>
+ */
+ private void replaceTag( Document doc, String tag, String replacementText )
+ throws Exception
+ {
+ NodeList sourceChildren = doc.getElementsByTagName( tag );
+ int count = sourceChildren.getLength();
+
+ for ( int i = 0; i < count; i++ )
+ {
+ Node oldChild = sourceChildren.item( i );
+ Node newChild = doc.createTextNode( replacementText );
+
+ if ( oldChild != null )
+ {
+ Node parent = oldChild.getParentNode();
+
+ if ( parent != null ) { parent.insertBefore( newChild, oldChild ); }
+ }
+ }
+
+ for ( int i = count-1; i > -1; i-- )
+ {
+ Node oldChild = sourceChildren.item( i );
+
+ if ( oldChild != null )
+ {
+ Node parent = oldChild.getParentNode();
+
+ if ( parent != null ) { parent.removeChild( oldChild ); }
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // JIRA MINIONS
+ //
+ ////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Get an array of JiraIssues from a JIRA report.
+ * </p>
+ */
+ private JiraIssue[] getJiraIssues( Document report )
+ throws Exception
+ {
+ Element reportRoot = report.getDocumentElement();
+ NodeList itemList = reportRoot.getElementsByTagName( JIRA_ITEM );
+ int count = itemList.getLength();
+ JiraIssue[] issues = new JiraIssue[ count ];
+
+
+
+ //for ( int i = 0; i < count; i++ ) { issues[ i ] = makeJiraIssue( (Element) itemList.item( i ) ); }
+ for ( int i = 0; i < count; i++ )
+ {
+ JiraIssue ji = makeJiraIssue( (Element) itemList.item( i ) );
+ if (ji != null)
+ {
+ issues[ i ] = ji;
+ }
+ }
+
+ return issues;
+ }
+
+ /**
+ * <p>
+ * Create a JiraIssue from an <item> element in a JIRA report.
+ * </p>
+ */
+ private JiraIssue makeJiraIssue( Element itemElement )
+ throws Exception
+ {
+ String key = squeezeText( getFirstChild( itemElement, JIRA_KEY ) );
+ String title = squeezeText( getFirstChild( itemElement, JIRA_TITLE ) );
+
+ //
+ // 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, title.length() );
+
+ //return new JiraIssue( key, title, releaseNoteAttachmentID );
+ String type=squeezeText(getFirstChild(itemElement, "type"));
+
+ try {
+ String resolution=squeezeText(getOptionalChild(itemElement, "resolution"));
+ if (resolution != null)
+ {
+ if (!resolution.equals("Fixed"))
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+
+ String fixVersion=null;
+ try {
+ fixVersion=squeezeText(getOptionalChild(itemElement, JIRA_FIXIN));
+ } catch (Exception e) {
+ return null;
+ }
+
+ while (fixVersion != null)
+ {
+
+ NodeList subItemList = itemElement.getElementsByTagName( JIRA_FIXIN );
+ int fixcount = subItemList.getLength();
+ for (int i=0; i<fixcount; i++)
+ {
+ // if we encounter the previous release's ID, we can do away with entire issue
+ if (_previousReleaseID.equals(fixVersion))
+ {
+ return null;
+ }
+ // hardcode excluding 10.2.1.6; we want to exclude those also
+ if (fixVersion.equals("10.2.1.6"))
+ {
+ return null;
+ }
+ // if the first fixVersion does not match the current release, or the beta,
+ // check the next one
+ if ( (!_releaseID.equals(fixVersion)) &&
+ (!"10.3.0.0".equals(fixVersion)) &&
+ (!"10.3.1.1".equals(fixVersion)) &&
+ (!"10.3.1.2".equals(fixVersion)) &&
+ (!"10.3.1.3".equals(fixVersion))) {
+ try {
+ fixVersion = squeezeText(getNextChild( itemElement, JIRA_FIXIN, i+1));
+ continue;
+ } catch (Exception e) {
+ fixVersion=null;
+ return null;
+ }
+ }
+ }
+ return new JiraIssue( key, title );
+ }
+ return null;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // EXCEPTION PROCESSING MINIONS
+ //
+ ////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Special processing for special exceptions.
+ * </p>
+ */
+ private void processThrowable( Throwable t )
+ {
+ if ( t instanceof java.net.UnknownHostException )
+ {
+ println( "Unknown host '" + t.getMessage() + "'. Can you ping this host from a shell window?" );
+ }
+ }
+
+ /**
+ * <p>
+ * Format an error for later reporting.
+ * </p>
+ */
+ private String formatError( String text, Throwable t )
+ {
+ text = text + ": " + t.toString() + "\n" + stringifyStackTrace( t );
+
+ return text;
+ }
+
+ /**
+ * <p>
+ * Print a stack trace as a string.
+ * </p>
+ */
+ private String stringifyStackTrace( Throwable t )
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter( sw, true );
+
+ t.printStackTrace( pw );
+ pw.flush();
+ sw.flush();
+
+ return sw.toString();
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // MISC MINIONS
+ //
+ ////////////////////////////////////////////////////////
+
+ private void println( String text )
+ {
+ if ( _invokedByAnt )
+ {
+ log( text, Project.MSG_WARN );
+ }
+ else
+ {
+ System.out.println( text );
+ }
+ }
+
+}
+
Propchange: db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ChangesFileGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/JiraConnector.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/JiraConnector.java?view=diff&rev=560065&r1=560064&r2=560065
==============================================================================
--- db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/JiraConnector.java (original)
+++ db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/JiraConnector.java Thu Jul 26 19:10:21 2007
@@ -50,7 +50,9 @@
public static String jira_fixedBugsSource =
"http://issues.apache.org/jira/sr/jira.issueviews:" +
"searchrequest-xml/temp/SearchRequest.xml?&pid=10594&resolution=1&" +
- "fixVersion=10.3.0.0&fixVersion=10.3.1.1&fixVersion=10.3.1.2&fixVersion=10.3.1.3&sorter/field=issuekey&sorter/order=DESC&" +
+ "fixVersion=10.3.0.0&fixVersion=10.3.1.1&fixVersion=10.3.1.2&" +
+ "fixVersion=10.3.1.3&fixVersion=10.3.1.4&" +
+ "sorter/field=issuekey&sorter/order=DESC&" +
"tempMax=2000&reset=true&decorator=none";
// other urls to some cute jira reports in xml.
Modified: db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java?view=diff&rev=560065&r1=560064&r2=560065
==============================================================================
--- db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java (original)
+++ db/derby/code/branches/10.3/java/build/org/apache/derbyBuild/ReleaseNotesGenerator.java Thu Jul 26 19:10:21 2007
@@ -1505,7 +1505,7 @@
}
// if the first fixVersion does not match the current release, or the beta,
// check the next one
- if ( (!_releaseID.equals(fixVersion)) && (!"10.3.0.0".equals(fixVersion)) && (!"10.3.1.1".equals(fixVersion)) && (!"10.3.1.2".equals(fixVersion))) {
+ if ( (!_releaseID.equals(fixVersion)) && (!"10.3.0.0".equals(fixVersion)) && (!"10.3.1.1".equals(fixVersion)) && (!"10.3.1.2".equals(fixVersion)) && (!"10.3.1.3".equals(fixVersion))) {
try {
fixVersion = squeezeText(getNextChild( itemElement, JIRA_FIXIN, i+1));
continue;
Modified: db/derby/code/branches/10.3/releaseSummary.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/releaseSummary.xml?view=diff&rev=560065&r1=560064&r2=560065
==============================================================================
--- db/derby/code/branches/10.3/releaseSummary.xml (original)
+++ db/derby/code/branches/10.3/releaseSummary.xml Thu Jul 26 19:10:21 2007
@@ -29,9 +29,9 @@
<!--
Release identifier.
- E.g.: 10.3.0.3
+ E.g.: 10.3.0.4
-->
-<releaseID>10.3.1.3</releaseID>
+<releaseID>10.3.1.4</releaseID>
<!--
Identifier of previous release. The release notes describe the
Modified: db/derby/code/branches/10.3/tools/release/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/tools/release/build.xml?view=diff&rev=560065&r1=560064&r2=560065
==============================================================================
--- db/derby/code/branches/10.3/tools/release/build.xml (original)
+++ db/derby/code/branches/10.3/tools/release/build.xml Thu Jul 26 19:10:21 2007
@@ -57,6 +57,7 @@
<property name="relnotes.src.buglist" value="${relnotes.src.reports}/fixedBugsList.xml" />
<property name="relnotes.src.notes" value="${relnotes.src.reports}/releaseNotesList.xml" />
<property name="relnotes.out.pamphlet" value="${basedir}/RELEASE-NOTES.html" />
+ <property name="changesfile.out.pamphlet" value="${basedir}/CHANGES.html" />
<!-- Define the task which generates the release notes -->
<taskdef
@@ -65,6 +66,13 @@
classpath="${out.dir}"
/>
+<!-- Define the task which generates the release notes -->
+ <taskdef
+ name="generateChangesFile"
+ classname="org.apache.derbyBuild.ChangesFileGenerator"
+ classpath="${out.dir}"
+ />
+
<!-- Targets -->
<target name="release" depends="clean,bin,lib,lib-debug,src"/>
@@ -113,6 +121,25 @@
bugListFileName="${relnotes.src.buglist}"
releaseNotesListFileName="${relnotes.src.notes}"
pamphletFileName="${relnotes.out.pamphlet}"
+ />
+
+ </target>
+
+<!--
+ Generate the Changes File Notes
+
+ The ${relnotes.src.reports} property must point at a
+ directory containing the following JIRA report:
+
+ fixedBugsList.xml - This is a JIRA xml report of issues fixed in the release.
+
+-->
+ <target name="genchanges">
+
+ <generateChangesFile
+ summaryFileName="${relnotes.src.summary}"
+ bugListFileName="${relnotes.src.buglist}"
+ pamphletFileName="${changesfile.out.pamphlet}"
/>
</target>