diff --git a/.hgtags b/.hgtags index 18f00fc6ce6..56f428ed291 100644 --- a/.hgtags +++ b/.hgtags @@ -302,3 +302,5 @@ c97e2d1bad9708d379793ba2a4c848eda14c741e jdk9-b55 ddb95d8f169b09544cc17e72a6baaff2400092f5 jdk9-b57 f40752db7773ca0c737f2ad88371e35c57fdfed7 jdk9-b58 da950f343762a856d69751570a4c07cfa68a415b jdk9-b59 +38f98cb6b33562a926ec3b79c7b34128be37647d jdk9-b60 +ac3f5a39d4ff14d70c365e12cf5ec8f2abd52a04 jdk9-b61 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 2b62f114837..b5bc828524d 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -302,3 +302,5 @@ eb7febe45865ba6b81f2ea68082262d0708a0b22 jdk9-b56 f25ee9f62427a9ba27418e5531a89754791a305b jdk9-b57 6e78dd9b121037719a065fe8fb25b936babdfecb jdk9-b58 39e8a131289e8386aa4c3e4b184faa812a7c0421 jdk9-b59 +9fa2185bee17462d1014538bff60af6e6f0b01e7 jdk9-b60 +ea38728b4f4bdd8fd0d7a89b18069f521cf05013 jdk9-b61 diff --git a/README-builds.html b/README-builds.html index edc8f742d65..b0cc892f9c4 100644 --- a/README-builds.html +++ b/README-builds.html @@ -41,7 +41,8 @@ The build is now a "configure && make" style build
  • - Any GNU make 3.81 or newer should work + Any GNU make 3.81 or newer should work, except on + Windows where 4.0 or newer is recommended.
  • The build should scale, i.e. more processors should @@ -358,8 +359,8 @@ For all systems:
    + *
    * When FEATURE_SECURE_PROCESSING is enabled, it is recommended that implementations * restrict external connections by default, though this may cause problems for applications * that process XML/XSD/XSL with external references. * - *

    + * *

    * Granting all access: the keyword "all" grants permission to all protocols. - *

    * *

    * System Property: The value of this property can be set or overridden by * system property {@code javax.xml.accessExternalSchema} - *

    * *

    * jaxp.properties: This configuration file is in standard @@ -323,12 +314,11 @@ public final class XMLConstants { * of the property. * * @since 1.7 - *

    */ public static final String ACCESS_EXTERNAL_SCHEMA = "http://javax.xml.XMLConstants/property/accessExternalSchema"; /** - *

    Property: accessExternalStylesheet

    + * Property: accessExternalStylesheet * *

    * Restrict access to the protocols specified for external references set by the @@ -338,7 +328,7 @@ public final class XMLConstants { * {@link javax.xml.transform.Transformer} for example, * {@link javax.xml.transform.TransformerConfigurationException} * will be thrown by the {@link javax.xml.transform.TransformerFactory}. - *

    + * *

    * Value: a list of protocols separated by comma. A protocol is the scheme portion of a * {@link java.net.URI}, or in the case of the JAR protocol, "jar" plus the scheme portion @@ -358,9 +348,8 @@ public final class XMLConstants { * Examples of protocols are file, http, jar:file. * * - *

    * - *

    + *

    * Default value: The default value is implementation specific and therefore not specified. * The following options are provided for consideration: *

    @@ -368,20 +357,18 @@ public final class XMLConstants { *
  • an empty string to deny all access to external references;
  • *
  • a specific protocol, such as file, to give permission to only the protocol;
  • *
  • the keyword "all" to grant permission to all protocols.
  • - *
    + *
    * When FEATURE_SECURE_PROCESSING is enabled, it is recommended that implementations * restrict external connections by default, though this may cause problems for applications * that process XML/XSD/XSL with external references. *
    - *

    + * *

    * Granting all access: the keyword "all" grants permission to all protocols. - *

    * *

    * System Property: The value of this property can be set or overridden by * system property {@code javax.xml.accessExternalStylesheet} - *

    * *

    * jaxp.properties: This configuration file is in standard diff --git a/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java index d3afb25888e..001b682e42b 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/DatatypeFactory.java @@ -32,11 +32,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Factory that creates new javax.xml.datatype Objects that map XML to/from Java Objects. + * Factory that creates new {@code javax.xml.datatype} {@code Object}s that map XML to/from Java {@code Object}s. *

    * A new instance of the {@code DatatypeFactory} is created through the {@link #newInstance()} method * that uses the following implementation resolution mechanisms to determine an implementation: - *

    *

      *
    1. * If the system property specified by {@link #DATATYPEFACTORY_PROPERTY}, "{@code javax.xml.datatype.DatatypeFactory}", @@ -89,9 +88,9 @@ import java.util.regex.Pattern; public abstract class DatatypeFactory { /** - *

      Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.

      + * Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3. * - *

      Default value is {@code javax.xml.datatype.DatatypeFactory}.

      + *

      Default value is {@code javax.xml.datatype.DatatypeFactory}. */ public static final String DATATYPEFACTORY_PROPERTY = // We use a String constant here, rather than calling @@ -100,16 +99,15 @@ public abstract class DatatypeFactory { "javax.xml.datatype.DatatypeFactory"; /** - *

      Default implementation class name as defined in - * JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.

      + * Default implementation class name as defined in + * JSR 206: Java(TM) API for XML Processing (JAXP) 1.3. * *

      Implementers should specify the name of an appropriate class * to be instantiated if no other implementation resolution mechanism - * succeeds.

      + * succeeds. * *

      Users should not refer to this field; it is intended only to * document a factory implementation detail. - *

      */ public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = // We use new String() here to prevent javadoc from generating @@ -130,18 +128,18 @@ public abstract class DatatypeFactory { Pattern.compile("[^YM]*[DT].*"); /** - *

      Protected constructor to prevent instantiation outside of package.

      + * Protected constructor to prevent instantiation outside of package. * - *

      Use {@link #newInstance()} to create a {@code DatatypeFactory}.

      + *

      Use {@link #newInstance()} to create a {@code DatatypeFactory}. */ protected DatatypeFactory() { } /** - *

      Obtain a new instance of a {@code DatatypeFactory}.

      + * Obtain a new instance of a {@code DatatypeFactory}. * *

      The implementation resolution mechanisms are defined in this - * Class's documentation.

      + * {@code Class}'s documentation. * * @return New instance of a {@code DatatypeFactory} * @@ -161,33 +159,33 @@ public abstract class DatatypeFactory { } /** - *

      Obtain a new instance of a {@code DatatypeFactory} from class name. + * Obtain a new instance of a {@code DatatypeFactory} from class name. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider - * should be loaded.

      + * should be loaded. * *

      Once an application has obtained a reference to a {@code DatatypeFactory} - * it can use the factory to configure and obtain datatype instances.

      + * it can use the factory to configure and obtain datatype instances. * * *

      Tip for Trouble-shooting

      - *

      Setting the jaxp.debug system property will cause + *

      Setting the {@code jaxp.debug} system property will cause * this method to print a lot of debug messages - * to System.err about what it is doing and where it is looking at.

      + * to {@code System.err} about what it is doing and where it is looking at. * - *

      If you have problems try:

      + *

      If you have problems try: *

            * java -Djaxp.debug=1 YourProgram ....
            * 
      * * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.datatype.DatatypeFactory}. * - * @param classLoader ClassLoader used to load the factory class. If null - * current Thread's context classLoader is used to load the factory class. + * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} + * current {@code Thread}'s context classLoader is used to load the factory class. * * @return New instance of a {@code DatatypeFactory} * - * @throws DatatypeConfigurationException if factoryClassName is null, or + * @throws DatatypeConfigurationException if {@code factoryClassName} is {@code null}, or * the factory class cannot be loaded, instantiated. * * @see #newInstance() @@ -201,11 +199,11 @@ public abstract class DatatypeFactory { } /** - *

      Obtain a new instance of a Duration - * specifying the Duration as its string representation, "PnYnMnDTnHnMnS", - * as defined in XML Schema 1.0 section 3.2.6.1.

      + * Obtain a new instance of a {@code Duration} + * specifying the {@code Duration} as its string representation, "PnYnMnDTnHnMnS", + * as defined in XML Schema 1.0 section 3.2.6.1. * - *

      XML Schema Part 2: Datatypes, 3.2.6 duration, defines duration as:

      + *

      XML Schema Part 2: Datatypes, 3.2.6 duration, defines {@code duration} as: *

      * duration represents a duration of time. * The value space of duration is a six-dimensional space where the coordinates designate the @@ -213,28 +211,28 @@ public abstract class DatatypeFactory { * These components are ordered in their significance by their order of appearance i.e. as * year, month, day, hour, minute, and second. *
      - *

      All six values are set and available from the created {@link Duration}

      + *

      All six values are set and available from the created {@link Duration} * *

      The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits - * if implementation capacities are exceeded.

      + * if implementation capacities are exceeded. * - * @param lexicalRepresentation String representation of a Duration. + * @param lexicalRepresentation {@code String} representation of a {@code Duration}. * - * @return New Duration created from parsing the lexicalRepresentation. + * @return New {@code Duration} created from parsing the {@code lexicalRepresentation}. * - * @throws IllegalArgumentException If lexicalRepresentation is not a valid representation of a Duration. + * @throws IllegalArgumentException If {@code lexicalRepresentation} is not a valid representation of a {@code Duration}. * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException if lexicalRepresentation is null. + * @throws NullPointerException if {@code lexicalRepresentation} is {@code null}. */ public abstract Duration newDuration(final String lexicalRepresentation); /** - *

      Obtain a new instance of a Duration - * specifying the Duration as milliseconds.

      + * Obtain a new instance of a {@code Duration} + * specifying the {@code Duration} as milliseconds. * - *

      XML Schema Part 2: Datatypes, 3.2.6 duration, defines duration as:

      + *

      XML Schema Part 2: Datatypes, 3.2.6 duration, defines {@code duration} as: *

      * duration represents a duration of time. * The value space of duration is a six-dimensional space where the coordinates designate the @@ -243,8 +241,8 @@ public abstract class DatatypeFactory { * year, month, day, hour, minute, and second. *
      *

      All six values are set by computing their values from the specified milliseconds - * and are available using the get methods of the created {@link Duration}. - * The values conform to and are defined by:

      + * and are available using the {@code get} methods of the created {@link Duration}. + * The values conform to and are defined by: *
        *
      • ISO 8601:2000(E) Section 5.5.3.2 Alternative format
      • *
      • @@ -259,38 +257,38 @@ public abstract class DatatypeFactory { * {@link java.util.Calendar#DATE} = 1, etc. * This is important as there are variations in the Gregorian Calendar, * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.

        + * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced. * * @param durationInMilliSeconds Duration in milliseconds to create. * - * @return New Duration representing durationInMilliSeconds. + * @return New {@code Duration} representing {@code durationInMilliSeconds}. */ public abstract Duration newDuration(final long durationInMilliSeconds); /** - *

        Obtain a new instance of a Duration - * specifying the Duration as isPositive, years, months, days, hours, minutes, seconds.

        + * Obtain a new instance of a {@code Duration} + * specifying the {@code Duration} as isPositive, years, months, days, hours, minutes, seconds. * *

        The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits - * if implementation capacities are exceeded.

        + * if implementation capacities are exceeded. * - *

        A null value indicates that field is not set.

        + *

        A {@code null} value indicates that field is not set. * - * @param isPositive Set to false to create a negative duration. When the length + * @param isPositive Set to {@code false} to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param years of this Duration - * @param months of this Duration - * @param days of this Duration - * @param hours of this Duration - * @param minutes of this Duration - * @param seconds of this Duration + * @param years of this {@code Duration} + * @param months of this {@code Duration} + * @param days of this {@code Duration} + * @param hours of this {@code Duration} + * @param minutes of this {@code Duration} + * @param seconds of this {@code Duration} * - * @return New Duration created from the specified values. + * @return New {@code Duration} created from the specified values. * * @throws IllegalArgumentException If the values are not a valid representation of a - * Duration: if all the fields (years, months, ...) are null or + * {@code Duration}: if all the fields (years, months, ...) are null or * if any of the fields is negative. * @throws UnsupportedOperationException If implementation cannot support requested values. */ @@ -304,24 +302,24 @@ public abstract class DatatypeFactory { final BigDecimal seconds); /** - *

        Obtain a new instance of a Duration - * specifying the Duration as isPositive, years, months, days, hours, minutes, seconds.

        + * Obtain a new instance of a {@code Duration} + * specifying the {@code Duration} as isPositive, years, months, days, hours, minutes, seconds. * - *

        A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

        + *

        A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * - * @param isPositive Set to false to create a negative duration. When the length + * @param isPositive Set to {@code false} to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param years of this Duration - * @param months of this Duration - * @param days of this Duration - * @param hours of this Duration - * @param minutes of this Duration - * @param seconds of this Duration + * @param years of this {@code Duration} + * @param months of this {@code Duration} + * @param days of this {@code Duration} + * @param hours of this {@code Duration} + * @param minutes of this {@code Duration} + * @param seconds of this {@code Duration} * - * @return New Duration created from the specified values. + * @return New {@code Duration} created from the specified values. * * @throws IllegalArgumentException If the values are not a valid representation of a - * Duration: if any of the fields is negative. + * {@code Duration}: if any of the fields is negative. * * @see #newDuration( * boolean isPositive, @@ -371,28 +369,30 @@ public abstract class DatatypeFactory { } /** - *

        Create a Duration of type xdt:dayTimeDuration by parsing its String representation, + * Create a {@code Duration} of type {@code xdt:dayTimeDuration} + * by parsing its {@code String} representation, * "PnDTnHnMnS", - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

        + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration. * - *

        The datatype xdt:dayTimeDuration is a subtype of xs:duration + *

        The datatype {@code xdt:dayTimeDuration} is a subtype of {@code xs:duration} * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

        + * This datatype resides in the namespace {@code http://www.w3.org/2003/11/xpath-datatypes}. * - *

        All four values are set and available from the created {@link Duration}

        + *

        All four values are set and available from the created {@link Duration} * *

        The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits - * if implementation capacities are exceeded.

        + * if implementation capacities are exceeded. * * @param lexicalRepresentation Lexical representation of a duration. * - * @return New Duration created using the specified lexicalRepresentation. + * @return New {@code Duration} created using the specified {@code lexicalRepresentation}. * - * @throws IllegalArgumentException If lexicalRepresentation is not a valid representation of a Duration expressed only in terms of days and time. + * @throws IllegalArgumentException If {@code lexicalRepresentation} is + * not a valid representation of a {@code Duration} expressed only in terms of days and time. * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException If lexicalRepresentation is null. + * @throws NullPointerException If {@code lexicalRepresentation} is {@code null}. */ public Duration newDurationDayTime(final String lexicalRepresentation) { // lexicalRepresentation must be non-null @@ -415,17 +415,18 @@ public abstract class DatatypeFactory { } /** - *

        Create a Duration of type xdt:dayTimeDuration using the specified milliseconds as defined in + * Create a {@code Duration} of type {@code xdt:dayTimeDuration} + * using the specified milliseconds as defined in * - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

        + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration. * - *

        The datatype xdt:dayTimeDuration is a subtype of xs:duration + *

        The datatype {@code xdt:dayTimeDuration} is a subtype of {@code xs:duration} * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

        + * This datatype resides in the namespace {@code http://www.w3.org/2003/11/xpath-datatypes}. * *

        All four values are set by computing their values from the specified milliseconds - * and are available using the get methods of the created {@link Duration}. - * The values conform to and are defined by:

        + * and are available using the {@code get} methods of the created {@link Duration}. + * The values conform to and are defined by: *
          *
        • ISO 8601:2000(E) Section 5.5.3.2 Alternative format
        • *
        • @@ -440,13 +441,13 @@ public abstract class DatatypeFactory { * {@link java.util.Calendar#DATE} = 1, etc. * This is important as there are variations in the Gregorian Calendar, * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getDays()} can be influenced.

          + * so the result of {@link Duration#getDays()} can be influenced. * - *

          Any remaining milliseconds after determining the day, hour, minute and second are discarded.

          + *

          Any remaining milliseconds after determining the day, hour, minute and second are discarded. * - * @param durationInMilliseconds Milliseconds of Duration to create. + * @param durationInMilliseconds Milliseconds of {@code Duration} to create. * - * @return New Duration created with the specified durationInMilliseconds. + * @return New {@code Duration} created with the specified {@code durationInMilliseconds}. * * @see * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration @@ -457,34 +458,34 @@ public abstract class DatatypeFactory { } /** - *

          Create a Duration of type xdt:dayTimeDuration using the specified - * day, hour, minute and second as defined in + * Create a {@code Duration} of type {@code xdt:dayTimeDuration} using the specified + * {@code day}, {@code hour}, {@code minute} and {@code second} as defined in * - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

          + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration. * - *

          The datatype xdt:dayTimeDuration is a subtype of xs:duration + *

          The datatype {@code xdt:dayTimeDuration} is a subtype of {@code xs:duration} * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

          + * This datatype resides in the namespace {@code http://www.w3.org/2003/11/xpath-datatypes}. * *

          The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits - * if implementation capacities are exceeded.

          + * if implementation capacities are exceeded. * - *

          A null value indicates that field is not set.

          + *

          A {@code null} value indicates that field is not set. * - * @param isPositive Set to false to create a negative duration. When the length + * @param isPositive Set to {@code false} to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param day Day of Duration. - * @param hour Hour of Duration. - * @param minute Minute of Duration. - * @param second Second of Duration. + * @param day Day of {@code Duration}. + * @param hour Hour of {@code Duration}. + * @param minute Minute of {@code Duration}. + * @param second Second of {@code Duration}. * - * @return New Duration created with the specified day, hour, minute - * and second. + * @return New {@code Duration} created with the specified {@code day}, {@code hour}, {@code minute} + * and {@code second}. * * @throws IllegalArgumentException If the values are not a valid representation of a - * Duration: if all the fields (day, hour, ...) are null or + * {@code Duration}: if all the fields (day, hour, ...) are null or * if any of the fields is negative. * @throws UnsupportedOperationException If implementation cannot support requested values. */ @@ -507,29 +508,29 @@ public abstract class DatatypeFactory { } /** - *

          Create a Duration of type xdt:dayTimeDuration using the specified - * day, hour, minute and second as defined in + * Create a {@code Duration} of type {@code xdt:dayTimeDuration} using the specified + * {@code day}, {@code hour}, {@code minute} and {@code second} as defined in * - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

          + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration. * - *

          The datatype xdt:dayTimeDuration is a subtype of xs:duration + *

          The datatype {@code xdt:dayTimeDuration} is a subtype of {@code xs:duration} * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

          + * This datatype resides in the namespace {@code http://www.w3.org/2003/11/xpath-datatypes}. * - *

          A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

          + *

          A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * - * @param isPositive Set to false to create a negative duration. When the length + * @param isPositive Set to {@code false} to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param day Day of Duration. - * @param hour Hour of Duration. - * @param minute Minute of Duration. - * @param second Second of Duration. + * @param day Day of {@code Duration}. + * @param hour Hour of {@code Duration}. + * @param minute Minute of {@code Duration}. + * @param second Second of {@code Duration}. * - * @return New Duration created with the specified day, hour, minute - * and second. + * @return New {@code Duration} created with the specified {@code day}, {@code hour}, {@code minute} + * and {@code second}. * * @throws IllegalArgumentException If the values are not a valid representation of a - * Duration: if any of the fields (day, hour, ...) is negative. + * {@code Duration}: if any of the fields (day, hour, ...) is negative. */ public Duration newDurationDayTime( final boolean isPositive, @@ -548,28 +549,30 @@ public abstract class DatatypeFactory { } /** - *

          Create a Duration of type xdt:yearMonthDuration by parsing its String representation, + * Create a {@code Duration} of type {@code xdt:yearMonthDuration} + * by parsing its {@code String} representation, * "PnYnM", - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

          + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration. * - *

          The datatype xdt:yearMonthDuration is a subtype of xs:duration + *

          The datatype {@code xdt:yearMonthDuration} is a subtype of {@code xs:duration} * whose lexical representation contains only year and month components. - * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.

          + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}. * - *

          Both values are set and available from the created {@link Duration}

          + *

          Both values are set and available from the created {@link Duration} * *

          The XML Schema specification states that values can be of an arbitrary size. - * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. - * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits - * if implementation capacities are exceeded.

          + * Implementations may chose not to or be incapable of supporting + * arbitrarily large and/or small values. An {@link UnsupportedOperationException} + * will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded. * * @param lexicalRepresentation Lexical representation of a duration. * - * @return New Duration created using the specified lexicalRepresentation. + * @return New {@code Duration} created using the specified {@code lexicalRepresentation}. * - * @throws IllegalArgumentException If lexicalRepresentation is not a valid representation of a Duration expressed only in terms of years and months. + * @throws IllegalArgumentException If {@code lexicalRepresentation} is not a valid representation of a {@code Duration} expressed only in terms of years and months. * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException If lexicalRepresentation is null. + * @throws NullPointerException If {@code lexicalRepresentation} is {@code null}. */ public Duration newDurationYearMonth( final String lexicalRepresentation) { @@ -594,17 +597,18 @@ public abstract class DatatypeFactory { } /** - *

          Create a Duration of type xdt:yearMonthDuration using the specified milliseconds as defined in + * Create a {@code Duration} of type {@code xdt:yearMonthDuration} + * using the specified milliseconds as defined in * - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

          + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration. * - *

          The datatype xdt:yearMonthDuration is a subtype of xs:duration + *

          The datatype {@code xdt:yearMonthDuration} is a subtype of {@code xs:duration} * whose lexical representation contains only year and month components. - * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.

          + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}. * *

          Both values are set by computing their values from the specified milliseconds - * and are available using the get methods of the created {@link Duration}. - * The values conform to and are defined by:

          + * and are available using the {@code get} methods of the created {@link Duration}. + * The values conform to and are defined by: *
            *
          • ISO 8601:2000(E) Section 5.5.3.2 Alternative format
          • *
          • @@ -619,13 +623,13 @@ public abstract class DatatypeFactory { * {@link java.util.Calendar#DATE} = 1, etc. * This is important as there are variations in the Gregorian Calendar, * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getMonths()} can be influenced.

            + * so the result of {@link Duration#getMonths()} can be influenced. * - *

            Any remaining milliseconds after determining the year and month are discarded.

            + *

            Any remaining milliseconds after determining the year and month are discarded. * - * @param durationInMilliseconds Milliseconds of Duration to create. + * @param durationInMilliseconds Milliseconds of {@code Duration} to create. * - * @return New Duration created using the specified durationInMilliseconds. + * @return New {@code Duration} created using the specified {@code durationInMilliseconds}. */ public Duration newDurationYearMonth( final long durationInMilliseconds) { @@ -646,27 +650,27 @@ public abstract class DatatypeFactory { } /** - *

            Create a Duration of type xdt:yearMonthDuration using the specified - * year and month as defined in + * Create a {@code Duration} of type {@code xdt:yearMonthDuration} using the specified + * {@code year} and {@code month} as defined in * - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

            + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration. * *

            The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits - * if implementation capacities are exceeded.

            + * if implementation capacities are exceeded. * - *

            A null value indicates that field is not set.

            + *

            A {@code null} value indicates that field is not set. * - * @param isPositive Set to false to create a negative duration. When the length + * @param isPositive Set to {@code false} to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param year Year of Duration. - * @param month Month of Duration. + * @param year Year of {@code Duration}. + * @param month Month of {@code Duration}. * - * @return New Duration created using the specified year and month. + * @return New {@code Duration} created using the specified {@code year} and {@code month}. * * @throws IllegalArgumentException If the values are not a valid representation of a - * Duration: if all of the fields (year, month) are null or + * {@code Duration}: if all of the fields (year, month) are null or * if any of the fields is negative. * @throws UnsupportedOperationException If implementation cannot support requested values. */ @@ -687,22 +691,22 @@ public abstract class DatatypeFactory { } /** - *

            Create a Duration of type xdt:yearMonthDuration using the specified - * year and month as defined in + * Create a {@code Duration} of type {@code xdt:yearMonthDuration} using the specified + * {@code year} and {@code month} as defined in * - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

            + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration. * - *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

            + *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * - * @param isPositive Set to false to create a negative duration. When the length + * @param isPositive Set to {@code false} to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param year Year of Duration. - * @param month Month of Duration. + * @param year Year of {@code Duration}. + * @param month Month of {@code Duration}. * - * @return New Duration created using the specified year and month. + * @return New {@code Duration} created using the specified {@code year} and {@code month}. * * @throws IllegalArgumentException If the values are not a valid representation of a - * Duration: if any of the fields (year, month) is negative. + * {@code Duration}: if any of the fields (year, month) is negative. */ public Duration newDurationYearMonth( final boolean isPositive, @@ -716,44 +720,44 @@ public abstract class DatatypeFactory { } /** - *

            Create a new instance of an XMLGregorianCalendar.

            + * Create a new instance of an {@code XMLGregorianCalendar}. * - *

            All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.

            + *

            All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null. * - * @return New XMLGregorianCalendar with all date/time datatype fields set to + * @return New {@code XMLGregorianCalendar} with all date/time datatype fields set to * {@link DatatypeConstants#FIELD_UNDEFINED} or null. */ public abstract XMLGregorianCalendar newXMLGregorianCalendar(); /** - *

            Create a new XMLGregorianCalendar by parsing the String as a lexical representation.

            + * Create a new XMLGregorianCalendar by parsing the String as a lexical representation. * *

            Parsing the lexical string representation is defined in * XML Schema 1.0 Part 2, Section 3.2.[7-14].1, - * Lexical Representation.

            + * Lexical Representation. * - *

            The string representation may not have any leading and trailing whitespaces.

            + *

            The string representation may not have any leading and trailing whitespaces. * *

            The parsing is done field by field so that - * the following holds for any lexically correct String x:

            + * the following holds for any lexically correct String x: *
                  * newXMLGregorianCalendar(x).toXMLFormat().equals(x)
                  * 
            *

            Except for the noted lexical/canonical representation mismatches * listed in - * XML Schema 1.0 errata, Section 3.2.7.2.

            + * XML Schema 1.0 errata, Section 3.2.7.2. * * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. * - * @return XMLGregorianCalendar created from the lexicalRepresentation. + * @return {@code XMLGregorianCalendar} created from the {@code lexicalRepresentation}. * - * @throws IllegalArgumentException If the lexicalRepresentation is not a valid XMLGregorianCalendar. - * @throws NullPointerException If lexicalRepresentation is null. + * @throws IllegalArgumentException If the {@code lexicalRepresentation} is not a valid {@code XMLGregorianCalendar}. + * @throws NullPointerException If {@code lexicalRepresentation} is {@code null}. */ public abstract XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation); /** - *

            Create an XMLGregorianCalendar from a {@link GregorianCalendar}.

            + * Create an {@code XMLGregorianCalendar} from a {@link GregorianCalendar}. * * * @@ -764,30 +768,30 @@ public abstract class DatatypeFactory { * * * - * - * + * + * * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * * * *
            java.util.GregorianCalendar fieldjavax.xml.datatype.XMLGregorianCalendar field{@code java.util.GregorianCalendar} field{@code javax.xml.datatype.XMLGregorianCalendar} field
            ERA == GregorianCalendar.BC ? -YEAR : YEAR{@code ERA == GregorianCalendar.BC ? -YEAR : YEAR}{@link XMLGregorianCalendar#setYear(int year)}
            MONTH + 1{@code MONTH + 1}{@link XMLGregorianCalendar#setMonth(int month)}
            DAY_OF_MONTH{@code DAY_OF_MONTH}{@link XMLGregorianCalendar#setDay(int day)}
            HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND{@code HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND}{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}
            - * (ZONE_OFFSET + DST_OFFSET) / (60*1000)
            + * {@code (ZONE_OFFSET + DST_OFFSET) / (60*1000)}
            * (in minutes) *
            {@link XMLGregorianCalendar#setTimezone(int offset)}* @@ -796,49 +800,50 @@ public abstract class DatatypeFactory { *
            *

            *conversion loss of information. It is not possible to represent - * a java.util.GregorianCalendar daylight savings timezone id in the - * XML Schema 1.0 date/time datatype representation.

            + * a {@code java.util.GregorianCalendar} daylight savings timezone id in the + * XML Schema 1.0 date/time datatype representation. * - *

            To compute the return value's TimeZone field, + *

            To compute the return value's {@code TimeZone} field, *

              - *
            • when this.getTimezone() != FIELD_UNDEFINED, - * create a java.util.TimeZone with a custom timezone id - * using the this.getTimezone().
            • - *
            • else use the GregorianCalendar default timezone value + *
            • when {@code this.getTimezone() != FIELD_UNDEFINED}, + * create a {@code java.util.TimeZone} with a custom timezone id + * using the {@code this.getTimezone()}.
            • + *
            • else use the {@code GregorianCalendar} default timezone value * for the host is defined as specified by - * java.util.TimeZone.getDefault().
            • + * {@code java.util.TimeZone.getDefault()}. + *
            * - * @param cal java.util.GregorianCalendar used to create XMLGregorianCalendar + * @param cal {@code java.util.GregorianCalendar} used to create {@code XMLGregorianCalendar} * - * @return XMLGregorianCalendar created from java.util.GregorianCalendar + * @return {@code XMLGregorianCalendar} created from {@code java.util.GregorianCalendar} * - * @throws NullPointerException If cal is null. + * @throws NullPointerException If {@code cal} is {@code null}. */ public abstract XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal); /** - *

            Constructor allowing for complete value spaces allowed by + * Constructor allowing for complete value spaces allowed by * W3C XML Schema 1.0 recommendation for xsd:dateTime and related - * builtin datatypes. Note that year parameter supports + * builtin datatypes. Note that {@code year} parameter supports * arbitrarily large numbers and fractionalSecond has infinite - * precision.

            + * precision. * - *

            A null value indicates that field is not set.

            + *

            A {@code null} value indicates that field is not set. * - * @param year of XMLGregorianCalendar to be created. - * @param month of XMLGregorianCalendar to be created. - * @param day of XMLGregorianCalendar to be created. - * @param hour of XMLGregorianCalendar to be created. - * @param minute of XMLGregorianCalendar to be created. - * @param second of XMLGregorianCalendar to be created. - * @param fractionalSecond of XMLGregorianCalendar to be created. - * @param timezone of XMLGregorianCalendar to be created. + * @param year of {@code XMLGregorianCalendar} to be created. + * @param month of {@code XMLGregorianCalendar} to be created. + * @param day of {@code XMLGregorianCalendar} to be created. + * @param hour of {@code XMLGregorianCalendar} to be created. + * @param minute of {@code XMLGregorianCalendar} to be created. + * @param second of {@code XMLGregorianCalendar} to be created. + * @param fractionalSecond of {@code XMLGregorianCalendar} to be created. + * @param timezone of {@code XMLGregorianCalendar} to be created. * - * @return XMLGregorianCalendar created from specified values. + * @return {@code XMLGregorianCalendar} created from specified values. * * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid XMLGregorianCalendar instance + * or if the composite values constitute an invalid {@code XMLGregorianCalendar} instance * as determined by {@link XMLGregorianCalendar#isValid()}. */ public abstract XMLGregorianCalendar newXMLGregorianCalendar( @@ -852,29 +857,29 @@ public abstract class DatatypeFactory { final int timezone); /** - *

            Constructor of value spaces that a - * java.util.GregorianCalendar instance would need to convert to an - * XMLGregorianCalendar instance.

            + * Constructor of value spaces that a + * {@code java.util.GregorianCalendar} instance would need to convert to an + * {@code XMLGregorianCalendar} instance. * - *

            XMLGregorianCalendar eon and - * fractionalSecond are set to null

            + *

            {@code XMLGregorianCalendar eon} and + * {@code fractionalSecond} are set to {@code null} * - *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

            + *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * - * @param year of XMLGregorianCalendar to be created. - * @param month of XMLGregorianCalendar to be created. - * @param day of XMLGregorianCalendar to be created. - * @param hour of XMLGregorianCalendar to be created. - * @param minute of XMLGregorianCalendar to be created. - * @param second of XMLGregorianCalendar to be created. - * @param millisecond of XMLGregorianCalendar to be created. - * @param timezone of XMLGregorianCalendar to be created. + * @param year of {@code XMLGregorianCalendar} to be created. + * @param month of {@code XMLGregorianCalendar} to be created. + * @param day of {@code XMLGregorianCalendar} to be created. + * @param hour of {@code XMLGregorianCalendar} to be created. + * @param minute of {@code XMLGregorianCalendar} to be created. + * @param second of {@code XMLGregorianCalendar} to be created. + * @param millisecond of {@code XMLGregorianCalendar} to be created. + * @param timezone of {@code XMLGregorianCalendar} to be created. * - * @return XMLGregorianCalendar created from specified values. + * @return {@code XMLGregorianCalendar} created from specified values. * * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid XMLGregorianCalendar instance + * or if the composite values constitute an invalid {@code XMLGregorianCalendar} instance * as determined by {@link XMLGregorianCalendar#isValid()}. */ public XMLGregorianCalendar newXMLGregorianCalendar( @@ -918,26 +923,26 @@ public abstract class DatatypeFactory { } /** - *

            Create a Java representation of XML Schema builtin datatype date or g*.

            + * Create a Java representation of XML Schema builtin datatype {@code date} or {@code g*}. * - *

            For example, an instance of gYear can be created invoking this factory - * with month and day parameters set to - * {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            For example, an instance of {@code gYear} can be created invoking this factory + * with {@code month} and {@code day} parameters set to + * {@link DatatypeConstants#FIELD_UNDEFINED}. * - *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

            + *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * - * @param year of XMLGregorianCalendar to be created. - * @param month of XMLGregorianCalendar to be created. - * @param day of XMLGregorianCalendar to be created. + * @param year of {@code XMLGregorianCalendar} to be created. + * @param month of {@code XMLGregorianCalendar} to be created. + * @param day of {@code XMLGregorianCalendar} to be created. * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. * - * @return XMLGregorianCalendar created from parameter values. + * @return {@code XMLGregorianCalendar} created from parameter values. * * @see DatatypeConstants#FIELD_UNDEFINED * * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid XMLGregorianCalendar instance + * or if the composite values constitute an invalid {@code XMLGregorianCalendar} instance * as determined by {@link XMLGregorianCalendar#isValid()}. */ public XMLGregorianCalendar newXMLGregorianCalendarDate( @@ -958,20 +963,20 @@ public abstract class DatatypeFactory { } /** - *

            Create a Java instance of XML Schema builtin datatype time.

            + * Create a Java instance of XML Schema builtin datatype {@code time}. * - *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

            + *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * * @param hours number of hours * @param minutes number of minutes * @param seconds number of seconds * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. * - * @return XMLGregorianCalendar created from parameter values. + * @return {@code XMLGregorianCalendar} created from parameter values. * * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid XMLGregorianCalendar instance + * or if the composite values constitute an invalid {@code XMLGregorianCalendar} instance * as determined by {@link XMLGregorianCalendar#isValid()}. * * @see DatatypeConstants#FIELD_UNDEFINED @@ -994,24 +999,24 @@ public abstract class DatatypeFactory { } /** - *

            Create a Java instance of XML Schema builtin datatype time.

            + * Create a Java instance of XML Schema builtin datatype time. * - *

            A null value indicates that field is not set.

            - *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

            + *

            A {@code null} value indicates that field is not set. + *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * * @param hours number of hours * @param minutes number of minutes * @param seconds number of seconds - * @param fractionalSecond value of null indicates that this optional field is not set. + * @param fractionalSecond value of {@code null} indicates that this optional field is not set. * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. * - * @return XMLGregorianCalendar created from parameter values. + * @return {@code XMLGregorianCalendar} created from parameter values. * * @see DatatypeConstants#FIELD_UNDEFINED * * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid XMLGregorianCalendar instance + * or if the composite values constitute an invalid {@code XMLGregorianCalendar} instance * as determined by {@link XMLGregorianCalendar#isValid()}. */ public XMLGregorianCalendar newXMLGregorianCalendarTime( @@ -1033,9 +1038,9 @@ public abstract class DatatypeFactory { } /** - *

            Create a Java instance of XML Schema builtin datatype time.

            + * Create a Java instance of XML Schema builtin datatype time. * - *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

            + *

            A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set. * * @param hours number of hours * @param minutes number of minutes @@ -1043,13 +1048,13 @@ public abstract class DatatypeFactory { * @param milliseconds number of milliseconds * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. * - * @return XMLGregorianCalendar created from parameter values. + * @return {@code XMLGregorianCalendar} created from parameter values. * * @see DatatypeConstants#FIELD_UNDEFINED * * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid XMLGregorianCalendar instance + * or if the composite values constitute an invalid {@code XMLGregorianCalendar} instance * as determined by {@link XMLGregorianCalendar#isValid()}. */ public XMLGregorianCalendar newXMLGregorianCalendarTime( diff --git a/jaxp/src/java.xml/share/classes/javax/xml/datatype/Duration.java b/jaxp/src/java.xml/share/classes/javax/xml/datatype/Duration.java index 350f4af01cc..90f016edfed 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/Duration.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/Duration.java @@ -35,37 +35,37 @@ import javax.xml.namespace.QName; /** *

            Immutable representation of a time span as defined in - * the W3C XML Schema 1.0 specification.

            + * the W3C XML Schema 1.0 specification. * *

            A Duration object represents a period of Gregorian time, * which consists of six fields (years, months, days, hours, - * minutes, and seconds) plus a sign (+/-) field.

            + * minutes, and seconds) plus a sign (+/-) field. * - *

            The first five fields have non-negative (>=0) integers or null + *

            The first five fields have non-negative ({@literal >=}0) integers or null * (which represents that the field is not set), * and the seconds field has a non-negative decimal or null. - * A negative sign indicates a negative duration.

            + * A negative sign indicates a negative duration. * *

            This class provides a number of methods that make it easy * to use for the duration datatype of XML Schema 1.0 with - * the errata.

            + * the errata. * *

            Order relationship

            *

            Duration objects only have partial order, where two values A and B - * maybe either:

            + * maybe either: *
              - *
            1. A<B (A is shorter than B) - *
            2. A>B (A is longer than B) + *
            3. A{@literal <}B (A is shorter than B) + *
            4. A{@literal >}B (A is longer than B) *
            5. A==B (A and B are of the same duration) - *
            6. A<>B (Comparison between A and B is indeterminate) + *
            7. A{@literal <>}B (Comparison between A and B is indeterminate) *
            * *

            For example, 30 days cannot be meaningfully compared to one month. * The {@link #compare(Duration duration)} method implements this - * relationship.

            + * relationship. * *

            See the {@link #isLongerThan(Duration)} method for details about - * the order relationship among Duration objects.

            + * the order relationship among {@code Duration} objects. * *

            Operations over Duration

            *

            This class provides a set of basic arithmetic operations, such @@ -73,20 +73,20 @@ import javax.xml.namespace.QName; * Because durations don't have total order, an operation could * fail for some combinations of operations. For example, you cannot * subtract 15 days from 1 month. See the javadoc of those methods - * for detailed conditions where this could happen.

            + * for detailed conditions where this could happen. * *

            Also, division of a duration by a number is not provided because - * the Duration class can only deal with finite precision - * decimal numbers. For example, one cannot represent 1 sec divided by 3.

            + * the {@code Duration} class can only deal with finite precision + * decimal numbers. For example, one cannot represent 1 sec divided by 3. * *

            However, you could substitute a division by 3 with multiplying - * by numbers such as 0.3 or 0.333.

            + * by numbers such as 0.3 or 0.333. * *

            Range of allowed values

            *

            - * Because some operations of Duration rely on {@link Calendar} + * Because some operations of {@code Duration} rely on {@link Calendar} * even though {@link Duration} can hold very large or very small values, - * some of the methods may not work correctly on such Durations. + * some of the methods may not work correctly on such {@code Duration}s. * The impacted methods document their dependency on {@link Calendar}. * * @author Joseph Fialli @@ -99,7 +99,7 @@ import javax.xml.namespace.QName; public abstract class Duration { /** - *

            Debugging true or false.

            + * Debugging {@code true} or {@code false}. */ private static final boolean DEBUG = true; @@ -107,24 +107,24 @@ public abstract class Duration { * Default no-arg constructor. * *

            Note: Always use the {@link DatatypeFactory} to - * construct an instance of Duration. + * construct an instance of {@code Duration}. * The constructor on this class cannot be guaranteed to * produce an object with a consistent state and may be - * removed in the future.

            + * removed in the future. */ public Duration() { } /** - *

            Return the name of the XML Schema date/time type that this instance + * Return the name of the XML Schema date/time type that this instance * maps to. Type is computed based on fields that are set, - * i.e. {@link #isSet(DatatypeConstants.Field field)} == true.

            + * i.e. {@link #isSet(DatatypeConstants.Field field)} == {@code true}. * * * * * * @@ -238,16 +238,16 @@ public abstract class Duration { public abstract int getSign(); /** - *

            Get the years value of this Duration as an int or 0 if not present.

            + * Get the years value of this {@code Duration} as an {@code int} or {@code 0} if not present. * - *

            getYears() is a convenience method for - * {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)}.

            + *

            {@code getYears()} is a convenience method for + * {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)}. * - *

            As the return value is an int, an incorrect value will be returned for Durations - * with years that go beyond the range of an int. - * Use {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)} to avoid possible loss of precision.

            + *

            As the return value is an {@code int}, an incorrect value will be returned for {@code Duration}s + * with years that go beyond the range of an {@code int}. + * Use {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)} to avoid possible loss of precision. * - * @return If the years field is present, return its value as an int, else return 0. + * @return If the years field is present, return its value as an {@code int}, else return {@code 0}. */ public int getYears() { return getField(DatatypeConstants.YEARS).intValue(); @@ -260,7 +260,7 @@ public abstract class Duration { * This method works just like {@link #getYears()} except * that this method works on the MONTHS field. * - * @return Months of this Duration. + * @return Months of this {@code Duration}. */ public int getMonths() { return getField(DatatypeConstants.MONTHS).intValue(); @@ -273,7 +273,7 @@ public abstract class Duration { * This method works just like {@link #getYears()} except * that this method works on the DAYS field. * - * @return Days of this Duration. + * @return Days of this {@code Duration}. */ public int getDays() { return getField(DatatypeConstants.DAYS).intValue(); @@ -286,7 +286,7 @@ public abstract class Duration { * This method works just like {@link #getYears()} except * that this method works on the HOURS field. * - * @return Hours of this Duration. + * @return Hours of this {@code Duration}. * */ public int getHours() { @@ -300,7 +300,7 @@ public abstract class Duration { * This method works just like {@link #getYears()} except * that this method works on the MINUTES field. * - * @return Minutes of this Duration. + * @return Minutes of this {@code Duration}. * */ public int getMinutes() { @@ -323,32 +323,32 @@ public abstract class Duration { } /** - *

            Returns the length of the duration in milli-seconds.

            + * Returns the length of the duration in milli-seconds. * *

            If the seconds field carries more digits than milli-second order, * those will be simply discarded (or in other words, rounded to zero.) - * For example, for any Calendar value x,

            + * For example, for any Calendar value {@code x}, *
            -     * new Duration("PT10.00099S").getTimeInMills(x) == 10000.
            -     * new Duration("-PT10.00099S").getTimeInMills(x) == -10000.
            +     * {@code new Duration("PT10.00099S").getTimeInMills(x) == 10000}
            +     * {@code new Duration("-PT10.00099S").getTimeInMills(x) == -10000}
                  * 
            * *

            * Note that this method uses the {@link #addTo(Calendar)} method, - * which may work incorrectly with Duration objects with + * which may work incorrectly with {@code Duration} objects with * very large values in its fields. See the {@link #addTo(Calendar)} * method for details. * * @param startInstant - * The length of a month/year varies. The startInstant is + * The length of a month/year varies. The {@code startInstant} is * used to disambiguate this variance. Specifically, this method - * returns the difference between startInstant and - * startInstant+duration + * returns the difference between {@code startInstant} and + * {@code startInstant+duration} * - * @return milliseconds between startInstant and - * startInstant plus this Duration + * @return milliseconds between {@code startInstant} and + * {@code startInstant} plus this {@code Duration} * - * @throws NullPointerException if startInstant parameter + * @throws NullPointerException if {@code startInstant} parameter * is null. * */ @@ -360,33 +360,33 @@ public abstract class Duration { } /** - *

            Returns the length of the duration in milli-seconds.

            + * Returns the length of the duration in milli-seconds. * *

            If the seconds field carries more digits than milli-second order, * those will be simply discarded (or in other words, rounded to zero.) - * For example, for any Date value x,

            + * For example, for any {@code Date} value {@code x}, *
            -     * new Duration("PT10.00099S").getTimeInMills(x) == 10000.
            -     * new Duration("-PT10.00099S").getTimeInMills(x) == -10000.
            +     * {@code new Duration("PT10.00099S").getTimeInMills(x) == 10000}
            +     * {@code new Duration("-PT10.00099S").getTimeInMills(x) == -10000}
                  * 
            * *

            * Note that this method uses the {@link #addTo(Date)} method, - * which may work incorrectly with Duration objects with + * which may work incorrectly with {@code Duration} objects with * very large values in its fields. See the {@link #addTo(Date)} * method for details. * * @param startInstant - * The length of a month/year varies. The startInstant is + * The length of a month/year varies. The {@code startInstant} is * used to disambiguate this variance. Specifically, this method - * returns the difference between startInstant and - * startInstant+duration. + * returns the difference between {@code startInstant} and + * {@code startInstant+duration}. * * @throws NullPointerException * If the startInstant parameter is null. * - * @return milliseconds between startInstant and - * startInstant plus this Duration + * @return milliseconds between {@code startInstant} and + * {@code startInstant} plus this {@code Duration} * * @see #getTimeInMillis(Calendar) */ @@ -418,7 +418,7 @@ public abstract class Duration { * returns a {@link java.math.BigInteger} object. For SECONDS, this * method returns a {@link java.math.BigDecimal}. * - * @throws NullPointerException If the field is null. + * @throws NullPointerException If the {@code field} is {@code null}. */ public abstract Number getField(final DatatypeConstants.Field field); @@ -440,9 +440,9 @@ public abstract class Duration { public abstract boolean isSet(final DatatypeConstants.Field field); /** - *

            Computes a new duration whose value is this+rhs.

            + * Computes a new duration whose value is {@code this+rhs}. * - *

            For example,

            + *

            For example, *

                  * "1 day" + "-3 days" = "-2 days"
                  * "1 year" + "1 day" = "1 year and 1 day"
            @@ -453,28 +453,28 @@ public abstract class Duration {
                  *
                  * 

            Since there's no way to meaningfully subtract 1 day from 1 month, * there are cases where the operation fails in - * {@link IllegalStateException}.

            + * {@link IllegalStateException}. * *

            - * Formally, the computation is defined as follows.

            + * Formally, the computation is defined as follows. *

            - * Firstly, we can assume that two Durations to be added + * Firstly, we can assume that two {@code Duration}s to be added * are both positive without losing generality (i.e., - * (-X)+Y=Y-X, X+(-Y)=X-Y, - * (-X)+(-Y)=-(X+Y)) + * {@code (-X)+Y=Y-X}, {@code X+(-Y)=X-Y}, + * {@code (-X)+(-Y)=-(X+Y)}) * *

            - * Addition of two positive Durations are simply defined as + * Addition of two positive {@code Duration}s are simply defined as * field by field addition where missing fields are treated as 0. *

            - * A field of the resulting Duration will be unset if and - * only if respective fields of two input Durations are unset. + * A field of the resulting {@code Duration} will be unset if and + * only if respective fields of two input {@code Duration}s are unset. *

            - * Note that lhs.add(rhs) will be always successful if - * lhs.signum()*rhs.signum()!=-1 or both of them are - * normalized.

            + * Note that {@code lhs.add(rhs)} will be always successful if + * {@code lhs.signum()*rhs.signum()!=-1} or both of them are + * normalized. * - * @param rhs Duration to add to this Duration + * @param rhs {@code Duration} to add to this {@code Duration} * * @return * non-null valid Duration object. @@ -501,25 +501,22 @@ public abstract class Duration { * uses int to hold values, there are cases where this method * won't work correctly (for example if values of fields * exceed the range of int.) - *

            * *

            * Also, since this duration class is a Gregorian duration, this * method will not work correctly if the given {@link Calendar} * object is based on some other calendar systems. - *

            * *

            - * Any fractional parts of this Duration object + * Any fractional parts of this {@code Duration} object * beyond milliseconds will be simply ignored. For example, if * this duration is "P1.23456S", then 1 is added to SECONDS, * 234 is added to MILLISECONDS, and the rest will be unused. - *

            * *

            * Note that because {@link Calendar#add(int, int)} is using - * int, Duration with values beyond the - * range of int in its fields + * {@code int}, {@code Duration} with values beyond the + * range of {@code int} in its fields * will cause overflow/underflow to the given {@link Calendar}. * {@link XMLGregorianCalendar#add(Duration)} provides the same * basic operation as this method while avoiding @@ -571,9 +568,9 @@ public abstract class Duration { } /** - *

            Computes a new duration whose value is this-rhs.

            + * Computes a new duration whose value is {@code this-rhs}. * - *

            For example:

            + *

            For example: *

                  * "1 day" - "-3 days" = "4 days"
                  * "1 year" - "1 day" = IllegalStateException
            @@ -583,31 +580,31 @@ public abstract class Duration {
                  * 
            * *

            Since there's no way to meaningfully subtract 1 day from 1 month, - * there are cases where the operation fails in {@link IllegalStateException}.

            + * there are cases where the operation fails in {@link IllegalStateException}. * *

            Formally the computation is defined as follows. - * First, we can assume that two Durations are both positive + * First, we can assume that two {@code Duration}s are both positive * without losing generality. (i.e., - * (-X)-Y=-(X+Y), X-(-Y)=X+Y, - * (-X)-(-Y)=-(X-Y))

            + * {@code (-X)-Y=-(X+Y)}, {@code X-(-Y)=X+Y}, + * {@code (-X)-(-Y)=-(X-Y)}) * *

            Then two durations are subtracted field by field. - * If the sign of any non-zero field F is different from + * If the sign of any non-zero field {@code F} is different from * the sign of the most significant field, - * 1 (if F is negative) or -1 (otherwise) - * will be borrowed from the next bigger unit of F.

            + * 1 (if {@code F} is negative) or -1 (otherwise) + * will be borrowed from the next bigger unit of {@code F}. * *

            This process is repeated until all the non-zero fields have - * the same sign.

            + * the same sign. * *

            If a borrow occurs in the days field (in other words, if * the computation needs to borrow 1 or -1 month to compensate * days), then the computation fails by throwing an - * {@link IllegalStateException}.

            + * {@link IllegalStateException}. * - * @param rhs Duration to subtract from this Duration. + * @param rhs {@code Duration} to subtract from this {@code Duration}. * - * @return New Duration created from subtracting rhs from this Duration. + * @return New {@code Duration} created from subtracting {@code rhs} from this {@code Duration}. * * @throws IllegalStateException * If two durations cannot be meaningfully subtracted. For @@ -624,18 +621,18 @@ public abstract class Duration { } /** - *

            Computes a new duration whose value is factor times - * longer than the value of this duration.

            + * Computes a new duration whose value is {@code factor} times + * longer than the value of this duration. * *

            This method is provided for the convenience. - * It is functionally equivalent to the following code:

            + * It is functionally equivalent to the following code: *
                  * multiply(new BigDecimal(String.valueOf(factor)))
                  * 
            * - * @param factor Factor times longer of new Duration to create. + * @param factor Factor times longer of new {@code Duration} to create. * - * @return New Duration that is factortimes longer than this Duration. + * @return New {@code Duration} that is {@code factor}times longer than this {@code Duration}. * * @see #multiply(BigDecimal) */ @@ -644,7 +641,7 @@ public abstract class Duration { } /** - * Computes a new duration whose value is factor times + * Computes a new duration whose value is {@code factor} times * longer than the value of this duration. * *

            @@ -656,7 +653,7 @@ public abstract class Duration { *

            * *

            - * Since the Duration class is immutable, this method + * Since the {@code Duration} class is immutable, this method * doesn't change the value of this object. It simply computes * a new Duration object and returns it. * @@ -671,7 +668,7 @@ public abstract class Duration { * When fractions of month cannot be meaningfully carried down * to days, or year to months, this will cause an * {@link IllegalStateException} to be thrown. - * For example if you multiple one month by 0.5.

            + * For example if you multiple one month by 0.5. * *

            * To avoid {@link IllegalStateException}, use @@ -681,39 +678,39 @@ public abstract class Duration { * @param factor to multiply by * * @return - * returns a non-null valid Duration object + * returns a non-null valid {@code Duration} object * * @throws IllegalStateException if operation produces fraction in * the months field. * - * @throws NullPointerException if the factor parameter is - * null. + * @throws NullPointerException if the {@code factor} parameter is + * {@code null}. * */ public abstract Duration multiply(final BigDecimal factor); /** - * Returns a new Duration object whose - * value is -this. + * Returns a new {@code Duration} object whose + * value is {@code -this}. * *

            - * Since the Duration class is immutable, this method + * Since the {@code Duration} class is immutable, this method * doesn't change the value of this object. It simply computes * a new Duration object and returns it. * * @return - * always return a non-null valid Duration object. + * always return a non-null valid {@code Duration} object. */ public abstract Duration negate(); /** - *

            Converts the years and months fields into the days field - * by using a specific time instant as the reference point.

            + * Converts the years and months fields into the days field + * by using a specific time instant as the reference point. * *

            For example, duration of one month normalizes to 31 days - * given the start time instance "July 8th 2003, 17:40:32".

            + * given the start time instance "July 8th 2003, 17:40:32". * - *

            Formally, the computation is done as follows:

            + *

            Formally, the computation is done as follows: *

              *
            1. the given Calendar object is cloned
            2. *
            3. the years, months and days fields will be added to the {@link Calendar} object @@ -725,37 +722,37 @@ public abstract class Duration { * Duration object.
            4. *
            * - *

            Note that since the Calendar class uses int to + *

            Note that since the Calendar class uses {@code int} to * hold the value of year and month, this method may produce * an unexpected result if this duration object holds - * a very large value in the years or months fields.

            + * a very large value in the years or months fields. * - * @param startTimeInstant Calendar reference point. + * @param startTimeInstant {@code Calendar} reference point. * - * @return Duration of years and months of this Duration as days. + * @return {@code Duration} of years and months of this {@code Duration} as days. * * @throws NullPointerException If the startTimeInstant parameter is null. */ public abstract Duration normalizeWith(final Calendar startTimeInstant); /** - *

            Partial order relation comparison with this Duration instance.

            + * Partial order relation comparison with this {@code Duration} instance. * *

            Comparison result must be in accordance with * W3C XML Schema 1.0 Part 2, Section 3.2.7.6.2, - * Order relation on duration.

            + * Order relation on duration. * - *

            Return:

            + *

            Return: *

              - *
            • {@link DatatypeConstants#LESSER} if this Duration is shorter than duration parameter
            • - *
            • {@link DatatypeConstants#EQUAL} if this Duration is equal to duration parameter
            • - *
            • {@link DatatypeConstants#GREATER} if this Duration is longer than duration parameter
            • + *
            • {@link DatatypeConstants#LESSER} if this {@code Duration} is shorter than {@code duration} parameter
            • + *
            • {@link DatatypeConstants#EQUAL} if this {@code Duration} is equal to {@code duration} parameter
            • + *
            • {@link DatatypeConstants#GREATER} if this {@code Duration} is longer than {@code duration} parameter
            • *
            • {@link DatatypeConstants#INDETERMINATE} if a conclusive partial order relation cannot be determined
            • *
            * * @param duration to compare * - * @return the relationship between thisDurationand duration parameter as + * @return the relationship between {@code this Duration} and {@code duration} parameter as * {@link DatatypeConstants#LESSER}, {@link DatatypeConstants#EQUAL}, {@link DatatypeConstants#GREATER} * or {@link DatatypeConstants#INDETERMINATE}. * @@ -763,7 +760,7 @@ public abstract class Duration { * cannot reasonably process the request, e.g. W3C XML Schema allows for * arbitrarily large/small/precise values, the request may be beyond the * implementations capability. - * @throws NullPointerException if duration is null. + * @throws NullPointerException if {@code duration} is {@code null}. * * @see #isShorterThan(Duration) * @see #isLongerThan(Duration) @@ -771,23 +768,23 @@ public abstract class Duration { public abstract int compare(final Duration duration); /** - *

            Checks if this duration object is strictly longer than - * another Duration object.

            + * Checks if this duration object is strictly longer than + * another {@code Duration} object. * - *

            Duration X is "longer" than Y if and only if X>Y + *

            Duration X is "longer" than Y if and only if X {@literal >} Y * as defined in the section 3.2.6.2 of the XML Schema 1.0 - * specification.

            + * specification. * - *

            For example, "P1D" (one day) > "PT12H" (12 hours) and - * "P2Y" (two years) > "P23M" (23 months).

            + *

            For example, "P1D" (one day) {@literal >} "PT12H" (12 hours) and + * "P2Y" (two years) {@literal >} "P23M" (23 months). * - * @param duration Duration to test this Duration against. + * @param duration {@code Duration} to test this {@code Duration} against. * * @throws UnsupportedOperationException If the underlying implementation * cannot reasonably process the request, e.g. W3C XML Schema allows for * arbitrarily large/small/precise values, the request may be beyond the * implementations capability. - * @throws NullPointerException If duration is null. + * @throws NullPointerException If {@code duration} is null. * * @return * true if the duration represented by this object @@ -801,19 +798,19 @@ public abstract class Duration { } /** - *

            Checks if this duration object is strictly shorter than - * another Duration object.

            + * Checks if this duration object is strictly shorter than + * another {@code Duration} object. * - * @param duration Duration to test this Duration against. + * @param duration {@code Duration} to test this {@code Duration} against. * - * @return true if duration parameter is shorter than this Duration, - * else false. + * @return {@code true} if {@code duration} parameter is shorter than this {@code Duration}, + * else {@code false}. * * @throws UnsupportedOperationException If the underlying implementation * cannot reasonably process the request, e.g. W3C XML Schema allows for * arbitrarily large/small/precise values, the request may be beyond the * implementations capability. - * @throws NullPointerException if duration is null. + * @throws NullPointerException if {@code duration} is null. * * @see #isLongerThan(Duration duration) * @see #compare(Duration duration) @@ -823,19 +820,19 @@ public abstract class Duration { } /** - *

            Checks if this duration object has the same duration - * as another Duration object.

            + * Checks if this duration object has the same duration + * as another {@code Duration} object. * - *

            For example, "P1D" (1 day) is equal to "PT24H" (24 hours).

            + *

            For example, "P1D" (1 day) is equal to "PT24H" (24 hours). * *

            Duration X is equal to Y if and only if time instant * t+X and t+Y are the same for all the test time instants * specified in the section 3.2.6.2 of the XML Schema 1.0 - * specification.

            + * specification. * - *

            Note that there are cases where two Durations are + *

            Note that there are cases where two {@code Duration}s are * "incomparable" to each other, like one month and 30 days. - * For example,

            + * For example, *
                  * !new Duration("P1M").isShorterThan(new Duration("P30D"))
                  * !new Duration("P1M").isLongerThan(new Duration("P30D"))
            @@ -843,14 +840,14 @@ public abstract class Duration {
                  * 
            * * @param duration - * The object to compare this Duration against. + * The object to compare this {@code Duration} against. * * @return - * true if this duration is the same length as - * duration. - * false if duration is null, + * {@code true} if this duration is the same length as + * {@code duration}. + * {@code false} if {@code duration} is {@code null}, * is not a - * Duration object, + * {@code Duration} object, * or its length is different from this duration. * * @throws UnsupportedOperationException If the underlying implementation @@ -877,18 +874,19 @@ public abstract class Duration { public abstract int hashCode(); /** - *

            Returns a String representation of this Duration Object.

            + * Returns a {@code String} representation of this {@code Duration Object}. * - *

            The result is formatted according to the XML Schema 1.0 spec and can be always parsed back later into the - * equivalent Duration Object by {@link DatatypeFactory#newDuration(String lexicalRepresentation)}.

            + *

            The result is formatted according to the XML Schema 1.0 spec + * and can be always parsed back later into the + * equivalent {@code Duration Object} by {@link DatatypeFactory#newDuration(String lexicalRepresentation)}. * - *

            Formally, the following holds for any Duration - * Object x:

            + *

            Formally, the following holds for any {@code Duration} + * {@code Object} x: *

                  * new Duration(x.toString()).equals(x)
                  * 
            * - * @return A non-null valid String representation of this Duration. + * @return A non-{@code null} valid {@code String} representation of this {@code Duration}. */ public String toString() { @@ -934,14 +932,14 @@ public abstract class Duration { } /** - *

            Turns {@link BigDecimal} to a string representation.

            + * Turns {@link BigDecimal} to a string representation. * *

            Due to a behavior change in the {@link BigDecimal#toString()} - * method in JDK1.5, this had to be implemented here.

            + * method in JDK1.5, this had to be implemented here. * - * @param bd BigDecimal to format as a String + * @param bd {@code BigDecimal} to format as a {@code String} * - * @return String representation of BigDecimal + * @return {@code String} representation of {@code BigDecimal} */ private String toString(BigDecimal bd) { String intString = bd.unscaledValue().toString(); @@ -972,15 +970,15 @@ public abstract class Duration { /** - *

            Calls the {@link Calendar#getTimeInMillis} method. + * Calls the {@link Calendar#getTimeInMillis} method. * Prior to JDK1.4, this method was protected and therefore - * cannot be invoked directly.

            + * cannot be invoked directly. * - *

            TODO: In future, this should be replaced by cal.getTimeInMillis().

            + *

            TODO: In future, this should be replaced by {@code cal.getTimeInMillis()}. * - * @param cal Calendar to get time in milliseconds. + * @param cal {@code Calendar} to get time in milliseconds. * - * @return Milliseconds of cal. + * @return Milliseconds of {@code cal}. */ private static long getCalendarTimeInMillis(final Calendar cal) { return cal.getTime().getTime(); diff --git a/jaxp/src/java.xml/share/classes/javax/xml/datatype/XMLGregorianCalendar.java b/jaxp/src/java.xml/share/classes/javax/xml/datatype/XMLGregorianCalendar.java index ce16b9c9e1b..35355075b13 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/datatype/XMLGregorianCalendar.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/datatype/XMLGregorianCalendar.java @@ -43,17 +43,17 @@ import java.util.GregorianCalendar; * {@link DatatypeConstants#GMONTH}, and * {@link DatatypeConstants#GDAY} * defined in the XML Namespace - * "http://www.w3.org/2001/XMLSchema". + * {@code "http://www.w3.org/2001/XMLSchema"}. * These datatypes are normatively defined in - * W3C XML Schema 1.0 Part 2, Section 3.2.7-14.

            + * W3C XML Schema 1.0 Part 2, Section 3.2.7-14. * *

            The table below defines the mapping between XML Schema 1.0 * date/time datatype fields and this class' fields. It also summarizes * the value constraints for the date and time fields defined in * W3C XML Schema 1.0 Part 2, Appendix D, - * ISO 8601 Date and Time Formats.

            + * ISO 8601 Date and Time Formats. * - * + * *
            - * Required fields for XML Schema 1.0 Date/Time Datatypes.
            + * Required fields for XML Schema 1.0 Date/Time Datatypes.
            * (timezone is optional for all date/time datatypes) *
            * * @@ -64,22 +64,22 @@ import java.util.GregorianCalendar; * * * - * - * + * * * * - * - * + * - * * * - * + * * * * * - * + * * - * * * - * + * * * * * - * + * * * * * - * + * * * * * - * + * * *
            XML Schema 1.0
            - * datatype
            + *
            XML Schema 1.0
            + * datatype
            * field
            Related
            XMLGregorianCalendar
            Accessor(s)
            Related
            XMLGregorianCalendar
            Accessor(s)
            Value Range
            year {@link #getYear()} + {@link #getEon()} or
            + *
            year {@link #getYear()} + {@link #getEon()} or
            * {@link #getEonAndYear} *
            getYear() is a value between -(10^9-1) to (10^9)-1 - * or {@link DatatypeConstants#FIELD_UNDEFINED}.
            - * {@link #getEon()} is high order year value in billion of years.
            - * getEon() has values greater than or equal to (10^9) or less than or equal to -(10^9). - * A value of null indicates field is undefined.
            + *
            {@code getYear()} is a value between -(10^9-1) to (10^9)-1 + * or {@link DatatypeConstants#FIELD_UNDEFINED}.
            + * {@link #getEon()} is high order year value in billion of years.
            + * {@code getEon()} has values greater than or equal to (10^9) or less than or equal to -(10^9). + * A value of null indicates field is undefined.
            * Given that XML Schema 1.0 errata states that the year zero * will be a valid lexical value in a future version of XML Schema, * this class allows the year field to be set to zero. Otherwise, @@ -89,20 +89,20 @@ import java.util.GregorianCalendar; *
            monthmonth {@link #getMonth()} 1 to 12 or {@link DatatypeConstants#FIELD_UNDEFINED}
            dayday {@link #getDay()} Independent of month, max range is 1 to 31 or {@link DatatypeConstants#FIELD_UNDEFINED}.
            + *
            Independent of month, max range is 1 to 31 or {@link DatatypeConstants#FIELD_UNDEFINED}.
            * The normative value constraint stated relative to month * field's value is in W3C XML Schema 1.0 Part 2, Appendix D. *
            hourhour{@link #getHour()} * 0 to 23 or {@link DatatypeConstants#FIELD_UNDEFINED}. @@ -114,28 +114,28 @@ import java.util.GregorianCalendar; *
            minuteminute {@link #getMinute()} 0 to 59 or {@link DatatypeConstants#FIELD_UNDEFINED}
            secondsecond - * {@link #getSecond()} + {@link #getMillisecond()}/1000 or
            + * {@link #getSecond()} + {@link #getMillisecond()}/1000 or
            * {@link #getSecond()} + {@link #getFractionalSecond()} *
            - * {@link #getSecond()} from 0 to 60 or {@link DatatypeConstants#FIELD_UNDEFINED}.
            - * (Note: 60 only allowable for leap second.)
            + * {@link #getSecond()} from 0 to 60 or {@link DatatypeConstants#FIELD_UNDEFINED}.
            + * (Note: 60 only allowable for leap second.)
            * {@link #getFractionalSecond()} allows for infinite precision over the range from 0.0 to 1.0 when - * the {@link #getSecond()} is defined.
            - * FractionalSecond is optional and has a value of null when it is undefined.
            + * the {@link #getSecond()} is defined.
            + * {@code FractionalSecond} is optional and has a value of {@code null} when it is undefined.
            * {@link #getMillisecond()} is the convenience * millisecond precision of value of {@link #getFractionalSecond()}. *
            timezonetimezone {@link #getTimezone()} Number of minutes or {@link DatatypeConstants#FIELD_UNDEFINED}. * Value range from -14 hours (-14 * 60 minutes) to 14 hours (14 * 60 minutes). @@ -145,14 +145,13 @@ import java.util.GregorianCalendar; *
            * *

            All maximum value space constraints listed for the fields in the table - * above are checked by factory methods, @{link DatatypeFactory}, + * above are checked by factory methods, {@link DatatypeFactory}, * setter methods and parse methods of - * this class. IllegalArgumentException is thrown when a + * this class. {@code IllegalArgumentException} is thrown when a * parameter's value is outside the value constraint for the field or * if the composite * values constitute an invalid XMLGregorianCalendar instance (for example, if * the 31st of June is specified). - *

            * *

            The following operations are defined for this class: *

              @@ -169,7 +168,6 @@ import java.util.GregorianCalendar; * W3C XML Schema 1.0 Part 2, Appendix E, Adding durations to dateTimes. * *
            - *

            * * @author Joseph Fialli * @author Kohsuke Kawaguchi @@ -187,26 +185,26 @@ public abstract class XMLGregorianCalendar * Default no-arg constructor. * *

            Note: Always use the {@link DatatypeFactory} to - * construct an instance of XMLGregorianCalendar. + * construct an instance of {@code XMLGregorianCalendar}. * The constructor on this class cannot be guaranteed to * produce an object with a consistent state and may be - * removed in the future.

            + * removed in the future. */ public XMLGregorianCalendar() { } /** - *

            Unset all fields to undefined.

            + * Unset all fields to undefined. * *

            Set all int fields to {@link DatatypeConstants#FIELD_UNDEFINED} and reference fields - * to null.

            + * to null. */ public abstract void clear(); /** - *

            Reset this XMLGregorianCalendar to its original values.

            + * Reset this {@code XMLGregorianCalendar} to its original values. * - *

            XMLGregorianCalendar is reset to the same values as when it was created with + *

            {@code XMLGregorianCalendar} is reset to the same values as when it was created with * {@link DatatypeFactory#newXMLGregorianCalendar()}, * {@link DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation)}, * {@link DatatypeFactory#newXMLGregorianCalendar( @@ -250,83 +248,82 @@ public abstract class XMLGregorianCalendar * int seconds, * int milliseconds, * int timezone)}. - *

            * - *

            reset() is designed to allow the reuse of existing XMLGregorianCalendars - * thus saving resources associated with the creation of new XMLGregorianCalendars.

            + *

            {@code reset()} is designed to allow the reuse of existing {@code XMLGregorianCalendar}s + * thus saving resources associated with the creation of new {@code XMLGregorianCalendar}s. */ public abstract void reset(); /** - *

            Set low and high order component of XSD dateTime year field.

            + * Set low and high order component of XSD {@code dateTime} year field. * - *

            Unset this field by invoking the setter with a parameter value of null.

            + *

            Unset this field by invoking the setter with a parameter value of {@code null}. * * @param year value constraints summarized in year field of date/time field mapping table. * - * @throws IllegalArgumentException if year parameter is + * @throws IllegalArgumentException if {@code year} parameter is * outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setYear(BigInteger year); /** - *

            Set year of XSD dateTime year field.

            + * Set year of XSD {@code dateTime} year field. * *

            Unset this field by invoking the setter with a parameter value of - * {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * {@link DatatypeConstants#FIELD_UNDEFINED}. * - *

            Note: if the absolute value of the year parameter + *

            Note: if the absolute value of the {@code year} parameter * is less than 10^9, the eon component of the XSD year field is set to - * null by this method.

            + * {@code null} by this method. * * @param year value constraints are summarized in year field of date/time field mapping table. - * If year is {@link DatatypeConstants#FIELD_UNDEFINED}, then eon is set to null. + * If year is {@link DatatypeConstants#FIELD_UNDEFINED}, then eon is set to {@code null}. */ public abstract void setYear(int year); /** - *

            Set month.

            + * Set month. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param month value constraints summarized in month field of date/time field mapping table. * - * @throws IllegalArgumentException if month parameter is + * @throws IllegalArgumentException if {@code month} parameter is * outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setMonth(int month); /** - *

            Set days in month.

            + * Set days in month. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param day value constraints summarized in day field of date/time field mapping table. * - * @throws IllegalArgumentException if day parameter is + * @throws IllegalArgumentException if {@code day} parameter is * outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setDay(int day); /** - *

            Set the number of minutes in the timezone offset.

            + * Set the number of minutes in the timezone offset. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param offset value constraints summarized in * timezone field of date/time field mapping table. * - * @throws IllegalArgumentException if offset parameter is + * @throws IllegalArgumentException if {@code offset} parameter is * outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setTimezone(int offset); /** - *

            Set time as one unit.

            + * Set time as one unit. * * @param hour value constraints are summarized in * hour field of date/time field mapping table. @@ -352,71 +349,71 @@ public abstract class XMLGregorianCalendar } /** - *

            Set hours.

            + * Set hours. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param hour value constraints summarized in hour field of date/time field mapping table. * - * @throws IllegalArgumentException if hour parameter is outside value constraints for the field as specified in + * @throws IllegalArgumentException if {@code hour} parameter is outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setHour(int hour); /** - *

            Set minutes.

            + * Set minutes. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param minute value constraints summarized in minute field of date/time field mapping table. * - * @throws IllegalArgumentException if minute parameter is outside value constraints for the field as specified in + * @throws IllegalArgumentException if {@code minute} parameter is outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setMinute(int minute); /** - *

            Set seconds.

            + * Set seconds. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param second value constraints summarized in second field of date/time field mapping table. * - * @throws IllegalArgumentException if second parameter is outside value constraints for the field as specified in + * @throws IllegalArgumentException if {@code second} parameter is outside value constraints for the field as specified in * date/time field mapping table. */ public abstract void setSecond(int second); /** - *

            Set milliseconds.

            + * Set milliseconds. * - *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

            + *

            Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}. * * @param millisecond value constraints summarized in * second field of date/time field mapping table. * - * @throws IllegalArgumentException if millisecond parameter is outside value constraints for the field as specified + * @throws IllegalArgumentException if {@code millisecond} parameter is outside value constraints for the field as specified * in date/time field mapping table. */ public abstract void setMillisecond(int millisecond); /** - *

            Set fractional seconds.

            + * Set fractional seconds. * - *

            Unset this field by invoking the setter with a parameter value of null.

            + *

            Unset this field by invoking the setter with a parameter value of {@code null}. * * @param fractional value constraints summarized in * second field of date/time field mapping table. * - * @throws IllegalArgumentException if fractional parameter is outside value constraints for the field as specified + * @throws IllegalArgumentException if {@code fractional} parameter is outside value constraints for the field as specified * in date/time field mapping table. */ public abstract void setFractionalSecond(BigDecimal fractional); /** - *

            Set time as one unit, including the optional infinite precision - * fractional seconds.

            + * Set time as one unit, including the optional infinite precision + * fractional seconds. * * @param hour value constraints are summarized in * hour field of date/time field mapping table. @@ -424,7 +421,7 @@ public abstract class XMLGregorianCalendar * minute field of date/time field mapping table. * @param second value constraints are summarized in * second field of date/time field mapping table. - * @param fractional value of null indicates this optional + * @param fractional value of {@code null} indicates this optional * field is not set. * * @throws IllegalArgumentException if any parameter is @@ -445,7 +442,7 @@ public abstract class XMLGregorianCalendar /** - *

            Set time as one unit, including optional milliseconds.

            + * Set time as one unit, including optional milliseconds. * * @param hour value constraints are summarized in * hour field of date/time field mapping table. @@ -469,13 +466,13 @@ public abstract class XMLGregorianCalendar } /** - *

            Return high order component for XML Schema 1.0 dateTime datatype field for - * year. - * null if this optional part of the year field is not defined.

            + * Return high order component for XML Schema 1.0 dateTime datatype field for + * {@code year}. + * {@code null} if this optional part of the year field is not defined. * *

            Value constraints for this value are summarized in - * year field of date/time field mapping table.

            - * @return eon of this XMLGregorianCalendar. The value + * year field of date/time field mapping table. + * @return eon of this {@code XMLGregorianCalendar}. The value * returned is an integer multiple of 10^9. * * @see #getYear() @@ -484,13 +481,13 @@ public abstract class XMLGregorianCalendar public abstract BigInteger getEon(); /** - *

            Return low order component for XML Schema 1.0 dateTime datatype field for - * year or {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * Return low order component for XML Schema 1.0 dateTime datatype field for + * {@code year} or {@link DatatypeConstants#FIELD_UNDEFINED}. * *

            Value constraints for this value are summarized in - * year field of date/time field mapping table.

            + * year field of date/time field mapping table. * - * @return year of this XMLGregorianCalendar. + * @return year of this {@code XMLGregorianCalendar}. * * @see #getEon() * @see #getEonAndYear() @@ -498,16 +495,16 @@ public abstract class XMLGregorianCalendar public abstract int getYear(); /** - *

            Return XML Schema 1.0 dateTime datatype field for - * year.

            + * Return XML Schema 1.0 dateTime datatype field for + * {@code year}. * *

            Value constraints for this value are summarized in - * year field of date/time field mapping table.

            + * year field of date/time field mapping table. * - * @return sum of eon and BigInteger.valueOf(year) - * when both fields are defined. When only year is defined, - * return it. When both eon and year are not - * defined, return null. + * @return sum of {@code eon} and {@code BigInteger.valueOf(year)} + * when both fields are defined. When only {@code year} is defined, + * return it. When both {@code eon} and {@code year} are not + * defined, return {@code null}. * * @see #getEon() * @see #getYear() @@ -515,21 +512,21 @@ public abstract class XMLGregorianCalendar public abstract BigInteger getEonAndYear(); /** - *

            Return number of month or {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * Return number of month or {@link DatatypeConstants#FIELD_UNDEFINED}. * *

            Value constraints for this value are summarized in - * month field of date/time field mapping table.

            + * month field of date/time field mapping table. * - * @return year of this XMLGregorianCalendar. + * @return year of this {@code XMLGregorianCalendar}. * */ public abstract int getMonth(); /** - * Return day in month or {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * Return day in month or {@link DatatypeConstants#FIELD_UNDEFINED}. * *

            Value constraints for this value are summarized in - * day field of date/time field mapping table.

            + * day field of date/time field mapping table. * * @see #setDay(int) */ @@ -540,7 +537,7 @@ public abstract class XMLGregorianCalendar * {@link DatatypeConstants#FIELD_UNDEFINED} if this optional field is not defined. * *

            Value constraints for this value are summarized in - * timezone field of date/time field mapping table.

            + * timezone field of date/time field mapping table. * * @see #setTimezone(int) */ @@ -551,34 +548,34 @@ public abstract class XMLGregorianCalendar * Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined. * *

            Value constraints for this value are summarized in - * hour field of date/time field mapping table.

            + * hour field of date/time field mapping table. * @see #setTime(int, int, int) */ public abstract int getHour(); /** - * Return minutes or {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * Return minutes or {@link DatatypeConstants#FIELD_UNDEFINED}. * Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined. * *

            Value constraints for this value are summarized in - * minute field of date/time field mapping table.

            + * minute field of date/time field mapping table. * @see #setTime(int, int, int) */ public abstract int getMinute(); /** - *

            Return seconds or {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * Return seconds or {@link DatatypeConstants#FIELD_UNDEFINED}. * *

            Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined. * When this field is not defined, the optional xs:dateTime * fractional seconds field, represented by * {@link #getFractionalSecond()} and {@link #getMillisecond()}, - * must not be defined.

            + * must not be defined. * *

            Value constraints for this value are summarized in - * second field of date/time field mapping table.

            + * second field of date/time field mapping table. * - * @return Second of this XMLGregorianCalendar. + * @return Second of this {@code XMLGregorianCalendar}. * * @see #getFractionalSecond() * @see #getMillisecond() @@ -587,20 +584,20 @@ public abstract class XMLGregorianCalendar public abstract int getSecond(); /** - *

            Return millisecond precision of {@link #getFractionalSecond()}.

            + * Return millisecond precision of {@link #getFractionalSecond()}. * *

            This method represents a convenience accessor to infinite * precision fractional second value returned by * {@link #getFractionalSecond()}. The returned value is the rounded * down to milliseconds value of * {@link #getFractionalSecond()}. When {@link #getFractionalSecond()} - * returns null, this method must return - * {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * returns {@code null}, this method must return + * {@link DatatypeConstants#FIELD_UNDEFINED}. * *

            Value constraints for this value are summarized in - * second field of date/time field mapping table.

            + * second field of date/time field mapping table. * - * @return Millisecond of this XMLGregorianCalendar. + * @return Millisecond of this {@code XMLGregorianCalendar}. * * @see #getFractionalSecond() * @see #setTime(int, int, int) @@ -618,18 +615,18 @@ public abstract class XMLGregorianCalendar } /** - *

            Return fractional seconds.

            + * Return fractional seconds. * - *

            null is returned when this optional field is not defined.

            + *

            {@code null} is returned when this optional field is not defined. * *

            Value constraints are detailed in - * second field of date/time field mapping table.

            + * second field of date/time field mapping table. * *

            This optional field can only have a defined value when the * xs:dateTime second field, represented by {@link #getSecond()}, - * does not return {@link DatatypeConstants#FIELD_UNDEFINED}.

            + * does not return {@link DatatypeConstants#FIELD_UNDEFINED}. * - * @return fractional seconds of this XMLGregorianCalendar. + * @return fractional seconds of this {@code XMLGregorianCalendar}. * * @see #getSecond() * @see #setTime(int, int, int, BigDecimal) @@ -638,51 +635,51 @@ public abstract class XMLGregorianCalendar // comparisons /** - *

            Compare two instances of W3C XML Schema 1.0 date/time datatypes + * Compare two instances of W3C XML Schema 1.0 date/time datatypes * according to partial order relation defined in * W3C XML Schema 1.0 Part 2, Section 3.2.7.3, - * Order relation on dateTime.

            + * Order relation on dateTime. * - *

            xsd:dateTime datatype field mapping to accessors of + *

            {@code xsd:dateTime} datatype field mapping to accessors of * this class are defined in - * date/time field mapping table.

            + * date/time field mapping table. * - * @param xmlGregorianCalendar Instance of XMLGregorianCalendar to compare + * @param xmlGregorianCalendar Instance of {@code XMLGregorianCalendar} to compare * - * @return The relationship between this XMLGregorianCalendar and - * the specified xmlGregorianCalendar as + * @return The relationship between {@code this} {@code XMLGregorianCalendar} and + * the specified {@code xmlGregorianCalendar} as * {@link DatatypeConstants#LESSER}, * {@link DatatypeConstants#EQUAL}, * {@link DatatypeConstants#GREATER} or * {@link DatatypeConstants#INDETERMINATE}. * - * @throws NullPointerException if xmlGregorianCalendar is null. + * @throws NullPointerException if {@code xmlGregorianCalendar} is null. */ public abstract int compare(XMLGregorianCalendar xmlGregorianCalendar); /** - *

            Normalize this instance to UTC.

            + * Normalize this instance to UTC. * - *

            2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z

            - *

            Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).

            + *

            2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z + *

            Implements W3C XML Schema Part 2, Section 3.2.7.3 (A). * - * @return this XMLGregorianCalendar normalized to UTC. + * @return {@code this} {@code XMLGregorianCalendar} normalized to UTC. */ public abstract XMLGregorianCalendar normalize(); /** - *

            Compares this calendar to the specified object. The result is - * true if and only if the argument is not null and is an - * XMLGregorianCalendar object that represents the same - * instant in time as this object.

            + * Compares this calendar to the specified object. The result is + * {@code true} if and only if the argument is not null and is an + * {@code XMLGregorianCalendar} object that represents the same + * instant in time as this object. * * @param obj to compare. * - * @return true when obj is an instance of - * XMLGregorianCalendar and + * @return {@code true} when {@code obj} is an instance of + * {@code XMLGregorianCalendar} and * {@link #compare(XMLGregorianCalendar obj)} * returns {@link DatatypeConstants#EQUAL}, - * otherwise false. + * otherwise {@code false}. */ public boolean equals(Object obj) { @@ -693,7 +690,7 @@ public abstract class XMLGregorianCalendar } /** - *

            Returns a hash code consistent with the definition of the equals method.

            + * Returns a hash code consistent with the definition of the equals method. * * @return hash code of this object. */ @@ -721,15 +718,15 @@ public abstract class XMLGregorianCalendar } /** - *

            Return the lexical representation of this instance. + * Return the lexical representation of {@code this} instance. * The format is specified in * XML Schema 1.0 Part 2, Section 3.2.[7-14].1, - * Lexical Representation".

            + * Lexical Representation". * *

            Specific target lexical representation format is determined by - * {@link #getXMLSchemaType()}.

            + * {@link #getXMLSchemaType()}. * - * @return XML, as String, representation of this XMLGregorianCalendar + * @return XML, as {@code String}, representation of this {@code XMLGregorianCalendar} * * @throws IllegalStateException if the combination of set fields * does not match one of the eight defined XML Schema builtin date/time datatypes. @@ -737,14 +734,14 @@ public abstract class XMLGregorianCalendar public abstract String toXMLFormat(); /** - *

            Return the name of the XML Schema date/time type that this instance - * maps to. Type is computed based on fields that are set.

            + * Return the name of the XML Schema date/time type that this instance + * maps to. Type is computed based on fields that are set. * * * * * * @@ -850,11 +847,11 @@ public abstract class XMLGregorianCalendar public abstract QName getXMLSchemaType(); /** - *

            Returns a String representation of this XMLGregorianCalendar Object.

            + * Returns a {@code String} representation of this {@code XMLGregorianCalendar} {@code Object}. * - *

            The result is a lexical representation generated by {@link #toXMLFormat()}.

            + *

            The result is a lexical representation generated by {@link #toXMLFormat()}. * - * @return A non-null valid String representation of this XMLGregorianCalendar. + * @return A non-{@code null} valid {@code String} representation of this {@code XMLGregorianCalendar}. * * @throws IllegalStateException if the combination of set fields * does not match one of the eight defined XML Schema builtin date/time datatypes. @@ -867,89 +864,89 @@ public abstract class XMLGregorianCalendar } /** - * Validate instance by getXMLSchemaType() constraints. + * Validate instance by {@code getXMLSchemaType()} constraints. * @return true if data values are valid. */ public abstract boolean isValid(); /** - *

            Add duration to this instance.

            + * Add {@code duration} to this instance. * *

            The computation is specified in * XML Schema 1.0 Part 2, Appendix E, - * Adding durations to dateTimes>. + * Adding durations to dateTimes. * date/time field mapping table - * defines the mapping from XML Schema 1.0 dateTime fields - * to this class' representation of those fields.

            + * defines the mapping from XML Schema 1.0 {@code dateTime} fields + * to this class' representation of those fields. * - * @param duration Duration to add to this XMLGregorianCalendar. + * @param duration Duration to add to this {@code XMLGregorianCalendar}. * - * @throws NullPointerException when duration parameter is null. + * @throws NullPointerException when {@code duration} parameter is {@code null}. */ public abstract void add(Duration duration); /** - *

            Convert this XMLGregorianCalendar to a {@link GregorianCalendar}.

            + * Convert this {@code XMLGregorianCalendar} to a {@link GregorianCalendar}. * - *

            When this instance has an undefined field, this - * conversion relies on the java.util.GregorianCalendar default + *

            When {@code this} instance has an undefined field, this + * conversion relies on the {@code java.util.GregorianCalendar} default * for its corresponding field. A notable difference between - * XML Schema 1.0 date/time datatypes and java.util.GregorianCalendar + * XML Schema 1.0 date/time datatypes and {@code java.util.GregorianCalendar} * is that Timezone value is optional for date/time datatypes and it is - * a required field for java.util.GregorianCalendar. See javadoc - * for java.util.TimeZone.getDefault() on how the default - * is determined. To explicitly specify the TimeZone + * a required field for {@code java.util.GregorianCalendar}. See javadoc + * for {@code java.util.TimeZone.getDefault()} on how the default + * is determined. To explicitly specify the {@code TimeZone} * instance, see - * {@link #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)}.

            + * {@link #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)}. * *
            - * Required fields for XML Schema 1.0 Date/Time Datatypes.
            + * Required fields for XML Schema 1.0 Date/Time Datatypes.
            * (timezone is optional for all date/time datatypes) *
            * * * * * * * - * - * + * + * * * - * - * + * + * * * - * - * + * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * @@ -958,74 +955,74 @@ public abstract class XMLGregorianCalendar * to source datatype having higher precision than target datatype. * *

            To ensure consistency in conversion implementations, the new - * GregorianCalendar should be instantiated in following + * {@code GregorianCalendar} should be instantiated in following * manner. *

              - *
            • Using timeZone value as defined above, create a new - * java.util.GregorianCalendar(timeZone,Locale.getDefault()). + *
            • Using {@code timeZone} value as defined above, create a new + * {@code java.util.GregorianCalendar(timeZone,Locale.getDefault())}. *
            • *
            • Initialize all GregorianCalendar fields by calling {@link java.util.GregorianCalendar#clear()}.
            • *
            • Obtain a pure Gregorian Calendar by invoking - * GregorianCalendar.setGregorianChange( - * new Date(Long.MIN_VALUE)).
            • + * {@code GregorianCalendar.setGregorianChange( + * new Date(Long.MIN_VALUE))}. *
            • Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, * MINUTE, SECOND and MILLISECOND are set using the method - * Calendar.set(int,int)
            • + * {@code Calendar.set(int,int)} *
            - *

            * * @see #toGregorianCalendar(java.util.TimeZone, java.util.Locale, XMLGregorianCalendar) */ public abstract GregorianCalendar toGregorianCalendar(); /** - *

            Convert this XMLGregorianCalendar along with provided parameters - * to a {@link GregorianCalendar} instance.

            + * Convert this {@code XMLGregorianCalendar} along with provided parameters + * to a {@link GregorianCalendar} instance. * *

            Since XML Schema 1.0 date/time datetypes has no concept of * timezone ids or daylight savings timezone ids, this conversion operation * allows the user to explicitly specify one with - * timezone parameter.

            + * {@code timezone} parameter. * - *

            To compute the return value's TimeZone field, + *

            To compute the return value's {@code TimeZone} field, *

              - *
            • when parameter timeZone is non-null, + *
            • when parameter {@code timeZone} is non-null, * it is the timezone field.
            • - *
            • else when this.getTimezone() != FIELD_UNDEFINED, - * create a java.util.TimeZone with a custom timezone id - * using the this.getTimezone().
            • - *
            • else when defaults.getTimezone() != FIELD_UNDEFINED, - * create a java.util.TimeZone with a custom timezone id - * using defaults.getTimezone().
            • - *
            • else use the GregorianCalendar default timezone value + *
            • else when {@code this.getTimezone() != FIELD_UNDEFINED}, + * create a {@code java.util.TimeZone} with a custom timezone id + * using the {@code this.getTimezone()}.
            • + *
            • else when {@code defaults.getTimezone() != FIELD_UNDEFINED}, + * create a {@code java.util.TimeZone} with a custom timezone id + * using {@code defaults.getTimezone()}.
            • + *
            • else use the {@code GregorianCalendar} default timezone value * for the host is defined as specified by - * java.util.TimeZone.getDefault().
            • + * {@code java.util.TimeZone.getDefault()}. + *
            * *

            To ensure consistency in conversion implementations, the new - * GregorianCalendar should be instantiated in following + * {@code GregorianCalendar} should be instantiated in following * manner. *

              - *
            • Create a new java.util.GregorianCalendar(TimeZone, - * Locale) with TimeZone set as specified above and the - * Locale parameter. + *
            • Create a new {@code java.util.GregorianCalendar(TimeZone, + * Locale)} with TimeZone set as specified above and the + * {@code Locale} parameter. *
            • *
            • Initialize all GregorianCalendar fields by calling {@link GregorianCalendar#clear()}
            • *
            • Obtain a pure Gregorian Calendar by invoking - * GregorianCalendar.setGregorianChange( - * new Date(Long.MIN_VALUE)).
            • + * {@code GregorianCalendar.setGregorianChange( + * new Date(Long.MIN_VALUE))}. *
            • Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, * MINUTE, SECOND and MILLISECOND are set using the method - * Calendar.set(int,int)
            • + * {@code Calendar.set(int,int)} *
            * - * @param timezone provide Timezone. null is a legal value. + * @param timezone provide Timezone. {@code null} is a legal value. * @param aLocale provide explicit Locale. Use default GregorianCalendar locale if - * value is null. + * value is {@code null}. * @param defaults provide default field values to use when corresponding * field for this instance is FIELD_UNDEFINED or null. - * If defaultsis null or a field - * within the specified defaults is undefined, - * just use java.util.GregorianCalendar defaults. + * If {@code defaults}is {@code null} or a field + * within the specified {@code defaults} is undefined, + * just use {@code java.util.GregorianCalendar} defaults. * @return a java.util.GregorianCalendar conversion of this instance. */ public abstract GregorianCalendar toGregorianCalendar( @@ -1034,7 +1031,7 @@ public abstract class XMLGregorianCalendar XMLGregorianCalendar defaults); /** - *

            Returns a java.util.TimeZone for this class.

            + * Returns a {@code java.util.TimeZone} for this class. * *

            If timezone field is defined for this instance, * returns TimeZone initialized with custom timezone id @@ -1042,7 +1039,7 @@ public abstract class XMLGregorianCalendar * try the defaultZoneoffset that was passed in. * If defaultZoneoffset is FIELD_UNDEFINED, return * default timezone for this host. - * (Same default as java.util.GregorianCalendar).

            + * (Same default as java.util.GregorianCalendar). * * @param defaultZoneoffset default zoneoffset if this zoneoffset is * {@link DatatypeConstants#FIELD_UNDEFINED}. @@ -1054,9 +1051,9 @@ public abstract class XMLGregorianCalendar /** - *

            Creates and returns a copy of this object.

            + * Creates and returns a copy of this object. * - * @return copy of this Object + * @return copy of this {@code Object} */ public abstract Object clone(); } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/namespace/NamespaceContext.java b/jaxp/src/java.xml/share/classes/javax/xml/namespace/NamespaceContext.java index f1ce6932144..09e46e7dfbf 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/namespace/NamespaceContext.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/namespace/NamespaceContext.java @@ -28,44 +28,44 @@ package javax.xml.namespace; import java.util.Iterator; /** - *

            Interface for read only XML Namespace context processing.

            + * Interface for read only XML Namespace context processing. * - *

            An XML Namespace has the properties:

            + *

            An XML Namespace has the properties: *

              *
            • Namespace URI: * Namespace name expressed as a URI to which the prefix is bound
            • *
            • prefix: syntactically, this is the part of the attribute name - * following the XMLConstants.XMLNS_ATTRIBUTE + * following the {@code XMLConstants.XMLNS_ATTRIBUTE} * ("xmlns") in the Namespace declaration
            • *
            *

            example: - * <element xmlns:prefix="http://Namespace-name-URI">

            + * {@code } * - *

            All get*(*) methods operate in the current scope - * for Namespace URI and prefix resolution.

            + *

            All {@code get*(*)} methods operate in the current scope + * for Namespace URI and prefix resolution. * *

            Note that a Namespace URI can be bound to * multiple prefixes in the current scope. This can - * occur when multiple XMLConstants.XMLNS_ATTRIBUTE + * occur when multiple {@code XMLConstants.XMLNS_ATTRIBUTE} * ("xmlns") Namespace declarations occur in the same Start-Tag and - * refer to the same Namespace URI. e.g.
            - *

            - * <element xmlns:prefix1="http://Namespace-name-URI"
            - *          xmlns:prefix2="http://Namespace-name-URI">
            + * refer to the same Namespace URI. e.g.
            + *
             {@code
            + *  }
              * 
            * This can also occur when the same Namespace URI is used in multiple - * XMLConstants.XMLNS_ATTRIBUTE ("xmlns") Namespace - * declarations in the logical parent element hierarchy. e.g.
            - *
            - * <parent xmlns:prefix1="http://Namespace-name-URI">
            - *   <child xmlns:prefix2="http://Namespace-name-URI">
            + * {@code XMLConstants.XMLNS_ATTRIBUTE} ("xmlns") Namespace
            + * declarations in the logical parent element hierarchy.  e.g.
            + *
             {@code
            + * 
            + *   
              *     ...
            - *   </child>
            - * </parent>
            - * 

            + * + * } + *
            * *

            A prefix can only be bound to a single - * Namespace URI in the current scope.

            + * Namespace URI in the current scope. * * @author Jeff Suttor * @see javax.xml.XMLConstants @@ -82,17 +82,17 @@ import java.util.Iterator; public interface NamespaceContext { /** - *

            Get Namespace URI bound to a prefix in the current scope.

            + * Get Namespace URI bound to a prefix in the current scope. * *

            When requesting a Namespace URI by prefix, the following * table describes the returned Namespace URI value for all - * possible prefix values:

            + * possible prefix values: * *
            * Field by Field Conversion from this class to - * java.util.GregorianCalendar + * {@code java.util.GregorianCalendar} *
            java.util.GregorianCalendar fieldjavax.xml.datatype.XMLGregorianCalendar field{@code java.util.GregorianCalendar} field{@code javax.xml.datatype.XMLGregorianCalendar} field
            ERA{@link #getEonAndYear()}.signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD{@code ERA}{@link #getEonAndYear()}{@code .signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD}
            YEAR{@link #getEonAndYear()}.abs().intValue()*{@code YEAR}{@link #getEonAndYear()}{@code .abs().intValue()}*
            MONTH{@code MONTH}{@link #getMonth()} - {@link DatatypeConstants#JANUARY} + {@link GregorianCalendar#JANUARY}
            DAY_OF_MONTH{@code DAY_OF_MONTH}{@link #getDay()}
            HOUR_OF_DAY{@code HOUR_OF_DAY}{@link #getHour()}
            MINUTE{@code MINUTE}{@link #getMinute()}
            SECOND{@code SECOND}{@link #getSecond()}
            MILLISECOND{@code MILLISECOND}get millisecond order from {@link #getFractionalSecond()}*
            GregorianCalendar.setTimeZone(TimeZone){@code GregorianCalendar.setTimeZone(TimeZone)}{@link #getTimezone()} formatted into Custom timezone id
            * * * * @@ -103,9 +103,9 @@ public interface NamespaceContext { * * * - * + * * @@ -117,24 +117,24 @@ public interface NamespaceContext { * * * * * - * - * + * * * - * - * + * * * - * - * + * + * * * *
            - * getNamespaceURI(prefix) + * {@code getNamespaceURI(prefix)} * return value for specified prefixes *
            DEFAULT_NS_PREFIX (""){@code DEFAULT_NS_PREFIX} ("")default Namespace URI in the current scope or - * {@link + * {@link * javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI("")} * * when there is no default Namespace URI in the current scope
            unbound prefix - * {@link + * {@link * javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI("")} * *
            XMLConstants.XML_NS_PREFIX ("xml")XMLConstants.XML_NS_URI + * {@code XMLConstants.XML_NS_PREFIX} ("xml"){@code XMLConstants.XML_NS_URI} * ("http://www.w3.org/XML/1998/namespace")
            XMLConstants.XMLNS_ATTRIBUTE ("xmlns")XMLConstants.XMLNS_ATTRIBUTE_NS_URI + * {@code XMLConstants.XMLNS_ATTRIBUTE} ("xmlns"){@code XMLConstants.XMLNS_ATTRIBUTE_NS_URI} * ("http://www.w3.org/2000/xmlns/")
            nullIllegalArgumentException is thrown{@code null}{@code IllegalArgumentException} is thrown
            @@ -143,26 +143,26 @@ public interface NamespaceContext { * * @return Namespace URI bound to prefix in the current scope * - * @throws IllegalArgumentException When prefix is - * null + * @throws IllegalArgumentException When {@code prefix} is + * {@code null} */ String getNamespaceURI(String prefix); /** - *

            Get prefix bound to Namespace URI in the current scope.

            + * Get prefix bound to Namespace URI in the current scope. * *

            To get all prefixes bound to a Namespace URI in the current - * scope, use {@link #getPrefixes(String namespaceURI)}.

            + * scope, use {@link #getPrefixes(String namespaceURI)}. * *

            When requesting a prefix by Namespace URI, the following * table describes the returned prefix value for all Namespace URI - * values:

            + * values: * * * * * * @@ -173,8 +173,8 @@ public interface NamespaceContext { * * * - * - * + * * * @@ -186,21 +186,21 @@ public interface NamespaceContext { * * * - * + * * * - * - * + * * * - * - * + * * * - * - * + * + * * * *
            - * getPrefix(namespaceURI) return value for + * {@code getPrefix(namespaceURI)} return value for * specified Namespace URIs *
            <default Namespace URI>XMLConstants.DEFAULT_NS_PREFIX ("") + * {@code }{@code XMLConstants.DEFAULT_NS_PREFIX} ("") *
            unbound Namespace URInull{@code null}
            XMLConstants.XML_NS_URI + * {@code XMLConstants.XML_NS_URI} * ("http://www.w3.org/XML/1998/namespace")XMLConstants.XML_NS_PREFIX ("xml"){@code XMLConstants.XML_NS_PREFIX} ("xml")
            XMLConstants.XMLNS_ATTRIBUTE_NS_URI + * {@code XMLConstants.XMLNS_ATTRIBUTE_NS_URI} * ("http://www.w3.org/2000/xmlns/")XMLConstants.XMLNS_ATTRIBUTE ("xmlns"){@code XMLConstants.XMLNS_ATTRIBUTE} ("xmlns")
            nullIllegalArgumentException is thrown{@code null}{@code IllegalArgumentException} is thrown
            @@ -209,32 +209,32 @@ public interface NamespaceContext { * * @return prefix bound to Namespace URI in current context * - * @throws IllegalArgumentException When namespaceURI is - * null + * @throws IllegalArgumentException When {@code namespaceURI} is + * {@code null} */ String getPrefix(String namespaceURI); /** - *

            Get all prefixes bound to a Namespace URI in the current - * scope.

            + * Get all prefixes bound to a Namespace URI in the current + * scope. * *

            An Iterator over String elements is returned in an arbitrary, - * implementation dependent, order.

            + * implementation dependent, order. * - *

            The Iterator is + *

            The {@code Iterator} is * not modifiable. e.g. the - * remove() method will throw - * UnsupportedOperationException.

            + * {@code remove()} method will throw + * {@code UnsupportedOperationException}. * *

            When requesting prefixes by Namespace URI, the following * table describes the returned prefixes value for all Namespace - * URI values:

            + * URI values: * * * * - * * * @@ -245,9 +245,9 @@ public interface NamespaceContext { * * * + * including the {@code } * * * - * + * * * - * - * + * * * - * - * + * * * - * - * + * + * * * *
            - * getPrefixes(namespaceURI) return value for + * {@code + * getPrefixes(namespaceURI)} return value for * specified Namespace URIs
            bound Namespace URI, - * including the <default Namespace URI> - * Iterator over prefixes bound to Namespace URI in + * {@code Iterator} over prefixes bound to Namespace URI in * the current scope in an arbitrary, * implementation dependent, * order @@ -255,34 +255,34 @@ public interface NamespaceContext { *
            unbound Namespace URIempty Iteratorempty {@code Iterator}
            XMLConstants.XML_NS_URI + * {@code XMLConstants.XML_NS_URI} * ("http://www.w3.org/XML/1998/namespace")Iterator with one element set to - * XMLConstants.XML_NS_PREFIX ("xml"){@code Iterator} with one element set to + * {@code XMLConstants.XML_NS_PREFIX} ("xml")
            XMLConstants.XMLNS_ATTRIBUTE_NS_URI + * {@code XMLConstants.XMLNS_ATTRIBUTE_NS_URI} * ("http://www.w3.org/2000/xmlns/")Iterator with one element set to - * XMLConstants.XMLNS_ATTRIBUTE ("xmlns"){@code Iterator} with one element set to + * {@code XMLConstants.XMLNS_ATTRIBUTE} ("xmlns")
            nullIllegalArgumentException is thrown{@code null}{@code IllegalArgumentException} is thrown
            * * @param namespaceURI URI of Namespace to lookup * - * @return Iterator for all prefixes bound to the + * @return {@code Iterator} for all prefixes bound to the * Namespace URI in the current scope * - * @throws IllegalArgumentException When namespaceURI is - * null + * @throws IllegalArgumentException When {@code namespaceURI} is + * {@code null} */ Iterator getPrefixes(String namespaceURI); } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/parsers/DocumentBuilderFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/parsers/DocumentBuilderFactory.java index c500869cd7f..71fed6c2c15 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/parsers/DocumentBuilderFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/parsers/DocumentBuilderFactory.java @@ -47,8 +47,8 @@ public abstract class DocumentBuilderFactory { private boolean coalescing = false; /** - *

            Protected constructor to prevent instantiation. - * Use {@link #newInstance()}.

            + * Protected constructor to prevent instantiation. + * Use {@link #newInstance()}. */ protected DocumentBuilderFactory () { } @@ -60,7 +60,6 @@ public abstract class DocumentBuilderFactory { * This method uses the following ordered lookup procedure to determine * the {@code DocumentBuilderFactory} implementation class to * load: - *

            *

              *
            • * Use the {@code javax.xml.parsers.DocumentBuilderFactory} system @@ -131,7 +130,7 @@ public abstract class DocumentBuilderFactory { } /** - *

              Obtain a new instance of a {@code DocumentBuilderFactory} from class name. + * Obtain a new instance of a {@code DocumentBuilderFactory} from class name. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider * should be loaded. @@ -143,21 +142,22 @@ public abstract class DocumentBuilderFactory { *

              Tip for Trouble-shooting

              *

              Setting the {@code jaxp.debug} system property will cause * this method to print a lot of debug messages - * to {@code System.err} about what it is doing and where it is looking at.

              + * to {@code System.err} about what it is doing and where it is looking at. * - *

              If you have problems try:

              + *

              If you have problems try: *

                    * java -Djaxp.debug=1 YourProgram ....
                    * 
              * - * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.parsers.DocumentBuilderFactory}. + * @param factoryClassName fully qualified factory class name that provides + * implementation of {@code javax.xml.parsers.DocumentBuilderFactory}. * - * @param classLoader ClassLoader used to load the factory class. If null - * current Thread's context classLoader is used to load the factory class. + * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} + * current {@code Thread}'s context classLoader is used to load the factory class. * * @return New instance of a {@code DocumentBuilderFactory} * - * @throws FactoryConfigurationError if factoryClassName is null, or + * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or * the factory class cannot be loaded, instantiated. * * @see #newInstance() @@ -187,7 +187,7 @@ public abstract class DocumentBuilderFactory { /** * Specifies that the parser produced by this code will * provide support for XML namespaces. By default the value of this is set - * to false + * to {@code false} * * @param awareness true if the parser produced will provide support * for XML namespaces; false otherwise. @@ -200,7 +200,7 @@ public abstract class DocumentBuilderFactory { /** * Specifies that the parser produced by this code will * validate documents as they are parsed. By default the value of this - * is set to false. + * is set to {@code false}. * *

              * Note that "the validation" here means @@ -208,15 +208,13 @@ public abstract class DocumentBuilderFactory { * parser as defined in the XML recommendation. * In other words, it essentially just controls the DTD validation. * (except the legacy two properties defined in JAXP 1.2.) - *

              * *

              * To use modern schema languages such as W3C XML Schema or * RELAX NG instead of DTD, you can configure your parser to be * a non-validating parser by leaving the {@link #setValidating(boolean)} - * method false, then use the {@link #setSchema(Schema)} + * method {@code false}, then use the {@link #setSchema(Schema)} * method to associate a schema to a parser. - *

              * * @param validating true if the parser produced will validate documents * as they are parsed; false otherwise. @@ -234,7 +232,7 @@ public abstract class DocumentBuilderFactory { * element content that has an element only content model (see XML * Rec 3.2.1) will be eliminated. Due to reliance on the content model * this setting requires the parser to be in validating mode. By default - * the value of this is set to false. + * the value of this is set to {@code false}. * * @param whitespace true if the parser created must eliminate whitespace * in the element content when parsing XML documents; @@ -248,7 +246,7 @@ public abstract class DocumentBuilderFactory { /** * Specifies that the parser produced by this code will * expand entity reference nodes. By default the value of this is set to - * true + * {@code true} * * @param expandEntityRef true if the parser produced will expand entity * reference nodes; false otherwise. @@ -259,11 +257,10 @@ public abstract class DocumentBuilderFactory { } /** - *

              Specifies that the parser produced by this code will - * ignore comments. By default the value of this is set to false - * .

              + * Specifies that the parser produced by this code will + * ignore comments. By default the value of this is set to {@code false}. * - * @param ignoreComments boolean value to ignore comments during processing + * @param ignoreComments {@code boolean} value to ignore comments during processing */ public void setIgnoringComments(boolean ignoreComments) { @@ -274,7 +271,7 @@ public abstract class DocumentBuilderFactory { * Specifies that the parser produced by this code will * convert CDATA nodes to Text nodes and append it to the * adjacent (if any) text node. By default the value of this is set to - * false + * {@code false} * * @param coalescing true if the parser produced will convert CDATA nodes * to Text nodes and append it to the adjacent (if any) @@ -367,25 +364,23 @@ public abstract class DocumentBuilderFactory { * All implementations that implement JAXP 1.5 or newer are required to * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. - *

              + * *
                *
              • - *

                * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property * restricts the access to external DTDs, external Entity References to the * protocols specified by the property. * If access is denied during parsing due to the restriction of this property, * {@link org.xml.sax.SAXException} will be thrown by the parse methods defined by * {@link javax.xml.parsers.DocumentBuilder}. - *

                - *

                + *

              • + *
              • * Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property * restricts the access to external Schema set by the schemaLocation attribute to * the protocols specified by the property. If access is denied during parsing * due to the restriction of this property, {@link org.xml.sax.SAXException} * will be thrown by the parse methods defined by * {@link javax.xml.parsers.DocumentBuilder}. - *

                *
              • *
              * @@ -413,61 +408,61 @@ public abstract class DocumentBuilderFactory { throws IllegalArgumentException; /** - *

              Set a feature for this {@code DocumentBuilderFactory} and DocumentBuilders created by this factory.

              + * Set a feature for this {@code DocumentBuilderFactory} + * and {@code DocumentBuilder}s created by this factory. * *

              * Feature names are fully qualified {@link java.net.URI}s. * Implementations may define their own features. * A {@link ParserConfigurationException} is thrown if this {@code DocumentBuilderFactory} or the - * DocumentBuilders it creates cannot support the feature. + * {@code DocumentBuilder}s it creates cannot support the feature. * It is possible for a {@code DocumentBuilderFactory} to expose a feature value but be unable to change its state. - *

              + * * *

              * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. - * When the feature is:

              + * When the feature is: *
                *
              • - * true: the implementation will limit XML processing to conform to implementation limits. + * {@code true}: the implementation will limit XML processing to conform to implementation limits. * Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources. * If XML processing is limited for security reasons, it will be reported via a call to the registered * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. * See {@link DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}. *
              • *
              • - * false: the implementation will processing XML according to the XML specifications without + * {@code false}: the implementation will processing XML according to the XML specifications without * regard to possible implementation limits. *
              • *
              * * @param name Feature name. - * @param value Is feature state true or false. + * @param value Is feature state {@code true} or {@code false}. * - * @throws ParserConfigurationException if this {@code DocumentBuilderFactory} or the DocumentBuilders + * @throws ParserConfigurationException if this {@code DocumentBuilderFactory} or the {@code DocumentBuilder}s * it creates cannot support this feature. - * @throws NullPointerException If the name parameter is null. + * @throws NullPointerException If the {@code name} parameter is null. * @since 1.5 */ public abstract void setFeature(String name, boolean value) throws ParserConfigurationException; /** - *

              Get the state of the named feature.

              + * Get the state of the named feature. * *

              * Feature names are fully qualified {@link java.net.URI}s. * Implementations may define their own features. * An {@link ParserConfigurationException} is thrown if this {@code DocumentBuilderFactory} or the - * DocumentBuilders it creates cannot support the feature. + * {@code DocumentBuilder}s it creates cannot support the feature. * It is possible for an {@code DocumentBuilderFactory} to expose a feature value but be unable to change its state. - *

              * * @param name Feature name. * * @return State of the named feature. * * @throws ParserConfigurationException if this {@code DocumentBuilderFactory} - * or the DocumentBuilders it creates cannot support this feature. + * or the {@code DocumentBuilder}s it creates cannot support this feature. * @since 1.5 */ public abstract boolean getFeature(String name) @@ -501,7 +496,7 @@ public abstract class DocumentBuilderFactory { } /** - *

              Set the {@link Schema} to be used by parsers created + * Set the {@link Schema} to be used by parsers created * from this factory. * *

              @@ -529,26 +524,26 @@ public abstract class DocumentBuilderFactory { * *

              * This processing will take effect even if - * the {@link #isValidating()} method returns false. + * the {@link #isValidating()} method returns {@code false}. * *

              It is an error to use - * the http://java.sun.com/xml/jaxp/properties/schemaSource - * property and/or the http://java.sun.com/xml/jaxp/properties/schemaLanguage + * the {@code http://java.sun.com/xml/jaxp/properties/schemaSource} + * property and/or the {@code http://java.sun.com/xml/jaxp/properties/schemaLanguage} * property in conjunction with a {@link Schema} object. * Such configuration will cause a {@link ParserConfigurationException} - * exception when the {@link #newDocumentBuilder()} is invoked.

              + * exception when the {@link #newDocumentBuilder()} is invoked. * * - *

              Note for implementors

              + *

              Note for implementors

              * *

              * A parser must be able to work with any {@link Schema} * implementation. However, parsers and schemas are allowed * to use implementation-specific custom mechanisms * as long as they yield the result described in the specification. - *

              * - * @param schema Schema to use or null + * + * @param schema {@code Schema} to use or {@code null} * to remove a schema. * * @throws UnsupportedOperationException When implementation does not @@ -569,16 +564,16 @@ public abstract class DocumentBuilderFactory { /** - *

              Set state of XInclude processing.

              + * Set state of XInclude processing. * *

              If XInclude markup is found in the document instance, should it be * processed as specified in - * XML Inclusions (XInclude) Version 1.0.

              + * XML Inclusions (XInclude) Version 1.0. * - *

              XInclude processing defaults to false.

              + *

              XInclude processing defaults to {@code false}. * - * @param state Set XInclude processing to true or - * false + * @param state Set XInclude processing to {@code true} or + * {@code false} * * @throws UnsupportedOperationException When implementation does not * override this method. @@ -594,7 +589,7 @@ public abstract class DocumentBuilderFactory { } /** - *

              Get state of XInclude processing.

              + * Get state of XInclude processing. * * @return current state of XInclude processing * diff --git a/jaxp/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java index 1160a62edf4..1732047ee5e 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/parsers/SAXParserFactory.java @@ -42,17 +42,17 @@ import org.xml.sax.SAXNotSupportedException; public abstract class SAXParserFactory { /** - *

              Should Parsers be validating?

              + * Should Parsers be validating? */ private boolean validating = false; /** - *

              Should Parsers be namespace aware?

              + * Should Parsers be namespace aware? */ private boolean namespaceAware = false; /** - *

              Protected constructor to force use of {@link #newInstance()}.

              + * Protected constructor to force use of {@link #newInstance()}. */ protected SAXParserFactory () { @@ -64,7 +64,6 @@ public abstract class SAXParserFactory { * This method uses the following ordered lookup procedure to determine * the {@code SAXParserFactory} implementation class to * load: - *

              *

                *
              • * Use the {@code javax.xml.parsers.SAXParserFactory} system @@ -138,19 +137,19 @@ public abstract class SAXParserFactory { } /** - *

                Obtain a new instance of a {@code SAXParserFactory} from class name. + * Obtain a new instance of a {@code SAXParserFactory} from class name. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider - * should be loaded.

                + * should be loaded. * *

                Once an application has obtained a reference to a {@code SAXParserFactory} - * it can use the factory to configure and obtain parser instances.

                + * it can use the factory to configure and obtain parser instances. * * *

                Tip for Trouble-shooting

                *

                Setting the {@code jaxp.debug} system property will cause * this method to print a lot of debug messages - * to {@code System.err} about what it is doing and where it is looking at.

                + * to {@code System.err} about what it is doing and where it is looking at. * *

                * If you have problems, try: @@ -160,12 +159,12 @@ public abstract class SAXParserFactory { * * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.parsers.SAXParserFactory}. * - * @param classLoader ClassLoader used to load the factory class. If null - * current Thread's context classLoader is used to load the factory class. + * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} + * current {@code Thread}'s context classLoader is used to load the factory class. * * @return New instance of a {@code SAXParserFactory} * - * @throws FactoryConfigurationError if factoryClassName is null, or + * @throws FactoryConfigurationError if {@code factoryClassName} is {@code null}, or * the factory class cannot be loaded, instantiated. * * @see #newInstance() @@ -179,8 +178,8 @@ public abstract class SAXParserFactory { } /** - *

                Creates a new instance of a SAXParser using the currently - * configured factory parameters.

                + * Creates a new instance of a SAXParser using the currently + * configured factory parameters. * * @return A new instance of a SAXParser. * @@ -196,7 +195,7 @@ public abstract class SAXParserFactory { /** * Specifies that the parser produced by this code will * provide support for XML namespaces. By default the value of this is set - * to false. + * to {@code false}. * * @param awareness true if the parser produced by this code will * provide support for XML namespaces; false otherwise. @@ -209,7 +208,7 @@ public abstract class SAXParserFactory { /** * Specifies that the parser produced by this code will * validate documents as they are parsed. By default the value of this is - * set to false. + * set to {@code false}. * *

                * Note that "the validation" here means @@ -217,15 +216,13 @@ public abstract class SAXParserFactory { * parser as defined in the XML recommendation. * In other words, it essentially just controls the DTD validation. * (except the legacy two properties defined in JAXP 1.2.) - *

                * *

                * To use modern schema languages such as W3C XML Schema or * RELAX NG instead of DTD, you can configure your parser to be * a non-validating parser by leaving the {@link #setValidating(boolean)} - * method false, then use the {@link #setSchema(Schema)} + * method {@code false}, then use the {@link #setSchema(Schema)} * method to associate a schema to a parser. - *

                * * @param validating true if the parser produced by this code will * validate documents as they are parsed; false otherwise. @@ -260,24 +257,23 @@ public abstract class SAXParserFactory { } /** - * - *

                Sets the particular feature in the underlying implementation of + * Sets the particular feature in the underlying implementation of * org.xml.sax.XMLReader. * A list of the core features and properties can be found at - * http://www.saxproject.org/

                + * http://www.saxproject.org/ * *

                All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. - * When the feature is

                + * When the feature is *
                  *
                • - * true: the implementation will limit XML processing to conform to implementation limits. + * {@code true}: the implementation will limit XML processing to conform to implementation limits. * Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources. * If XML processing is limited for security reasons, it will be reported via a call to the registered * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. - * See {@link SAXParser} parse methods for handler specification. + * See {@link SAXParser} {@code parse} methods for handler specification. *
                • *
                • - * When the feature is false, the implementation will processing XML according to the XML specifications without + * When the feature is {@code false}, the implementation will processing XML according to the XML specifications without * regard to possible implementation limits. *
                • *
                @@ -292,7 +288,7 @@ public abstract class SAXParserFactory { * @throws SAXNotSupportedException When the underlying XMLReader * recognizes the property name but doesn't support the * property. - * @throws NullPointerException If the name parameter is null. + * @throws NullPointerException If the {@code name} parameter is null. * * @see org.xml.sax.XMLReader#setFeature */ @@ -302,8 +298,8 @@ public abstract class SAXParserFactory { /** * - *

                Returns the particular property requested for in the underlying - * implementation of org.xml.sax.XMLReader.

                + * Returns the particular property requested for in the underlying + * implementation of org.xml.sax.XMLReader. * * @param name The name of the property to be retrieved. * @@ -347,12 +343,12 @@ public abstract class SAXParserFactory { } /** - *

                Set the {@link Schema} to be used by parsers created - * from this factory.

                + * Set the {@link Schema} to be used by parsers created + * from this factory. * *

                When a {@link Schema} is non-null, a parser will use a validator * created from it to validate documents before it passes information - * down to the application.

                + * down to the application. * *

                When warnings/errors/fatal errors are found by the validator, the parser must * handle them as if those errors were found by the parser itself. @@ -364,29 +360,28 @@ public abstract class SAXParserFactory { *

                A validator may modify the SAX event stream (for example by * adding default values that were missing in documents), and a parser * is responsible to make sure that the application will receive - * those modified event stream.

                + * those modified event stream. * - *

                Initially, null is set as the {@link Schema}.

                + *

                Initially, {@code null} is set as the {@link Schema}. * *

                This processing will take effect even if - * the {@link #isValidating()} method returns false. + * the {@link #isValidating()} method returns {@code false}. * *

                It is an error to use - * the http://java.sun.com/xml/jaxp/properties/schemaSource - * property and/or the http://java.sun.com/xml/jaxp/properties/schemaLanguage + * the {@code http://java.sun.com/xml/jaxp/properties/schemaSource} + * property and/or the {@code http://java.sun.com/xml/jaxp/properties/schemaLanguage} * property in conjunction with a non-null {@link Schema} object. * Such configuration will cause a {@link SAXException} - * exception when those properties are set on a {@link SAXParser}.

                + * exception when those properties are set on a {@link SAXParser}. * - *

                Note for implementors

                + *

                Note for implementors

                *

                * A parser must be able to work with any {@link Schema} * implementation. However, parsers and schemas are allowed * to use implementation-specific custom mechanisms * as long as they yield the result described in the specification. - *

                * - * @param schema Schema to use, null to remove a schema. + * @param schema {@code Schema} to use, {@code null} to remove a schema. * * @throws UnsupportedOperationException When implementation does not * override this method @@ -404,16 +399,16 @@ public abstract class SAXParserFactory { } /** - *

                Set state of XInclude processing.

                + * Set state of XInclude processing. * *

                If XInclude markup is found in the document instance, should it be * processed as specified in - * XML Inclusions (XInclude) Version 1.0.

                + * XML Inclusions (XInclude) Version 1.0. * - *

                XInclude processing defaults to false.

                + *

                XInclude processing defaults to {@code false}. * - * @param state Set XInclude processing to true or - * false + * @param state Set XInclude processing to {@code true} or + * {@code false} * * @throws UnsupportedOperationException When implementation does not * override this method @@ -429,7 +424,7 @@ public abstract class SAXParserFactory { } /** - *

                Get state of XInclude processing.

                + * Get state of XInclude processing. * * @return current state of XInclude processing * diff --git a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java index fc14bc620bc..1ec4d382711 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventFactory.java @@ -70,7 +70,6 @@ public abstract class XMLEventFactory { * This static method creates a new factory instance. * This method uses the following ordered lookup procedure to determine * the XMLEventFactory implementation class to load: - *

                *

                  *
                • * Use the javax.xml.stream.XMLEventFactory system property. @@ -158,7 +157,6 @@ public abstract class XMLEventFactory { *

                  * This method uses the following ordered lookup procedure to determine * the XMLEventFactory implementation class to load: - *

                  *

                    *
                  • * Use the value of the system property identified by {@code factoryId}. diff --git a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java index 90030378467..191a6df6f19 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLInputFactory.java @@ -160,7 +160,7 @@ public abstract class XMLInputFactory { * This static method creates a new factory instance. * This method uses the following ordered lookup procedure to determine * the XMLInputFactory implementation class to load: - *

                    + * *
                      *
                    • *

                      Use the javax.xml.stream.XMLInputFactory system property. @@ -201,12 +201,11 @@ public abstract class XMLInputFactory { *

                      * Once an application has obtained a reference to a XMLInputFactory it * can use the factory to configure and obtain stream instances. - *

                      *

                      * Note that this is a new method that replaces the deprecated newInstance() method. * No changes in behavior are defined by this replacement method relative to * the deprecated method. - *

                      + * * @throws FactoryConfigurationError in case of {@linkplain * java.util.ServiceConfigurationError service configuration error} or if * the implementation is not available or cannot be instantiated. @@ -245,7 +244,6 @@ public abstract class XMLInputFactory { *

                      * This method uses the following ordered lookup procedure to determine * the XMLInputFactory implementation class to load: - *

                      *

                        *
                      • *

                        @@ -488,7 +486,6 @@ public abstract class XMLInputFactory { *

                        * All implementations that implement JAXP 1.5 or newer are required to * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. - *

                        *
                          *
                        • *

                          @@ -497,7 +494,7 @@ public abstract class XMLInputFactory { * due to the restriction of this property, {@link javax.xml.stream.XMLStreamException} * will be thrown by the {@link javax.xml.stream.XMLStreamReader#next()} or * {@link javax.xml.stream.XMLEventReader#nextEvent()} method. - *

                          + * *
                        • *
                        * @param name The name of the property (may not be null) diff --git a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java index 4524a4e8315..caa230594db 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLOutputFactory.java @@ -54,17 +54,18 @@ import javax.xml.transform.Result; * Default Value * Required * - * javax.xml.stream.isRepairingNamespacesdefaults prefixes on the output sideBooleanFalseYes + * javax.xml.stream.isRepairingNamespacesdefaults prefixes + * on the output sideBooleanFalseYes * * * - *

                        The following paragraphs describe the namespace and prefix repair algorithm:

                        + *

                        The following paragraphs describe the namespace and prefix repair algorithm: * *

                        The property can be set with the following code line: - * setProperty("javax.xml.stream.isRepairingNamespaces",new Boolean(true|false));

                        + * {@code setProperty("javax.xml.stream.isRepairingNamespaces", new Boolean(true|false));} * *

                        This property specifies that the writer default namespace prefix declarations. - * The default value is false.

                        + * The default value is false. * *

                        If a writer isRepairingNamespaces it will create a namespace declaration * on the current StartElement for @@ -74,11 +75,11 @@ import javax.xml.transform.Result; * has not been declared in a parent of the current StartElement it will be declared * on the current StartElement. If the defaultNamespace is bound and in scope * and the default namespace matches the URI of the attribute or StartElement - * QName no prefix will be assigned.

                        + * QName no prefix will be assigned. * *

                        If an element or attribute name has a prefix, but is not * bound to any namespace URI, then the prefix will be removed - * during serialization.

                        + * during serialization. * *

                        If element and/or attribute names in the same start or * empty-element tag are bound to different namespace URIs and @@ -86,20 +87,20 @@ import javax.xml.transform.Result; * occurring attribute retains the original prefix and the * following attributes have their prefixes replaced with a * new prefix that is bound to the namespace URIs of those - * attributes.

                        + * attributes. * *

                        If an element or attribute name uses a prefix that is * bound to a different URI than that inherited from the * namespace context of the parent of that element and there * is no namespace declaration in the context of the current - * element then such a namespace declaration is added.

                        + * element then such a namespace declaration is added. * *

                        If an element or attribute name is bound to a prefix and * there is a namespace declaration that binds that prefix * to a different URI then that namespace declaration is * either removed if the correct mapping is inherited from * the parent context of that element, or changed to the - * namespace URI of the element or attribute using that prefix.

                        + * namespace URI of the element or attribute using that prefix. * * @version 1.2 * @author Copyright (c) 2009, 2015 by Oracle Corporation. All Rights Reserved. @@ -136,7 +137,6 @@ public abstract class XMLOutputFactory { * This static method creates a new factory instance. This method uses the * following ordered lookup procedure to determine the XMLOutputFactory * implementation class to load: - *

                        *

                          *
                        • * Use the javax.xml.stream.XMLOutputFactory system property. @@ -177,6 +177,7 @@ public abstract class XMLOutputFactory { *

                          * Otherwise, the system-default implementation is returned. *

                        • + *
                        *

                        * Once an application has obtained a reference to a XMLOutputFactory it * can use the factory to configure and obtain stream instances. @@ -222,7 +223,6 @@ public abstract class XMLOutputFactory { *

                        * This method uses the following ordered lookup procedure to determine * the XMLOutputFactory implementation class to load: - *

                        *

                          *
                        • * Use the value of the system property identified by {@code factoryId}. diff --git a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java index fd15819f3d8..e92e979ed08 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java @@ -57,9 +57,9 @@ import javax.xml.namespace.QName; * javax.xml.stream.notations and javax.xml.stream.entities. * When the current event is a DTD the following call will return a * list of Notations - * List l = (List) getProperty("javax.xml.stream.notations"); + * {@code List l = (List) getProperty("javax.xml.stream.notations");} * The following call will return a list of entity declarations: - * List l = (List) getProperty("javax.xml.stream.entities"); + * {@code List l = (List) getProperty("javax.xml.stream.entities");} * These properties can only be accessed during a DTD event and * are defined to return null if the information is not available. * @@ -97,12 +97,13 @@ import javax.xml.namespace.QName; * getElementText(), nextTag() * * + * * ATTRIBUTE * next(), nextTag() * getAttributeXXX(), isAttributeSpecified(), * * - * + * * NAMESPACE * next(), nextTag() * getNamespaceXXX() @@ -184,7 +185,7 @@ public interface XMLStreamReader extends XMLStreamConstants { * If element content is empty (i.e. content is "") then no CHARACTERS event will be reported. * *

                          Given the following XML:
                          - * <foo><!--description-->content text<![CDATA[<greeting>Hello</greeting>]]>other content</foo>
                          + * {@code content textHello>/greeting>]]>other content>/foo>}
                          * The behavior of calling next() when being on foo will be:
                          * 1- the comment (COMMENT)
                          * 2- then the characters section (CHARACTERS)
                          @@ -192,14 +193,14 @@ public interface XMLStreamReader extends XMLStreamConstants { * 4- then the next characters section (another CHARACTERS)
                          * 5- then the END_ELEMENT
                          * - *

                          NOTE: empty element (such as <tag/>) will be reported + *

                          NOTE: empty element (such as {@code }) will be reported * with two separate events: START_ELEMENT, END_ELEMENT - This preserves - * parsing equivalency of empty element to <tag></tag>. + * parsing equivalency of empty element to {@code }. * * This method will throw an IllegalStateException if it is called after hasNext() returns false. * @see javax.xml.stream.events.XMLEvent * @return the integer code corresponding to the current parse event - * @throws NoSuchElementException if this is called when hasNext() returns false + * @throws java.util.NoSuchElementException if this is called when hasNext() returns false * @throws XMLStreamException if there is an error processing the underlying XML source */ public int next() throws XMLStreamException; @@ -219,38 +220,39 @@ public interface XMLStreamReader extends XMLStreamConstants { * Reads the content of a text-only element, an exception is thrown if this is * not a text-only element. * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content. - *
                          Precondition: the current event is START_ELEMENT. - *
                          Postcondition: the current event is the corresponding END_ELEMENT. + *
                          Precondition: the current event is START_ELEMENT. + *
                          Postcondition: the current event is the corresponding END_ELEMENT. * - *
                          The method does the following (implementations are free to optimized + *
                          The method does the following (implementations are free to optimized * but must do equivalent processing): *

                              * if(getEventType() != XMLStreamConstants.START_ELEMENT) {
                          -   * throw new XMLStreamException(
                          -   * "parser must be on START_ELEMENT to read next text", getLocation());
                          +   *     throw new XMLStreamException(
                          +   *     "parser must be on START_ELEMENT to read next text", getLocation());
                              * }
                          +   *
                              * int eventType = next();
                              * StringBuffer content = new StringBuffer();
                          -   * while(eventType != XMLStreamConstants.END_ELEMENT ) {
                          -   * if(eventType == XMLStreamConstants.CHARACTERS
                          -   * || eventType == XMLStreamConstants.CDATA
                          -   * || eventType == XMLStreamConstants.SPACE
                          -   * || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
                          -   * buf.append(getText());
                          -   * } else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
                          -   * || eventType == XMLStreamConstants.COMMENT) {
                          -   * // skipping
                          -   * } else if(eventType == XMLStreamConstants.END_DOCUMENT) {
                          -   * throw new XMLStreamException(
                          -   * "unexpected end of document when reading element text content", this);
                          -   * } else if(eventType == XMLStreamConstants.START_ELEMENT) {
                          -   * throw new XMLStreamException(
                          -   * "element text content may not contain START_ELEMENT", getLocation());
                          -   * } else {
                          -   * throw new XMLStreamException(
                          -   * "Unexpected event type "+eventType, getLocation());
                          -   * }
                          -   * eventType = next();
                          +   * while(eventType != XMLStreamConstants.END_ELEMENT) {
                          +   *     if(eventType == XMLStreamConstants.CHARACTERS
                          +   *        || eventType == XMLStreamConstants.CDATA
                          +   *        || eventType == XMLStreamConstants.SPACE
                          +   *        || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
                          +   *           buf.append(getText());
                          +   *     } else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
                          +   *               || eventType == XMLStreamConstants.COMMENT) {
                          +   *         // skipping
                          +   *     } else if(eventType == XMLStreamConstants.END_DOCUMENT) {
                          +   *         throw new XMLStreamException(
                          +   *         "unexpected end of document when reading element text content", this);
                          +   *     } else if(eventType == XMLStreamConstants.START_ELEMENT) {
                          +   *         throw new XMLStreamException(
                          +   *         "element text content may not contain START_ELEMENT", getLocation());
                          +   *     } else {
                          +   *         throw new XMLStreamException(
                          +   *         "Unexpected event type "+eventType, getLocation());
                          +   *     }
                          +   *     eventType = next();
                              * }
                              * return buf.toString();
                              * 
                          @@ -268,33 +270,33 @@ public interface XMLStreamReader extends XMLStreamConstants { * are encountered, an exception is thrown. This method should * be used when processing element-only content seperated by white space. * - *
                          Precondition: none - *
                          Postcondition: the current event is START_ELEMENT or END_ELEMENT + *
                          Precondition: none + *
                          Postcondition: the current event is START_ELEMENT or END_ELEMENT * and cursor may have moved over any whitespace event. * - *
                          Essentially it does the following (implementations are free to optimized + *
                          Essentially it does the following (implementations are free to optimized * but must do equivalent processing): - *
                          +   * 
                           {@code
                              * int eventType = next();
                          -   * while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
                          -   * || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
                          +   * while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
                          +   * || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
                              * // skip whitespace
                              * || eventType == XMLStreamConstants.SPACE
                              * || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
                              * || eventType == XMLStreamConstants.COMMENT
                              * ) {
                          -   * eventType = next();
                          +   *     eventType = next();
                              * }
                          -   * if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
                          -   * throw new String XMLStreamException("expected start or end tag", getLocation());
                          +   * if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
                          +   *     throw new String XMLStreamException("expected start or end tag", getLocation());
                              * }
                          -   * return eventType;
                          +   * return eventType; }
                              * 
                          * * @return the event type of the element read (START_ELEMENT or END_ELEMENT) * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION, * START_ELEMENT or END_ELEMENT - * @throws NoSuchElementException if this is called when hasNext() returns false + * @throws java.util.NoSuchElementException if this is called when hasNext() returns false */ public int nextTag() throws XMLStreamException; @@ -309,7 +311,7 @@ public interface XMLStreamReader extends XMLStreamConstants { public boolean hasNext() throws XMLStreamException; /** - * Frees any resources associated with this Reader. This method does not close the + * Frees any resources associated with this Reader. This method does not close the * underlying input source. * @throws XMLStreamException if there are errors freeing associated resources */ @@ -542,7 +544,7 @@ public interface XMLStreamReader extends XMLStreamConstants { * If the number of characters actually copied is less than the "length", then there is no more text. * Otherwise, subsequent calls need to be made until all text has been retrieved. For example: * - * + *
                          {@code
                              * int length = 1024;
                              * char[] myBuffer = new char[ length ];
                              *
                          @@ -553,7 +555,7 @@ public interface XMLStreamReader extends XMLStreamConstants {
                              *   if (nCopied < length)
                              *       break;
                              * }
                          -   * 
                          +   * } 
                          * XMLStreamException may be thrown if there are any XML errors in the underlying source. * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target", * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target". @@ -564,8 +566,8 @@ public interface XMLStreamReader extends XMLStreamConstants { * @param length the number of characters to copy * @return the number of characters actually copied * @throws XMLStreamException if the underlying XML source is not well-formed - * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target - * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target + * @throws IndexOutOfBoundsException if targetStart {@literal <} 0 or {@literal >} than the length of target + * @throws IndexOutOfBoundsException if length {@literal <} 0 or targetStart + length {@literal >} length of target * @throws UnsupportedOperationException if this method is not supported * @throws NullPointerException is if target is null */ diff --git a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamWriter.java b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamWriter.java index f3615892b7a..ca05fc083be 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamWriter.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamWriter.java @@ -33,9 +33,9 @@ import javax.xml.namespace.NamespaceContext; /** * The XMLStreamWriter interface specifies how to write XML. The XMLStreamWriter does * not perform well formedness checking on its input. However - * the writeCharacters method is required to escape & , < and > + * the writeCharacters method is required to escape {@literal &, < and >} * For attribute values the writeAttribute method will escape the - * above characters plus " to ensure that all character content + * above characters plus {@literal "} to ensure that all character content * and attribute values are well formed. * * Each NAMESPACE @@ -44,12 +44,12 @@ import javax.xml.namespace.NamespaceContext; * * * - * + * * * * - * - * + * + * * * * @@ -62,7 +62,7 @@ import javax.xml.namespace.NamespaceContext; * * * - * + * * * * * * * - * + * * * * * * * - * + * * * * * * * * * * - * + * * * * * * * * * @@ -175,10 +175,14 @@ import javax.xml.namespace.NamespaceContext; * Notes: *
                            *
                          • [1] if namespaceURI == default Namespace URI, then no prefix is written
                          • - *
                          • [2] if prefix == "" || null && namespaceURI == "", then no prefix or Namespace declaration is generated or written
                          • + *
                          • [2] if prefix == "" || null {@literal &&} namespaceURI == "", then + * no prefix or Namespace declaration is generated or written
                          • *
                          • [3] if prefix == "" || null, then a prefix is randomly generated
                          • - *
                          • [4] if prefix == "" || null, then it is treated as the default Namespace and no prefix is generated or written, an xmlns declaration is generated and written if the namespaceURI is unbound
                          • - *
                          • [5] if prefix == "" || null, then it is treated as an invalid attempt to define the default Namespace and an XMLStreamException is thrown
                          • + *
                          • [4] if prefix == "" || null, then it is treated as the default Namespace and + * no prefix is generated or written, an xmlns declaration is generated + * and written if the namespaceURI is unbound
                          • + *
                          • [5] if prefix == "" || null, then it is treated as an invalid attempt to + * define the default Namespace and an XMLStreamException is thrown
                          • *
                          * * diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/Result.java b/jaxp/src/java.xml/share/classes/javax/xml/transform/Result.java index fb5a42ee923..dab8dcde123 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/Result.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/Result.java @@ -27,7 +27,7 @@ package javax.xml.transform; /** *

                          An object that implements this interface contains the information - * needed to build a transformation result tree.

                          + * needed to build a transformation result tree. * * @author Jeff Suttor * @since 1.4 @@ -38,7 +38,7 @@ public interface Result { * The name of the processing instruction that is sent if the * result tree disables output escaping. * - *

                          Normally, result tree serialization escapes & and < (and + *

                          Normally, result tree serialization escapes{@literal & and <} (and * possibly other characters) when outputting text nodes. * This ensures that the output is well-formed XML. However, * it is sometimes convenient to be able to produce output that is @@ -46,10 +46,10 @@ public interface Result { * the output may include ill-formed sections that will * be transformed into well-formed XML by a subsequent non-XML aware * process. If a processing instruction is sent with this name, - * serialization should be output without any escaping.

                          + * serialization should be output without any escaping. * *

                          Result DOM trees may also have PI_DISABLE_OUTPUT_ESCAPING and - * PI_ENABLE_OUTPUT_ESCAPING inserted into the tree.

                          + * PI_ENABLE_OUTPUT_ESCAPING inserted into the tree. * * @see disable-output-escaping in XSLT Specification */ @@ -71,7 +71,7 @@ public interface Result { * *

                          If the Result is not to be written to a file, the system identifier is optional. * The application may still want to provide one, however, for use in error messages - * and warnings, or to resolve relative output identifiers.

                          + * and warnings, or to resolve relative output identifiers. * * @param systemId The system identifier as a URI string. */ diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java index 2fd931df891..b0957826a0b 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/TransformerFactory.java @@ -28,13 +28,13 @@ package javax.xml.transform; /** *

                          A TransformerFactory instance can be used to create * {@link javax.xml.transform.Transformer} and - * {@link javax.xml.transform.Templates} objects.

                          + * {@link javax.xml.transform.Templates} objects. * *

                          The system property that determines which Factory implementation - * to create is named "javax.xml.transform.TransformerFactory". + * to create is named {@code "javax.xml.transform.TransformerFactory"}. * This property names a concrete subclass of the * {@code TransformerFactory} abstract class. If the property is not - * defined, a platform default is be used.

                          + * defined, a platform default is be used. * * @author Jeff Suttor * @author Neeraj Bajaj @@ -51,14 +51,11 @@ public abstract class TransformerFactory { /** - *

                          * Obtain a new instance of a {@code TransformerFactory}. * This static method creates a new factory instance. *

                          * This method uses the following ordered lookup procedure to determine - * the {@code TransformerFactory} implementation class to - * load: - *

                          + * the {@code TransformerFactory} implementation class to load: *

                            *
                          • * Use the {@code javax.xml.transform.TransformerFactory} system @@ -118,34 +115,34 @@ public abstract class TransformerFactory { } /** - *

                            Obtain a new instance of a {@code TransformerFactory} from factory class name. + * Obtain a new instance of a {@code TransformerFactory} from factory class name. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider - * should be loaded.

                            + * should be loaded. * *

                            Once an application has obtained a reference to a * {@code TransformerFactory} it can use the factory to configure - * and obtain transformer instances.

                            + * and obtain transformer instances. * *

                            Tip for Trouble-shooting

                            - *

                            Setting the jaxp.debug system property will cause + *

                            Setting the {@code jaxp.debug} system property will cause * this method to print a lot of debug messages - * to System.err about what it is doing and where it is looking at.

                            + * to {@code System.err} about what it is doing and where it is looking at. * - *

                            If you have problems try:

                            + *

                            If you have problems try: *

                                  * java -Djaxp.debug=1 YourProgram ....
                                  * 
                            * * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.transform.TransformerFactory}. * - * @param classLoader ClassLoader used to load the factory class. If null - * current Thread's context classLoader is used to load the factory class. + * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} + * current {@code Thread}'s context classLoader is used to load the factory class. * * @return new TransformerFactory instance, never null. * * @throws TransformerFactoryConfigurationError - * if factoryClassName is null, or + * if {@code factoryClassName} is {@code null}, or * the factory class cannot be loaded, instantiated. * * @see #newInstance() @@ -160,29 +157,29 @@ public abstract class TransformerFactory { factoryClassName, classLoader, false, false); } /** - *

                            Process the Source into a Transformer - * Object. The Source is an XSLT document that + * Process the {@code Source} into a {@code Transformer} + * {@code Object}. The {@code Source} is an XSLT document that * conforms to * XSL Transformations (XSLT) Version 1.0. Care must - * be taken not to use this Transformer in multiple - * Threads running concurrently. - * Different TransformerFactories can be used concurrently by - * different Threads.

                            + * be taken not to use this {@code Transformer} in multiple + * {@code Thread}s running concurrently. + * Different {@code TransformerFactories} can be used concurrently by + * different {@code Thread}s. * - * @param source Source of XSLT document used to create - * Transformer. - * Examples of XML Sources include + * @param source {@code Source } of XSLT document used to create + * {@code Transformer}. + * Examples of XML {@code Source}s include * {@link javax.xml.transform.dom.DOMSource DOMSource}, * {@link javax.xml.transform.sax.SAXSource SAXSource}, and * {@link javax.xml.transform.stream.StreamSource StreamSource}. * - * @return A Transformer object that may be used to perform - * a transformation in a single Thread, never - * null. + * @return A {@code Transformer} object that may be used to perform + * a transformation in a single {@code Thread}, never + * {@code null}. * * @throws TransformerConfigurationException Thrown if there are errors when - * parsing the Source or it is not possible to create a - * Transformer instance. + * parsing the {@code Source} or it is not possible to create a + * {@code Transformer} instance. * * @see * XSL Transformations (XSLT) Version 1.0 @@ -191,15 +188,15 @@ public abstract class TransformerFactory { throws TransformerConfigurationException; /** - *

                            Create a new Transformer that performs a copy - * of the Source to the Result. - * i.e. the "identity transform".

                            + * Create a new {@code Transformer} that performs a copy + * of the {@code Source} to the {@code Result}. + * i.e. the "identity transform". * * @return A Transformer object that may be used to perform a transformation * in a single thread, never null. * * @throws TransformerConfigurationException When it is not - * possible to create a Transformer instance. + * possible to create a {@code Transformer} instance. */ public abstract Transformer newTransformer() throws TransformerConfigurationException; @@ -215,7 +212,7 @@ public abstract class TransformerFactory { * @param source An object that holds a URL, input stream, etc. * * @return A Templates object capable of being used for transformation - * purposes, never null. + * purposes, never {@code null}. * * @throws TransformerConfigurationException When parsing to * construct the Templates object fails. @@ -224,13 +221,13 @@ public abstract class TransformerFactory { throws TransformerConfigurationException; /** - *

                            Get the stylesheet specification(s) associated with the - * XML Source document via the + * Get the stylesheet specification(s) associated with the + * XML {@code Source} document via the * * xml-stylesheet processing instruction that match the given criteria. * Note that it is possible to return several stylesheets, in which case * they are applied as if they were a list of imports or cascades in a - * single stylesheet.

                            + * single stylesheet. * * @param source The XML source document. * @param media The media attribute to be matched. May be null, in which @@ -238,12 +235,12 @@ public abstract class TransformerFactory { * @param title The value of the title attribute to match. May be null. * @param charset The value of the charset attribute to match. May be null. * - * @return A Source Object suitable for passing + * @return A {@code Source} {@code Object} suitable for passing * to the {@code TransformerFactory}. * - * @throws TransformerConfigurationException An Exception + * @throws TransformerConfigurationException An {@code Exception} * is thrown if an error occurings during parsing of the - * source. + * {@code source}. * * @see * Associating Style Sheets with XML documents Version 1.0 @@ -275,22 +272,21 @@ public abstract class TransformerFactory { //======= CONFIGURATION METHODS ======= /** - *

                            Set a feature for this {@code TransformerFactory} and Transformers - * or Templates created by this factory.

                            + *

                            Set a feature for this {@code TransformerFactory} and {@code Transformer}s + * or {@code Template}s created by this factory. * *

                            * Feature names are fully qualified {@link java.net.URI}s. * Implementations may define their own features. * An {@link TransformerConfigurationException} is thrown if this {@code TransformerFactory} or the - * Transformers or Templates it creates cannot support the feature. + * {@code Transformer}s or {@code Template}s it creates cannot support the feature. * It is possible for an {@code TransformerFactory} to expose a feature value but be unable to change its state. - *

                            * *

                            All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. - * When the feature is:

                            + * When the feature is: *
                              *
                            • - * true: the implementation will limit XML processing to conform to implementation limits + * {@code true}: the implementation will limit XML processing to conform to implementation limits * and behave in a secure fashion as defined by the implementation. * Examples include resolving user defined style sheets and functions. * If XML processing is limited for security reasons, it will be reported via a call to the registered @@ -298,17 +294,17 @@ public abstract class TransformerFactory { * See {@link #setErrorListener(ErrorListener listener)}. *
                            • *
                            • - * false: the implementation will processing XML according to the XML specifications without + * {@code false}: the implementation will processing XML according to the XML specifications without * regard to possible implementation limits. *
                            • *
                            * * @param name Feature name. - * @param value Is feature state true or false. + * @param value Is feature state {@code true} or {@code false}. * * @throws TransformerConfigurationException if this {@code TransformerFactory} - * or the Transformers or Templates it creates cannot support this feature. - * @throws NullPointerException If the name parameter is null. + * or the {@code Transformer}s or {@code Template}s it creates cannot support this feature. + * @throws NullPointerException If the {@code name} parameter is null. */ public abstract void setFeature(String name, boolean value) throws TransformerConfigurationException; @@ -319,16 +315,15 @@ public abstract class TransformerFactory { *

                            * Feature names are fully qualified {@link java.net.URI}s. * Implementations may define their own features. - * false is returned if this {@code TransformerFactory} or the - * Transformers or Templates it creates cannot support the feature. + * {@code false} is returned if this {@code TransformerFactory} or the + * {@code Transformer}s or {@code Template}s it creates cannot support the feature. * It is possible for an {@code TransformerFactory} to expose a feature value but be unable to change its state. - *

                            * * @param name Feature name. * - * @return The current state of the feature, true or false. + * @return The current state of the feature, {@code true} or {@code false}. * - * @throws NullPointerException If the name parameter is null. + * @throws NullPointerException If the {@code name} parameter is null. */ public abstract boolean getFeature(String name); @@ -336,13 +331,13 @@ public abstract class TransformerFactory { * Allows the user to set specific attributes on the underlying * implementation. An attribute in this context is defined to * be an option that the implementation provides. - * An IllegalArgumentException is thrown if the underlying + * An {@code IllegalArgumentException} is thrown if the underlying * implementation doesn't recognize the attribute. *

                            * All implementations that implement JAXP 1.5 or newer are required to * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_STYLESHEET} properties. - *

                            + * *
                              *
                            • *

                              @@ -351,7 +346,7 @@ public abstract class TransformerFactory { * If access is denied during transformation due to the restriction of this property, * {@link javax.xml.transform.TransformerException} will be thrown by * {@link javax.xml.transform.Transformer#transform(Source, Result)}. - *

                              + * *

                              * Access to external DTDs in the stylesheet is restricted to the protocols * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. @@ -359,7 +354,7 @@ public abstract class TransformerFactory { * restriction of this property, * {@link javax.xml.transform.TransformerConfigurationException} will be thrown * by the {@link #newTransformer(Source)} method. - *

                              + * *

                              * Access to external reference set by the stylesheet processing instruction, * Import and Include element is restricted to the protocols specified by the @@ -368,14 +363,14 @@ public abstract class TransformerFactory { * restriction of this property, * {@link javax.xml.transform.TransformerConfigurationException} will be thrown * by the {@link #newTransformer(Source)} method. - *

                              + * *

                              * Access to external document through XSLT document function is restricted * to the protocols specified by the property. If access is denied during * the transformation due to the restriction of this property, * {@link javax.xml.transform.TransformerException} will be thrown by the * {@link javax.xml.transform.Transformer#transform(Source, Result)} method. - *

                              + * *
                            • *
                            * @@ -390,7 +385,7 @@ public abstract class TransformerFactory { /** * Allows the user to retrieve specific attributes on the underlying * implementation. - * An IllegalArgumentException is thrown if the underlying + * An {@code IllegalArgumentException} is thrown if the underlying * implementation doesn't recognize the attribute. * * @param name The name of the attribute. @@ -406,13 +401,13 @@ public abstract class TransformerFactory { * Set the error event listener for the TransformerFactory, which * is used for the processing of transformation instructions, * and not for the transformation itself. - * An IllegalArgumentException is thrown if the - * ErrorListener listener is null. + * An {@code IllegalArgumentException} is thrown if the + * {@code ErrorListener} listener is {@code null}. * * @param listener The new error listener. * - * @throws IllegalArgumentException When listener is - * null + * @throws IllegalArgumentException When {@code listener} is + * {@code null} */ public abstract void setErrorListener(ErrorListener listener); diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/dom/DOMResult.java b/jaxp/src/java.xml/share/classes/javax/xml/transform/dom/DOMResult.java index 67ec2418740..8c4a1b789f9 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/dom/DOMResult.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/dom/DOMResult.java @@ -29,29 +29,32 @@ import javax.xml.transform.Result; import org.w3c.dom.Node; /** - *

                            Acts as a holder for a transformation result tree in the form of a Document Object Model (DOM) tree.

                            + * Acts as a holder for a transformation result tree + * in the form of a Document Object Model (DOM) tree. * - *

                            If no output DOM source is set, the transformation will create a Document node as the holder for the result of the transformation, - * which may be retrieved with {@link #getNode()}.

                            + *

                            If no output DOM source is set, the transformation will create + * a Document node as the holder for the result of the transformation, + * which may be retrieved with {@link #getNode()}. * * @author Jeff Suttor * @since 1.4 */ public class DOMResult implements Result { - /**

                            If {@link javax.xml.transform.TransformerFactory#getFeature} - * returns true when passed this value as an argument, - * the Transformer supports Result output of this type.

                            + /** + * If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns {@code true} when passed this value as an argument, + * the {@code Transformer} supports {@code Result} output of this type. */ public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature"; /** - *

                            Zero-argument default constructor.

                            + * Zero-argument default constructor. * - *

                            node, - * siblingNode and - * systemId - * will be set to null.

                            + *

                            {@code node}, + * {@code siblingNode} and + * {@code systemId} + * will be set to {@code null}. */ public DOMResult() { setNode(null); @@ -60,17 +63,17 @@ public class DOMResult implements Result { } /** - *

                            Use a DOM node to create a new output target.

                            + * Use a DOM node to create a new output target. * *

                            In practice, the node should be * a {@link org.w3c.dom.Document} node, * a {@link org.w3c.dom.DocumentFragment} node, or * a {@link org.w3c.dom.Element} node. - * In other words, a node that accepts children.

                            + * In other words, a node that accepts children. * - *

                            siblingNode and - * systemId - * will be set to null.

                            + *

                            {@code siblingNode} and + * {@code systemId} + * will be set to {@code null}. * * @param node The DOM node that will contain the result tree. */ @@ -81,15 +84,15 @@ public class DOMResult implements Result { } /** - *

                            Use a DOM node to create a new output target with the specified System ID.

                            + * Use a DOM node to create a new output target with the specified System ID. * *

                            In practice, the node should be * a {@link org.w3c.dom.Document} node, * a {@link org.w3c.dom.DocumentFragment} node, or * a {@link org.w3c.dom.Element} node. - * In other words, a node that accepts children.

                            + * In other words, a node that accepts children. * - *

                            siblingNode will be set to null.

                            + *

                            {@code siblingNode} will be set to {@code null}. * * @param node The DOM node that will contain the result tree. * @param systemId The system identifier which may be used in association with this node. @@ -101,32 +104,33 @@ public class DOMResult implements Result { } /** - *

                            Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before.

                            + * Use a DOM node to create a new output target specifying + * the child node where the result nodes should be inserted before. * - *

                            In practice, node and nextSibling should be + *

                            In practice, {@code node} and {@code nextSibling} should be * a {@link org.w3c.dom.Document} node, * a {@link org.w3c.dom.DocumentFragment} node, or * a {@link org.w3c.dom.Element} node. - * In other words, a node that accepts children.

                            + * In other words, a node that accepts children. * - *

                            Use nextSibling to specify the child node + *

                            Use {@code nextSibling} to specify the child node * where the result nodes should be inserted before. - * If nextSibling is not a sibling of node, - * then an IllegalArgumentException is thrown. - * If node is null and nextSibling is not null, - * then an IllegalArgumentException is thrown. - * If nextSibling is null, + * If {@code nextSibling} is not a sibling of {@code node}, + * then an {@code IllegalArgumentException} is thrown. + * If {@code node} is {@code null} and {@code nextSibling} is not {@code null}, + * then an {@code IllegalArgumentException} is thrown. + * If {@code nextSibling} is {@code null}, * then the behavior is the same as calling {@link #DOMResult(Node node)}, - * i.e. append the result nodes as the last child of the specified node.

                            + * i.e. append the result nodes as the last child of the specified {@code node}. * - *

                            systemId will be set to null.

                            + *

                            {@code systemId} will be set to {@code null}. * * @param node The DOM node that will contain the result tree. * @param nextSibling The child node where the result nodes should be inserted before. * - * @throws IllegalArgumentException If nextSibling is not a sibling of node or - * node is null and nextSibling - * is not null. + * @throws IllegalArgumentException If {@code nextSibling} is not a sibling of {@code node} or + * {@code node} is {@code null} and {@code nextSibling} + * is not {@code null}. * * @since 1.5 */ @@ -151,33 +155,35 @@ public class DOMResult implements Result { } /** - *

                            Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before and - * the specified System ID.

                            + * Use a DOM node to create a new output target specifying the child + * node where the result nodes should be inserted before and + * the specified System ID. * - *

                            In practice, node and nextSibling should be + *

                            In practice, {@code node} and {@code nextSibling} should be * a {@link org.w3c.dom.Document} node, * a {@link org.w3c.dom.DocumentFragment} node, or a * {@link org.w3c.dom.Element} node. - * In other words, a node that accepts children.

                            + * In other words, a node that accepts children. * - *

                            Use nextSibling to specify the child node + *

                            Use {@code nextSibling} to specify the child node * where the result nodes should be inserted before. - * If nextSibling is not a sibling of node, - * then an IllegalArgumentException is thrown. - * If node is null and nextSibling is not null, - * then an IllegalArgumentException is thrown. - * If nextSibling is null, + * If {@code nextSibling} is not a sibling of {@code node}, + * then an {@code IllegalArgumentException} is thrown. + * If {@code node} is {@code null} and {@code nextSibling} is not {@code null}, + * then an {@code IllegalArgumentException} is thrown. + * If {@code nextSibling} is {@code null}, * then the behavior is the same as calling {@link #DOMResult(Node node, String systemId)}, - * i.e. append the result nodes as the last child of the specified node and use the specified System ID.

                            + * i.e. append the result nodes as the last child of the specified + * node and use the specified System ID. * * @param node The DOM node that will contain the result tree. * @param nextSibling The child node where the result nodes should be inserted before. * @param systemId The system identifier which may be used in association with this node. * - * @throws IllegalArgumentException If nextSibling is not a - * sibling of node or - * node is null and nextSibling - * is not null. + * @throws IllegalArgumentException If {@code nextSibling} is not a + * sibling of {@code node} or + * {@code node} is {@code null} and {@code nextSibling} + * is not {@code null}. * * @since 1.5 */ @@ -202,27 +208,27 @@ public class DOMResult implements Result { } /** - *

                            Set the node that will contain the result DOM tree.

                            + * Set the node that will contain the result DOM tree. * *

                            In practice, the node should be * a {@link org.w3c.dom.Document} node, * a {@link org.w3c.dom.DocumentFragment} node, or * a {@link org.w3c.dom.Element} node. - * In other words, a node that accepts children.

                            + * In other words, a node that accepts children. * - *

                            An IllegalStateException is thrown if - * nextSibling is not null and - * node is not a parent of nextSibling. - * An IllegalStateException is thrown if node is null and - * nextSibling is not null.

                            + *

                            An {@code IllegalStateException} is thrown if + * {@code nextSibling} is not {@code null} and + * {@code node} is not a parent of {@code nextSibling}. + * An {@code IllegalStateException} is thrown if {@code node} is {@code null} and + * {@code nextSibling} is not {@code null}. * * @param node The node to which the transformation will be appended. * - * @throws IllegalStateException If nextSibling is not - * null and - * nextSibling is not a child of node or - * node is null and - * nextSibling is not null. + * @throws IllegalStateException If {@code nextSibling} is not + * {@code null} and + * {@code nextSibling} is not a child of {@code node} or + * {@code node} is {@code null} and + * {@code nextSibling} is not {@code null}. */ public void setNode(Node node) { // does the corrent parent/child relationship exist? @@ -242,7 +248,7 @@ public class DOMResult implements Result { } /** - *

                            Get the node that will contain the result DOM tree.

                            + * Get the node that will contain the result DOM tree. * *

                            If no node was set via * {@link #DOMResult(Node node)}, @@ -251,7 +257,7 @@ public class DOMResult implements Result { * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or * {@link #setNode(Node node)}, * then the node will be set by the transformation, and may be obtained from this method once the transformation is complete. - * Calling this method before the transformation will return null.

                            + * Calling this method before the transformation will return {@code null}. * * @return The node to which the transformation will be appended. */ @@ -260,24 +266,24 @@ public class DOMResult implements Result { } /** - *

                            Set the child node before which the result nodes will be inserted.

                            + * Set the child node before which the result nodes will be inserted. * - *

                            Use nextSibling to specify the child node + *

                            Use {@code nextSibling} to specify the child node * before which the result nodes should be inserted. - * If nextSibling is not a descendant of node, - * then an IllegalArgumentException is thrown. - * If node is null and nextSibling is not null, - * then an IllegalStateException is thrown. - * If nextSibling is null, + * If {@code nextSibling} is not a descendant of {@code node}, + * then an {@code IllegalArgumentException} is thrown. + * If {@code node} is {@code null} and {@code nextSibling} is not {@code null}, + * then an {@code IllegalStateException} is thrown. + * If {@code nextSibling} is {@code null}, * then the behavior is the same as calling {@link #DOMResult(Node node)}, - * i.e. append the result nodes as the last child of the specified node.

                            + * i.e. append the result nodes as the last child of the specified {@code node}. * * @param nextSibling The child node before which the result nodes will be inserted. * - * @throws IllegalArgumentException If nextSibling is not a - * descendant of node. - * @throws IllegalStateException If node is null - * and nextSibling is not null. + * @throws IllegalArgumentException If {@code nextSibling} is not a + * descendant of {@code node}. + * @throws IllegalStateException If {@code node} is {@code null} + * and {@code nextSibling} is not {@code null}. * * @since 1.5 */ @@ -300,13 +306,13 @@ public class DOMResult implements Result { } /** - *

                            Get the child node before which the result nodes will be inserted.

                            + * Get the child node before which the result nodes will be inserted. * *

                            If no node was set via * {@link #DOMResult(Node node, Node nextSibling)}, * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or * {@link #setNextSibling(Node nextSibling)}, - * then null will be returned.

                            + * then {@code null} will be returned. * * @return The child node before which the result nodes will be inserted. * @@ -317,7 +323,7 @@ public class DOMResult implements Result { } /** - *

                            Set the systemId that may be used in association with the node.

                            + * Set the systemId that may be used in association with the node. * * @param systemId The system identifier as a URI string. */ @@ -326,13 +332,13 @@ public class DOMResult implements Result { } /** - *

                            Get the System Identifier.

                            + * Get the System Identifier. * *

                            If no System ID was set via * {@link #DOMResult(Node node, String systemId)}, * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or * {@link #setSystemId(String systemId)}, - * then null will be returned.

                            + * then {@code null} will be returned. * * @return The system identifier. */ @@ -345,19 +351,19 @@ public class DOMResult implements Result { ////////////////////////////////////////////////////////////////////// /** - *

                            The node to which the transformation will be appended.

                            + * The node to which the transformation will be appended. */ private Node node = null; /** - *

                            The child node before which the result nodes will be inserted.

                            + * The child node before which the result nodes will be inserted. * * @since 1.5 */ private Node nextSibling = null; /** - *

                            The System ID that may be used in association with the node.

                            + * The System ID that may be used in association with the node. */ private String systemId = null; } diff --git a/jaxp/src/java.xml/share/classes/javax/xml/transform/stax/package.html b/jaxp/src/java.xml/share/classes/javax/xml/transform/stax/package.html index d07e037142b..abdd5ecd846 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/transform/stax/package.html +++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/stax/package.html @@ -65,9 +65,6 @@ questions.
                          • @see XMLEventReader
                          -

                          - @since 1.6 -

                          - + @since 1.6 diff --git a/jaxp/src/java.xml/share/classes/javax/xml/validation/SchemaFactory.java b/jaxp/src/java.xml/share/classes/javax/xml/validation/SchemaFactory.java index ad7e61f9a7f..8152b675c7e 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/validation/SchemaFactory.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/validation/SchemaFactory.java @@ -37,7 +37,7 @@ import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; /** - * Factory that creates {@link Schema} objects. Entry-point to + * Factory that creates {@link Schema} objects. Entry-point to * the validation API. * *

                          @@ -49,12 +49,12 @@ import org.xml.sax.SAXParseException; * it is the application's responsibility to ensure that at most * one thread is using a {@link SchemaFactory} object at any * given moment. Implementations are encouraged to mark methods - * as synchronized to protect themselves from broken clients. + * as {@code synchronized} to protect themselves from broken clients. * *

                          * {@link SchemaFactory} is not re-entrant. While one of the - * newSchema methods is being invoked, applications - * may not attempt to recursively invoke the newSchema method, + * {@code newSchema} methods is being invoked, applications + * may not attempt to recursively invoke the {@code newSchema} method, * even from the same thread. * *

                          Schema Language

                          @@ -92,11 +92,11 @@ import org.xml.sax.SAXParseException; * * * - * + * * * * - * + * * * * @@ -112,24 +112,24 @@ public abstract class SchemaFactory { private static SecuritySupport ss = new SecuritySupport(); /** - *

                          Constructor for derived classes.

                          + * Constructor for derived classes. * - *

                          The constructor does nothing.

                          + *

                          The constructor does nothing. * *

                          Derived classes must create {@link SchemaFactory} objects that have - * null {@link ErrorHandler} and - * null {@link LSResourceResolver}.

                          + * {@code null} {@link ErrorHandler} and + * {@code null} {@link LSResourceResolver}. */ protected SchemaFactory() { } /** - *

                          Lookup an implementation of the SchemaFactory that supports the specified - * schema language and return it.

                          + * Lookup an implementation of the {@code SchemaFactory} that supports the specified + * schema language and return it. * - *

                          To find a SchemaFactory object for a given schema language, + *

                          To find a {@code SchemaFactory} object for a given schema language, * this method looks the following places in the following order - * where "the class loader" refers to the context class loader:

                          + * where "the class loader" refers to the context class loader: *
                            *
                          1. *

                            @@ -178,9 +178,9 @@ public abstract class SchemaFactory { *

                          2. *
                          3. *

                            - * Platform default SchemaFactory is located + * Platform default {@code SchemaFactory} is located * in a implementation specific way. There must be a platform default - * SchemaFactory for W3C XML Schema. + * {@code SchemaFactory} for W3C XML Schema. *

                          4. *
                          * @@ -201,12 +201,12 @@ public abstract class SchemaFactory { * the list of available * schema languages for the possible values. * - * @return New instance of a SchemaFactory + * @return New instance of a {@code SchemaFactory} * * @throws IllegalArgumentException * If no implementation of the schema language is available. * @throws NullPointerException - * If the schemaLanguage parameter is null. + * If the {@code schemaLanguage} parameter is null. * @throws SchemaFactoryConfigurationError * If a configuration error is encountered. * @@ -233,42 +233,42 @@ public abstract class SchemaFactory { } /** - *

                          Obtain a new instance of a SchemaFactory from class name. SchemaFactory + * Obtain a new instance of a {@code SchemaFactory} from class name. {@code SchemaFactory} * is returned if specified factory class name supports the specified schema language. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider - * should be loaded.

                          + * should be loaded. * *

                          Tip for Trouble-shooting

                          - *

                          Setting the jaxp.debug system property will cause + *

                          Setting the {@code jaxp.debug} system property will cause * this method to print a lot of debug messages - * to System.err about what it is doing and where it is looking at.

                          + * to {@code System.err} about what it is doing and where it is looking at. * - *

                          If you have problems try:

                          + *

                          If you have problems try: *

                                * java -Djaxp.debug=1 YourProgram ....
                                * 
                          * * @param schemaLanguage Specifies the schema language which the returned - * SchemaFactory will understand. See + * {@code SchemaFactory} will understand. See * the list of available * schema languages for the possible values. * - * @param factoryClassName fully qualified factory class name that provides implementation of javax.xml.validation.SchemaFactory. + * @param factoryClassName fully qualified factory class name that provides implementation of {@code javax.xml.validation.SchemaFactory}. * - * @param classLoader ClassLoader used to load the factory class. If null - * current Thread's context classLoader is used to load the factory class. + * @param classLoader {@code ClassLoader} used to load the factory class. If {@code null} + * current {@code Thread}'s context classLoader is used to load the factory class. * - * @return New instance of a SchemaFactory + * @return New instance of a {@code SchemaFactory} * * @throws IllegalArgumentException - * if factoryClassName is null, or + * if {@code factoryClassName} is {@code null}, or * the factory class cannot be loaded, instantiated or doesn't - * support the schema language specified in schemLanguage + * support the schema language specified in {@code schemLanguage} * parameter. * * @throws NullPointerException - * If the schemaLanguage parameter is null. + * If the {@code schemaLanguage} parameter is null. * * @see #newInstance(String schemaLanguage) * @@ -299,16 +299,16 @@ public abstract class SchemaFactory { } /** - *

                          Is specified schema supported by this SchemaFactory?

                          + * Is specified schema supported by this {@code SchemaFactory}? * - * @param schemaLanguage Specifies the schema language which the returned SchemaFactory will understand. - * schemaLanguage must specify a valid schema language. + * @param schemaLanguage Specifies the schema language which the returned {@code SchemaFactory} will understand. + * {@code schemaLanguage} must specify a valid schema language. * - * @return true if SchemaFactory supports schemaLanguage, else false. + * @return {@code true} if {@code SchemaFactory} supports {@code schemaLanguage}, else {@code false}. * - * @throws NullPointerException If schemaLanguage is null. - * @throws IllegalArgumentException If schemaLanguage.length() == 0 - * or schemaLanguage does not specify a valid schema language. + * @throws NullPointerException If {@code schemaLanguage} is {@code null}. + * @throws IllegalArgumentException If {@code schemaLanguage.length() == 0} + * or {@code schemaLanguage} does not specify a valid schema language. */ public abstract boolean isSchemaLanguageSupported(String schemaLanguage); @@ -320,7 +320,7 @@ public abstract class SchemaFactory { * temporarily be unable to return its value. * *

                          Implementors are free (and encouraged) to invent their own features, - * using names built on their own URIs.

                          + * using names built on their own URIs. * * @param name The feature name, which is a non-null fully-qualified URI. * @@ -331,7 +331,7 @@ public abstract class SchemaFactory { * @throws SAXNotSupportedException When the * {@link SchemaFactory} recognizes the feature name but * cannot determine its value at this time. - * @throws NullPointerException If name is null. + * @throws NullPointerException If {@code name} is {@code null}. * * @see #setFeature(String, boolean) */ @@ -345,38 +345,37 @@ public abstract class SchemaFactory { } /** - *

                          Set a feature for this SchemaFactory, + * Set a feature for this {@code SchemaFactory}, * {@link Schema}s created by this factory, and by extension, * {@link Validator}s and {@link ValidatorHandler}s created by * those {@link Schema}s. - *

                          * *

                          Implementors and developers should pay particular attention * to how the special {@link Schema} object returned by {@link * #newSchema()} is processed. In some cases, for example, when the - * SchemaFactory and the class actually loading the + * {@code SchemaFactory} and the class actually loading the * schema come from different implementations, it may not be possible - * for SchemaFactory features to be inherited automatically. + * for {@code SchemaFactory} features to be inherited automatically. * Developers should * make sure that features, such as secure processing, are explicitly - * set in both places.

                          + * set in both places. * *

                          The feature name is any fully-qualified URI. It is * possible for a {@link SchemaFactory} to expose a feature value but - * to be unable to change the current value.

                          + * to be unable to change the current value. * *

                          All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. - * When the feature is:

                          + * When the feature is: *
                            *
                          • - * true: the implementation will limit XML processing to conform to implementation limits. + * {@code true}: the implementation will limit XML processing to conform to implementation limits. * Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources. * If XML processing is limited for security reasons, it will be reported via a call to the registered * {@link ErrorHandler#fatalError(SAXParseException exception)}. * See {@link #setErrorHandler(ErrorHandler errorHandler)}. *
                          • *
                          • - * false: the implementation will processing XML according to the XML specifications without + * {@code false}: the implementation will processing XML according to the XML specifications without * regard to possible implementation limits. *
                          • *
                          @@ -389,7 +388,7 @@ public abstract class SchemaFactory { * @throws SAXNotSupportedException When the * {@link SchemaFactory} recognizes the feature name but * cannot set the requested value. - * @throws NullPointerException If name is null. + * @throws NullPointerException If {@code name} is {@code null}. * * @see #getFeature(String) */ @@ -405,15 +404,15 @@ public abstract class SchemaFactory { /** * Set the value of a property. * - *

                          The property name is any fully-qualified URI. It is + *

                          The property name is any fully-qualified URI. It is * possible for a {@link SchemaFactory} to recognize a property name but - * to be unable to change the current value.

                          + * to be unable to change the current value. * *

                          * All implementations that implement JAXP 1.5 or newer are required to * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. - *

                          + * *
                            *
                          • *

                            Access to external DTDs in Schema files is restricted to the protocols @@ -421,14 +420,14 @@ public abstract class SchemaFactory { * If access is denied during the creation of new Schema due to the restriction * of this property, {@link org.xml.sax.SAXException} will be thrown by the * {@link #newSchema(Source)} or {@link #newSchema(File)} - * or {@link #newSchema(URL)} or or {@link #newSchema(Source[])} method.

                            + * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method. * *

                            Access to external DTDs in xml source files is restricted to the protocols * specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property. * If access is denied during validation due to the restriction * of this property, {@link org.xml.sax.SAXException} will be thrown by the * {@link javax.xml.validation.Validator#validate(Source)} or - * {@link javax.xml.validation.Validator#validate(Source, Result)} method.

                            + * {@link javax.xml.validation.Validator#validate(Source, Result)} method. * *

                            Access to external reference set by the schemaLocation attribute is * restricted to the protocols specified by the @@ -436,7 +435,7 @@ public abstract class SchemaFactory { * If access is denied during validation due to the restriction of this property, * {@link org.xml.sax.SAXException} will be thrown by the * {@link javax.xml.validation.Validator#validate(Source)} or - * {@link javax.xml.validation.Validator#validate(Source, Result)} method.

                            + * {@link javax.xml.validation.Validator#validate(Source, Result)} method. * *

                            Access to external reference set by the Import * and Include element is restricted to the protocols specified by the @@ -444,7 +443,7 @@ public abstract class SchemaFactory { * If access is denied during the creation of new Schema due to the restriction * of this property, {@link org.xml.sax.SAXException} will be thrown by the * {@link #newSchema(Source)} or {@link #newSchema(File)} - * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method.

                            + * or {@link #newSchema(URL)} or {@link #newSchema(Source[])} method. *
                          • *
                          * @@ -456,7 +455,7 @@ public abstract class SchemaFactory { * @throws SAXNotSupportedException When the * {@link SchemaFactory} recognizes the property name but * cannot set the requested value. - * @throws NullPointerException If name is null. + * @throws NullPointerException If {@code name} is {@code null}. */ public void setProperty(String name, Object object) throws SAXNotRecognizedException, SAXNotSupportedException { @@ -472,13 +471,13 @@ public abstract class SchemaFactory { * *

                          The property name is any fully-qualified URI. It is * possible for a {@link SchemaFactory} to recognize a property name but - * temporarily be unable to return its value.

                          + * temporarily be unable to return its value. * *

                          {@link SchemaFactory}s are not required to recognize any specific - * property names.

                          + * property names. * *

                          Implementors are free (and encouraged) to invent their own properties, - * using names built on their own URIs.

                          + * using names built on their own URIs. * * @param name The property name, which is a non-null fully-qualified URI. * @@ -489,7 +488,7 @@ public abstract class SchemaFactory { * @throws SAXNotSupportedException When the * XMLReader recognizes the property name but * cannot determine its value at this time. - * @throws NullPointerException If name is null. + * @throws NullPointerException If {@code name} is {@code null}. * * @see #setProperty(String, Object) */ @@ -504,7 +503,7 @@ public abstract class SchemaFactory { /** * Sets the {@link ErrorHandler} to receive errors encountered - * during the newSchema method invocation. + * during the {@code newSchema} method invocation. * *

                          * Error handler can be used to customize the error handling process @@ -521,7 +520,7 @@ public abstract class SchemaFactory { *

                          * If any {@link Throwable} (or instances of its derived classes) * is thrown from an {@link ErrorHandler}, - * the caller of the newSchema method will be thrown + * the caller of the {@code newSchema} method will be thrown * the same {@link Throwable} object. * *

                          @@ -557,7 +556,7 @@ public abstract class SchemaFactory { * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. * * @param errorHandler A new error handler to be set. - * This parameter can be null. + * This parameter can be {@code null}. */ public abstract void setErrorHandler(ErrorHandler errorHandler); @@ -583,7 +582,7 @@ public abstract class SchemaFactory { * when it needs to locate external resources while parsing schemas, * although exactly what constitutes "locating external resources" is * up to each schema language. For example, for W3C XML Schema, - * this includes files <include>d or <import>ed, + * this includes files {@code }d or {@code }ed, * and DTD referenced from schema files, etc. * *

                          @@ -607,7 +606,7 @@ public abstract class SchemaFactory { * If a {@link LSResourceResolver} throws a {@link RuntimeException} * (or instances of its derived classes), * then the {@link SchemaFactory} will abort the parsing and - * the caller of the newSchema method will receive + * the caller of the {@code newSchema} method will receive * the same {@link RuntimeException}. * *

                          @@ -635,48 +634,48 @@ public abstract class SchemaFactory { public abstract LSResourceResolver getResourceResolver(); /** - *

                          Parses the specified source as a schema and returns it as a schema.

                          + * Parses the specified source as a schema and returns it as a schema. * - *

                          This is a convenience method for {@link #newSchema(Source[] schemas)}.

                          + *

                          This is a convenience method for {@link #newSchema(Source[] schemas)}. * * @param schema Source that represents a schema. * - * @return New Schema from parsing schema. + * @return New {@code Schema} from parsing {@code schema}. * * @throws SAXException If a SAX error occurs during parsing. - * @throws NullPointerException if schema is null. + * @throws NullPointerException if {@code schema} is null. */ public Schema newSchema(Source schema) throws SAXException { return newSchema(new Source[]{schema}); } /** - *

                          Parses the specified File as a schema and returns it as a Schema.

                          + * Parses the specified {@code File} as a schema and returns it as a {@code Schema}. * - *

                          This is a convenience method for {@link #newSchema(Source schema)}.

                          + *

                          This is a convenience method for {@link #newSchema(Source schema)}. * * @param schema File that represents a schema. * - * @return New Schema from parsing schema. + * @return New {@code Schema} from parsing {@code schema}. * * @throws SAXException If a SAX error occurs during parsing. - * @throws NullPointerException if schema is null. + * @throws NullPointerException if {@code schema} is null. */ public Schema newSchema(File schema) throws SAXException { return newSchema(new StreamSource(schema)); } /** - *

                          Parses the specified URL as a schema and returns it as a Schema.

                          + * Parses the specified {@code URL} as a schema and returns it as a {@code Schema}. * - *

                          This is a convenience method for {@link #newSchema(Source schema)}.

                          + *

                          This is a convenience method for {@link #newSchema(Source schema)}. * - * @param schema URL that represents a schema. + * @param schema {@code URL} that represents a schema. * - * @return New Schema from parsing schema. + * @return New {@code Schema} from parsing {@code schema}. * * @throws SAXException If a SAX error occurs during parsing. - * @throws NullPointerException if schema is null. + * @throws NullPointerException if {@code schema} is null. */ public Schema newSchema(URL schema) throws SAXException { return newSchema(new StreamSource(schema.toExternalForm())); @@ -710,7 +709,7 @@ public abstract class SchemaFactory { * regard. While a processor should be consistent in its treatment of * JAXP schema sources and XML Schema imports, the behaviour between * JAXP-compliant parsers may vary; in particular, parsers may choose - * to ignore all but the first <import> for a given namespace, + * to ignore all but the first {@code } for a given namespace, * regardless of information provided in schemaLocation. * *

                          @@ -721,7 +720,7 @@ public abstract class SchemaFactory { *

                          RELAX NG

                          * *

                          For RELAX NG, this method must throw {@link UnsupportedOperationException} - * if schemas.length!=1. + * if {@code schemas.length!=1}. * * * @param schemas @@ -748,7 +747,7 @@ public abstract class SchemaFactory { * When an {@link ErrorHandler} is set, errors are reported to * there first. See {@link #setErrorHandler(ErrorHandler)}. * @throws NullPointerException - * If the schemas parameter itself is null or + * If the {@code schemas} parameter itself is null or * any item in the array is null. * @throws IllegalArgumentException * If any item in the array is not recognized by this method. @@ -765,7 +764,7 @@ public abstract class SchemaFactory { * is created. * *

                          Also, implementations are allowed to use implementation-specific - * property/feature to alter the semantics of this method.

                          + * property/feature to alter the semantics of this method. * *

                          Implementors and developers should pay particular attention * to how the features set on this {@link SchemaFactory} are @@ -776,7 +775,7 @@ public abstract class SchemaFactory { * for {@link SchemaFactory} features to be inherited automatically. * Developers should * make sure that features, such as secure processing, are explicitly - * set in both places.

                          + * set in both places. * *

                          W3C XML Schema 1.0

                          *

                          diff --git a/jaxp/src/java.xml/share/classes/javax/xml/validation/Validator.java b/jaxp/src/java.xml/share/classes/javax/xml/validation/Validator.java index 4983e03982d..bd746b40e84 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/validation/Validator.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/validation/Validator.java @@ -37,16 +37,15 @@ import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; /** - *

                          A processor that checks an XML document against {@link Schema}.

                          + * A processor that checks an XML document against {@link Schema}. * *

                          * A validator object is not thread-safe and not reentrant. * In other words, it is the application's responsibility to make * sure that one {@link Validator} object is not used from - * more than one thread at any given time, and while the validate + * more than one thread at any given time, and while the {@code validate} * method is invoked, applications may not recursively call - * the validate method. - *

                          + * the {@code validate} method. * * * @author Kohsuke Kawaguchi @@ -57,27 +56,28 @@ public abstract class Validator { /** * Constructor for derived classes. * - *

                          The constructor does nothing.

                          + *

                          The constructor does nothing. * *

                          Derived classes must create {@link Validator} objects that have - * null {@link ErrorHandler} and - * null {@link LSResourceResolver}. - *

                          + * {@code null} {@link ErrorHandler} and + * {@code null} {@link LSResourceResolver}. */ protected Validator() { } /** - *

                          Reset this Validator to its original configuration.

                          + * Reset this {@code Validator} to its original configuration. * - *

                          Validator is reset to the same state as when it was created with + *

                          {@code Validator} is reset to the same state as when it was created with * {@link Schema#newValidator()}. - * reset() is designed to allow the reuse of existing Validators - * thus saving resources associated with the creation of new Validators.

                          + * {@code reset()} is designed to allow the reuse of existing {@code Validator}s + * thus saving resources associated with the creation of new {@code Validator}s. * - *

                          The reset Validator is not guaranteed to have the same {@link LSResourceResolver} or {@link ErrorHandler} - * Objects, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal - * LSResourceResolver and ErrorHandler.

                          + *

                          The reset {@code Validator} is not guaranteed to have + * the same {@link LSResourceResolver} or {@link ErrorHandler} + * {@code Object}s, e.g. {@link Object#equals(Object obj)}. + * It is guaranteed to have a functionally equal + * {@code LSResourceResolver} and {@code ErrorHandler}. */ public abstract void reset(); @@ -86,7 +86,7 @@ public abstract class Validator { * *

                          This is just a convenience method for * {@link #validate(Source source, Result result)} - * with result of null.

                          + * with {@code result} of {@code null}. * * @param source * XML to be validated. Must be an XML document or @@ -97,7 +97,7 @@ public abstract class Validator { * or throw an IllegalArgumentException. * * @throws IllegalArgumentException - * If the Source + * If the {@code Source} * is an XML artifact that the implementation cannot * validate (for example, a processing instruction). * @@ -113,8 +113,8 @@ public abstract class Validator { * {@link IOException}. * * - * @throws NullPointerException If source is - * null. + * @throws NullPointerException If {@code source} is + * {@code null}. * * @see #validate(Source source, Result result) */ @@ -125,16 +125,16 @@ public abstract class Validator { } /** - *

                          Validates the specified input and send the augmented validation - * result to the specified output.

                          + * Validates the specified input and send the augmented validation + * result to the specified output. * *

                          This method places the following restrictions on the types of - * the {@link Source}/{@link Result} accepted.

                          + * the {@link Source}/{@link Result} accepted. * *
                          XML Namespaces, javax.xml.stream.isRepairingNamespaces and write method behaviourXML Namespaces, {@code javax.xml.stream.isRepairingNamespaces} and write method behaviour
                          Method isRepairingNamespaces == trueisRepairingNamespaces == false{@code isRepairingNamespaces} == true{@code isRepairingNamespaces} == false
                          writeAttribute(namespaceURI, localName, value){@code writeAttribute(namespaceURI, localName, value)} * @@ -79,19 +79,19 @@ import javax.xml.namespace.NamespaceContext; * * - * XMLStreamException + * {@code XMLStreamException} *
                          writeAttribute(prefix, namespaceURI, localName, value){@code writeAttribute(prefix, namespaceURI, localName, value)} * - * bound to same prefix:
                          - * prefix:localName="value" [1]
                          - *
                          - * bound to different prefix:
                          + * bound to same prefix:
                          + * prefix:localName="value" [1]
                          + *
                          + * bound to different prefix:
                          * xmlns:{generated}="namespaceURI" {generated}:localName="value" *
                          @@ -101,11 +101,11 @@ import javax.xml.namespace.NamespaceContext; * * * - * bound to same prefix:
                          - * prefix:localName="value" [1][2]
                          - *
                          - * bound to different prefix:
                          - * XMLStreamException[2] + * bound to same prefix:
                          + * prefix:localName="value" [1][2]
                          + *
                          + * bound to different prefix:
                          + * {@code XMLStreamException}[2] *
                          * @@ -114,58 +114,58 @@ import javax.xml.namespace.NamespaceContext; *
                          writeStartElement(namespaceURI, localName)
                          - *
                          - * writeEmptyElement(namespaceURI, localName)
                          {@code writeStartElement(namespaceURI, localName)}
                          + *
                          + * {@code writeEmptyElement(namespaceURI, localName)}
                          * - * <prefix:localName> [1] + * {@code [1] * * - * <{generated}:localName xmlns:{generated}="namespaceURI"> + * {@code <{generated}:localName xmlns:{generated}="namespaceURI">} * * - * <prefix:localName> [1] + * {@code prefix:localName>} [1] * * - * XMLStreamException + * {@code XMLStreamException} *
                          writeStartElement(prefix, localName, namespaceURI)
                          - *
                          - * writeEmptyElement(prefix, localName, namespaceURI)
                          {@code writeStartElement(prefix, localName, namespaceURI)}
                          + *
                          + * {@code writeEmptyElement(prefix, localName, namespaceURI)}
                          * - * bound to same prefix:
                          - * <prefix:localName> [1]
                          - *
                          - * bound to different prefix:
                          - * <{generated}:localName xmlns:{generated}="namespaceURI"> + * bound to same prefix:
                          + * {@code [1]
                          + *
                          + * bound to different prefix:
                          + * {@code <{generated}:localName xmlns:{generated}="namespaceURI">} *
                          * - * <prefix:localName xmlns:prefix="namespaceURI"> [4] + * {@code [4] * * - * bound to same prefix:
                          - * <prefix:localName> [1]
                          - *
                          - * bound to different prefix:
                          - * XMLStreamException + * bound to same prefix:
                          + * {@code [1]
                          + *
                          + * bound to different prefix:
                          + * {@code XMLStreamException} *
                          * - * <prefix:localName>  + * {@code }  *
                          {@link javax.xml.XMLConstants#W3C_XML_SCHEMA_NS_URI} ("http://www.w3.org/2001/XMLSchema"){@link javax.xml.XMLConstants#W3C_XML_SCHEMA_NS_URI} ("{@code http://www.w3.org/2001/XMLSchema}")W3C XML Schema 1.0
                          {@link javax.xml.XMLConstants#RELAXNG_NS_URI} ("http://relaxng.org/ns/structure/1.0"){@link javax.xml.XMLConstants#RELAXNG_NS_URI} ("{@code http://relaxng.org/ns/structure/1.0}")RELAX NG 1.0
                          * * - * + * * * * @@ -146,7 +146,7 @@ public abstract class Validator { * * * - * + * * * * @@ -155,44 +155,44 @@ public abstract class Validator { * * * - * - * - * + * + * + * * * * - * + * * - * - * + * + * * * * - * - * + * + * * - * + * * * * - * - * - * + * + * + * * * * *
                          Source / Result Accepted{@code Source} / {@code Result} Accepted
                          null{@code null}OKOKOK
                          {@link javax.xml.transform.stream.StreamResult}OKIllegalArgumentExceptionIllegalArgumentExceptionIllegalArgumentException{@code IllegalArgumentException}{@code IllegalArgumentException}{@code IllegalArgumentException}
                          {@link javax.xml.transform.sax.SAXResult}IllegalArgumentException{@code IllegalArgumentException}OKIllegalArgumentExceptionIllegalArgumentException{@code IllegalArgumentException}{@code IllegalArgumentException}
                          {@link javax.xml.transform.dom.DOMResult}IllegalArgumentExceptionIllegalArgumentException{@code IllegalArgumentException}{@code IllegalArgumentException}OKIllegalArgumentException{@code IllegalArgumentException}
                          {@link javax.xml.transform.stax.StAXResult}IllegalArgumentExceptionIllegalArgumentExceptionIllegalArgumentException{@code IllegalArgumentException}{@code IllegalArgumentException}{@code IllegalArgumentException}OK
                          * - *

                          To validate one Source into another kind of - * Result, use the identity transformer (see - * {@link javax.xml.transform.TransformerFactory#newTransformer()}).

                          + *

                          To validate one {@code Source} into another kind of + * {@code Result}, use the identity transformer (see + * {@link javax.xml.transform.TransformerFactory#newTransformer()}). * *

                          Errors found during the validation is sent to the specified - * {@link ErrorHandler}.

                          + * {@link ErrorHandler}. * *

                          If a document is valid, or if a document contains some errors - * but none of them were fatal and the ErrorHandler didn't - * throw any exception, then the method returns normally.

                          + * but none of them were fatal and the {@code ErrorHandler} didn't + * throw any exception, then the method returns normally. * * @param source * XML to be validated. Must be an XML document or @@ -203,34 +203,34 @@ public abstract class Validator { * or throw an IllegalArgumentException. * * @param result - * The Result object that receives (possibly augmented) + * The {@code Result} object that receives (possibly augmented) * XML. This parameter can be null if the caller is not interested * in it. * - * Note that when a DOMResult is used, + * Note that when a {@code DOMResult} is used, * a validator might just pass the same DOM node from - * DOMSource to DOMResult - * (in which case source.getNode()==result.getNode()), + * {@code DOMSource} to {@code DOMResult} + * (in which case {@code source.getNode()==result.getNode()}), * it might copy the entire DOM tree, or it might alter the * node given by the source. * * @throws IllegalArgumentException - * If the Result type doesn't match the - * Source type of if the Source + * If the {@code Result} type doesn't match the + * {@code Source} type of if the {@code Source} * is an XML artifact that the implementation cannot * validate (for example, a processing instruction). * @throws SAXException - * If the ErrorHandler throws a - * SAXException or - * if a fatal error is found and the ErrorHandler returns + * If the {@code ErrorHandler} throws a + * {@code SAXException} or + * if a fatal error is found and the {@code ErrorHandler} returns * normally. * @throws IOException * If the validator is processing a - * SAXSource and the + * {@code SAXSource} and the * underlying {@link org.xml.sax.XMLReader} throws an - * IOException. + * {@code IOException}. * @throws NullPointerException - * If the source parameter is null. + * If the {@code source} parameter is {@code null}. * * @see #validate(Source source) */ @@ -239,7 +239,7 @@ public abstract class Validator { /** * Sets the {@link ErrorHandler} to receive errors encountered - * during the validate method invocation. + * during the {@code validate} method invocation. * *

                          * Error handler can be used to customize the error handling process @@ -255,7 +255,7 @@ public abstract class Validator { * *

                          * If any {@link Throwable} is thrown from an {@link ErrorHandler}, - * the caller of the validate method will be thrown + * the caller of the {@code validate} method will be thrown * the same {@link Throwable} object. * *

                          @@ -329,7 +329,7 @@ public abstract class Validator { * If a {@link LSResourceResolver} throws a {@link RuntimeException} * (or instances of its derived classes), * then the {@link Validator} will abort the parsing and - * the caller of the validate method will receive + * the caller of the {@code validate} method will receive * the same {@link RuntimeException}. * *

                          @@ -366,7 +366,7 @@ public abstract class Validator { * contexts, such as before, during, or after a validation. * *

                          Implementors are free (and encouraged) to invent their own features, - * using names built on their own URIs.

                          + * using names built on their own URIs. * * @param name The feature name, which is a non-null fully-qualified URI. * @@ -398,14 +398,14 @@ public abstract class Validator { *

                          * Feature can be used to control the way a {@link Validator} * parses schemas, although {@link Validator}s are not required - * to recognize any specific feature names.

                          + * to recognize any specific feature names. * *

                          The feature name is any fully-qualified URI. It is * possible for a {@link Validator} to expose a feature value but * to be unable to change the current value. * Some feature values may be immutable or mutable only * in specific contexts, such as before, during, or after - * a validation.

                          + * a validation. * * @param name The feature name, which is a non-null fully-qualified URI. * @param value The requested value of the feature (true or false). @@ -438,27 +438,27 @@ public abstract class Validator { * to be unable to change the current value. * Some property values may be immutable or mutable only * in specific contexts, such as before, during, or after - * a validation.

                          + * a validation. * *

                          * All implementations that implement JAXP 1.5 or newer are required to * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties. - *

                          + * *
                            *
                          • *

                            Access to external DTDs in source or Schema file is restricted to * the protocols specified by the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} * property. If access is denied during validation due to the restriction * of this property, {@link org.xml.sax.SAXException} will be thrown by the - * {@link #validate(Source)} method.

                            + * {@link #validate(Source)} method. * *

                            Access to external reference set by the schemaLocation attribute is * restricted to the protocols specified by the * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property. * If access is denied during validation due to the restriction of this property, * {@link org.xml.sax.SAXException} will be thrown by the - * {@link #validate(Source)} method.

                            + * {@link #validate(Source)} method. *
                          • *
                          * @@ -490,13 +490,13 @@ public abstract class Validator { * possible for a {@link Validator} to recognize a property name but * temporarily be unable to return its value. * Some property values may be available only in specific - * contexts, such as before, during, or after a validation.

                          + * contexts, such as before, during, or after a validation. * *

                          {@link Validator}s are not required to recognize any specific - * property names.

                          + * property names. * *

                          Implementors are free (and encouraged) to invent their own properties, - * using names built on their own URIs.

                          + * using names built on their own URIs. * * @param name The property name, which is a non-null fully-qualified URI. * diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java index 6e77e23e441..9d63bf24637 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java @@ -32,7 +32,7 @@ import org.xml.sax.InputSource; /** * {@code XPath} provides access to the XPath evaluation environment and expressions. * - * + * * * * @@ -90,7 +90,6 @@ import org.xml.sax.InputSource; * more than one thread at any given time, and while the {@code evaluate} * method is invoked, applications may not recursively call * the {@code evaluate} method. - *

                          * * @author Norman Walsh * @author Jeff Suttor @@ -462,7 +461,6 @@ public interface XPath { *

                           {@code
                                *     evaluateExpression(expression, item, XPathEvaluationResult.class);
                                * }
                          - *

                          * * @implSpec * The default implementation in the XPath API is equivalent to: diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java index 745473975e5..84d1f399e08 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java @@ -32,7 +32,6 @@ import org.w3c.dom.Node; * evaluation of an XPath expression within the context of a particular node. * The evaluation of an XPath expression can result in various result types as * defined in XML Path Language (XPath) Version 1.0. - *

                          * * @param the object type returned by the XPath evaluation. * @see XML Path Language (XPath) Version @@ -121,7 +120,7 @@ public interface XPathEvaluationResult { public XPathResultType type(); /** - * Returns the value of the result as the type <T> specified for the class. + * Returns the value of the result as the type {@code } specified for the class. * * @return The value of the result. */ diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathException.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathException.java index ee680287cae..dadeeb95892 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathException.java @@ -33,7 +33,7 @@ import java.io.ObjectStreamField; import java.io.InvalidClassException; /** - * XPathException represents a generic XPath exception.

                          + * {@code XPathException} represents a generic XPath exception. * * @author Norman Walsh * @author Jeff Suttor @@ -46,23 +46,23 @@ public class XPathException extends Exception { }; /** - *

                          Stream Unique Identifier.

                          + * Stream Unique Identifier. */ private static final long serialVersionUID = -1837080260374986980L; /** - *

                          Constructs a new XPathException - * with the specified detail message.

                          + * Constructs a new {@code XPathException} + * with the specified detail {@code message}. * - *

                          The cause is not initialized.

                          + *

                          The {@code cause} is not initialized. * - *

                          If message is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code message} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param message The detail message. * - * @throws NullPointerException When message is - * null. + * @throws NullPointerException When {@code message} is + * {@code null}. */ public XPathException(String message) { super(message); @@ -72,15 +72,15 @@ public class XPathException extends Exception { } /** - *

                          Constructs a new XPathException - * with the specified cause.

                          + * Constructs a new {@code XPathException} + * with the specified {@code cause}. * - *

                          If cause is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code cause} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param cause The cause. * - * @throws NullPointerException if cause is null. + * @throws NullPointerException if {@code cause} is {@code null}. */ public XPathException(Throwable cause) { super(cause); @@ -90,7 +90,7 @@ public class XPathException extends Exception { } /** - *

                          Get the cause of this XPathException.

                          + * Get the cause of this XPathException. * * @return Cause of this XPathException. */ @@ -103,7 +103,7 @@ public class XPathException extends Exception { * The cause is got from the parent class. * * @param out stream used for serialization. - * @throws IOException thrown by ObjectOutputStream + * @throws IOException thrown by {@code ObjectOutputStream} * */ private void writeObject(ObjectOutputStream out) @@ -120,8 +120,8 @@ public class XPathException extends Exception { * done before. * * @param in stream used for deserialization - * @throws IOException thrown by ObjectInputStream - * @throws ClassNotFoundException thrown by ObjectInputStream + * @throws IOException thrown by {@code ObjectInputStream} + * @throws ClassNotFoundException thrown by {@code ObjectInputStream} */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException @@ -139,9 +139,9 @@ public class XPathException extends Exception { } /** - *

                          Print stack trace to specified PrintStream.

                          + * Print stack trace to specified {@code PrintStream}. * - * @param s Print stack trace to this PrintStream. + * @param s Print stack trace to this {@code PrintStream}. */ public void printStackTrace(java.io.PrintStream s) { if (getCause() != null) { @@ -153,16 +153,16 @@ public class XPathException extends Exception { } /** - *

                          Print stack trace to System.err.

                          + * Print stack trace to {@code System.err}. */ public void printStackTrace() { printStackTrace(System.err); } /** - *

                          Print stack trace to specified PrintWriter.

                          + * Print stack trace to specified {@code PrintWriter}. * - * @param s Print stack trace to this PrintWriter. + * @param s Print stack trace to this {@code PrintWriter}. */ public void printStackTrace(PrintWriter s) { diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java index a7625ec1b87..f0464d6061a 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java @@ -29,9 +29,9 @@ import javax.xml.namespace.QName; import org.xml.sax.InputSource; /** - *

                          {@code XPathExpression} provides access to compiled XPath expressions.

                          + * {@code XPathExpression} provides access to compiled XPath expressions. * - * + * *
                          * * @@ -54,7 +54,7 @@ import org.xml.sax.InputSource; * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}. * An {@link XPathExpressionException} is raised if the variable resolver is undefined or * the resolver returns {@code null} for the variable. - * The value of a variable must be immutable through the course of any single evaluation.

                          + * The value of a variable must be immutable through the course of any single evaluation. * * * @@ -62,7 +62,7 @@ import org.xml.sax.InputSource; * * * @@ -76,9 +76,10 @@ import org.xml.sax.InputSource; * * + * *
                          * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}. * An {@link XPathExpressionException} is raised if the function resolver is undefined or - * the function resolver returns {@code null} for the function.

                          + * the function resolver returns {@code null} for the function. *
                          * This result of evaluating an expression is converted to an instance of the desired return type. * Valid return types are defined in {@link XPathConstants}. - * Conversion to the return type follows XPath conversion rules.

                          + * Conversion to the return type follows XPath conversion rules. *
                          * *

                          An XPath expression is not thread-safe and not reentrant. @@ -87,7 +88,6 @@ import org.xml.sax.InputSource; * more than one thread at any given time, and while the {@code evaluate} * method is invoked, applications may not recursively call * the {@code evaluate} method. - *

                          * * @author Norman Walsh * @author Jeff Suttor @@ -98,10 +98,10 @@ public interface XPathExpression { /** - *

                          Evaluate the compiled XPath expression in the specified context and return the result as the specified type.

                          + * Evaluate the compiled XPath expression in the specified context and return the result as the specified type. * *

                          See Evaluation of XPath Expressions for context item evaluation, - * variable, function and QName resolution and return type conversion.

                          + * variable, function and QName resolution and return type conversion. * *

                          * The parameter {@code item} represents the context the XPath expression @@ -126,13 +126,13 @@ public interface XPathExpression { throws XPathExpressionException; /** - *

                          Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}.

                          + * Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}. * *

                          This method calls {@link #evaluate(Object item, QName returnType)} with a {@code returnType} of - * {@link XPathConstants#STRING}.

                          + * {@link XPathConstants#STRING}. * *

                          See Evaluation of XPath Expressions for context item evaluation, - * variable, function and QName resolution and return type conversion.

                          + * variable, function and QName resolution and return type conversion. * *

                          * The parameter {@code item} represents the context the XPath expression @@ -153,20 +153,21 @@ public interface XPathExpression { throws XPathExpressionException; /** - *

                          Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as the - * specified type.

                          + * Evaluate the compiled XPath expression in the context + * of the specified {@code InputSource} and return the result as the + * specified type. * *

                          This method builds a data model for the {@link InputSource} and calls - * {@link #evaluate(Object item, QName returnType)} on the resulting document object.

                          + * {@link #evaluate(Object item, QName returnType)} on the resulting document object. * *

                          See Evaluation of XPath Expressions for context item evaluation, - * variable, function and QName resolution and return type conversion.

                          + * variable, function and QName resolution and return type conversion. * *

                          If {@code returnType} is not one of the types defined in {@link XPathConstants}, - * then an {@code IllegalArgumentException} is thrown.

                          + * then an {@code IllegalArgumentException} is thrown. * *

                          If {@code source} or {@code returnType} is {@code null}, - * then a {@code NullPointerException} is thrown.

                          + * then a {@code NullPointerException} is thrown. * * @param source The {@code InputSource} of the document to evaluate over. * @param returnType The desired return type. @@ -182,16 +183,17 @@ public interface XPathExpression { throws XPathExpressionException; /** - *

                          Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as a - * {@code String}.

                          + * Evaluate the compiled XPath expression in the context + * of the specified {@code InputSource} and return the result as a + * {@code String}. * *

                          This method calls {@link #evaluate(InputSource source, QName returnType)} with a {@code returnType} of - * {@link XPathConstants#STRING}.

                          + * {@link XPathConstants#STRING}. * *

                          See Evaluation of XPath Expressions for context item evaluation, - * variable, function and QName resolution and return type conversion.

                          + * variable, function and QName resolution and return type conversion. * - *

                          If {@code source} is {@code null}, then a {@code NullPointerException} is thrown.

                          + *

                          If {@code source} is {@code null}, then a {@code NullPointerException} is thrown. * * @param source The {@code InputSource} of the document to evaluate over. * @@ -351,7 +353,6 @@ public interface XPathExpression { *

                           {@code
                                *     evaluateExpression(source, XPathEvaluationResult.class);
                                * }
                          - *

                          * * @implSpec * The default implementation in the XPath API is equivalent to: diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpressionException.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpressionException.java index 02190781f96..aebcf94da86 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpressionException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpressionException.java @@ -26,7 +26,7 @@ package javax.xml.xpath; /** - * XPathExpressionException represents an error in an XPath expression.

                          + * {@code XPathExpressionException} represents an error in an XPath expression. * * @author Norman Walsh * @author Jeff Suttor @@ -35,38 +35,38 @@ package javax.xml.xpath; public class XPathExpressionException extends XPathException { /** - *

                          Stream Unique Identifier.

                          + * Stream Unique Identifier. */ private static final long serialVersionUID = -1837080260374986980L; /** - *

                          Constructs a new XPathExpressionException - * with the specified detail message.

                          + * Constructs a new {@code XPathExpressionException} + * with the specified detail {@code message}. * - *

                          The cause is not initialized.

                          + *

                          The {@code cause} is not initialized. * - *

                          If message is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code message} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param message The detail message. * - * @throws NullPointerException When message is - * null. + * @throws NullPointerException When {@code message} is + * {@code null}. */ public XPathExpressionException(String message) { super(message); } /** - *

                          Constructs a new XPathExpressionException - * with the specified cause.

                          + * Constructs a new {@code XPathExpressionException} + * with the specified {@code cause}. * - *

                          If cause is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code cause} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param cause The cause. * - * @throws NullPointerException if cause is null. + * @throws NullPointerException if {@code cause} is {@code null}. */ public XPathExpressionException(Throwable cause) { super(cause); diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryConfigurationException.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryConfigurationException.java index cd3ebdf4917..6879508d34a 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryConfigurationException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryConfigurationException.java @@ -26,7 +26,8 @@ package javax.xml.xpath; /** - * XPathFactoryConfigurationException represents a configuration error in a XPathFactory environment.

                          + * {@code XPathFactoryConfigurationException} represents + * a configuration error in a {@code XPathFactory} environment. * * @author Norman Walsh * @author Jeff Suttor @@ -35,37 +36,38 @@ package javax.xml.xpath; public class XPathFactoryConfigurationException extends XPathException { /** - *

                          Stream Unique Identifier.

                          + * Stream Unique Identifier. */ private static final long serialVersionUID = -1837080260374986980L; /** - *

                          Constructs a new XPathFactoryConfigurationException with the specified detail message.

                          + * Constructs a new {@code XPathFactoryConfigurationException} + * with the specified detail {@code message}. * - *

                          The cause is not initialized.

                          + *

                          The {@code cause} is not initialized. * - *

                          If message is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code message} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param message The detail message. * - * @throws NullPointerException When message is - * null. + * @throws NullPointerException When {@code message} is + * {@code null}. */ public XPathFactoryConfigurationException(String message) { super(message); } /** - *

                          Constructs a new XPathFactoryConfigurationException - * with the specified cause.

                          + * Constructs a new {@code XPathFactoryConfigurationException} + * with the specified {@code cause}. * - *

                          If cause is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code cause} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param cause The cause. * - * @throws NullPointerException if cause is null. + * @throws NullPointerException if {@code cause} is {@code null}. */ public XPathFactoryConfigurationException(Throwable cause) { super(cause); diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFunctionException.java b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFunctionException.java index 398fe7c38de..c086d87c897 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFunctionException.java +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFunctionException.java @@ -26,7 +26,7 @@ package javax.xml.xpath; /** - * XPathFunctionException represents an error with an XPath function.

                          + * {@code XPathFunctionException} represents an error with an XPath function. * * @author Norman Walsh * @author Jeff Suttor @@ -35,36 +35,36 @@ package javax.xml.xpath; public class XPathFunctionException extends XPathExpressionException { /** - *

                          Stream Unique Identifier.

                          + * Stream Unique Identifier. */ private static final long serialVersionUID = -1837080260374986980L; /** - *

                          Constructs a new XPathFunctionException with the specified detail message.

                          + * Constructs a new {@code XPathFunctionException} with the specified detail {@code message}. * - *

                          The cause is not initialized.

                          + *

                          The {@code cause} is not initialized. * - *

                          If message is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code message} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param message The detail message. * - * @throws NullPointerException When message is - * null. + * @throws NullPointerException When {@code message} is + * {@code null}. */ public XPathFunctionException(String message) { super(message); } /** - *

                          Constructs a new XPathFunctionException with the specified cause.

                          + * Constructs a new {@code XPathFunctionException} with the specified {@code cause}. * - *

                          If cause is null, - * then a NullPointerException is thrown.

                          + *

                          If {@code cause} is {@code null}, + * then a {@code NullPointerException} is thrown. * * @param cause The cause. * - * @throws NullPointerException if cause is null. + * @throws NullPointerException if {@code cause} is {@code null}. */ public XPathFunctionException(Throwable cause) { super(cause); diff --git a/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html b/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html index af0d152bc58..585160a726e 100644 --- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html +++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html @@ -282,7 +282,6 @@ It is an XML document tree represented as a hierarchy of nodes, a

                          5. Using the XPath API

                          Consider the following XML document: -

                           <widgets>
                          @@ -366,7 +365,6 @@ The XPath 1.0 Number data type is defined as a double. However, the XPath
                           specification also provides functions that returns Integer type. To facilitate
                           such operations, the XPath API allows Integer and Long to be used in 
                           {@code evaluateExpression} method such as the following code: 
                          -

                           int count = xpath.evaluate("count(/widgets/widget)", document, Integer.class);
                          diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/ranges/package.html b/jaxp/src/java.xml/share/classes/org/w3c/dom/ranges/package.html
                          index 012315bfd27..83a1a986ae5 100644
                          --- a/jaxp/src/java.xml/share/classes/org/w3c/dom/ranges/package.html
                          +++ b/jaxp/src/java.xml/share/classes/org/w3c/dom/ranges/package.html
                          @@ -21,11 +21,11 @@
                                 W3C IPR SOFTWARE NOTICE
                               
                               

                          - Copyright © 2000 World Wide Web - Consortium, (Massachusetts - Institute of Technology, Institut - National de Recherche en Informatique et en Automatique, Keio University). All Rights + Copyright © 2000 World Wide Web + Consortium, (Massachusetts + Institute of Technology, Institut + National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved.

                          @@ -66,25 +66,25 @@

                          1. - The full text of this NOTICE in a location viewable to users of the - redistributed or derivative work. + The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work.
                          2. - Any pre-existing intellectual property disclaimers, notices, or terms - and conditions. If none exist, a short notice of the following form - (hypertext is preferred, text is permitted) should be used within the - body of any redistributed or derivative code: "Copyright © - [$date-of-software] World Wide Web - Consortium, (Massachusetts - Institute of Technology, Institut - National de Recherche en Informatique et en Automatique, Keio University). All Rights - Reserved. http://www.w3.org/Consortium/Legal/" + Any pre-existing intellectual property disclaimers, notices, or terms + and conditions. If none exist, a short notice of the following form + (hypertext is preferred, text is permitted) should be used within the + body of any redistributed or derivative code: "Copyright © + [$date-of-software] World Wide Web + Consortium, (Massachusetts + Institute of Technology, Institut + National de Recherche en Informatique et en Automatique, Keio University). All Rights + Reserved. http://www.w3.org/Consortium/Legal/"
                          3. - Notice of any changes or modifications to the W3C files, including the - date changes were made. (We recommend you provide URIs to the location - from which the code is derived.) + Notice of any changes or modifications to the W3C files, including the + date changes were made. (We recommend you provide URIs to the location + from which the code is derived.)

                          diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java b/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java index 877155409c5..3b9f0f0f376 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java @@ -42,7 +42,7 @@ package org.xml.sax; * *

                          This is the original SAX1 interface for reporting an element's * attributes. Unlike the new {@link org.xml.sax.Attributes Attributes} - * interface, it does not support Namespace-related information.

                          + * interface, it does not support Namespace-related information. * *

                          When an attribute list is supplied as part of a * {@link org.xml.sax.DocumentHandler#startElement startElement} @@ -51,16 +51,16 @@ package org.xml.sax; * to the parser, the attribute list is invalid. To save a * persistent copy of the attribute list, use the SAX1 * {@link org.xml.sax.helpers.AttributeListImpl AttributeListImpl} - * helper class.

                          + * helper class. * *

                          An attribute list includes only attributes that have been - * specified or defaulted: #IMPLIED attributes will not be included.

                          + * specified or defaulted: #IMPLIED attributes will not be included. * *

                          There are two ways for the SAX application to obtain information * from the AttributeList. First, it can iterate through the entire - * list:

                          + * list: * - *
                          + * 
                          {@code
                            * public void startElement (String name, AttributeList atts) {
                            *   for (int i = 0; i < atts.getLength(); i++) {
                            *     String name = atts.getName(i);
                          @@ -69,13 +69,13 @@ package org.xml.sax;
                            *     [...]
                            *   }
                            * }
                          - * 
                          + * }
                          * *

                          (Note that the result of getLength() will be zero if there * are no attributes.) * *

                          As an alternative, the application can request the value or - * type of specific attributes:

                          + * type of specific attributes: * *
                            * public void startElement (String name, AttributeList atts) {
                          @@ -107,7 +107,7 @@ public interface AttributeList {
                                * 

                          The SAX parser may provide attributes in any * arbitrary order, regardless of the order in which they were * declared or specified. The number of attributes may be - * zero.

                          + * zero. * * @return The number of attributes in the list. */ @@ -120,10 +120,10 @@ public interface AttributeList { *

                          The names must be unique: the SAX parser shall not include the * same attribute twice. Attributes without values (those declared * #IMPLIED without a value specified in the start tag) will be - * omitted from the list.

                          + * omitted from the list. * *

                          If the attribute name has a namespace prefix, the prefix - * will still be attached.

                          + * will still be attached. * * @param i The index of the attribute in the list (starting at 0). * @return The name of the indexed attribute, or null @@ -138,15 +138,15 @@ public interface AttributeList { * *

                          The attribute type is one of the strings "CDATA", "ID", * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", - * or "NOTATION" (always in upper case).

                          + * or "NOTATION" (always in upper case). * *

                          If the parser has not read a declaration for the attribute, * or if the parser does not report attribute types, then it must * return the value "CDATA" as stated in the XML 1.0 Recommentation - * (clause 3.3.3, "Attribute-Value Normalization").

                          + * (clause 3.3.3, "Attribute-Value Normalization"). * *

                          For an enumerated attribute that is not a notation, the - * parser will report the type as "NMTOKEN".

                          + * parser will report the type as "NMTOKEN". * * @param i The index of the attribute in the list (starting at 0). * @return The attribute type as a string, or @@ -162,7 +162,7 @@ public interface AttributeList { * *

                          If the attribute value is a list of tokens (IDREFS, * ENTITIES, or NMTOKENS), the tokens will be concatenated - * into a single string separated by whitespace.

                          + * into a single string separated by whitespace. * * @param i The index of the attribute in the list (starting at 0). * @return The attribute value as a string, or @@ -183,10 +183,10 @@ public interface AttributeList { * Return the type of an attribute in the list (by name). * *

                          The return value is the same as the return value for - * getType(int).

                          + * getType(int). * *

                          If the attribute name has a namespace prefix in the document, - * the application must include the prefix here.

                          + * the application must include the prefix here. * * @param name The name of the attribute. * @return The attribute type as a string, or null if no @@ -200,10 +200,10 @@ public interface AttributeList { * Return the value of an attribute in the list (by name). * *

                          The return value is the same as the return value for - * getValue(int).

                          + * getValue(int). * *

                          If the attribute name has a namespace prefix in the document, - * the application must include the prefix here.

                          + * the application must include the prefix here. * * @param name the name of the attribute to return * @return The attribute value as a string, or null if diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/ext/EntityResolver2.java b/jaxp/src/java.xml/share/classes/org/xml/sax/ext/EntityResolver2.java index 178adf08aa7..5c647d5a463 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/ext/EntityResolver2.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/ext/EntityResolver2.java @@ -61,7 +61,6 @@ import org.xml.sax.SAXException; * recognized). If that flag is unrecognized, or its value is false, * or the resolver does not implement this interface, then only the * {@link EntityResolver} method will be used. - *

                          * *

                          That supports three categories of application that modify entity * resolution. Old Style applications won't know about this interface; @@ -76,7 +75,6 @@ import org.xml.sax.SAXException; * They will insist that feature flag have a value of "true", and the * EntityResolver2 implementation they provide might throw an exception * if the original SAX 1.0 style entity resolution method is invoked. - *

                          * * @see org.xml.sax.XMLReader#setEntityResolver * @@ -95,7 +93,7 @@ public interface EntityResolver2 extends EntityResolver * through the {@link LexicalHandler#startDTD startDTD()} method as if * the document text had originally included the external subset; * this callback is made before any internal subset data or errors - * are reported.

                          + * are reported. * *

                          This method can also be used with documents that have no DOCTYPE * declaration. When the root element is encountered, @@ -104,7 +102,7 @@ public interface EntityResolver2 extends EntityResolver * element is declared to be the root element, giving the effect of * splicing a DOCTYPE declaration at the end the prolog of a document * that could not otherwise be valid. The sequence of parser callbacks - * in that case logically resembles this:

                          + * in that case logically resembles this: * *
                                * ... comments and PIs from the prolog (as usual)
                          @@ -122,7 +120,7 @@ public interface EntityResolver2 extends EntityResolver
                                * {@link #resolveEntity resolveEntity()} to gain benefits such as use
                                * of local caches of DTD entities.  Also, this method will never be
                                * used by a (non-validating) processor that is not including external
                          -     * parameter entities. 

                          + * parameter entities. * *

                          Uses for this method include facilitating data validation when * interoperating with XML processors that would always require @@ -131,12 +129,11 @@ public interface EntityResolver2 extends EntityResolver * Non-validation motives include forcing documents to include DTDs so * that attributes are handled consistently. * For example, an XPath processor needs to know which attibutes have - * type "ID" before it can process a widely used type of reference.

                          + * type "ID" before it can process a widely used type of reference. * *

                          Warning: Returning an external subset modifies * the input document. By providing definitions for general entities, * it can make a malformed document appear to be well formed. - *

                          * * @param name Identifies the document root element. This name comes * from a DOCTYPE declaration (where available) or from the actual @@ -166,8 +163,8 @@ public interface EntityResolver2 extends EntityResolver * This method provides more flexibility than the {@link EntityResolver} * interface, supporting implementations of more complex catalogue * schemes such as the one defined by the OASIS XML Catalogs specification.

                          + * "http://www.oasis-open.org/committees/entity/spec-2001-08-06.html" + * >OASIS XML Catalogs specification. * *

                          Parsers configured to use this resolver method will call it * to determine the input source to use for any external entity @@ -176,13 +173,13 @@ public interface EntityResolver2 extends EntityResolver * by {@link #getExternalSubset getExternalSubset()}. * When a (non-validating) processor is configured not to include * a class of entities (parameter or general) through use of feature - * flags, this method is not invoked for such entities.

                          + * flags, this method is not invoked for such entities. * *

                          Note that the entity naming scheme used here is the same one * used in the {@link LexicalHandler}, or in the {@link - org.xml.sax.ContentHandler#skippedEntity - ContentHandler.skippedEntity()} - * method.

                          + * org.xml.sax.ContentHandler#skippedEntity + * ContentHandler.skippedEntity()} + * method. * * @param name Identifies the external entity being resolved. * Either "[dtd]" for the external subset, or a name starting @@ -196,7 +193,7 @@ public interface EntityResolver2 extends EntityResolver * are interpreted. This is always an absolute URI, unless it is * null (likely because the XMLReader was given an InputSource without * one). This URI is defined by the XML specification to be the one - * associated with the "<" starting the relevant declaration. + * associated with the "{@literal <}" starting the relevant declaration. * @param systemId The system identifier of the external entity * being referenced; either a relative or absolute URI. * This is never null when invoked by a SAX2 parser; only declared diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java index f8d27363331..9635e4cf777 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java @@ -49,7 +49,7 @@ import org.xml.sax.SAXException; *
                          * *

                          This class contains static methods for creating an XML reader - * from an explicit class name, or based on runtime defaults:

                          + * from an explicit class name, or based on runtime defaults: * *
                            * try {
                          @@ -64,8 +64,8 @@ import org.xml.sax.SAXException;
                            * createXMLReader to handle cases where the external
                            * configuration mechanisms aren't set up.  That method should do its
                            * best to return a parser when one is in the class path, even when
                          - * nothing bound its class name to org.xml.sax.driver so
                          - * those configuration mechanisms would see it.

                          + * nothing bound its class name to {@code org.xml.sax.driver} so + * those configuration mechanisms would see it. * * @since 1.4, SAX 2.0 * @author David Megginson, David Brownell @@ -76,7 +76,7 @@ final public class XMLReaderFactory /** * Private constructor. * - *

                          This constructor prevents the class from being instantiated.

                          + *

                          This constructor prevents the class from being instantiated. */ private XMLReaderFactory () { @@ -91,9 +91,10 @@ final public class XMLReaderFactory * Attempt to create an XMLReader from system defaults. * In environments which can support it, the name of the XMLReader * class is determined by trying each these options in order, and - * using the first one which succeeds:

                            + * using the first one which succeeds: + *
                              * - *
                            • If the system property org.xml.sax.driver + *
                            • If the system property {@code org.xml.sax.driver} * has a value, that is used as an XMLReader class name.
                            • * *
                            • The JAR "Services API" is used to look for a class name @@ -107,14 +108,13 @@ final public class XMLReaderFactory *
                            • Finally, if {@link ParserFactory#makeParser()} can * return a system default SAX1 parser, that parser is wrapped in * a {@link ParserAdapter}. (This is a migration aid for SAX1 - * environments, where the org.xml.sax.parser system + * environments, where the {@code org.xml.sax.parser} system * property will often be usable.)
                            • - * *
                            * *

                            In environments such as small embedded systems, which can not * support that flexibility, other mechanisms to determine the default - * may be used.

                            + * may be used. * *

                            Note that many Java environments allow system properties to be * initialized on a command line. This means that in most cases @@ -122,7 +122,6 @@ final public class XMLReaderFactory * method will succeed, except when security policies intervene. * This will also maximize application portability to older SAX * environments, with less robust implementations of this method. - *

                            * * @return A new XMLReader. * @exception org.xml.sax.SAXException If no default XMLReader class @@ -204,11 +203,11 @@ final public class XMLReaderFactory * Attempt to create an XML reader from a class name. * *

                            Given a class name, this method attempts to load - * and instantiate the class as an XML reader.

                            + * and instantiate the class as an XML reader. * *

                            Note that this method will not be usable in environments where * the caller (perhaps an applet) is not permitted to load classes - * dynamically.

                            + * dynamically. * * @return A new XML reader. * @exception org.xml.sax.SAXException If the class cannot be diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSS2Properties.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSS2Properties.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSS2Properties.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSS2Properties.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSCharsetRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSCharsetRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSCharsetRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSCharsetRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSFontFaceRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSFontFaceRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSFontFaceRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSFontFaceRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSImportRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSImportRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSImportRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSImportRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSMediaRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSMediaRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSMediaRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSMediaRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSPageRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSPageRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSPageRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSPageRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSPrimitiveValue.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSPrimitiveValue.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSPrimitiveValue.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSPrimitiveValue.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSRuleList.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSRuleList.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSRuleList.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSRuleList.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSStyleDeclaration.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSStyleDeclaration.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSStyleDeclaration.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSStyleDeclaration.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSStyleRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSStyleRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSStyleRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSStyleRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSStyleSheet.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSStyleSheet.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSStyleSheet.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSStyleSheet.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSUnknownRule.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSUnknownRule.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSUnknownRule.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSUnknownRule.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSValue.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSValue.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSValue.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSValue.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSValueList.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSValueList.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/CSSValueList.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/CSSValueList.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/Counter.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/Counter.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/Counter.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/Counter.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/DOMImplementationCSS.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/DOMImplementationCSS.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/DOMImplementationCSS.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/DOMImplementationCSS.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/DocumentCSS.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/DocumentCSS.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/DocumentCSS.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/DocumentCSS.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/ElementCSSInlineStyle.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/ElementCSSInlineStyle.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/ElementCSSInlineStyle.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/ElementCSSInlineStyle.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/RGBColor.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/RGBColor.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/RGBColor.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/RGBColor.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/Rect.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/Rect.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/Rect.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/Rect.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/css/ViewCSS.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/ViewCSS.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/css/ViewCSS.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/css/ViewCSS.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLAnchorElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLAnchorElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLAnchorElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLAnchorElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLAppletElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLAppletElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLAppletElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLAppletElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLAreaElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLAreaElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLAreaElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLAreaElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBRElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBRElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBRElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBRElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBaseElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBaseElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBaseElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBaseElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBaseFontElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBaseFontElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBaseFontElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBaseFontElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBodyElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBodyElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLBodyElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLBodyElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLButtonElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLButtonElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLButtonElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLButtonElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLCollection.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLCollection.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLCollection.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLCollection.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDListElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDListElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDListElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDListElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDOMImplementation.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDOMImplementation.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDOMImplementation.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDOMImplementation.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDirectoryElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDirectoryElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDirectoryElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDirectoryElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDivElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDivElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDivElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDivElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDocument.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDocument.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLDocument.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLDocument.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFieldSetElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFieldSetElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFieldSetElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFieldSetElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFontElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFontElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFontElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFontElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFormElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFormElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFormElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFormElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFrameElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFrameElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFrameElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFrameElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFrameSetElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFrameSetElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLFrameSetElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLFrameSetElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHRElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHRElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHRElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHRElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHeadElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHeadElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHeadElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHeadElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHeadingElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHeadingElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHeadingElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHeadingElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHtmlElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHtmlElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLHtmlElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLHtmlElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLIFrameElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLIFrameElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLIFrameElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLIFrameElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLImageElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLImageElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLImageElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLImageElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLInputElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLInputElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLInputElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLInputElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLIsIndexElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLIsIndexElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLIsIndexElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLIsIndexElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLIElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLIElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLIElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLIElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLabelElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLabelElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLabelElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLabelElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLegendElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLegendElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLegendElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLegendElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLinkElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLinkElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLLinkElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLLinkElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLMapElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLMapElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLMapElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLMapElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLMenuElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLMenuElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLMenuElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLMenuElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLMetaElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLMetaElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLMetaElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLMetaElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLModElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLModElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLModElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLModElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLOListElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLOListElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLOListElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLOListElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLObjectElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLObjectElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLObjectElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLObjectElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLOptGroupElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLOptGroupElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLOptGroupElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLOptGroupElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLOptionElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLOptionElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLOptionElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLOptionElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLParagraphElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLParagraphElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLParagraphElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLParagraphElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLParamElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLParamElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLParamElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLParamElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLPreElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLPreElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLPreElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLPreElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLQuoteElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLQuoteElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLQuoteElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLQuoteElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLScriptElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLScriptElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLScriptElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLScriptElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLSelectElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLSelectElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLSelectElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLSelectElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLStyleElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLStyleElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLStyleElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLStyleElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableCaptionElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableCaptionElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableCaptionElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableCaptionElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableCellElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableCellElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableCellElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableCellElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableColElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableColElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableColElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableColElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableRowElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableRowElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableRowElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableRowElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableSectionElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableSectionElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTableSectionElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTableSectionElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTextAreaElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTextAreaElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTextAreaElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTextAreaElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTitleElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTitleElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLTitleElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLTitleElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLUListElement.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLUListElement.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/html/HTMLUListElement.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/html/HTMLUListElement.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/DocumentStyle.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/DocumentStyle.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/DocumentStyle.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/DocumentStyle.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/LinkStyle.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/LinkStyle.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/LinkStyle.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/LinkStyle.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/MediaList.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/MediaList.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/MediaList.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/MediaList.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/StyleSheet.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/StyleSheet.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/StyleSheet.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/StyleSheet.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/StyleSheetList.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/StyleSheetList.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/stylesheets/StyleSheetList.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/stylesheets/StyleSheetList.java diff --git a/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/COPYRIGHT.html b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/COPYRIGHT.html new file mode 100644 index 00000000000..c7e0e497a5f --- /dev/null +++ b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/COPYRIGHT.html @@ -0,0 +1,106 @@ + + + + + W3C IPR SOFTWARE NOTICE + + + +

                            + W3C IPR SOFTWARE NOTICE +

                            +

                            + Copyright © 2002 World Wide Web + Consortium, (Massachusetts + Institute of Technology, Institut + National de Recherche en Informatique et en Automatique, Keio University). All Rights + Reserved. +

                            +

                            + The DOM bindings are published under the W3C Software Copyright Notice + and License. The software license requires "Notice of any changes or + modifications to the W3C files, including the date changes were made." + Consequently, modified versions of the DOM bindings must document that + they do not conform to the W3C standard; in the case of the IDL + definitions, the pragma prefix can no longer be 'w3c.org'; in the case of + the Java language binding, the package names can no longer be in the + 'org.w3c' package. +

                            +

                            + Note: The original version of the W3C Software Copyright Notice + and License could be found at http://www.w3.org/Consortium/Legal/copyright-software-19980720 +

                            +

                            + Copyright © 1994-2002 World Wide Web + Consortium, (Massachusetts + Institute of Technology, Institut + National de Recherche en Informatique et en Automatique, Keio University). All Rights + Reserved. http://www.w3.org/Consortium/Legal/ +

                            +

                            + This W3C work (including software, documents, or other related items) is + being provided by the copyright holders under the following license. By + obtaining, using and/or copying this work, you (the licensee) agree that + you have read, understood, and will comply with the following terms and + conditions: +

                            +

                            + Permission to use, copy, and modify this software and its documentation, + with or without modification,  for any purpose and without fee or + royalty is hereby granted, provided that you include the following on ALL + copies of the software and documentation or portions thereof, including + modifications, that you make: +

                            +
                              +
                            1. + The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work. +
                            2. +
                            3. + Any pre-existing intellectual property disclaimers, notices, or terms + and conditions. If none exist, a short notice of the following form + (hypertext is preferred, text is permitted) should be used within the + body of any redistributed or derivative code: "Copyright © + [$date-of-software] World Wide Web + Consortium, (Massachusetts + Institute of Technology, Institut + National de Recherche en Informatique et en Automatique, Keio University). All Rights + Reserved. http://www.w3.org/Consortium/Legal/" +
                            4. +
                            5. + Notice of any changes or modifications to the W3C files, including the + date changes were made. (We recommend you provide URIs to the location + from which the code is derived.) +
                            6. +
                            +

                            + THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT + HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS + FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR + DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS. +

                            +

                            + COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR + DOCUMENTATION. +

                            +

                            + The name and trademarks of copyright holders may NOT be used in + advertising or publicity pertaining to the software without specific, + written prior permission. Title to copyright in this software and any + associated documentation will at all times remain with copyright + holders. +

                            + + diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathEvaluator.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathEvaluator.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathEvaluator.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathEvaluator.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathException.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathException.java similarity index 97% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathException.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathException.java index 75121d48025..2a13869df45 100644 --- a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathException.java +++ b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathException.java @@ -47,6 +47,8 @@ package org.w3c.dom.xpath; *

                            See also the Document Object Model (DOM) Level 3 XPath Specification. */ public class XPathException extends RuntimeException { + private static final long serialVersionUID = 3471034171575979943L; + public XPathException(short code, String message) { super(message); this.code = code; diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathExpression.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathExpression.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathExpression.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathExpression.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathNSResolver.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathNSResolver.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathNSResolver.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathNSResolver.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathNamespace.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathNamespace.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathNamespace.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathNamespace.java diff --git a/jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathResult.java b/jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathResult.java similarity index 100% rename from jaxp/src/java.xml/share/classes/org/w3c/dom/xpath/XPathResult.java rename to jaxp/src/jdk.xml.dom/share/classes/org/w3c/dom/xpath/XPathResult.java diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/AbstractCharacterDataTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/AbstractCharacterDataTest.java new file mode 100644 index 00000000000..c1ef1140136 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/AbstractCharacterDataTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; +import static org.w3c.dom.DOMException.INDEX_SIZE_ERR; +import static org.w3c.dom.ptests.DOMTestUtil.DOMEXCEPTION_EXPECTED; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.CharacterData; +import org.w3c.dom.DOMException; +import org.xml.sax.SAXException; + +/* + * @summary common test for the CharacterData Interface + */ +public abstract class AbstractCharacterDataTest extends JAXPFileBaseTest { + @DataProvider(name = "data-for-length") + public Object[][] getDataForTestLength() { + return new Object[][] { + { "", 0 }, + { "test", 4 } }; + } + + /* + * Verify getLength method works as the spec, for an empty string, should + * return zero + */ + @Test(dataProvider = "data-for-length") + public void testGetLength(String text, int length) throws Exception { + CharacterData cd = createCharacterData(text); + assertEquals(cd.getLength(), length); + + } + + /* + * Test appendData method and verify by getData method. + */ + @Test + public void testAppendData() throws Exception { + CharacterData cd = createCharacterData("DOM"); + cd.appendData("2"); + assertEquals(cd.getData(), "DOM2"); + + } + + @DataProvider(name = "data-for-delete") + public Object[][] getDataForTestDelete() { + return new Object[][] { + { "DOM", 2, 1, "DO" }, + { "DOM", 0, 2, "M" }, + { "DOM", 2, 3, "DO" } }; + } + + /* + * Verify deleteData method works as the spec. + */ + @Test(dataProvider = "data-for-delete") + public void testDeleteData(String text, int offset, int count, String result) throws Exception { + CharacterData cd = createCharacterData(text); + cd.deleteData(offset, count); + assertEquals(cd.getData(), result); + } + + @DataProvider(name = "data-for-replace") + public Object[][] getDataForTestReplace() { + return new Object[][] { + { "DOM", 0, 3, "SAX", "SAX" }, + { "DOM", 1, 1, "AA", "DAAM" }, + { "DOM", 1, 2, "A", "DA" }, + { "DOM", 2, 2, "SAX", "DOSAX" } }; + } + + /* + * Verify replaceData method works as the spec. + */ + @Test(dataProvider = "data-for-replace") + public void testReplaceData(String text, int offset, int count, String arg, String result) throws Exception { + CharacterData cd = createCharacterData(text); + cd.replaceData(offset, count, arg); + assertEquals(cd.getData(), result); + } + + @DataProvider(name = "data-for-replace-neg") + public Object[][] getDataForTestReplaceNeg() { + return new Object[][] { + { "DOM", -1, 3, "SAX" }, //offset if neg + { "DOM", 0, -1, "SAX" }, //count is neg + { "DOM", 4, 1, "SAX" } };//offset is greater than length + } + + /* + * Test for replaceData method: verifies that DOMException with + * INDEX_SIZE_ERR is thrown if offset or count is out of the bound. + */ + @Test(dataProvider = "data-for-replace-neg") + public void testReplaceDataNeg(String text, int offset, int count, String arg) throws Exception { + CharacterData cd = createCharacterData(text); + try { + cd.replaceData(offset, count, arg); + fail(DOMEXCEPTION_EXPECTED); + } catch (DOMException e) { + assertEquals(e.code, INDEX_SIZE_ERR); + } + } + + @DataProvider(name = "data-for-insert") + public Object[][] getDataForTestInsert() { + return new Object[][] { + { "DOM", 0, "SAX", "SAXDOM" }, + { "DOM", 3, "SAX", "DOMSAX" } }; + } + + /* + * Verify insertData method works as the spec. + */ + @Test(dataProvider = "data-for-insert") + public void testInsertData(String text, int offset, String arg, String result) throws Exception { + CharacterData cd = createCharacterData(text); + cd.insertData(offset, arg); + assertEquals(cd.getData(), result); + } + + @DataProvider(name = "data-for-insert-neg") + public Object[][] getDataForTestInsertNeg() { + return new Object[][] { + { "DOM", -1 }, //offset is neg + { "DOM", 4 } };//offset is greater than length + } + + /* + * Test for insertData method: verifies that DOMException with + * INDEX_SIZE_ERR is thrown if offset is out of the bound. + */ + @Test(dataProvider = "data-for-insert-neg") + public void testInsertDataNeg(String text, int offset) throws Exception { + CharacterData cd = createCharacterData(text); + try { + cd.insertData(offset, "TEST"); + fail(DOMEXCEPTION_EXPECTED); + } catch (DOMException e) { + assertEquals(e.code, INDEX_SIZE_ERR); + } + } + + /* + * Test setData method and verify by getData method. + */ + @Test + public void testSetData() throws Exception { + CharacterData cd = createCharacterData("DOM"); + cd.setData("SAX"); + assertEquals(cd.getData(), "SAX"); + } + + @DataProvider(name = "data-for-substring") + public Object[][] getDataForTestSubstring() { + return new Object[][] { + { "DOM Level 2", 0, 3, "DOM" }, + { "DOM", 0, 3, "DOM" }, + { "DOM", 2, 5, "M" } }; + } + + /* + * Verify substringData method works as the spec. + */ + @Test(dataProvider = "data-for-substring") + public void testSubstringData(String text, int offset, int count, String result) throws Exception { + CharacterData cd = createCharacterData(text); + String retStr = cd.substringData(offset, count); + assertEquals(retStr, result); + } + + @DataProvider(name = "data-for-substring-neg") + public Object[][] getDataForTestSubstringNeg() { + return new Object[][] { + { "DOM Level 2", -1, 3 }, //offset is neg + { "DOM", 0, -1 }, //count is neg + { "DOM", 3, 1 } }; //offset exceeds length + } + + /* + * Test for substringData method: verifies that DOMException with + * INDEX_SIZE_ERR is thrown if offset or count is out of the bound. + */ + @Test(dataProvider = "data-for-substring-neg") + public void testSubstringDataNeg(String text, int offset, int count) throws Exception { + CharacterData cd = createCharacterData(text); + try { + cd.substringData(offset, count); + fail(DOMEXCEPTION_EXPECTED); + } catch (DOMException e) { + assertEquals(e.code, INDEX_SIZE_ERR); + } + + } + + /* + * Return a concrete CharacterData instance. + */ + abstract protected CharacterData createCharacterData(String text) throws IOException, SAXException, ParserConfigurationException; + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/AttrTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/AttrTest.java new file mode 100644 index 00000000000..b166c307a81 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/AttrTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.w3c.dom.ptests.DOMTestUtil.createDOM; +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; + + +/* + * @summary Test for the Attr Interface + */ +public class AttrTest extends JAXPFileBaseTest { + /* + * Verify getName method against both existing Attr and new Attr. + */ + @Test + public void testGetName() throws Exception { + Document document = createDOM("Attr01.xml"); + //test a new created Attr + Attr attr = document.createAttribute("newAttribute"); + assertEquals(attr.getName(), "newAttribute"); + + //test a Attr loaded from xml file + Element elemNode = (Element) document.getElementsByTagName("book").item(1); + Attr attr2 = (Attr) elemNode.getAttributes().item(0); + assertEquals(attr2.getName(), "category1"); + } + + /* + * Verify getOwnerElement method against both existing Attr and new Attr. + */ + @Test + public void testGetOwnerElement() throws Exception { + Document document = createDOM("Attr01.xml"); + + //test Attr loaded from xml file + Element elemNode = (Element) document.getElementsByTagName("book").item(1); + NamedNodeMap nnMap = elemNode.getAttributes(); + for (int i = 0; i < nnMap.getLength(); i++) { + Attr attr = (Attr) nnMap.item(i); + assertEquals(attr.getOwnerElement().getNodeName(), "book"); + } + + //test an Attr without owner node + Attr attr = document.createAttribute("newAttribute"); + assertNull(attr.getOwnerElement()); + + } + + /* + * Verify getSpecified method works as the spec. + */ + @Test + public void testGetSpecified1() throws Exception { + Document document = createDOM("Attr01.xml"); + + Element elemNode = (Element) document.getElementsByTagName("book").item(1); + Attr attr = elemNode.getAttributeNode("category1"); + assertTrue(attr.getSpecified()); + + } + + /* + * In this xml file, the dtd has the value for the attrribute, but the xml + * element does not specify the value for the attrribute, as per the spec it + * should return false. + */ + @Test + public void testGetSpecified2() throws Exception { + + Document document = createDOM("Attr2.xml"); + Element elemNode = (Element) document.getElementsByTagName("Name").item(0); + Attr attr = elemNode.getAttributeNode("type"); + + assertFalse(attr.getSpecified()); + } + + /* + * Creating a new attribute, the owner element is null since the attribute + * has just been created, getSpecified should return true. + */ + @Test + public void testNewCreatedAttribute() throws Exception { + Document document = createDOM("Attr01.xml"); + Attr attr = document.createAttribute("newAttribute"); + assertTrue(attr.getSpecified()); + assertNull(attr.getOwnerElement()); + + } + + /* + * The xml file includes the dtd having the IMPLIED value for the attrribute + * and the xml element does not specify the value. As per the spec it should + * not be seen as a part of the structure model hence getAttributeNode + * rerurn null if the attribute is even found. + */ + @Test + public void testIMPLIEDAttribute() throws Exception { + Document document = createDOM("Attr3.xml"); + Element elemNode = (Element) document.getElementsByTagName("Name").item(0); + Attr attr = elemNode.getAttributeNode("type"); + assertNull(attr); + } + + /* + * Test setValue method and verify by getValue method. + */ + @Test + public void testSetValue() throws Exception { + Document document = createDOM("Attr01.xml"); + Attr attr = document.createAttribute("newAttribute"); + attr.setValue("newVal"); + assertEquals(attr.getValue(), "newVal"); + + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/CommentTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/CommentTest.java new file mode 100644 index 00000000000..daf585bf09b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/CommentTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.CharacterData; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/* + * @summary Test for Comment implementation returned by Document.createComment(String) + */ +public class CommentTest extends AbstractCharacterDataTest { + @Override + protected CharacterData createCharacterData(String text) throws IOException, SAXException, ParserConfigurationException { + Document document = createNewDocument(); + return document.createComment(text); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DocumentTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DocumentTest.java new file mode 100644 index 00000000000..90dd8cc64a8 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DocumentTest.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI; +import static javax.xml.XMLConstants.XML_NS_URI; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.fail; +import static org.w3c.dom.DOMException.NAMESPACE_ERR; +import static org.w3c.dom.ptests.DOMTestUtil.DOMEXCEPTION_EXPECTED; +import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS; +import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument; +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/* + * @summary Test createAttributeNS, getElementsByTagNameNS and createElementNS method of Document + */ +public class DocumentTest extends JAXPFileBaseTest { + + @DataProvider(name = "invalid-nsuri") + public Object[][] getInvalidNamespaceURI() { + return new Object[][] { + { " ", "xml:novel" }, //blank + { "hello", "xml:novel" }, //unqualified + { null, "xml:novel" }, //null + { "", "xmlns:novel" } };//empty + } + + /* + * Test for createAttributeNS method: verifies that DOMException is thrown + * if reserved prefixes are used with an arbitrary namespace name. + */ + @Test(dataProvider = "invalid-nsuri", expectedExceptions = DOMException.class) + public void testCreateAttributeNSNeg(String namespaceURI, String name) throws Exception { + Document document = createDOMWithNS("DocumentTest01.xml"); + document.createAttributeNS(namespaceURI, name); + } + + @DataProvider(name = "valid-nsuri") + public Object[][] getValidNamespaceURI() { + return new Object[][] { + { XML_NS_URI, "xml:novel" }, + { XMLNS_ATTRIBUTE_NS_URI, "xmlns:novel" }, + { "urn:BooksAreUs.org:BookInfo", "attributeNew"}, + { "urn:BooksAreUs.org:BookInfonew", "attributeNew"} }; + } + + /* + * Verify the Attr from createAttributeNS. + */ + @Test(dataProvider = "valid-nsuri") + public void testCreateAttributeNS(String namespaceURI, String name) throws Exception { + Document document = createDOMWithNS("DocumentTest01.xml"); + Attr attr = document.createAttributeNS(namespaceURI, name); + assertEquals(attr.getNamespaceURI(), namespaceURI); + assertEquals(attr.getName(), name); + } + + @DataProvider(name = "elementName") + public Object[][] getElementName() { + return new Object[][] { + { "author", 1 }, + { "b:author", 0 } }; + } + + /* + * Verify the NodeList from getElementsByTagNameNS. + */ + @Test(dataProvider = "elementName") + public void testGetElementsByTagNameNS(String localName, int number) throws Exception { + Document document = createDOMWithNS("DocumentTest01.xml"); + NodeList nodeList = document.getElementsByTagNameNS("urn:BooksAreUs.org:BookInfo", localName); + assertEquals(nodeList.getLength(), number); + } + + /* + * Test for createElementNS method: verifies that DOMException is thrown + * if reserved prefixes are used with an arbitrary namespace name. + */ + @Test(dataProvider = "invalid-nsuri") + public void testCreateElementNSNeg(String namespaceURI, String name) throws Exception { + Document document = createDOMWithNS("DocumentTest01.xml"); + try { + document.createElementNS(namespaceURI, name); + fail(DOMEXCEPTION_EXPECTED); + } catch (DOMException e) { + assertEquals(e.code, NAMESPACE_ERR); + } + } + + /* + * Test createElementNS method works as the spec. + */ + @Test + public void testCreateElementNS() throws Exception { + final String nsURI = "http://www.books.com"; + final String name = "b:novel"; + final String localName = "novel"; + Document document = createDOMWithNS("DocumentTest01.xml"); + Element element = document.createElementNS(nsURI, name); + assertEquals(element.getNamespaceURI(), nsURI); + assertEquals(element.getNodeName(), name); + assertEquals(element.getLocalName(), localName); + } + + /* + * Test createAttributeNS and then append it with setAttributeNode. + */ + @Test + public void testAddNewAttributeNode() throws Exception { + Document document = createDOMWithNS("DocumentTest01.xml"); + + NodeList nodeList = document.getElementsByTagNameNS("http://www.w3.org/TR/REC-html40", "body"); + NodeList childList = nodeList.item(0).getChildNodes(); + Element child = (Element) childList.item(1); + Attr a = document.createAttributeNS("urn:BooksAreUs.org:BookInfo", "attributeNew"); + child.setAttributeNode(a); + assertNotNull(child.getAttributeNodeNS("urn:BooksAreUs.org:BookInfo", "attributeNew")); + } + + /* + * Test createElementNS and then append it with appendChild. + */ + @Test + public void testAddNewElement() throws Exception { + Document document = createDOMWithNS("DocumentTest01.xml"); + + NodeList nodeList = document.getElementsByTagNameNS("http://www.w3.org/TR/REC-html40", "body"); + NodeList childList = nodeList.item(0).getChildNodes(); + Element child = (Element) childList.item(1); + Element elem = document.createElementNS("urn:BooksAreUs.org:BookInfonew", "newElement"); + assertNotNull(child.appendChild(elem)); + } + + /* + * Test createElement with unqualified xml name. + */ + @Test(expectedExceptions = DOMException.class) + public void testCreateElementNeg() throws Exception { + Document doc = createNewDocument(); + doc.createElement("!nc$%^*(!"); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DocumentTypeTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DocumentTypeTest.java new file mode 100644 index 00000000000..d260d1f7c8e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DocumentTypeTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.createDOM; +import jaxp.library.JAXPFileBaseTest; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.w3c.dom.DocumentType; +import org.w3c.dom.NamedNodeMap; + +/* + * @summary Test DocumentType + */ +public class DocumentTypeTest extends JAXPFileBaseTest { + + /* + * Test testGetEntities method, and verify the entity items. + */ + @Test + public void testGetEntities() throws Exception { + DocumentType documentType = createDOM("DocumentType01.xml").getDoctype(); + NamedNodeMap namedNodeMap = documentType.getEntities(); + // should return both external and internal. Parameter entities are not + // contained. Duplicates are discarded. + assertEquals(namedNodeMap.getLength(), 3); + assertEquals(namedNodeMap.item(0).getNodeName(), "author"); + assertEquals(namedNodeMap.item(1).getNodeName(), "test"); + assertEquals(namedNodeMap.item(2).getNodeName(), "writer"); + } + + /* + * Test getNotations method, and verify the notation items. + */ + @Test + public void testGetNotations() throws Exception { + DocumentType documentType = createDOM("DocumentType03.xml").getDoctype(); + NamedNodeMap nm = documentType.getNotations(); + assertEquals(nm.getLength(), 2); // should return 2 because the notation + // name is repeated and + // it considers only the first + // occurence + assertEquals(nm.item(0).getNodeName(), "gs"); + assertEquals(nm.item(1).getNodeName(), "name"); + } + + /* + * Test getName method. + */ + @Test + public void testGetName() throws Exception { + DocumentType documentType = createDOM("DocumentType03.xml").getDoctype(); + assertEquals(documentType.getName(), "note"); + } + + /* + * Test getSystemId and getPublicId method. + */ + @Test + public void testGetSystemId() throws Exception { + DocumentType documentType = createDOM("DocumentType05.xml").getDoctype(); + assertEquals(documentType.getSystemId(), "DocumentBuilderImpl02.dtd"); + Assert.assertNull(documentType.getPublicId()); + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DomImplementationTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DomImplementationTest.java new file mode 100644 index 00000000000..fb6ec4b5ea4 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/DomImplementationTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument; + +import javax.xml.parsers.ParserConfigurationException; + +import jaxp.library.JAXPBaseTest; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentType; + +/* + * @summary Test DomImplementation API + */ +public class DomImplementationTest extends JAXPBaseTest { + /* + * Test createDocument method with a namespace uri, qualified name and null + * for the doctype + */ + @Test + public void testCreateDocument() throws ParserConfigurationException { + final String nsURI = "http://www.document.com"; + final String name = "document:localName"; + DOMImplementation domImpl = getDOMImplementation(); + Document document = domImpl.createDocument(nsURI, name, null); + assertEquals(document.getDocumentElement().getNamespaceURI(), nsURI); + assertEquals(document.getDocumentElement().getNodeName(), name); + } + + /* + * Test createDocumentType method with name, public id and system id. + */ + @Test + public void testCreateDocumentType01() throws ParserConfigurationException { + final String name = "document:localName"; + final String publicId = "pubid"; + final String systemId = "sysid"; + + DOMImplementation domImpl = getDOMImplementation(); + DocumentType documentType = domImpl.createDocumentType(name, publicId, systemId); + verifyDocumentType(documentType, name, publicId, systemId); + } + + + /* + * Test createDocument method using a DocumentType, verify the document will + * take that Doctype. + */ + @Test + public void testCreateDocumentType02() throws ParserConfigurationException { + final String name = "document:localName"; + final String publicId = "-//W3C//DTD HTML 4.0 Transitional//EN"; + final String systemId = "http://www.w3.org/TR/REC-html40/loose.dtd"; + DOMImplementation domImpl = getDOMImplementation(); + + DocumentType documentType = domImpl.createDocumentType(name, publicId, systemId); + Document document = domImpl.createDocument("http://www.document.com", "document:localName", documentType); + verifyDocumentType(document.getDoctype(), name, publicId, systemId); + } + + @DataProvider(name = "feature-supported") + public Object[][] getFeatureSupportedList() throws ParserConfigurationException { + DOMImplementation impl = getDOMImplementation(); + return new Object[][] { + { impl, "XML", "2.0", true }, + { impl, "HTML", "2.0", false }, + { impl, "Views", "2.0", false }, + { impl, "StyleSheets", "2.0", false }, + { impl, "CSS", "2.0", false }, + { impl, "CSS2", "2.0", false }, + { impl, "Events", "2.0", true }, + { impl, "UIEvents", "2.0", false }, + { impl, "MouseEvents", "2.0", false }, + { impl, "HTMLEvents", "2.0", false }, + { impl, "Traversal", "2.0", true }, + { impl, "Range", "2.0", true }, + { impl, "Core", "2.0", true }, + { impl, "XML", "", true } }; + } + + + /* + * Verify DOMImplementation for feature supporting. + */ + @Test(dataProvider = "feature-supported") + public void testHasFeature(DOMImplementation impl, String feature, String version, boolean isSupported) { + assertEquals(impl.hasFeature(feature,version), isSupported); + } + + + private DOMImplementation getDOMImplementation() throws ParserConfigurationException { + return createNewDocument().getImplementation(); + } + + + private void verifyDocumentType(DocumentType documentType, String name, String publicId, String systemId) { + assertEquals(documentType.getPublicId(), publicId); + assertEquals(documentType.getSystemId(), systemId); + assertEquals(documentType.getName(), name); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/ElementTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/ElementTest.java new file mode 100644 index 00000000000..2e4841f438a --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/ElementTest.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static javax.xml.XMLConstants.XML_NS_URI; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; +import static org.w3c.dom.DOMException.INUSE_ATTRIBUTE_ERR; +import static org.w3c.dom.ptests.DOMTestUtil.DOMEXCEPTION_EXPECTED; +import static org.w3c.dom.ptests.DOMTestUtil.createDOM; +import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS; +import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilderFactory; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/* + * @summary Test for the methods of Element Interface + */ +public class ElementTest extends JAXPFileBaseTest { + @Test + public void testGetAttributeNS() throws Exception { + Document document = createDOMWithNS("ElementSample01.xml"); + Element elemNode = (Element) document.getElementsByTagName("book").item(0); + String s = elemNode.getAttributeNS("urn:BooksAreUs.org:BookInfo", "category"); + assertEquals(s, "research"); + } + + @Test + public void testGetAttributeNodeNS() throws Exception { + Document document = createDOMWithNS("ElementSample01.xml"); + Element elemNode = (Element) document.getElementsByTagName("book").item(0); + Attr attr = elemNode.getAttributeNodeNS("urn:BooksAreUs.org:BookInfo", "category"); + assertEquals(attr.getValue(), "research"); + + } + + /* + * Test getAttributeNode to get a Attr and then remove it successfully by + * removeAttributeNode. + */ + @Test + public void testRemoveAttributeNode() throws Exception { + Document document = createDOMWithNS("ElementSample01.xml"); + Element elemNode = (Element) document.getElementsByTagName("book").item(1); + Attr attr = elemNode.getAttributeNode("category1"); + assertEquals(attr.getValue(), "research"); + + assertEquals(elemNode.getTagName(), "book"); + elemNode.removeAttributeNode(attr); + assertEquals(elemNode.getAttribute("category1"), ""); + } + + /* + * Test removing an Attribute Node with removeAttributeNS(String + * namespaceURI, String localName). + */ + @Test + public void testRemoveAttributeNS() throws Exception { + final String nsURI = "urn:BooksAreUs.org:BookInfo"; + final String localName = "category"; + Document document = createDOMWithNS("ElementSample01.xml"); + Element elemNode = (Element) document.getElementsByTagName("book").item(0); + elemNode.removeAttributeNS(nsURI, localName); + + assertNull(elemNode.getAttributeNodeNS(nsURI, localName)); + } + + /* + * Test getFirstChild and getLastChild. + */ + @Test + public void testGetChild() throws Exception { + Document document = createDOMWithNS("ElementSample01.xml"); + Element elemNode = (Element) document.getElementsByTagName("b:aaa").item(0); + elemNode.normalize(); + Node firstChild = elemNode.getFirstChild(); + Node lastChild = elemNode.getLastChild(); + assertEquals(firstChild.getNodeValue(), "fjfjf"); + assertEquals(lastChild.getNodeValue(), "fjfjf"); + } + + /* + * Test setAttributeNode with an Attr from createAttribute. + */ + @Test + public void testSetAttributeNode() throws Exception { + final String attrName = "myAttr"; + final String attrValue = "attrValue"; + Document document = createDOM("ElementSample02.xml"); + Element elemNode = document.createElement("pricetag2"); + Attr myAttr = document.createAttribute(attrName); + myAttr.setValue(attrValue); + + assertNull(elemNode.setAttributeNode(myAttr)); + assertEquals(elemNode.getAttribute(attrName), attrValue); + } + + @DataProvider(name = "attribute") + public Object[][] getAttributeData() { + return new Object[][] { + { "thisisname", "thisisitsvalue" }, + { "style", "font-Family" } }; + } + + @Test(dataProvider = "attribute") + public void testSetAttribute(String name, String value) throws Exception { + Document document = createDOM("ElementSample02.xml"); + Element elemNode = document.createElement("pricetag2"); + elemNode.setAttribute(name, value); + assertEquals(elemNode.getAttribute(name), value); + } + + /* + * Negative test for setAttribute, null is not a valid name. + */ + @Test(expectedExceptions = DOMException.class) + public void testSetAttributeNeg() throws Exception { + Document document = createDOM("ElementSample02.xml"); + Element elemNode = document.createElement("pricetag2"); + elemNode.setAttribute(null, null); + } + + /* + * Test setAttributeNode, newAttr can't be an attribute of another Element + * object, must explicitly clone Attr nodes to re-use them in other + * elements. + */ + @Test + public void testDuplicateAttributeNode() throws Exception { + final String name = "testAttrName"; + final String value = "testAttrValue"; + Document document = createNewDocument(); + Attr attr = document.createAttribute(name); + attr.setValue(value); + + Element element1 = document.createElement("AFirstElement"); + element1.setAttributeNode(attr); + Element element2 = document.createElement("ASecondElement"); + Attr attr2 = (Attr) attr.cloneNode(true); + element2.setAttributeNode(attr2); + assertEquals(element1.getAttribute(name), element2.getAttribute(name)); + + Element element3 = document.createElement("AThirdElement"); + try { + element3.setAttributeNode(attr); + fail(DOMEXCEPTION_EXPECTED); + } catch (DOMException doe) { + assertEquals(doe.code, INUSE_ATTRIBUTE_ERR); + } + } + + /* + * If not setting the namsepace aware method of DocumentBuilderFactory to + * true, can't retrieve element by namespace and local name. + */ + @Test + public void testNamespaceAware() throws Exception { + Document document = createDOM("ElementSample02.xml"); + + NodeList nl = document.getElementsByTagNameNS("urn:BooksAreUs.org:BookInfo", "author"); + assertNull(nl.item(0)); + + nl = document.getDocumentElement().getElementsByTagNameNS("urn:BooksAreUs.org:BookInfo", "author"); + assertNull(nl.item(0)); + } + + @DataProvider(name = "nsattribute") + public Object[][] getNSAttributeData() { + return new Object[][] { + { "h:html", "html", "attrValue" }, + { "b:style", "style", "attrValue" } }; + } + + /* + * setAttributeNodeNS and verify it with getAttributeNS. + */ + @Test(dataProvider = "nsattribute") + public void testSetAttributeNodeNS(String qualifiedName, String localName, String value) throws Exception { + Document document = createDOM("ElementSample03.xml"); + Element elemNode = document.createElement("pricetag2"); + Attr myAttr = document.createAttributeNS(XML_NS_URI, qualifiedName); + myAttr.setValue(value); + assertNull(elemNode.setAttributeNodeNS(myAttr)); + assertEquals(elemNode.getAttributeNS(XML_NS_URI, localName), value); + } + + @Test + public void testHasAttributeNS() throws Exception { + Document document = createDOMWithNS("ElementSample04.xml"); + NodeList nodeList = document.getElementsByTagName("body"); + NodeList childList = nodeList.item(0).getChildNodes(); + Element child = (Element) childList.item(7); + assertTrue(child.hasAttributeNS("urn:BooksAreUs.org:BookInfo", "style")); + } + + @Test + public void testToString() throws Exception { + final String xml = + "" + + "" + + "" + + " \n" + + " " + + " " + + ""; + + Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xml))); + Element root = doc.getDocumentElement(); + + assertEquals(root.toString(), "[datacenterlist: null]"); + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/EntityChildTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/EntityChildTest.java new file mode 100644 index 00000000000..099b7c1fc83 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/EntityChildTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.XML_DIR; + +import java.io.File; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/* + * @summary Test DOM Parser: parsing an xml file that contains external entities. + */ +public class EntityChildTest extends JAXPFileBaseTest { + + @Test + public void test() throws Exception { + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(new File(XML_DIR + "entitychild.xml")); + + Element root = document.getDocumentElement(); + NodeList n = root.getElementsByTagName("table"); + NodeList nl = n.item(0).getChildNodes(); + assertEquals(n.getLength(), 1); + assertEquals(nl.getLength(), 3); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NamedNodeMapTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NamedNodeMapTest.java new file mode 100644 index 00000000000..49037f80c88 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NamedNodeMapTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS; +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/* + * @summary Test for the methods of NamedNodeMap Interface + */ +public class NamedNodeMapTest extends JAXPFileBaseTest { + /* + * Test setNamedItemNS method with a node having the same namespaceURI and + * qualified name as an existing one, and then test with a non-existing node. + */ + @Test + public void testSetNamedItemNS() throws Exception { + final String nsURI = "urn:BooksAreUs.org:BookInfo"; + Document document = createDOMWithNS("NamedNodeMap01.xml"); + NodeList nodeList = document.getElementsByTagName("body"); + nodeList = nodeList.item(0).getChildNodes(); + Node n = nodeList.item(3); + + NamedNodeMap namedNodeMap = n.getAttributes(); + + // creating an Attribute using createAttributeNS + // method having the same namespaceURI + // and the same qualified name as the existing one in the xml file + Attr attr = document.createAttributeNS(nsURI, "b:style"); + // setting to a new Value + attr.setValue("newValue"); + Node replacedAttr = namedNodeMap.setNamedItemNS(attr); // return the replaced attr + assertEquals(replacedAttr.getNodeValue(), "font-family"); + Node updatedAttr = namedNodeMap.getNamedItemNS(nsURI, "style"); + assertEquals(updatedAttr.getNodeValue(), "newValue"); + + + // creating a non existing attribute node + attr = document.createAttributeNS(nsURI, "b:newNode"); + attr.setValue("newValue"); + + assertNull(namedNodeMap.setNamedItemNS(attr)); // return null + + // checking if the node could be accessed + // using the getNamedItemNS method + Node newAttr = namedNodeMap.getNamedItemNS(nsURI, "newNode"); + assertEquals(newAttr.getNodeValue(), "newValue"); + } + + /* + * Verify getNamedItemNS works as the spec + */ + @Test + public void testGetNamedItemNS() throws Exception { + Document document = createDOMWithNS("NamedNodeMap03.xml"); + NodeList nodeList = document.getElementsByTagName("body"); + nodeList = nodeList.item(0).getChildNodes(); + Node n = nodeList.item(7); + NamedNodeMap namedNodeMap = n.getAttributes(); + Node node = namedNodeMap.getNamedItemNS("urn:BooksAreUs.org:BookInfo", "aaa"); + assertEquals(node.getNodeValue(), "value"); + + } + + /* + * Test setNamedItem method with a node having the same name as an existing + * one, and then test with a non-existing node. + */ + @Test + public void testSetNamedItem() throws Exception { + Document document = createDOMWithNS("NamedNodeMap03.xml"); + NodeList nodeList = document.getElementsByTagName("body"); + nodeList = nodeList.item(0).getChildNodes(); + Node n = nodeList.item(1); + + NamedNodeMap namedNodeMap = n.getAttributes(); + Attr attr = document.createAttribute("name"); + Node replacedAttr = namedNodeMap.setNamedItem(attr); + assertEquals(replacedAttr.getNodeValue(), "attributeValue"); + Node updatedAttrNode = namedNodeMap.getNamedItem("name"); + assertEquals(updatedAttrNode.getNodeValue(), ""); + + Attr newAttr = document.createAttribute("nonExistingName"); + assertNull(namedNodeMap.setNamedItem(newAttr)); + Node newAttrNode = namedNodeMap.getNamedItem("nonExistingName"); + assertEquals(newAttrNode.getNodeValue(), ""); + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NodeListTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NodeListTest.java new file mode 100644 index 00000000000..4aa51f76665 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NodeListTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.createDOM; +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/* + * @summary Verifies a bug found in jaxp1.0.1 and 1.1FCS. After going out of + * bound, the last element of a NodeList returns null. The bug has been fixed + * in jaxp 1.1.1 build. + */ +public class NodeListTest extends JAXPFileBaseTest { + + @DataProvider(name = "xml") + public Object[][] getTestData() { + return new Object[][] { { "nodelist.xml", "document" }, { "Node01.xml", "body" } }; + } + + @Test(dataProvider = "xml") + public void lastItemTest(String xmlFileName, String nodeName) throws Exception { + Document document = createDOM(xmlFileName); + + NodeList nl = document.getElementsByTagName(nodeName); + int n = nl.getLength(); + + Element elem1 = (Element) nl.item(n - 1); + nl.item(n); + Element elem3 = (Element) nl.item(n - 1); + assertEquals(elem3, elem1); + + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NodeTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NodeTest.java new file mode 100644 index 00000000000..dddc2ce24b0 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NodeTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static jaxp.library.JAXPTestUtilities.compareWithGold; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; +import static org.testng.Assert.assertTrue; +import static org.w3c.dom.ptests.DOMTestUtil.GOLDEN_DIR; +import static org.w3c.dom.ptests.DOMTestUtil.createDOM; +import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS; +import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument; + +import java.io.File; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/* + * @summary Test Node interface + */ +public class NodeTest extends JAXPFileBaseTest { + @DataProvider(name = "feature-supported") + public Object[][] getFeatureSupportedList() throws Exception { + Document document = createDOMWithNS("Node01.xml"); + Node node = document.getElementsByTagName("body").item(0); + return new Object[][] { + { node, "XML", "2.0", true }, + { node, "HTML", "2.0", false }, + { node, "Views", "2.0", false }, + { node, "StyleSheets", "2.0", false }, + { node, "CSS", "2.0", false }, + { node, "CSS2", "2.0", false }, + { node, "Events", "2.0", true }, + { node, "UIEvents", "2.0", false }, + { node, "MouseEvents", "2.0", false }, + { node, "HTMLEvents", "2.0", false }, + { node, "Traversal", "2.0", true }, + { node, "Range", "2.0", true } }; + } + + /* + * Verify Node for feature supporting. + */ + @Test(dataProvider = "feature-supported") + public void testHasFeature(Node node, String feature, String version, boolean supported) { + assertEquals(node.isSupported(feature, version), supported); + } + + /* + * Test normalize method will merge adjacent Text nodes. + */ + @Test + public void testNormalize() throws Exception { + Document document = createDOM("Node05.xml"); + + Element root = document.getDocumentElement(); + + Node node = document.getElementsByTagName("title").item(0); + node.appendChild(document.createTextNode("test")); + root.normalize(); + assertEquals(node.getChildNodes().item(0).getNodeValue(), "Typographytest"); + } + + /* + * Test cloneNode deeply, and the clone node can be appended on the same document. + */ + @Test + public void testCloneNode() throws Exception { + Document document = createDOMWithNS("Node02.xml"); + + NodeList nodeList = document.getElementsByTagName("body"); + Node node = nodeList.item(0); + Node cloneNode = node.cloneNode(true); + + assertTrue(node.isEqualNode(cloneNode)); + assertNotEquals(node, cloneNode); + + nodeList = document.getElementsByTagName("html"); + Node node2 = nodeList.item(0); + node2.appendChild(cloneNode); + } + + /* + * Test importing node from one document to another. + */ + @Test + public void testImportNode() throws Exception { + Document document = createDOMWithNS("Node02.xml"); + Document otherDocument = createDOMWithNS("ElementSample01.xml"); + + NodeList otherNodeList = otherDocument.getElementsByTagName("body"); + Node importedNode = otherNodeList.item(0); + Node clone = importedNode.cloneNode(true); + + Node retNode = document.importNode(importedNode, true); + assertTrue(clone.isEqualNode(importedNode)); //verify importedNode is not changed + assertNotEquals(retNode, importedNode); + assertTrue(importedNode.isEqualNode(retNode)); + + retNode = document.importNode(importedNode, false); + assertTrue(clone.isEqualNode(importedNode)); //verify importedNode is not changed + assertEquals(retNode.getNodeName(), importedNode.getNodeName()); + assertFalse(importedNode.isEqualNode(retNode)); + } + + /* + * Test inserting a document fragment before a particular node. + */ + @Test + public void testInsertBefore() throws Exception { + Document document = createDOM("Node04.xml"); + + Element parentElement = (Element) document.getElementsByTagName("to").item(0); + Element element = (Element) document.getElementsByTagName("sender").item(0); + parentElement.insertBefore(createTestDocumentFragment(document), element); + + String outputfile = "InsertBefore.out"; + String goldfile = GOLDEN_DIR + "InsertBeforeGF.out"; + outputXml(document, outputfile); + assertTrue(compareWithGold(goldfile, outputfile)); + } + + + /* + * Test replacing a particular node with a document fragment. + */ + @Test + public void testReplaceChild() throws Exception { + Document document = createDOM("Node04.xml"); + + Element parentElement = (Element) document.getElementsByTagName("to").item(0); + Element element = (Element) document.getElementsByTagName("sender").item(0); + parentElement.replaceChild(createTestDocumentFragment(document), element); + + String outputfile = "ReplaceChild3.out"; + String goldfile = GOLDEN_DIR + "ReplaceChild3GF.out"; + outputXml(document, outputfile); + assertTrue(compareWithGold(goldfile, outputfile)); + } + + /* + * This test case checks for the replaceChild replacing a particular node + * with a node which was created from a different document than the one + * which is trying to use this method. It should throw a DOMException. + */ + @Test(expectedExceptions = DOMException.class) + public void testReplaceChildNeg() throws Exception { + Document document = createDOM("Node04.xml"); + Document doc2 = createNewDocument(); + + Element parentElement = (Element) document.getElementsByTagName("to").item(0); + Element element = (Element) document.getElementsByTagName("sender").item(0); + parentElement.replaceChild(createTestDocumentFragment(doc2), element); + } + + private DocumentFragment createTestDocumentFragment(Document document) { + DocumentFragment docFragment = document.createDocumentFragment(); + Element elem = document.createElement("dfElement"); + elem.appendChild(document.createTextNode("Text in it")); + docFragment.appendChild(elem); + return docFragment; + } + + private void outputXml(Document document, String outputFileName) throws TransformerFactoryConfigurationError, TransformerException { + DOMSource domSource = new DOMSource(document); + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + StreamResult streamResult = new StreamResult(new File(outputFileName)); + transformer.transform(domSource, streamResult); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NotationTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NotationTest.java new file mode 100644 index 00000000000..eea6ab41b47 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/NotationTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.createDOM; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Notation; +import org.xml.sax.SAXException; + +/* + * @summary Test for Notation interface + */ +public class NotationTest extends JAXPFileBaseTest { + /* + * Test getSystemId method. + */ + @Test + public void testGetSystemId() throws Exception { + assertEquals(findNotation("gs").getSystemId(), "http://who.knows.where/"); + } + + /* + * Test getPublicId method. + */ + @Test + public void testGetPublicId() throws Exception { + assertEquals(findNotation("pubname").getPublicId(), "pubId"); + } + + //find notation in Notation01.xml + private Notation findNotation(String name) throws SAXException, IOException, ParserConfigurationException { + Document document = createDOM("Notation01.xml"); + NamedNodeMap nm = document.getDoctype().getNotations(); + for (int i = 0; i < nm.getLength(); i++) { + if (nm.item(i).getNodeName().equals(name)) { + return (Notation) nm.item(i); + } + } + throw new RuntimeException("Notation: '" + name + "' not found."); + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/PITest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/PITest.java new file mode 100644 index 00000000000..15bd6876c36 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/PITest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS; +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.ProcessingInstruction; + +/* + * @summary Test for the methods of Processing Instruction + */ +public class PITest extends JAXPFileBaseTest { + /* + * Test getData, setData and getTarget methods + */ + @Test + public void test() throws Exception { + Document document = createDOMWithNS("PITest01.xml"); + ProcessingInstruction pi = document.createProcessingInstruction("PI", "processing"); + assertEquals(pi.getData(), "processing"); + assertEquals(pi.getTarget(), "PI"); + + pi.setData("newProcessing"); + assertEquals(pi.getData(), "newProcessing"); + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/TextTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/TextTest.java new file mode 100644 index 00000000000..7932114b519 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/TextTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static org.testng.Assert.assertEquals; +import static org.w3c.dom.ptests.DOMTestUtil.createDOMWithNS; +import static org.w3c.dom.ptests.DOMTestUtil.createNewDocument; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.testng.annotations.Test; +import org.w3c.dom.CharacterData; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.SAXException; + +/* + * @summary Test for Text implementation returned by Document.createTextNode(String) + */ +public class TextTest extends AbstractCharacterDataTest { + /* + * Verify splitText method works as the spec. + */ + @Test + public void testSplitText() throws Exception { + Document document = createDOMWithNS("Text01.xml"); + + NodeList nodeList = document.getElementsByTagName("p"); + Node node = nodeList.item(0); + Text textNode = document.createTextNode("This is a text node"); + node.appendChild(textNode); + int rawChildNum = node.getChildNodes().getLength(); + + textNode.splitText(0); + int increased = node.getChildNodes().getLength() - rawChildNum; + assertEquals(increased, 1); + + } + + @Override + protected CharacterData createCharacterData(String text) throws IOException, SAXException, ParserConfigurationException { + Document document = createNewDocument(); + return document.createTextNode(text); + } + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/TypeInfoTest.java b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/TypeInfoTest.java new file mode 100644 index 00000000000..f68dd919e0d --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/ptests/TypeInfoTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import static org.testng.Assert.assertEquals; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import jaxp.library.JAXPBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.TypeInfo; +import org.xml.sax.InputSource; + +/* + * @summary Test getTypeName and getTypeNamespace methods of TypeInfo interface + */ +public class TypeInfoTest extends JAXPBaseTest { + /* + * Get the TypeInfo of the root element, and verify it. + */ + @Test + public void test() throws Exception { + TypeInfo typeInfo = getTypeOfRoot(SCHEMA_INSTANCE, "\n" + "\n"); + + assertEquals(typeInfo.getTypeName(), "Test"); + assertEquals(typeInfo.getTypeNamespace(), "testNS"); + + } + + private TypeInfo getTypeOfRoot(String schemaText, String docText) throws Exception { + Element root = getRoot(schemaText, docText); + return root.getSchemaTypeInfo(); + } + + private Element getRoot(String schemaText, String docText) throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + InputSource inSchema = new InputSource(new StringReader(schemaText)); + inSchema.setSystemId("schema.xsd"); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setAttribute(SCHEMA_SOURCE, inSchema); + + DocumentBuilder parser = dbf.newDocumentBuilder(); + + InputSource inSource = new InputSource(new StringReader(docText)); + inSource.setSystemId("doc.xml"); + Document document = parser.parse(inSource); + + return document.getDocumentElement(); + } + + private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + + private static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + /* + * Schema instance + */ + private static final String SCHEMA_INSTANCE = + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + " \n" + + "\n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + "\n"; + + +} diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr01.xml new file mode 100644 index 00000000000..62224035142 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr01.xml @@ -0,0 +1,18 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + Numerical Analysis of Partial Differential Equations + Numerical Analysis of Partial Differential Equations + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr2.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr2.xml new file mode 100644 index 00000000000..8439a564c00 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr2.xml @@ -0,0 +1,11 @@ + + + + +]> + + + World's best book + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr3.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr3.xml new file mode 100644 index 00000000000..527c68dd691 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Attr3.xml @@ -0,0 +1,10 @@ + + + +]> + + + World's best book + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Comment01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Comment01.xml new file mode 100644 index 00000000000..80f7b74eb9e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Comment01.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentBuilderImpl02.dtd b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentBuilderImpl02.dtd new file mode 100644 index 00000000000..28b8a7b586a --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentBuilderImpl02.dtd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentTest01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentTest01.xml new file mode 100644 index 00000000000..15b61585623 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentTest01.xml @@ -0,0 +1,12 @@ + + + + Typography + + + Welcome to the world of typography! Here is a book that you may find useful. + Digital Typography + Donald Knuth + + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType01.xml new file mode 100644 index 00000000000..348e73f30f1 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType01.xml @@ -0,0 +1,14 @@ + + + + + + + + +]> + +&writer; + + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType03.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType03.xml new file mode 100644 index 00000000000..de62c6db2e6 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType03.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + +]> + +lll + + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType05.dtd b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType05.dtd new file mode 100644 index 00000000000..28b8a7b586a --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType05.dtd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType05.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType05.xml new file mode 100644 index 00000000000..89e09643844 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/DocumentType05.xml @@ -0,0 +1,28 @@ + + + + + Publishers of the Music of New York Women Composers + + The Publishers + + + Alfred Publishing + &w; + 15535 Morrison + South Oaks CA 91403 + + + + eXtensible Markup Language + + + + + + Publishers are not noted in report by time. + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample01.xml new file mode 100644 index 00000000000..62224035142 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample01.xml @@ -0,0 +1,18 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + Numerical Analysis of Partial Differential Equations + Numerical Analysis of Partial Differential Equations + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample02.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample02.xml new file mode 100644 index 00000000000..e1c0b4352d5 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample02.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample03.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample03.xml new file mode 100644 index 00000000000..9fdef74cf64 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample03.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample04.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample04.xml new file mode 100644 index 00000000000..b4a307254ef --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ElementSample04.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + this is it + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/NamedNodeMap01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/NamedNodeMap01.xml new file mode 100644 index 00000000000..07906e988b7 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/NamedNodeMap01.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/NamedNodeMap03.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/NamedNodeMap03.xml new file mode 100644 index 00000000000..2e4b9d1588f --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/NamedNodeMap03.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node01.xml new file mode 100644 index 00000000000..07906e988b7 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node01.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node02.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node02.xml new file mode 100644 index 00000000000..2e4b9d1588f --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node02.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node04.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node04.xml new file mode 100644 index 00000000000..d7dd873ffb5 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node04.xml @@ -0,0 +1,8 @@ + + + +John + +message + weekend! + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node05.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node05.xml new file mode 100644 index 00000000000..d32c19dce44 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Node05.xml @@ -0,0 +1,6 @@ + + + + Typography + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Notation01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Notation01.xml new file mode 100644 index 00000000000..dd26b3ef82e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Notation01.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + +]> + +lll + + \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/PITest01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/PITest01.xml new file mode 100644 index 00000000000..07906e988b7 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/PITest01.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            Welcome to the world of typography! Here is a book that you may find useful.

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Text01.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Text01.xml new file mode 100644 index 00000000000..80f7b74eb9e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/Text01.xml @@ -0,0 +1,15 @@ + + + + Typography + + + +

                            + Digital Typography + Donald Knuth + fjfjf + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ee.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ee.xml new file mode 100644 index 00000000000..7370d56ebf7 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/ee.xml @@ -0,0 +1,7 @@ + + + + +&mkm; + +
                            diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/entitychild.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/entitychild.xml new file mode 100644 index 00000000000..6e2e0e90be7 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/entitychild.xml @@ -0,0 +1,15 @@ + + + + + + + + + +]> + +
                            +ⅇ +
                            diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/nodelist.xml b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/nodelist.xml new file mode 100644 index 00000000000..fbdbfe6830b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/nodelist.xml @@ -0,0 +1,2 @@ + +onenode diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/out/InsertBeforeGF.out b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/out/InsertBeforeGF.out new file mode 100644 index 00000000000..53cb987a33a --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/out/InsertBeforeGF.out @@ -0,0 +1,7 @@ + + +Text in itJohn + +message + weekend! + diff --git a/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/out/ReplaceChild3GF.out b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/out/ReplaceChild3GF.out new file mode 100644 index 00000000000..4199e493fc2 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/org/w3c/dom/xmlfiles/out/ReplaceChild3GF.out @@ -0,0 +1,7 @@ + + +Text in it + +message + weekend! + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/AstroTest.java b/jaxp/test/javax/xml/jaxp/functional/test/astro/AstroTest.java new file mode 100644 index 00000000000..d31fd23f605 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/AstroTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package test.astro; + +import static java.lang.String.valueOf; +import static org.testng.Assert.assertEquals; +import static test.astro.AstroConstants.ASTROCAT; +import static test.astro.AstroConstants.GOLDEN_DIR; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +import javax.xml.transform.sax.TransformerHandler; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/* + * @summary run astro application, test xslt + * + * There are vast amounts of textual astronomical data, typically user is + * interested in a small subset, which is the result from carrying out a query. + * A query can be composed of one or more filters, for example, the user could + * query the database for all stars of visual magnitude down to 6.5 that lie + * between right ascensions 0 h to 2 h, and between declinations of 45 to 90 degrees. + * + * Astro application uses JAXP to query astronomical data saved in an XML dataset. + * A FilterFactory implementation creates filter(A filter is an instance of a JAXP + * TransformerHandler) from an XSL stylesheet. + * A InputSourceFactory implementation creates a new sax input source from an XML file. + * AstroProcessor leverages InputSourceFactory to parse catalog.xml, which saves + * textual astronomical data, and then creates filters with specified parameters + * from FilterFactory, all of the filters are chained together, AstroProcessor + * appends the HTML filter at the end of filter chain, and hooks up the chain to + * the input source, finally processes and outputs to the user specified output file. + * + * AstroTest drives AstroProcessor to run the specified queries(total 4 in setup), + * and then compares the output with the golden files to determine PASS or FAIL. + * It provides variant implementations of FilterFactory and InputSourceFactory to + * AstroProcessor to test different JAXP classes and features. + * + */ +public class AstroTest extends JAXPFileBaseTest { + private FiltersAndGolden[] data; + + @BeforeClass + public void setup() throws Exception { + data = new FiltersAndGolden[4]; + data[0] = new FiltersAndGolden(getGoldenFileContent(1), astro -> astro.getRAFilter(0.106, 0.108)); + data[1] = new FiltersAndGolden(getGoldenFileContent(2), astro -> astro.getStellarTypeFilter("K0IIIbCN-0.5")); + data[2] = new FiltersAndGolden(getGoldenFileContent(3), astro -> astro.getStellarTypeFilter("G"), astro -> astro.getDecFilter(-5.0, 60.0)); + data[3] = new FiltersAndGolden(getGoldenFileContent(4), astro -> astro.getRADECFilter(0.084, 0.096, -5.75, 14.0)); + } + + /* + * Provide permutations of InputSourceFactory and FilterFactory for test. + */ + @DataProvider(name = "factories") + public Object[][] getQueryFactories() { + return new Object[][] { + { StreamFilterFactoryImpl.class, InputSourceFactoryImpl.class }, + { SAXFilterFactoryImpl.class, InputSourceFactoryImpl.class }, + { DOMFilterFactoryImpl.class, InputSourceFactoryImpl.class }, + { TemplatesFilterFactoryImpl.class, InputSourceFactoryImpl.class }, + { StreamFilterFactoryImpl.class, DOML3InputSourceFactoryImpl.class } }; + } + + @Test(dataProvider = "factories") + public void test(Class fFactClass, Class isFactClass) throws Exception { + System.out.println(fFactClass.getName() +" : " + isFactClass.getName()); + AstroProcessor astro = new AstroProcessor(fFactClass, ASTROCAT, isFactClass); + + for (int i = 0; i < data.length; i++) { + runProcess(astro, valueOf(i + 1), data[i].getGolden(), data[i].getFilters()); + } + } + + private void runProcess(AstroProcessor astro, String processNum, List goldenfileContent, FilterCreator... filterCreators) throws Exception { + System.out.println("run process " + processNum); + TransformerHandler[] filters = new TransformerHandler[filterCreators.length]; + for (int i = 0; i < filterCreators.length; i++) + filters[i] = filterCreators[i].createFilter(astro); + + String outputfile = Files.createTempFile(Paths.get("").toAbsolutePath(), "query" + processNum + ".out.", null).toString(); + System.out.println("output file: " + outputfile); + astro.process(outputfile, filters); + assertEquals(Files.readAllLines(Paths.get(outputfile)), goldenfileContent); + } + + private List getGoldenFileContent(int num) throws IOException { + return Files.readAllLines(Paths.get(GOLDEN_DIR + "query" + num + ".out")); + } + + @FunctionalInterface + private interface FilterCreator { + TransformerHandler createFilter(AstroProcessor astro) throws Exception; + } + + private static class FiltersAndGolden { + private FilterCreator[] filters; + private List golden; + + FiltersAndGolden(List golden, FilterCreator... filters) { + this.filters = filters; + this.golden = golden; + } + + FilterCreator[] getFilters() { + return filters; + } + + List getGolden() { + return golden; + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/DocumentLSTest.java b/jaxp/test/javax/xml/jaxp/functional/test/astro/DocumentLSTest.java new file mode 100644 index 00000000000..b0a76282f7d --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/DocumentLSTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.w3c.dom.ls.DOMImplementationLS.MODE_SYNCHRONOUS; +import static test.astro.AstroConstants.ASTROCAT; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSOutput; +import org.w3c.dom.ls.LSParser; +import org.w3c.dom.ls.LSSerializer; + +/* + * @summary org.w3c.dom.ls tests + */ +public class DocumentLSTest extends JAXPFileBaseTest { + /* + * Test creating an empty Document + */ + @Test + public void testNewDocument() throws ParserConfigurationException { + Document doc = getDocumentBuilder().newDocument(); + assertNull(doc.getDocumentElement()); + } + + /* + * Test creating an LSInput instance, and parsing ByteStream + */ + @Test + public void testLSInputParsingByteStream() throws Exception { + DOMImplementationLS impl = (DOMImplementationLS) getDocumentBuilder().getDOMImplementation(); + LSParser domParser = impl.createLSParser(MODE_SYNCHRONOUS, null); + LSInput src = impl.createLSInput(); + + try (InputStream is = new FileInputStream(ASTROCAT)) { + src.setByteStream(is); + assertNotNull(src.getByteStream()); + // set certified accessor methods + boolean origCertified = src.getCertifiedText(); + src.setCertifiedText(true); + assertTrue(src.getCertifiedText()); + src.setCertifiedText(origCertified); // set back to orig + + src.setSystemId(filenameToURL(ASTROCAT)); + + Document doc = domParser.parse(src); + Element result = doc.getDocumentElement(); + assertEquals(result.getTagName(), "stardb"); + } + } + + /* + * Test creating an LSInput instance, and parsing String + */ + @Test + public void testLSInputParsingString() throws Exception { + DOMImplementationLS impl = (DOMImplementationLS) getDocumentBuilder().getDOMImplementation(); + String xml = "runDocumentLS_Q6"; + + LSParser domParser = impl.createLSParser(MODE_SYNCHRONOUS, null); + LSSerializer domSerializer = impl.createLSSerializer(); + // turn off xml decl in serialized string for comparison + domSerializer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE); + LSInput src = impl.createLSInput(); + src.setStringData(xml); + assertEquals(src.getStringData(), xml); + + Document doc = domParser.parse(src); + String result = domSerializer.writeToString(doc); + + assertEquals(result, "runDocumentLS_Q6"); + } + + /* + * Test writing with an LSOutput instance + */ + @Test + public void testLSOutput() throws Exception { + DocumentBuilder db = getDocumentBuilder(); + // Create the Document using the supplied builder... + Document doc = db.parse(ASTROCAT); + + DOMImplementationLS impl = null; + + impl = (DOMImplementationLS) db.getDOMImplementation(); + LSSerializer domSerializer = impl.createLSSerializer(); + MyDOMOutput mydomoutput = new MyDOMOutput(); + try (OutputStream os = new FileOutputStream("test.out")) { + mydomoutput.setByteStream(os); + mydomoutput.setEncoding("UTF-8"); + assertTrue(domSerializer.write(doc, mydomoutput)); + } + } + + private static class MyDOMOutput implements LSOutput { + private OutputStream bytestream = null; + private String encoding = null; + private String sysId = null; + private Writer writer = null; + + public OutputStream getByteStream() { + return bytestream; + } + + public Writer getCharacterStream() { + return writer; + } + + public String getEncoding() { + return encoding; + } + + public String getSystemId() { + return sysId; + } + + public void setByteStream(OutputStream bs) { + bytestream = bs; + } + + public void setCharacterStream(Writer cs) { + writer = cs; + } + + public void setEncoding(String enc) { + encoding = enc; + } + + public void setSystemId(String sysId) { + this.sysId = sysId; + } + } + + private DocumentBuilder getDocumentBuilder() throws ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + return dbf.newDocumentBuilder(); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/NamespaceContextTest.java b/jaxp/test/javax/xml/jaxp/functional/test/astro/NamespaceContextTest.java new file mode 100644 index 00000000000..6a1d0dd3d66 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/NamespaceContextTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX; +import static javax.xml.XMLConstants.NULL_NS_URI; +import static org.testng.Assert.assertEquals; + +import javax.xml.namespace.QName; + +import jaxp.library.JAXPBaseTest; + +import org.testng.annotations.Test; + +/* + * @summary javax.xml.namespace.QName tests + */ +public class NamespaceContextTest extends JAXPBaseTest { + private static final String PREFIX = "astro"; + private static final String LOCAL_PART = "stardb"; + private static final String NS_URI = "http://www.astro.com"; + + /* + * Test QName(String, String, String) and accessors. + */ + @Test + public void testQNameConstructor() { + QName qname = new QName(NS_URI, LOCAL_PART, PREFIX); + assertEquals(qname.getNamespaceURI(), NS_URI); + assertEquals(qname.getLocalPart(), LOCAL_PART); + assertEquals(qname.getPrefix(), PREFIX); + } + + /* + * Construct QName(String localpart), then test for default ns_uri and + * prefix constant. + */ + @Test + public void testDefaultFields() { + QName qname = new QName(LOCAL_PART); // just the local part specified + assertEquals(qname.getNamespaceURI(), NULL_NS_URI); + assertEquals(qname.getLocalPart(), LOCAL_PART); + assertEquals(qname.getPrefix(), DEFAULT_NS_PREFIX); + } + + /* + * Construct QName(String ns,String localpart), then test for default prefix + * constant. + */ + @Test + public void testDefaultPrefix() { + QName qname = new QName(NS_URI, LOCAL_PART); // no pref + assertEquals(qname.getNamespaceURI(), NS_URI); + assertEquals(qname.getLocalPart(), LOCAL_PART); + assertEquals(qname.getPrefix(), DEFAULT_NS_PREFIX); + } + + /* + * Round trip testing of QName to String, String to QName and test for + * equality. + */ + @Test + public void testQNameString() { + QName qname = new QName(NS_URI, LOCAL_PART, PREFIX); + assertEquals(QName.valueOf(qname.toString()), qname); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/SAX201Test.java b/jaxp/test/javax/xml/jaxp/functional/test/astro/SAX201Test.java new file mode 100644 index 00000000000..bcba454c126 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/SAX201Test.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import javax.xml.parsers.SAXParserFactory; + +import jaxp.library.JAXPBaseTest; + +import org.testng.annotations.Test; +import org.xml.sax.XMLReader; + +/* + * @summary verify SAX 2.0.1 allows to use null in setters + */ +public class SAX201Test extends JAXPBaseTest { + @Test + public void test() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader reader = spf.newSAXParser().getXMLReader(); + reader.setErrorHandler(null); // SAX 2.0.1 allows + reader.setContentHandler(null); // SAX 2.0.1 allows + reader.setEntityResolver(null); // SAX 2.0.1 allows + reader.setDTDHandler(null); // SAX 2.0.1 allows + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/SchemaValidationTest.java b/jaxp/test/javax/xml/jaxp/functional/test/astro/SchemaValidationTest.java new file mode 100644 index 00000000000..c84fddb6882 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/SchemaValidationTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import static test.astro.AstroConstants.ASTROCAT; +import static test.astro.AstroConstants.JAXP_SCHEMA_LANGUAGE; +import static test.astro.AstroConstants.JAXP_SCHEMA_SOURCE; + +import java.io.File; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.Test; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/* + * @summary test parser sets schema related properties to do validation + */ +public class SchemaValidationTest extends JAXPFileBaseTest { + /* + * Only set the schemaLanguage, without setting schemaSource. It should + * work. + */ + @Test + public void testSchemaValidation() throws Exception { + SAXParser sp = getValidatingParser(); + sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + sp.parse(new File(ASTROCAT), new DefaultHandler()); + } + + /* + * Test SAXException shall be thrown if schemaSource is set but + * schemaLanguage is not set. + */ + @Test(expectedExceptions = SAXException.class) + public void testSchemaValidationNeg() throws Exception { + SAXParser sp = getValidatingParser(); + sp.setProperty(JAXP_SCHEMA_SOURCE, "catalog.xsd"); + sp.parse(new File(ASTROCAT), new DefaultHandler()); + } + + private SAXParser getValidatingParser() throws ParserConfigurationException, SAXException { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); + return spf.newSAXParser(); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/XPathAPITest.java b/jaxp/test/javax/xml/jaxp/functional/test/astro/XPathAPITest.java new file mode 100644 index 00000000000..a97590fef38 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/XPathAPITest.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import static javax.xml.xpath.XPathConstants.DOM_OBJECT_MODEL; +import static javax.xml.xpath.XPathConstants.NODESET; +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static org.testng.Assert.assertEquals; +import static test.astro.AstroConstants.ASTROCAT; +import static test.astro.AstroConstants.JAXP_SCHEMA_LANGUAGE; +import static test.astro.AstroConstants.JAXP_SCHEMA_SOURCE; + +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Iterator; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathVariableResolver; + +import jaxp.library.JAXPFileBaseTest; + +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/* + * @summary test XPath API + */ +@Test(singleThreaded = true) +public class XPathAPITest extends JAXPFileBaseTest { + private static final String STARDB_STAR_3_CONSTELLATION = "//astro:stardb/astro:star[3]/astro:constellation"; + private static final String STARDB_STAR = "//astro:stardb/astro:star"; + private Document doc; + private XPathFactory xpf; + private NamespaceContext nsContext; + + @BeforeClass + public void setup() throws Exception { + DocumentBuilderFactory df = DocumentBuilderFactory.newInstance(); + df.setNamespaceAware(true); + df.setValidating(true); + df.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + df.setAttribute(JAXP_SCHEMA_SOURCE, "catalog.xsd"); + DocumentBuilder bldr = df.newDocumentBuilder(); + doc = bldr.parse(ASTROCAT); + + xpf = XPathFactory.newInstance(DOM_OBJECT_MODEL); + + nsContext = new MyNamespaceContext(); + } + + @DataProvider(name = "nodelist-evaluator") + public Object[][] getNodeListEvaluator() throws MalformedURLException { + return new Object[][] { { (XPathEvaluator) expression -> getXPath().evaluate(expression, doc.getDocumentElement(), NODESET) }, + { (XPathEvaluator) expression -> getXPath().evaluate(expression, createXMLInputSource(), NODESET) }, + { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(doc.getDocumentElement(), NODESET) }, + { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(createXMLInputSource(), NODESET) } }; + } + + /* + * Test xpath expression evaluations method that returns type indicated by + * QName + */ + @Test(dataProvider = "nodelist-evaluator") + public void testEvaluateNodeList(XPathEvaluator evaluator) throws Exception { + NodeList o = (NodeList) evaluator.evaluate(STARDB_STAR); + assertEquals(o.getLength(), 10); + } + + @DataProvider(name = "string-evaluator") + public Object[][] getStringEvaluator() throws MalformedURLException { + return new Object[][] { { (XPathEvaluator) expression -> getXPath().evaluate(expression, doc.getDocumentElement()) }, + { (XPathEvaluator) expression -> getXPath().evaluate(expression, createXMLInputSource()) }, + { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(doc.getDocumentElement()) }, + { (XPathEvaluator) expression -> getXPathExpression(expression).evaluate(createXMLInputSource()) } }; + } + + /* + * Test xpath expression evaluations method that returns String + */ + @Test(dataProvider = "string-evaluator") + public void testEvaluateString(XPathEvaluator evaluator) throws Exception { + assertEquals(evaluator.evaluate(STARDB_STAR_3_CONSTELLATION), "Psc"); + } + + @Test + public void testXPathVariableResolver() throws Exception { + XPath xpath = getXPath(); + xpath.setXPathVariableResolver(new MyXPathVariableResolver()); + assertEquals(xpath.evaluate("//astro:stardb/astro:star[astro:hr=$id]/astro:constellation", doc.getDocumentElement()), "Peg"); + + } + + private static class MyXPathVariableResolver implements XPathVariableResolver { + public Object resolveVariable(QName vname) { + return "4"; // resolve $id as 4, xpath will locate to star[hr=4] + } + } + + /* + * Implementation of a NamespaceContext interface for the Xpath api tests. + * Used in xpath.setNamespaceContext(...) + */ + private static class MyNamespaceContext implements NamespaceContext { + public String getNamespaceURI(String prefix) { + return "astro".equals(prefix) ? "http://www.astro.com/astro" : ""; + } + + public String getPrefix(String nsURI) { + return "http://www.astro.com/astro".equals(nsURI) ? "astro" : ""; + } + + public Iterator getPrefixes(String nsURI) { + ArrayList list = new ArrayList(); + list.add("astro"); + return list.iterator(); + } + } + + @FunctionalInterface + private interface XPathEvaluator { + Object evaluate(String expression) throws XPathExpressionException; + } + + private XPath getXPath() { + XPath xpath = xpf.newXPath(); + xpath.setNamespaceContext(nsContext); + return xpath; + } + + private XPathExpression getXPathExpression(String expression) throws XPathExpressionException { + return getXPath().compile(expression); + } + + private InputSource createXMLInputSource() { + return new InputSource(filenameToURL(ASTROCAT)); + } +} diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xml b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xml new file mode 100644 index 00000000000..2137a1cad90 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xml @@ -0,0 +1,17 @@ + + + <_test01> + + + <_test-04>T%e!s#t$ +
                            1000509.90.0860833333333333345134545.22916666666667114.44-16.886.70A1Vn
                            +
                            2000503.80.08438888888888889-003011-0.503055555555555698.33-61.146.29gG9
                            +
                            3Psc33 Psc000520.10.08891666666666666-054227-5.707500000000000593.75-65.934.61K0IIIbCN-0.5
                            +
                            4Peg86 Peg000542.00.09513234613.39611111111111106.19-47.985.51G5III
                            +
                            5000616.00.1044444444444444558261258.43666666666666117.03-03.925.96G5V
                            +
                            6000619.00.10527777777777779-490430-49.075321.61-66.385.70G1IV
                            +
                            7Cas10 Cas000626.50.1073611111111111264114664.19611111111111118.061.755.59B9III
                            +
                            8000636.80.1102222222222222229011729.02138888888889111.26-32.836.13K0V
                            +
                            9000650.10.11391666666666667-230627-23.107552.21-79.146.18A7V
                            +
                            10000718.20.12172222222222222-172311-17.38638888888888874.36-75.906.19A6Vn
                            +
                            diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xml.bak b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xml.bak new file mode 100644 index 00000000000..0fa5eb7ab58 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xml.bak @@ -0,0 +1,2 @@ + +<_test01><_test-04>T%e!s#t$
                            1000509.90.0860833333333333345134545.22916666666667114.44-16.886.70A1Vn

                            2000503.80.08438888888888889-003011-0.503055555555555698.33-61.146.29gG9

                            3Psc33 Psc000520.10.08891666666666666-054227-5.707500000000000593.75-65.934.61K0IIIbCN-0.5

                            4Peg86 Peg000542.00.09513234613.39611111111111106.19-47.985.51G5III

                            5000616.00.1044444444444444558261258.43666666666666117.03-03.925.96G5V

                            6000619.00.10527777777777779-490430-49.075321.61-66.385.70G1IV

                            7Cas10 Cas000626.50.1073611111111111264114664.19611111111111118.061.755.59B9III

                            8000636.80.1102222222222222229011729.02138888888889111.26-32.836.13K0V

                            9000650.10.11391666666666667-230627-23.107552.21-79.146.18A7V

                            10000718.20.12172222222222222-172311-17.38638888888888874.36-75.906.19A6Vn
                            diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xsd b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xsd new file mode 100644 index 00000000000..6e95cb8e31f --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/catalog.xsd @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query1.out b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query1.out new file mode 100644 index 00000000000..d5ccc94fa11 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query1.out @@ -0,0 +1,15 @@ + +

                            Bright Star Catalog Extract

                            + +Star Id: 7
                            +Constellation: Cas
                            +Description: 10 Cas
                            +RA J2000: 00:06:26.5
                            +DEC J2000: 64:11:46
                            +Visual Magnitude: 5.59
                            +Spectral Type: B9III
                            +Galactic Longitude: 118.06
                            +Galactic Latitude: 1.75
                            +
                            + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query2.out b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query2.out new file mode 100644 index 00000000000..22dc28c6581 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query2.out @@ -0,0 +1,15 @@ + +

                            Bright Star Catalog Extract

                            + +Star Id: 3
                            +Constellation: Psc
                            +Description: 33 Psc
                            +RA J2000: 00:05:20.1
                            +DEC J2000: 05:42:27
                            +Visual Magnitude: 4.61
                            +Spectral Type: K0IIIbCN-0.5
                            +Galactic Longitude: 93.75
                            +Galactic Latitude: -65.93
                            +
                            + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query3.out b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query3.out new file mode 100644 index 00000000000..e3f7184369d --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query3.out @@ -0,0 +1,39 @@ + +

                            Bright Star Catalog Extract

                            + +Star Id: 2
                            +Constellation: +
                            +Description: +
                            +RA J2000: 00:05:03.8
                            +DEC J2000: 00:30:11
                            +Visual Magnitude: 6.29
                            +Spectral Type: gG9
                            +Galactic Longitude: 98.33
                            +Galactic Latitude: -61.14
                            +
                            +Star Id: 4
                            +Constellation: Peg
                            +Description: 86 Peg
                            +RA J2000: 00:05:42.0
                            +DEC J2000: 13:23:46
                            +Visual Magnitude: 5.51
                            +Spectral Type: G5III
                            +Galactic Longitude: 106.19
                            +Galactic Latitude: -47.98
                            +
                            +Star Id: 5
                            +Constellation: +
                            +Description: +
                            +RA J2000: 00:06:16.0
                            +DEC J2000: 58:26:12
                            +Visual Magnitude: 5.96
                            +Spectral Type: G5V
                            +Galactic Longitude: 117.03
                            +Galactic Latitude: -03.92
                            +
                            + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query4.out b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query4.out new file mode 100644 index 00000000000..71b99603efd --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query4.out @@ -0,0 +1,37 @@ + +

                            Bright Star Catalog Extract

                            + +Star Id: 2
                            +Constellation: +
                            +Description: +
                            +RA J2000: 00:05:03.8
                            +DEC J2000: 00:30:11
                            +Visual Magnitude: 6.29
                            +Spectral Type: gG9
                            +Galactic Longitude: 98.33
                            +Galactic Latitude: -61.14
                            +
                            +Star Id: 3
                            +Constellation: Psc
                            +Description: 33 Psc
                            +RA J2000: 00:05:20.1
                            +DEC J2000: 05:42:27
                            +Visual Magnitude: 4.61
                            +Spectral Type: K0IIIbCN-0.5
                            +Galactic Longitude: 93.75
                            +Galactic Latitude: -65.93
                            +
                            +Star Id: 4
                            +Constellation: Peg
                            +Description: 86 Peg
                            +RA J2000: 00:05:42.0
                            +DEC J2000: 13:23:46
                            +Visual Magnitude: 5.51
                            +Spectral Type: G5III
                            +Galactic Longitude: 106.19
                            +Galactic Latitude: -47.98
                            +
                            + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec-ent.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec-ent.xsl new file mode 100644 index 00000000000..f4d1ea1b491 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec-ent.xsl @@ -0,0 +1,36 @@ + + + +]> + + + + + + + + + + + &toplevel; + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec.xsl new file mode 100644 index 00000000000..9a4ce901cd4 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec.xsl @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec_frag.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec_frag.xsl new file mode 100644 index 00000000000..2628420e58d --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/dec_frag.xsl @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/html.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/html.xsl new file mode 100644 index 00000000000..9f4594d469b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/html.xsl @@ -0,0 +1,38 @@ + + + + + + + + +

                            Bright Star Catalog Extract

                            + + + + +
                            + + + Star Id:
                            + Constellation:
                            + Description:
                            + RA J2000: ::
                            + DEC J2000: ::
                            + Visual Magnitude:
                            + Spectral Type:
                            + Galactic Longitude:
                            + Galactic Latitude:
                            +
                            +
                            + + + + + + +
                            + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra-ent.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra-ent.xsl new file mode 100644 index 00000000000..5d08bf69c53 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra-ent.xsl @@ -0,0 +1,29 @@ + +]> + + + + + + + + + &toplevel; + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra-uri.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra-uri.xsl new file mode 100644 index 00000000000..b7211295e6c --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra-uri.xsl @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra.xsl new file mode 100644 index 00000000000..7b60fb35ae5 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra.xsl @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra_frag.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra_frag.xsl new file mode 100644 index 00000000000..d69ab83072b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/ra_frag.xsl @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/radec.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/radec.xsl new file mode 100644 index 00000000000..4a0b63c2797 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/radec.xsl @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/stellartype.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/stellartype.xsl new file mode 100644 index 00000000000..e19e9aec343 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/stellartype.xsl @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/toptemplate.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/toptemplate.xsl new file mode 100644 index 00000000000..e4191deefbd --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/toptemplate.xsl @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/toptemplateinc.xsl b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/toptemplateinc.xsl new file mode 100644 index 00000000000..81b6d938967 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/xsl/toptemplateinc.xsl @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff --git a/jaxp/test/javax/xml/jaxp/libs/org/w3c/dom/ptests/DOMTestUtil.java b/jaxp/test/javax/xml/jaxp/libs/org/w3c/dom/ptests/DOMTestUtil.java new file mode 100644 index 00000000000..6b32aa36e74 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/org/w3c/dom/ptests/DOMTestUtil.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom.ptests; + +import static jaxp.library.JAXPTestUtilities.FILE_SEP; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; + +import java.io.File; +import java.io.IOException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/* + * This class defines the path constant and common method + */ +public class DOMTestUtil { + /* + * XML source file directory. + */ + public static final String XML_DIR = getPathByClassName(DOMTestUtil.class, ".." + FILE_SEP + "xmlfiles"); + + /* + * Golden validation files directory. + */ + public static final String GOLDEN_DIR = getPathByClassName(DOMTestUtil.class, ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); + + /* + * Error Message for DOMException being expected. + */ + public static final String DOMEXCEPTION_EXPECTED = "Should throw DOMException"; + + /* + * Create DOM Document from an xml file. + */ + public static Document createDOM(String xmlFileName) throws SAXException, IOException, ParserConfigurationException { + return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(XML_DIR + xmlFileName)); + } + + /* + * Create DOM Document from an xml file with setNamespaceAware(true). + */ + public static Document createDOMWithNS(String xmlFileName) throws IOException, SAXException, ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + return dbf.newDocumentBuilder().parse(new File(XML_DIR + xmlFileName)); + } + + /* + * Create a new DOM Document. + */ + public static Document createNewDocument() throws ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + return db.newDocument(); + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/AbstractFilterFactory.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/AbstractFilterFactory.java new file mode 100644 index 00000000000..da6feeb6e01 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/AbstractFilterFactory.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static test.astro.AstroConstants.HTMLXSL; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.sax.TransformerHandler; + +import org.xml.sax.SAXException; + +public abstract class AbstractFilterFactory implements FilterFactory { + @Override + public TransformerHandler newRAFilter(double min, double max) throws TransformerConfigurationException, SAXException, ParserConfigurationException, + IOException { + TransformerHandler retval = getTransformerHandler(getRAXsl()); + Transformer xformer = retval.getTransformer(); + xformer.setParameter("ra_min_hr", String.valueOf(min)); + xformer.setParameter("ra_max_hr", String.valueOf(max)); + return retval; + } + + @Override + public TransformerHandler newDECFilter(double min, double max) throws TransformerConfigurationException, SAXException, ParserConfigurationException, + IOException { + TransformerHandler retval = getTransformerHandler(getDECXsl()); + Transformer xformer = retval.getTransformer(); + xformer.setParameter("dec_min_deg", String.valueOf(min)); + xformer.setParameter("dec_max_deg", String.valueOf(max)); + return retval; + } + + @Override + public TransformerHandler newRADECFilter(double rmin, double rmax, double dmin, double dmax) throws TransformerConfigurationException, SAXException, + ParserConfigurationException, IOException { + TransformerHandler retval = getTransformerHandler(getRADECXsl()); + Transformer xformer = retval.getTransformer(); + xformer.setParameter("ra_min_hr", String.valueOf(rmin)); + xformer.setParameter("ra_max_hr", String.valueOf(rmax)); + xformer.setParameter("dec_min_deg", String.valueOf(dmin)); + xformer.setParameter("dec_max_deg", String.valueOf(dmax)); + return retval; + } + + @Override + public TransformerHandler newStellarTypeFilter(String type) throws TransformerConfigurationException, SAXException, ParserConfigurationException, + IOException { + TransformerHandler retval = getTransformerHandler(getStellarXsl()); + Transformer xformer = retval.getTransformer(); + xformer.setParameter("type", type); + return retval; + } + + @Override + public TransformerHandler newHTMLOutput() throws TransformerConfigurationException, SAXException, ParserConfigurationException, IOException { + return getTransformerHandler(HTMLXSL); + } + + abstract protected TransformerHandler getTransformerHandler(String xslFileName) throws SAXException, ParserConfigurationException, + TransformerConfigurationException, IOException; + + abstract protected String getRAXsl(); + + abstract protected String getDECXsl(); + + abstract protected String getRADECXsl(); + + abstract protected String getStellarXsl(); +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/AstroConstants.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/AstroConstants.java new file mode 100644 index 00000000000..b3f2cb6e5c6 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/AstroConstants.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package test.astro; + +import static java.io.File.separator; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; + +public class AstroConstants { + // Query parameters : + + public static final double RA_MIN = 0.0; // hours + public static final double RA_MAX = 24.0; // hours + public static final double DEC_MIN = -90.000; // degrees + public static final double DEC_MAX = 90.000; // degrees + + // Stylesheet source paths: + + public static final String XSLPATH = getPathByClassName(AstroConstants.class, "xmlfiles" + separator + "xsl"); + public static final String RAXSL = XSLPATH + "ra.xsl"; + public static final String DECXSL = XSLPATH + "dec.xsl"; + public static final String RADECXSL = XSLPATH + "radec.xsl"; + public static final String STYPEXSL = XSLPATH + "stellartype.xsl"; + public static final String HTMLXSL = XSLPATH + "html.xsl"; + + public static final String RAENTXSL = XSLPATH + "ra-ent.xsl"; + public static final String DECENTXSL = XSLPATH + "dec-ent.xsl"; + public static final String RAURIXSL = XSLPATH + "ra-uri.xsl"; + public static final String TOPTEMPLXSL = XSLPATH + "toptemplate.xsl"; + public static final String TOPTEMPLINCXSL = XSLPATH + "toptemplateinc.xsl"; + + // Catalog references + + public static final String ASTROCAT = getPathByClassName(AstroConstants.class, "xmlfiles") + "catalog.xml"; + + + public static final String GOLDEN_DIR = getPathByClassName(AstroConstants.class, "xmlfiles" + separator + "gold"); + public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/AstroProcessor.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/AstroProcessor.java new file mode 100644 index 00000000000..0ed8a0dfb7b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/AstroProcessor.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import static test.astro.AstroConstants.DEC_MAX; +import static test.astro.AstroConstants.DEC_MIN; +import static test.astro.AstroConstants.JAXP_SCHEMA_LANGUAGE; +import static test.astro.AstroConstants.JAXP_SCHEMA_SOURCE; +import static test.astro.AstroConstants.RA_MAX; +import static test.astro.AstroConstants.RA_MIN; + +import java.io.File; +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; + +/* + * AstroProcessor is to carry out the user's query with filters and produce a table of + * star records that match the criterion, and finally output with HTML format. + */ +public class AstroProcessor { + private String catalogFileName; + + private FilterFactory ffact; + private InputSourceFactory isfact; + + private SAXParserFactory spf; + + /* + * Constructor for the Main astro class. + * + * @param fFactClass the class of the FilterFactory implementation + * + * @param catalogfilename the name of the XML input document (database) + * + * @param isFactClass the class of the Input Source Factory implementation + */ + public AstroProcessor(Class fFactClass, String catalogFileName, Class isFactClass) throws Exception { + // create the Filter Factory instance... + + ffact = fFactClass.newInstance(); + + // create the Input Source Instance + + isfact = isFactClass.newInstance(); + + spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); + + // All XML Readers are required to recognize these two: + spf.setFeature("http://xml.org/sax/features/namespaces", true); + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + + // Other features... + spf.setFeature("http://xml.org/sax/features/validation", true); + spf.setFeature("http://apache.org/xml/features/validation/schema", true); + spf.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true); + + this.catalogFileName = catalogFileName; + } + + /* + * Sets the star stellar type query. + * + * @param arg stellar type string, can be a substring. + */ + public TransformerHandler getStellarTypeFilter(String arg) throws TransformerConfigurationException, SAXException, ParserConfigurationException, + IOException { + String stellarType = null; + if (arg != null && arg.length() != 0) { + stellarType = arg; // set value of query + } else { + throw new IllegalArgumentException("\n Stellar type string of length zero found."); + } + + return ffact.newStellarTypeFilter(stellarType); + } + + /* + * Sets the right ascension parameters for a query. Parameters are validated + * to be in the range of 0h and 24h inclusive. + * + * @param min minimum right ascension in hours. + * + * @param max maximum right ascension in hours. + */ + public TransformerHandler getRAFilter(double min, double max) throws TransformerConfigurationException, SAXException, ParserConfigurationException, + IOException { + double raMin = RA_MIN; // hours + double raMax = RA_MAX; // hours + if (min < max) { + if ((min >= RA_MIN && min <= RA_MAX) && (max >= RA_MIN && max <= RA_MAX)) { + raMin = min; // set value of query + raMax = max; // set value of query + + } + } else { + throw new IllegalArgumentException("min must be less than max.\n" + "min=" + min + ", max=" + max); + } + + return ffact.newRAFilter(raMin, raMax); + } + + /* + * Sets the right ascension and dec parameters for a query. Parameters are + * validated to be in the range of ra 0h and 24h and dec -90 to +90 + * inclusive. + * + * @param rmin minimum right ascension in hours. + * + * @param rmax maximum right ascension in hours. + * + * @param dmin minimum declination in degs. + * + * @param dmax maximum declination in degs. + */ + public TransformerHandler getRADECFilter(double rmin, double rmax, double dmin, double dmax) throws TransformerConfigurationException, SAXException, + ParserConfigurationException, IOException { + double raMin = RA_MIN; // hours + double raMax = RA_MAX; // hours + double decMin = DEC_MIN; // degrees + double decMax = DEC_MAX; // degrees + if (rmin < rmax && dmin < dmax) { + if ((rmin >= RA_MIN && rmin <= RA_MAX) && (rmax >= RA_MIN && rmax <= RA_MAX)) { + raMin = rmin; // set value of query + raMax = rmax; // set value of query + } + if ((dmin >= DEC_MIN && dmin <= DEC_MAX) && (dmax >= DEC_MIN && dmax <= DEC_MAX)) { + decMin = dmin; // set value of query + decMax = dmax; // set value of query + } + + } else { + throw new IllegalArgumentException("min must be less than max.\n" + "rmin=" + rmin + ", rmax=" + rmax + ", dmin=" + dmin + ", dmax=" + dmax); + } + + return ffact.newRADECFilter(raMin, raMax, decMin, decMax); + } + + /* + * Sets the declination parameters for a query. Parameters are validated to + * be in the range of -90 and +90 degrees inclusive. + * + * @param min minimum declination in degrees. + * + * @param max maximum declination in degrees. + */ + public TransformerHandler getDecFilter(double min, double max) throws TransformerConfigurationException, SAXException, ParserConfigurationException, + IOException { + double decMin = DEC_MIN; // degrees + double decMax = DEC_MAX; // degrees + if (min < max) { + if ((min >= DEC_MIN && min <= DEC_MAX) && (max >= DEC_MIN && max <= DEC_MAX)) { + decMin = min; // set value of query + decMax = max; // set value of query + } + } else { + throw new IllegalArgumentException("min must be less than max.\n" + "min=" + min + ", max=" + max); + } + + return ffact.newDECFilter(decMin, decMax); + } + + /* + * Runs the filter process against the astronomical database. + * + * @throws Exception + */ + public void process(String outputfile, TransformerHandler... filters) throws Exception { + XMLReader catparser = getXMLReader(); + + File catalogfile = new File(catalogFileName); + InputSource catsrc = isfact.newInputSource(catalogfile.getPath()); + + TransformerHandler outfilter = ffact.newHTMLOutput(); + // create an array from the Vector of filters... + + // hook the filters up to each other, there may be zero filters + int nfilters = filters.length; + if (nfilters != 0) { + TransformerHandler prev = null; + for (int i = 0; i < filters.length; i++) { + TransformerHandler curr = filters[i]; + if (prev != null) { + prev.setResult(new SAXResult(curr)); + } + prev = curr; + } + // hook up the last filter to the output filter + prev.setResult(new SAXResult(outfilter)); + // hook up the catalog parser to the first filter... + catparser.setContentHandler(filters[0]); + } else { + // There are no query filters, + // hook up the catalog parser directly to output filter... + catparser.setContentHandler(outfilter); + } + // hook up the output filter to the output file or std out + if (outputfile != null) { + outfilter.setResult(new StreamResult(outputfile)); + } else { + outfilter.setResult(new StreamResult(System.out)); + } + + catparser.parse(catsrc); + } + + private XMLReader getXMLReader() throws Exception { + SAXParser parser = spf.newSAXParser(); + parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + parser.setProperty(JAXP_SCHEMA_SOURCE, "catalog.xsd"); + XMLReader catparser = parser.getXMLReader(); + catparser.setErrorHandler(new CatalogErrorHandler()); + return catparser; + } + + /* + * Error Handler for the parsing of the XML astronomical catalog. + */ + private static class CatalogErrorHandler implements ErrorHandler { + private String getParseExceptionInfo(SAXParseException spe) { + String systemId = spe.getSystemId(); + if (systemId == null) { + systemId = "null"; + } + String info = "Catalog URI=" + systemId + " Line=" + spe.getLineNumber() + ": " + spe.getMessage(); + return info; + } + + public void warning(SAXParseException spe) throws SAXException { + String message = "Warning: " + getParseExceptionInfo(spe); + throw new SAXException(message); + } + + public void error(SAXParseException spe) throws SAXException { + String message = "Error: " + getParseExceptionInfo(spe); + throw new SAXException(message); + } + + public void fatalError(SAXParseException spe) throws SAXException { + String message = "Fatal Error: " + getParseExceptionInfo(spe); + throw new SAXException(message); + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/DOMFilterFactoryImpl.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/DOMFilterFactoryImpl.java new file mode 100644 index 00000000000..e232fb61fcc --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/DOMFilterFactoryImpl.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static test.astro.AstroConstants.DECXSL; +import static test.astro.AstroConstants.RAXSL; +import static test.astro.AstroConstants.STYPEXSL; + +import java.io.IOException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; + +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/* + * Implementation of the filter factory interface that utilizes DOM + * sources rather than Stream or SAX sources. This factory utilizes a + * DocumentBuilder to read in the stylesheets and create the DOM used + * to create the filters for the query pipeline. + * + */ +public class DOMFilterFactoryImpl extends SourceFilterFactory { + @Override + protected Source getSource(String xslFileName) throws SAXException, ParserConfigurationException, IOException { + Document document = getStylesheetDOM(xslFileName); + return new DOMSource(document); + } + + + @Override + protected String getRAXsl() { + return RAXSL; + } + + @Override + protected String getDECXsl() { + return DECXSL; + } + + @Override + protected String getRADECXsl() { + return DECXSL; + } + + @Override + protected String getStellarXsl() { + return STYPEXSL; + } + + private Document getStylesheetDOM(String xslfilename) throws SAXException, IOException, ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + return dbf.newDocumentBuilder().parse(filenameToURL(xslfilename)); + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/DOML3InputSourceFactoryImpl.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/DOML3InputSourceFactoryImpl.java new file mode 100644 index 00000000000..6978900344e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/DOML3InputSourceFactoryImpl.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static org.w3c.dom.ls.DOMImplementationLS.MODE_SYNCHRONOUS; +import static org.w3c.dom.traversal.NodeFilter.SHOW_ELEMENT; + +import java.io.ByteArrayInputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.file.Files; +import java.nio.file.Paths; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.DOMConfiguration; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSParser; +import org.w3c.dom.ls.LSParserFilter; +import org.w3c.dom.ls.LSSerializer; +import org.w3c.dom.ls.LSSerializerFilter; +import org.xml.sax.InputSource; + +/* + * A specialized implementation of an Input Source factory that utilizes + * DOM Level 3 implementations to build a Document (DOM) from the + * astro input file (XML) and then will serialize the DOM. The serialized DOM + * of the astro input file is then used to create the sax InputSource + * and set it's system id. It is then returned to the caller. + * + */ +public class DOML3InputSourceFactoryImpl implements InputSourceFactory { + public InputSource newInputSource(String filename) throws Exception { + // Create DOMImplementationLS, and DOM L3 LSParser + DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); + DocumentBuilder bldr = fact.newDocumentBuilder(); + DOMImplementationLS impl = (DOMImplementationLS) bldr.getDOMImplementation(); + LSParser domparser = impl.createLSParser(MODE_SYNCHRONOUS, null); + domparser.setFilter(new MyDOMBuilderFilter()); + + // Parse the xml document to create the DOM Document using + // the DOM L3 LSParser and a LSInput (formerly LSInputSource) + Document doc = null; + LSInput src = impl.createLSInput(); + // register the input file with the input source... + String systemId = filenameToURL(filename); + src.setSystemId(systemId); + try (Reader reader = new FileReader(filename)) { + src.setCharacterStream(reader); + src.setEncoding("UTF-8"); + doc = domparser.parse(src); + } + + // Use DOM L3 LSSerializer (previously called a DOMWriter) + // to serialize the xml doc DOM to a file stream. + String tmpCatalog = Files.createTempFile(Paths.get("").toAbsolutePath(), "catalog.xml", null).toString(); + + LSSerializer domserializer = impl.createLSSerializer(); + domserializer.setFilter(new MyDOMWriterFilter()); + domserializer.getNewLine(); + DOMConfiguration config = domserializer.getDomConfig(); + config.setParameter("xml-declaration", Boolean.TRUE); + String result = domserializer.writeToString(doc); + try (FileWriter os = new FileWriter(tmpCatalog, false)) { + os.write(result); + os.flush(); + } + + // Return the Input Source created from the Serialized DOM L3 Document. + InputSource catsrc = new InputSource(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(tmpCatalog))))); + catsrc.setSystemId(systemId); + return catsrc; + } + + /* + * Implementation of a DOM L3 DOM Builder Filter. The filter is capable of + * examining nodes as they are available during the parse. This + * implementation both rejects (filters) and modifies particular nodes + * during the parse of the document. As such, the document in memory will + * become a subset of the document on the stream in accordance with the DOM + * Level 3 Load and Save Specification, v1.0, sect. 1.3 Load Interfaces. + */ + private static class MyDOMBuilderFilter implements LSParserFilter { + + /* + * Filter the DOM. Define element(s) and their children that should be + * efficiently skipped thereby filtering them out of the stream. + */ + @Override + public short startElement(Element e) { + return "_test01".equals(e.getTagName()) ? FILTER_REJECT : FILTER_ACCEPT; + } + + /* + * Modify the DOM 'in situ'. Find a particular Node and change the Node + * value of its child, allow other nodes to pass through unchanged. + */ + @Override + public short acceptNode(Node n) { + String localname = n.getLocalName(); + if (localname.equals("_test-04")) { + Node child = n.getFirstChild(); + String text = child.getNodeValue(); + if (text.equals("T%e!s#t$")) { + child.setNodeValue("T%E!S#T$"); + } + } + return FILTER_ACCEPT; + } + + /* + * Tells the DOMBuilder what types of nodes to show to the filter. + */ + @Override + public int getWhatToShow() { + return SHOW_ELEMENT; + } + } + + /* + * Implementation of a DOM Serializer Filter (previously called a DOM Writer + * Filter) which is a specialization of the NodeFilter interface. + */ + private static class MyDOMWriterFilter implements LSSerializerFilter { + public MyDOMWriterFilter() { + } + + /* + * Must implement method from NodeFilter interface + */ + @Override + public short acceptNode(Node node) { + return FILTER_ACCEPT; + } + + /* + * Tells the DOMBuilder what types of nodes to show to the filter. + */ + @Override + public int getWhatToShow() { + return SHOW_ELEMENT; + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/FilterFactory.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/FilterFactory.java new file mode 100644 index 00000000000..3fa8c17fbc2 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/FilterFactory.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.TransformerConfigurationException; + +import org.xml.sax.SAXException; + +/* + * Defines the interface for all concrete implementations of a Filter + * Factory. + */ +public interface FilterFactory { + /* + * Allows only the stars between right ascension (R.A.) of min and max to + * pass. Filters out all stars that are not in that range of right + * ascension. Units of right ascension are hours (h), range of parameters is + * 0h to 24h. + * + * @param min minimum R.A. + * + * @param max maxmimum R.A. + */ + TransformerHandler newRAFilter(double min, double max) throws TransformerConfigurationException, SAXException, ParserConfigurationException, IOException; + + /* + * Allows only the stars between declination (DEC) of min and max to pass. + * Filters out all stars that are not in that range of declination. Units of + * declination are degrees (degs), range of parameters is -90 and +90 degs. + * + * @param min minimum DEC + * + * @param max maxmimum DEC + */ + TransformerHandler newDECFilter(double min, double max) throws TransformerConfigurationException, SAXException, ParserConfigurationException, IOException; + + /* + * Combines the usage of newRAFilter and newDECFilter into one. + * + * @param rmin minimum R.A. + * + * @param rmax maxmimum R.A. + * + * @param dmin minimum DEC + * + * @param dmax maxmimum DEC + */ + TransformerHandler newRADECFilter(double rmin, double rmax, double dmin, double dmax) throws TransformerConfigurationException, SAXException, + ParserConfigurationException, IOException; + + TransformerHandler newStellarTypeFilter(String type) throws TransformerConfigurationException, SAXException, ParserConfigurationException, IOException; + + TransformerHandler newHTMLOutput() throws TransformerConfigurationException, SAXException, ParserConfigurationException, IOException; +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/InputSourceFactory.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/InputSourceFactory.java new file mode 100644 index 00000000000..1d3cb5f78f6 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/InputSourceFactory.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import org.xml.sax.InputSource; + +/* + * Interface for all input source factory objects. The default implementation + * 'InputSourceFactoryImpl' is provided as a straight forward factory + * class that creates a new sax input source from a filename. + * + */ +public interface InputSourceFactory { + /* + * Creates a new sax InputSource object from a filename. + * Also sets the system id of the input source. + * @param file filename of the XML input to create the input source. + */ + InputSource newInputSource(String file) throws Exception; +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/InputSourceFactoryImpl.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/InputSourceFactoryImpl.java new file mode 100644 index 00000000000..a2c5b8319c8 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/InputSourceFactoryImpl.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; + +import org.xml.sax.InputSource; + +/* + * Default implementation of a input source factory. This is the most + * straight forward way to create a sax input source and set it's + * system id. + * + */ +public class InputSourceFactoryImpl implements InputSourceFactory { + public InputSourceFactoryImpl() { + } + + public InputSource newInputSource(String filename) { + InputSource catSrc = new InputSource(filename); + catSrc.setSystemId(filenameToURL(filename)); + return catSrc; + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/SAXFilterFactoryImpl.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/SAXFilterFactoryImpl.java new file mode 100644 index 00000000000..4ef5d3cc259 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/SAXFilterFactoryImpl.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static test.astro.AstroConstants.DECENTXSL; +import static test.astro.AstroConstants.DECXSL; +import static test.astro.AstroConstants.RAENTXSL; +import static test.astro.AstroConstants.STYPEXSL; +import static test.astro.AstroConstants.TOPTEMPLXSL; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/* + * Implementation of the filter factory interface that utilizes SAX + * sources rather than Stream sources. This factory utilizes a + * SAX parser factory and XMLReader to read in the stylesheets used + * to create the filters for the query pipeline. + * The XMLReader has been equipped with an entity resolver + * SAXFilterFactoryEntityResolver, it is used to resolve external + * entities in two specialized stylesheets, ra-ent.xsl (derived from + * ra.xsl) and dec-ent.xsl (derived from dec.xsl). + * + */ +public class SAXFilterFactoryImpl extends SourceFilterFactory { + private EntityResolver entityResolver; + + public SAXFilterFactoryImpl() { + super(); + entityResolver = new SAXFilterFactoryEntityResolver(); + } + + @Override + protected Source getSource(String xslFileName) throws SAXException, ParserConfigurationException { + SAXSource saxsource = new SAXSource(new InputSource(filenameToURL(xslFileName))); + saxsource.setXMLReader(getXMLReader()); + return saxsource; + } + + @Override + protected String getRAXsl() { + return RAENTXSL; + } + + @Override + protected String getDECXsl() { + return DECENTXSL; + } + + @Override + protected String getRADECXsl() { + return DECXSL; + } + + @Override + protected String getStellarXsl() { + return STYPEXSL; + } + + /* + * Entity resolver implementation that is used in the SAXFilterFactory + * implementation for handling external entities that appear in two + * specialized stylesheets, 'ra-ent.xsl' and 'dec-ent.xsl'. Both of these + * stylesheets contain an external entity reference to the top level + * stylesheet template, which is stored in a separate file, + * 'toptemplate.xsl'. + */ + private static class SAXFilterFactoryEntityResolver implements EntityResolver { + public InputSource resolveEntity(String publicid, String sysId) { + if (sysId.equals("http://astro.com/stylesheets/toptemplate")) { + InputSource retval = new InputSource(TOPTEMPLXSL); + retval.setSystemId(filenameToURL(TOPTEMPLXSL)); + return retval; + } else { + return null; // use default behavior + } + } + } + + private XMLReader getXMLReader() throws SAXException, ParserConfigurationException { + SAXParserFactory pfactory = SAXParserFactory.newInstance(); + pfactory.setNamespaceAware(true); + // pfactory.setValidating(true); + XMLReader xmlreader = pfactory.newSAXParser().getXMLReader(); + // entity resolver is used in stylesheets ra-ent.xsl, + // dec-ent.xsl. Other stylehsheets will not use it + // since they do not contain ext entities. + xmlreader.setEntityResolver(entityResolver); + return xmlreader; + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/SourceFilterFactory.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/SourceFilterFactory.java new file mode 100644 index 00000000000..1bddec62158 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/SourceFilterFactory.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; + +import org.xml.sax.SAXException; + +public abstract class SourceFilterFactory extends AbstractFilterFactory { + @Override + protected TransformerHandler getTransformerHandler(String xslFileName) throws SAXException, ParserConfigurationException, + TransformerConfigurationException, IOException { + return getFactory().newTransformerHandler(getSource(xslFileName)); + } + + abstract protected Source getSource(String xslFileName) throws SAXException, ParserConfigurationException, IOException; + + private SAXTransformerFactory getFactory() { + return (SAXTransformerFactory) TransformerFactory.newInstance(); + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/StreamFilterFactoryImpl.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/StreamFilterFactoryImpl.java new file mode 100644 index 00000000000..0978161312e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/StreamFilterFactoryImpl.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static test.astro.AstroConstants.DECXSL; +import static test.astro.AstroConstants.RADECXSL; +import static test.astro.AstroConstants.RAXSL; +import static test.astro.AstroConstants.STYPEXSL; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +public class StreamFilterFactoryImpl extends SourceFilterFactory { + @Override + protected Source getSource(String xslFileName) { + return new StreamSource(filenameToURL(xslFileName)); + } + + @Override + protected String getRAXsl() { + return RAXSL; + } + + @Override + protected String getDECXsl() { + return DECXSL; + } + + @Override + protected String getRADECXsl() { + return RADECXSL; + } + + @Override + protected String getStellarXsl() { + return STYPEXSL; + } +} diff --git a/jaxp/test/javax/xml/jaxp/libs/test/astro/TemplatesFilterFactoryImpl.java b/jaxp/test/javax/xml/jaxp/libs/test/astro/TemplatesFilterFactoryImpl.java new file mode 100644 index 00000000000..09a71b1a534 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/libs/test/astro/TemplatesFilterFactoryImpl.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.astro; + +import static jaxp.library.JAXPTestUtilities.filenameToURL; +import static test.astro.AstroConstants.DECXSL; +import static test.astro.AstroConstants.RAURIXSL; +import static test.astro.AstroConstants.STYPEXSL; +import static test.astro.AstroConstants.TOPTEMPLINCXSL; + +import java.io.IOException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.URIResolver; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TemplatesHandler; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamSource; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/* + * Implementation of the filter factory interface that utilizes + * a TemplatesHandler and creates Templates from the stylesheets. + * The Templates objects are then used to create a TransformerHandler + * a.k.a Filter which is returned to the caller. + * This factory uses a Uri resolver which is registered with the + * Transformer factory. + * + */ +public class TemplatesFilterFactoryImpl extends AbstractFilterFactory { + private final URIResolver uriResolver = new TemplatesFilterFactoryURIResolver(); + + @Override + protected String getRAXsl() { + return RAURIXSL; + } + + @Override + protected String getDECXsl() { + return DECXSL; + } + + @Override + protected String getRADECXsl() { + return DECXSL; + } + + @Override + protected String getStellarXsl() { + return STYPEXSL; + } + + @Override + protected TransformerHandler getTransformerHandler(String xslFileName) throws SAXException, ParserConfigurationException, + TransformerConfigurationException, IOException { + SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance(); + factory.setURIResolver(uriResolver); + + TemplatesHandler templatesHandler = factory.newTemplatesHandler(); + + SAXParserFactory pFactory = SAXParserFactory.newInstance(); + pFactory.setNamespaceAware(true); + + XMLReader xmlreader = pFactory.newSAXParser().getXMLReader(); + + // create the stylesheet input source + InputSource xslSrc = new InputSource(xslFileName); + + xslSrc.setSystemId(filenameToURL(xslFileName)); + // hook up the templates handler as the xsl content handler + xmlreader.setContentHandler(templatesHandler); + // call parse on the xsl input source + + xmlreader.parse(xslSrc); + + // extract the Templates object created from the xsl input source + return factory.newTransformerHandler(templatesHandler.getTemplates()); + } + + /* + * Uri resolver used to resolve stylesheet used by the Templates filter + * factory. + */ + private static class TemplatesFilterFactoryURIResolver implements URIResolver { + public Source resolve(String href, String base) throws TransformerException { + if ("http://astro.com/stylesheets/topleveltemplate".equals(href)) { + StreamSource ss = new StreamSource(TOPTEMPLINCXSL); + ss.setSystemId(filenameToURL(TOPTEMPLINCXSL)); + return ss; + } else { + return null; + } + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/DOMXPathTest.java b/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/DOMXPathTest.java new file mode 100644 index 00000000000..fa92dc7175b --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/DOMXPathTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.testng.Assert; +import org.testng.annotations.Test; + +/* + * @bug 8042244 + * @summary Verifies that the experimental DOM L3 XPath implementation is no longer available. + */ +public class DOMXPathTest { + /* + Verifies that DOMImplementation::hasFeature returns false and getFeature + returns null for DOM L3 XPath. + */ + @Test + public void test() throws ParserConfigurationException { + DOMImplementation domImpl = DocumentBuilderFactory.newInstance() + .newDocumentBuilder() + .getDOMImplementation(); + + Assert.assertFalse(domImpl.hasFeature("+XPath", "3.0")); + Assert.assertEquals(domImpl.getFeature("+XPath", "3.0"), null); + } +} diff --git a/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/JdkXmlDomTest.java b/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/JdkXmlDomTest.java new file mode 100644 index 00000000000..b65b4fd6bff --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/org/w3c/dom/JdkXmlDomTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.w3c.dom; + +import org.testng.Assert; +import org.testng.annotations.Test; + +/* + * @bug 8078139 + * @summary Verifies that jdk.xml.dom classes are loaded by the ext class loader. + */ +public class JdkXmlDomTest { + @Test + public void test() throws ClassNotFoundException { + ClassLoader cl = ClassLoader.getSystemClassLoader().getParent(); + Class cls = Class.forName("org.w3c.dom.xpath.XPathEvaluator", false, cl); + + Assert.assertTrue(cls.getClassLoader() != null); + } +} diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 28dbe7d8a58..6233b33cd39 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -305,3 +305,5 @@ b4f913b48e699980bd11fe19cce134d0adb4c31c jdk9-b56 17c4241395e97312bd75e7acd693ffcdd41ae993 jdk9-b57 1e06b36bb396c0495e0774f1c6b0356d03847659 jdk9-b58 8a9ebae410bc388668fc203e559b5407bde757eb jdk9-b59 +f31835b59035377a220efc5a248b90f090ee1689 jdk9-b60 +77f44848c44c003205490bf5ab88035233b65418 jdk9-b61 diff --git a/jaxws/src/java.activation/share/classes/javax/activation/ActivationDataFlavor.java b/jaxws/src/java.activation/share/classes/javax/activation/ActivationDataFlavor.java index 41979db6b85..c4836e4d0a7 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/ActivationDataFlavor.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/ActivationDataFlavor.java @@ -31,10 +31,10 @@ import javax.activation.MimeType; /** * The ActivationDataFlavor class is a special subclass of - * java.awt.datatransfer.DataFlavor. It allows the JAF to + * {@code java.awt.datatransfer.DataFlavor}. It allows the JAF to * set all three values stored by the DataFlavor class via a new - * constructor. It also contains improved MIME parsing in the equals - * method. Except for the improved parsing, its semantics are + * constructor. It also contains improved MIME parsing in the {@code equals} + * method. Except for the improved parsing, its semantics are * identical to that of the JDK's DataFlavor class. * * @since 1.6 @@ -70,7 +70,6 @@ public class ActivationDataFlavor extends DataFlavor { * representationClass = representationClass
                            * mimeType = mimeType
                            * humanName = humanName - *

                            * * @param representationClass the class used in this DataFlavor * @param mimeType the MIME type of the data represented by this class @@ -98,7 +97,7 @@ public class ActivationDataFlavor extends DataFlavor { * otherwise: *

                            * representationClass = InputStream

                            - * mimeType = mimeType

                            + * mimeType = mimeType * * @param representationClass the class used in this DataFlavor * @param humanPresentableName the human presentable name of the flavor @@ -175,7 +174,7 @@ public class ActivationDataFlavor extends DataFlavor { /** * Compares the DataFlavor passed in with this DataFlavor; calls - * the isMimeTypeEqual method. + * the {@code isMimeTypeEqual} method. * * @param dataFlavor the DataFlavor to compare with * @return true if the MIME type and representation class diff --git a/jaxws/src/java.activation/share/classes/javax/activation/CommandInfo.java b/jaxws/src/java.activation/share/classes/javax/activation/CommandInfo.java index 92db2568ac0..b8dfd8b7091 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/CommandInfo.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/CommandInfo.java @@ -85,10 +85,10 @@ public class CommandInfo { * Return the instantiated JavaBean component. *

                            * Begin by instantiating the component with - * Beans.instantiate(). + * {@code Beans.instantiate()}. *

                            - * If the bean implements the javax.activation.CommandObject - * interface, call its setCommandContext method. + * If the bean implements the {@code javax.activation.CommandObject} + * interface, call its {@code setCommandContext} method. *

                            * If the DataHandler parameter is null, then the bean is * instantiated with no data. NOTE: this may be useful @@ -102,7 +102,7 @@ public class CommandInfo { * this method will check if it implements the * java.io.Externalizable interface. If it does, the bean's * readExternal method will be called if an InputStream - * can be acquired from the DataHandler.

                            + * can be acquired from the DataHandler. * * @param dh The DataHandler that describes the data to be * passed to the command. diff --git a/jaxws/src/java.activation/share/classes/javax/activation/CommandMap.java b/jaxws/src/java.activation/share/classes/javax/activation/CommandMap.java index acc194b5248..16e18ca5ff8 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/CommandMap.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/CommandMap.java @@ -46,7 +46,6 @@ public abstract class CommandMap { /** * Get the default CommandMap. - *

                            * *

                              *
                            • In cases where a CommandMap instance has been previously set @@ -54,7 +53,7 @@ public abstract class CommandMap { * return the CommandMap. *
                            • * In cases where no CommandMap has been set, the CommandMap - * creates an instance of MailcapCommandMap and + * creates an instance of {@code MailcapCommandMap} and * set that to the default, returning its value. * *
                            @@ -77,7 +76,7 @@ public abstract class CommandMap { /** * Set the default CommandMap. Reset the CommandMap to the default by - * calling this method with null. + * calling this method with {@code null}. * * @param commandMap The new default CommandMap. * @exception SecurityException if the caller doesn't have permission @@ -118,10 +117,10 @@ public abstract class CommandMap { * Get the preferred command list from a MIME Type. The actual semantics * are determined by the implementation of the CommandMap.

                            * - * The DataSource provides extra information, such as + * The {@code DataSource} provides extra information, such as * the file name, that a CommandMap implementation may use to further * refine the list of commands that are returned. The implementation - * in this class simply calls the getPreferredCommands + * in this class simply calls the {@code getPreferredCommands} * method that ignores this argument. * * @param mimeType the MIME type @@ -146,10 +145,10 @@ public abstract class CommandMap { * Get all the available commands for this type. This method * should return all the possible commands for this MIME type.

                            * - * The DataSource provides extra information, such as + * The {@code DataSource} provides extra information, such as * the file name, that a CommandMap implementation may use to further * refine the list of commands that are returned. The implementation - * in this class simply calls the getAllCommands + * in this class simply calls the {@code getAllCommands} * method that ignores this argument. * * @param mimeType the MIME type @@ -173,10 +172,10 @@ public abstract class CommandMap { /** * Get the default command corresponding to the MIME type.

                            * - * The DataSource provides extra information, such as + * The {@code DataSource} provides extra information, such as * the file name, that a CommandMap implementation may use to further * refine the command that is chosen. The implementation - * in this class simply calls the getCommand + * in this class simply calls the {@code getCommand} * method that ignores this argument. * * @param mimeType the MIME type @@ -206,10 +205,10 @@ public abstract class CommandMap { * The mechanism and semantics for determining this are determined * by the implementation of the particular CommandMap.

                            * - * The DataSource provides extra information, such as + * The {@code DataSource} provides extra information, such as * the file name, that a CommandMap implementation may use to further * refine the choice of DataContentHandler. The implementation - * in this class simply calls the createDataContentHandler + * in this class simply calls the {@code createDataContentHandler} * method that ignores this argument. * * @param mimeType the MIME type diff --git a/jaxws/src/java.activation/share/classes/javax/activation/CommandObject.java b/jaxws/src/java.activation/share/classes/javax/activation/CommandObject.java index 01602e8a92f..7dda0239819 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/CommandObject.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/CommandObject.java @@ -34,7 +34,7 @@ import java.io.IOException; * data they should operate on. JavaBeans that don't implement * this interface may be used as well. Such commands may obtain * the data using the Externalizable interface, or using an - * application-specific method.

                            + * application-specific method. * * @since 1.6 */ @@ -44,7 +44,7 @@ public interface CommandObject { * Initialize the Command with the verb it is requested to handle * and the DataHandler that describes the data it will * operate on. NOTE: it is acceptable for the caller - * to pass null as the value for DataHandler. + * to pass null as the value for {@code DataHandler}. * * @param verb The Command Verb this object refers to. * @param dh The DataHandler. diff --git a/jaxws/src/java.activation/share/classes/javax/activation/DataHandler.java b/jaxws/src/java.activation/share/classes/javax/activation/DataHandler.java index 6fef9302a83..27f72484f69 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/DataHandler.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/DataHandler.java @@ -54,11 +54,11 @@ import java.awt.datatransfer.UnsupportedFlavorException; * * DataHandler and CommandMaps

                            * The DataHandler keeps track of the current CommandMap that it uses to - * service requests for commands (getCommand, - * getAllCommands, getPreferredCommands). + * service requests for commands ({@code getCommand, getAllCommands, + * getPreferredCommands}). * Each instance of a DataHandler may have a CommandMap associated with - * it using the setCommandMap method. If a CommandMap was - * not set, DataHandler calls the getDefaultCommandMap + * it using the {@code setCommandMap} method. If a CommandMap was + * not set, DataHandler calls the {@code getDefaultCommandMap} * method in CommandMap and uses the value it returns. See * CommandMap for more information.

                            * @@ -105,7 +105,7 @@ public class DataHandler implements Transferable { private String shortType = null; /** - * Create a DataHandler instance referencing the + * Create a {@code DataHandler} instance referencing the * specified DataSource. The data exists in a byte stream form. * The DataSource will provide an InputStream to access the data. * @@ -118,7 +118,7 @@ public class DataHandler implements Transferable { } /** - * Create a DataHandler instance representing an object + * Create a {@code DataHandler} instance representing an object * of this MIME type. This constructor is * used when the application already has an in-memory representation * of the data in the form of a Java Object. @@ -133,8 +133,8 @@ public class DataHandler implements Transferable { } /** - * Create a DataHandler instance referencing a URL. - * The DataHandler internally creates a URLDataSource + * Create a {@code DataHandler} instance referencing a URL. + * The DataHandler internally creates a {@code URLDataSource} * instance to represent the URL. * * @param url a URL object @@ -181,7 +181,7 @@ public class DataHandler implements Transferable { /** * Return the name of the data object. If this DataHandler * was created with a DataSource, this method calls through - * to the DataSource.getName method, otherwise it + * to the {@code DataSource.getName} method, otherwise it * returns null. * * @return the name of the object @@ -211,7 +211,7 @@ public class DataHandler implements Transferable { * Get the InputStream for this object.

                            * * For DataHandlers instantiated with a DataSource, the DataHandler - * calls the DataSource.getInputStream method and + * calls the {@code DataSource.getInputStream} method and * returns the result to the caller. *

                            * For DataHandlers instantiated with an Object, the DataHandler @@ -219,11 +219,11 @@ public class DataHandler implements Transferable { * the DataHandler can not find a DataContentHandler for this MIME * type, it throws an UnsupportedDataTypeException. If it is * successful, it creates a pipe and a thread. The thread uses the - * DataContentHandler's writeTo method to write the + * DataContentHandler's {@code writeTo} method to write the * stream data into one end of the pipe. The other end of the pipe * is returned to the caller. Because a thread is created to copy * the data, IOExceptions that may occur during the copy can not be - * propagated back to the caller. The result is an empty stream.

                            + * propagated back to the caller. The result is an empty stream. * * @return the InputStream representing this data * @exception IOException if an I/O error occurs @@ -281,7 +281,7 @@ public class DataHandler implements Transferable { } /** - * Write the data to an OutputStream.

                            + * Write the data to an {@code OutputStream}.

                            * * If the DataHandler was created with a DataSource, writeTo * retrieves the InputStream and copies the bytes from the @@ -290,7 +290,7 @@ public class DataHandler implements Transferable { * If the DataHandler was created with an object, writeTo * retrieves the DataContentHandler for the object's type. * If the DataContentHandler was found, it calls the - * writeTo method on the DataContentHandler. + * {@code writeTo} method on the {@code DataContentHandler}. * * @param os the OutputStream to write to * @exception IOException if an I/O error occurs @@ -322,8 +322,8 @@ public class DataHandler implements Transferable { * Get an OutputStream for this DataHandler to allow overwriting * the underlying data. * If the DataHandler was created with a DataSource, the - * DataSource's getOutputStream method is called. - * Otherwise, null is returned. + * DataSource's {@code getOutputStream} method is called. + * Otherwise, {@code null} is returned. * * @return the OutputStream * @@ -348,12 +348,12 @@ public class DataHandler implements Transferable { * The DataHandler attempts to find a DataContentHandler that * corresponds to the MIME type of the data. If one is located, * the DataHandler calls the DataContentHandler's - * getTransferDataFlavors method.

                            + * {@code getTransferDataFlavors} method.

                            * * If a DataContentHandler can not be located, and if the * DataHandler was created with a DataSource (or URL), one * DataFlavor is returned that represents this object's MIME type - * and the java.io.InputStream class. If the + * and the {@code java.io.InputStream} class. If the * DataHandler was created with an object and a MIME type, * getTransferDataFlavors returns one DataFlavor that represents * this object's MIME type and the object's class. @@ -381,7 +381,7 @@ public class DataHandler implements Transferable { * for this object.

                            * * This method iterates through the DataFlavors returned from - * getTransferDataFlavors, comparing each with + * {@code getTransferDataFlavors}, comparing each with * the specified flavor. * * @param flavor the requested flavor for the data @@ -407,10 +407,10 @@ public class DataHandler implements Transferable { * * The DataHandler attempts to locate a DataContentHandler * for this MIME type. If one is found, the passed in DataFlavor - * and the type of the data are passed to its getTransferData + * and the type of the data are passed to its {@code getTransferData} * method. If the DataHandler fails to locate a DataContentHandler * and the flavor specifies this object's MIME type and the - * java.io.InputStream class, this object's InputStream + * {@code java.io.InputStream} class, this object's InputStream * is returned. * Otherwise it throws an UnsupportedFlavorException.

                            * @@ -438,10 +438,10 @@ public class DataHandler implements Transferable { /** * Set the CommandMap for use by this DataHandler. - * Setting it to null causes the CommandMap to revert + * Setting it to {@code null} causes the CommandMap to revert * to the CommandMap returned by the - * CommandMap.getDefaultCommandMap method. - * Changing the CommandMap, or setting it to null, + * {@code CommandMap.getDefaultCommandMap} method. + * Changing the CommandMap, or setting it to {@code null}, * clears out any data cached from the previous CommandMap. * * @param commandMap the CommandMap to use in this DataHandler @@ -460,7 +460,7 @@ public class DataHandler implements Transferable { /** * Return the preferred commands for this type of data. - * This method calls the getPreferredCommands method + * This method calls the {@code getPreferredCommands} method * in the CommandMap associated with this instance of DataHandler. * This method returns an array that represents a subset of * available commands. In cases where multiple commands for the @@ -484,7 +484,7 @@ public class DataHandler implements Transferable { * This method returns an array containing all commands * for the type of data represented by this DataHandler. The * MIME type for the underlying data represented by this DataHandler - * is used to call through to the getAllCommands method + * is used to call through to the {@code getAllCommands} method * of the CommandMap associated with this DataHandler. * * @return the CommandInfo objects representing all the commands @@ -502,7 +502,7 @@ public class DataHandler implements Transferable { * Get the command cmdName. Use the search semantics as * defined by the CommandMap installed in this DataHandler. The * MIME type for the underlying data represented by this DataHandler - * is used to call through to the getCommand method + * is used to call through to the {@code getCommand} method * of the CommandMap associated with this DataHandler. * * @param cmdName the command name @@ -527,7 +527,7 @@ public class DataHandler implements Transferable { * If the DataHandler was instantiated with a DataSource, * this method uses a DataContentHandler to return the content * object for the data represented by this DataHandler. If no - * DataContentHandler can be found for the + * {@code DataContentHandler} can be found for the * the type of this data, the DataHandler returns an * InputStream for the data. * @@ -547,9 +547,9 @@ public class DataHandler implements Transferable { * and instantiates the corresponding command, usually * a JavaBean component. *

                            - * This method calls the CommandInfo's getCommandObject - * method with the ClassLoader used to load - * the javax.activation.DataHandler class itself. + * This method calls the CommandInfo's {@code getCommandObject} + * method with the {@code ClassLoader} used to load + * the {@code javax.activation.DataHandler} class itself. * * @param cmdinfo the CommandInfo corresponding to a command * @return the instantiated command object @@ -701,16 +701,16 @@ class DataHandlerDataSource implements DataSource { } /** - * Returns an InputStream representing this object. - * @return the InputStream + * Returns an {@code InputStream} representing this object. + * @return the {@code InputStream} */ public InputStream getInputStream() throws IOException { return dataHandler.getInputStream(); } /** - * Returns the OutputStream for this object. - * @return the OutputStream + * Returns the {@code OutputStream} for this object. + * @return the {@code OutputStream} */ public OutputStream getOutputStream() throws IOException { return dataHandler.getOutputStream(); @@ -754,7 +754,7 @@ class DataSourceDataContentHandler implements DataContentHandler { } /** - * Return the DataFlavors for this DataContentHandler. + * Return the DataFlavors for this {@code DataContentHandler}. * @return the DataFlavors */ public DataFlavor[] getTransferDataFlavors() { @@ -842,7 +842,7 @@ class ObjectDataContentHandler implements DataContentHandler { } /** - * Return the DataFlavors for this DataContentHandler. + * Return the DataFlavors for this {@code DataContentHandler}. * @return the DataFlavors */ public synchronized DataFlavor[] getTransferDataFlavors() { diff --git a/jaxws/src/java.activation/share/classes/javax/activation/MailcapCommandMap.java b/jaxws/src/java.activation/share/classes/javax/activation/MailcapCommandMap.java index 7d13a9b506f..dd7530c3121 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/MailcapCommandMap.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/MailcapCommandMap.java @@ -45,14 +45,13 @@ import com.sun.activation.registries.LogSupport; * system for mailcap file entries. When requests are made * to search for commands in the MailcapCommandMap, it searches * mailcap files in the following order: - *

                            *

                              *
                            1. Programatically added entries to the MailcapCommandMap instance. - *
                            2. The file .mailcap in the user's home directory. - *
                            3. The file <java.home>/lib/mailcap. - *
                            4. The file or resources named META-INF/mailcap. - *
                            5. The file or resource named META-INF/mailcap.default - * (usually found only in the activation.jar file). + *
                            6. The file {@code .mailcap} in the user's home directory. + *
                            7. The file {@literal <}java.home{@literal >}{@code /lib/mailcap}. + *
                            8. The file or resources named {@code META-INF/mailcap}. + *
                            9. The file or resource named {@code META-INF/mailcap.default} + * (usually found only in the {@code activation.jar} file). *
                            *

                            * Mailcap file format:

                            @@ -70,46 +69,43 @@ import com.sun.activation.registries.LogSupport; * * When a mailcap file is * parsed, the MailcapCommandMap recognizes certain parameter signatures, - * specifically those parameter names that begin with x-java-. + * specifically those parameter names that begin with {@code x-java-}. * The MailcapCommandMap uses this signature to find * command entries for inclusion into its registries. - * Parameter names with the form x-java-<name> + * Parameter names with the form {@code x-java-} * are read by the MailcapCommandMap as identifying a command - * with the name name. When the name is - * content-handler the MailcapCommandMap recognizes the class + * with the name name. When the name is {@code + * content-handler} the MailcapCommandMap recognizes the class * signified by this parameter as a DataContentHandler. * All other commands are handled generically regardless of command * name. The command implementation is specified by a fully qualified * class name of a JavaBean(tm) component. For example; a command for viewing - * some data can be specified as: x-java-view=com.foo.ViewBean.

                            + * some data can be specified as: {@code x-java-view=com.foo.ViewBean}.

                            * - * When the command name is fallback-entry, the value of - * the command may be true or false. An + * When the command name is {@code fallback-entry}, the value of + * the command may be {@code true} or {@code false}. An * entry for a MIME type that includes a parameter of - * x-java-fallback-entry=true defines fallback commands + * {@code x-java-fallback-entry=true} defines fallback commands * for that MIME type that will only be used if no non-fallback entry - * can be found. For example, an entry of the form text/*; ; - * x-java-fallback-entry=true; x-java-view=com.sun.TextViewer + * can be found. For example, an entry of the form {@code text/*; ; + * x-java-fallback-entry=true; x-java-view=com.sun.TextViewer} * specifies a view command to be used for any text MIME type. This * view command would only be used if a non-fallback view command for * the MIME type could not be found.

                            * * MailcapCommandMap aware mailcap files have the - * following general form:

                            - * - * # Comments begin with a '#' and continue to the end of the line.
                            - * <mime type>; ; <parameter list>
                            - * # Where a parameter list consists of one or more parameters,
                            - * # where parameters look like: x-java-view=com.sun.TextViewer
                            - * # and a parameter list looks like:
                            + * following general form: + *

                            {@code
                            + * # Comments begin with a '#' and continue to the end of the line.
                            + * ; ; 
                            + * # Where a parameter list consists of one or more parameters,
                            + * # where parameters look like: x-java-view=com.sun.TextViewer
                            + * # and a parameter list looks like:
                              * text/plain; ; x-java-view=com.sun.TextViewer; x-java-edit=com.sun.TextEdit
                            - * 
                            - * # Note that mailcap entries that do not contain 'x-java' parameters
                            - * # and comply to RFC 1524 are simply ignored:
                            - * image/gif; /usr/dt/bin/sdtimage %s
                            - * - *
                            - *

                            + * # Note that mailcap entries that do not contain 'x-java' parameters + * # and comply to RFC 1524 are simply ignored: + * image/gif; /usr/dt/bin/sdtimage %s + * }

                            * * @author Bart Calder * @author Bill Shannon @@ -451,7 +447,7 @@ public class MailcapCommandMap extends CommandMap { } /** - * Get the command corresponding to cmdName for the MIME type. + * Get the command corresponding to {@code cmdName} for the MIME type. * * @param mimeType the MIME type * @param cmdName the command name diff --git a/jaxws/src/java.activation/share/classes/javax/activation/MimetypesFileTypeMap.java b/jaxws/src/java.activation/share/classes/javax/activation/MimetypesFileTypeMap.java index fca50572047..430b43b1ed7 100644 --- a/jaxws/src/java.activation/share/classes/javax/activation/MimetypesFileTypeMap.java +++ b/jaxws/src/java.activation/share/classes/javax/activation/MimetypesFileTypeMap.java @@ -33,33 +33,32 @@ import com.sun.activation.registries.LogSupport; /** * This class extends FileTypeMap and provides data typing of files - * via their file extension. It uses the .mime.types format.

                            + * via their file extension. It uses the {@code .mime.types} format.

                            * * MIME types file search order:

                            * The MimetypesFileTypeMap looks in various places in the user's * system for MIME types file entries. When requests are made * to search for MIME types in the MimetypesFileTypeMap, it searches * MIME types files in the following order: - *

                            *

                              *
                            1. Programmatically added entries to the MimetypesFileTypeMap instance. - *
                            2. The file .mime.types in the user's home directory. - *
                            3. The file <java.home>/lib/mime.types. - *
                            4. The file or resources named META-INF/mime.types. - *
                            5. The file or resource named META-INF/mimetypes.default - * (usually found only in the activation.jar file). + *
                            6. The file {@code .mime.types} in the user's home directory. + *
                            7. The file {@literal <}java.home{@literal >}{@code /lib/mime.types}. + *
                            8. The file or resources named {@code META-INF/mime.types}. + *
                            9. The file or resource named {@code META-INF/mimetypes.default} + * (usually found only in the {@code activation.jar} file). *
                            *

                            - * MIME types file format:

                            + * MIME types file format: * - * - * # comments begin with a '#'
                            - * # the format is <mime type> <space separated file extensions>
                            - * # for example:
                            - * text/plain txt text TXT
                            - * # this would map file.txt, file.text, and file.TXT to
                            - * # the mime type "text/plain"
                            - *
                            + *

                            {@code
                            + * # comments begin with a '#'
                            + * # the format is  
                            + * # for example:
                            + * text/plain    txt text TXT
                            + * # this would map file.txt, file.text, and file.TXT to
                            + * # the mime type "text/plain"
                            + * }
                            * * @author Bart Calder * @author Bill Shannon @@ -277,7 +276,7 @@ public class MimetypesFileTypeMap extends FileTypeMap { /** * Return the MIME type of the file object. * The implementation in this class calls - * getContentType(f.getName()). + * {@code getContentType(f.getName())}. * * @param f the file * @return the file's MIME type diff --git a/jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java b/jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java index fbe226ca42e..8a7b535c694 100644 --- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java +++ b/jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java @@ -39,7 +39,6 @@ import static java.lang.annotation.RetentionPolicy.*; * method can be annotated with this annotation. The method on which the * PostConstruct annotation is applied MUST fulfill all of the following * criteria: - *

                            *

                              *
                            • The method MUST NOT have any parameters except in the case of * interceptors in which case it takes an InvocationContext object as diff --git a/jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java b/jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java index eff974a5e4a..2dfbb878e08 100644 --- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java +++ b/jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java @@ -38,7 +38,6 @@ import static java.lang.annotation.RetentionPolicy.*; * except the application client container in Java EE 5. The method on which * the PreDestroy annotation is applied MUST fulfill all of the following * criteria: - *

                              *

                                *
                              • The method MUST NOT have any parameters except in the case of * interceptors in which case it takes an InvocationContext object as diff --git a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/ClassFactory.java b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/ClassFactory.java index 7bdffc4051e..4347bff9f07 100644 --- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/ClassFactory.java +++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/ClassFactory.java @@ -30,6 +30,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.ref.WeakReference; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Map; import java.util.WeakHashMap; import java.util.logging.Level; @@ -85,19 +87,25 @@ public final class ClassFactory { if(consRef!=null) cons = consRef.get(); if(cons==null) { - try { - cons = clazz.getDeclaredConstructor(emptyClass); - } catch (NoSuchMethodException e) { - logger.log(Level.INFO,"No default constructor found on "+clazz,e); - NoSuchMethodError exp; - if(clazz.getDeclaringClass()!=null && !Modifier.isStatic(clazz.getModifiers())) { - exp = new NoSuchMethodError(Messages.NO_DEFAULT_CONSTRUCTOR_IN_INNER_CLASS.format(clazz.getName())); - } else { - exp = new NoSuchMethodError(e.getMessage()); + cons = AccessController.doPrivileged(new PrivilegedAction>() { + @Override + public Constructor run() { + try { + return clazz.getDeclaredConstructor(emptyClass); + } catch (NoSuchMethodException e) { + logger.log(Level.INFO,"No default constructor found on "+clazz,e); + NoSuchMethodError exp; + if(clazz.getDeclaringClass()!=null && !Modifier.isStatic(clazz.getModifiers())) { + exp = new NoSuchMethodError(Messages.NO_DEFAULT_CONSTRUCTOR_IN_INNER_CLASS + .format(clazz.getName())); + } else { + exp = new NoSuchMethodError(e.getMessage()); + } + exp.initCause(e); + throw exp; + } } - exp.initCause(e); - throw exp; - } + }); int classMod = clazz.getModifiers(); diff --git a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/DatatypeConverterInterface.java b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/DatatypeConverterInterface.java index 0f4796e0db5..80828f88e7b 100644 --- a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/DatatypeConverterInterface.java +++ b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/DatatypeConverterInterface.java @@ -38,19 +38,16 @@ package javax.xml.bind; * functionality. Calling this api repeatedly will have no effect - the * DatatypeConverter instance passed into the first invocation is the one that * will be used from then on. - *

                                * *

                                * This interface defines the parse and print methods. There is one * parse and print method for each XML schema datatype specified in the * the default binding Table 5-1 in the JAXB specification. - *

                                * *

                                * The parse and print methods defined here are invoked by the static parse * and print methods defined in the {@link DatatypeConverter DatatypeConverter} * class. - *

                                * *

                                * A parse method for a XML schema datatype must be capable of converting any @@ -60,21 +57,23 @@ package javax.xml.bind; * If an error is encountered during conversion, then an IllegalArgumentException * or a subclass of IllegalArgumentException must be thrown by the method. * - *

                                - * *

                                * A print method for a XML schema datatype can output any lexical * representation that is valid with respect to the XML schema datatype. * If an error is encountered during conversion, then an IllegalArgumentException, * or a subclass of IllegalArgumentException must be thrown by the method. - *

                                * + *

                                * The prefix xsd: is used to refer to XML schema datatypes * XML Schema Part2: Datatypes * specification. * - *

                                - * @author

                                • Sekhar Vajjhala, Sun Microsystems, Inc.
                                • Joe Fialli, Sun Microsystems Inc.
                                • Kohsuke Kawaguchi, Sun Microsystems, Inc.
                                • Ryan Shoemaker,Sun Microsystems Inc.
                                + * @author
                                  + *
                                • Sekhar Vajjhala, Sun Microsystems, Inc.
                                • + *
                                • Joe Fialli, Sun Microsystems Inc.
                                • + *
                                • Kohsuke Kawaguchi, Sun Microsystems, Inc.
                                • + *
                                • Ryan Shoemaker,Sun Microsystems Inc.
                                • + *
                                * @see DatatypeConverter * @see ParseConversionEvent * @see PrintConversionEvent @@ -83,7 +82,6 @@ package javax.xml.bind; public interface DatatypeConverterInterface { /** - *

                                * Convert the string argument into a string. * @param lexicalXSDString * A lexical representation of the XML Schema datatype xsd:string @@ -93,91 +91,83 @@ public interface DatatypeConverterInterface { public String parseString( String lexicalXSDString ); /** - *

                                * Convert the string argument into a BigInteger value. * @param lexicalXSDInteger * A string containing a lexical representation of * xsd:integer. * @return * A BigInteger value represented by the string argument. - * @throws NumberFormatException lexicalXSDInteger is not a valid string representation of a {@link java.math.BigInteger} value. + * @throws NumberFormatException {@code lexicalXSDInteger} is not a valid string representation of a {@link java.math.BigInteger} value. */ public java.math.BigInteger parseInteger( String lexicalXSDInteger ); /** - *

                                * Convert the string argument into an int value. * @param lexicalXSDInt * A string containing a lexical representation of * xsd:int. * @return * An int value represented byte the string argument. - * @throws NumberFormatException lexicalXSDInt is not a valid string representation of an int value. + * @throws NumberFormatException {@code lexicalXSDInt} is not a valid string representation of an {@code int} value. */ public int parseInt( String lexicalXSDInt ); /** - *

                                * Converts the string argument into a long value. * @param lexicalXSDLong * A string containing lexical representation of * xsd:long. * @return * A long value represented by the string argument. - * @throws NumberFormatException lexicalXSDLong is not a valid string representation of a long value. + * @throws NumberFormatException {@code lexicalXSDLong} is not a valid string representation of a {@code long} value. */ public long parseLong( String lexicalXSDLong ); /** - *

                                * Converts the string argument into a short value. * @param lexicalXSDShort * A string containing lexical representation of * xsd:short. * @return * A short value represented by the string argument. - * @throws NumberFormatException lexicalXSDShort is not a valid string representation of a short value. + * @throws NumberFormatException {@code lexicalXSDShort} is not a valid string representation of a {@code short} value. */ public short parseShort( String lexicalXSDShort ); /** - *

                                * Converts the string argument into a BigDecimal value. * @param lexicalXSDDecimal * A string containing lexical representation of * xsd:decimal. * @return * A BigDecimal value represented by the string argument. - * @throws NumberFormatException lexicalXSDDecimal is not a valid string representation of {@link java.math.BigDecimal}. + * @throws NumberFormatException {@code lexicalXSDDecimal} is not a valid string representation of {@link java.math.BigDecimal}. */ public java.math.BigDecimal parseDecimal( String lexicalXSDDecimal ); /** - *

                                * Converts the string argument into a float value. * @param lexicalXSDFloat * A string containing lexical representation of * xsd:float. * @return * A float value represented by the string argument. - * @throws NumberFormatException lexicalXSDFloat is not a valid string representation of a float value. + * @throws NumberFormatException {@code lexicalXSDFloat} is not a valid string representation of a {@code float} value. */ public float parseFloat( String lexicalXSDFloat ); /** - *

                                * Converts the string argument into a double value. * @param lexicalXSDDouble * A string containing lexical representation of * xsd:double. * @return * A double value represented by the string argument. - * @throws NumberFormatException lexicalXSDDouble is not a valid string representation of a double value. + * @throws NumberFormatException {@code lexicalXSDDouble} is not a valid string representation of a {@code double} value. */ public double parseDouble( String lexicalXSDDouble ); /** - *

                                * Converts the string argument into a boolean value. * @param lexicalXSDBoolean * A string containing lexical representation of @@ -189,20 +179,18 @@ public interface DatatypeConverterInterface { public boolean parseBoolean( String lexicalXSDBoolean ); /** - *

                                * Converts the string argument into a byte value. * @param lexicalXSDByte * A string containing lexical representation of * xsd:byte. * @return * A byte value represented by the string argument. - * @throws NumberFormatException lexicalXSDByte does not contain a parseable byte. + * @throws NumberFormatException {@code lexicalXSDByte} does not contain a parseable byte. * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:byte. */ public byte parseByte( String lexicalXSDByte ); /** - *

                                * Converts the string argument into a QName value. * *

                                @@ -222,7 +210,6 @@ public interface DatatypeConverterInterface { javax.xml.namespace.NamespaceContext nsc); /** - *

                                * Converts the string argument into a Calendar value. * @param lexicalXSDDateTime * A string containing lexical representation of @@ -234,7 +221,6 @@ public interface DatatypeConverterInterface { public java.util.Calendar parseDateTime( String lexicalXSDDateTime ); /** - *

                                * Converts the string argument into an array of bytes. * @param lexicalXSDBase64Binary * A string containing lexical representation @@ -246,7 +232,6 @@ public interface DatatypeConverterInterface { public byte[] parseBase64Binary( String lexicalXSDBase64Binary ); /** - *

                                * Converts the string argument into an array of bytes. * @param lexicalXSDHexBinary * A string containing lexical representation of @@ -258,7 +243,6 @@ public interface DatatypeConverterInterface { public byte[] parseHexBinary( String lexicalXSDHexBinary ); /** - *

                                * Converts the string argument into a long value. * @param lexicalXSDUnsignedInt * A string containing lexical representation @@ -270,7 +254,6 @@ public interface DatatypeConverterInterface { public long parseUnsignedInt( String lexicalXSDUnsignedInt ); /** - *

                                * Converts the string argument into an int value. * @param lexicalXSDUnsignedShort * A string containing lexical @@ -282,7 +265,6 @@ public interface DatatypeConverterInterface { public int parseUnsignedShort( String lexicalXSDUnsignedShort ); /** - *

                                * Converts the string argument into a Calendar value. * @param lexicalXSDTime * A string containing lexical representation of @@ -294,7 +276,6 @@ public interface DatatypeConverterInterface { public java.util.Calendar parseTime( String lexicalXSDTime ); /** - *

                                * Converts the string argument into a Calendar value. * @param lexicalXSDDate * A string containing lexical representation of @@ -306,7 +287,6 @@ public interface DatatypeConverterInterface { public java.util.Calendar parseDate( String lexicalXSDDate ); /** - *

                                * Return a string containing the lexical representation of the * simple type. * @param lexicalXSDAnySimpleType @@ -319,7 +299,6 @@ public interface DatatypeConverterInterface { public String parseAnySimpleType( String lexicalXSDAnySimpleType ); /** - *

                                * Converts the string argument into a string. * @param val * A string value. @@ -329,7 +308,6 @@ public interface DatatypeConverterInterface { public String printString( String val ); /** - *

                                * Converts a BigInteger value into a string. * @param val * A BigInteger value @@ -340,7 +318,6 @@ public interface DatatypeConverterInterface { public String printInteger( java.math.BigInteger val ); /** - *

                                * Converts an int value into a string. * @param val * An int value @@ -351,7 +328,6 @@ public interface DatatypeConverterInterface { /** - *

                                * Converts a long value into a string. * @param val * A long value @@ -361,7 +337,6 @@ public interface DatatypeConverterInterface { public String printLong( long val ); /** - *

                                * Converts a short value into a string. * @param val * A short value @@ -371,7 +346,6 @@ public interface DatatypeConverterInterface { public String printShort( short val ); /** - *

                                * Converts a BigDecimal value into a string. * @param val * A BigDecimal value @@ -382,7 +356,6 @@ public interface DatatypeConverterInterface { public String printDecimal( java.math.BigDecimal val ); /** - *

                                * Converts a float value into a string. * @param val * A float value @@ -392,7 +365,6 @@ public interface DatatypeConverterInterface { public String printFloat( float val ); /** - *

                                * Converts a double value into a string. * @param val * A double value @@ -402,7 +374,6 @@ public interface DatatypeConverterInterface { public String printDouble( double val ); /** - *

                                * Converts a boolean value into a string. * @param val * A boolean value @@ -412,7 +383,6 @@ public interface DatatypeConverterInterface { public String printBoolean( boolean val ); /** - *

                                * Converts a byte value into a string. * @param val * A byte value @@ -422,7 +392,6 @@ public interface DatatypeConverterInterface { public String printByte( byte val ); /** - *

                                * Converts a QName instance into a string. * @param val * A QName value @@ -437,7 +406,6 @@ public interface DatatypeConverterInterface { javax.xml.namespace.NamespaceContext nsc ); /** - *

                                * Converts a Calendar value into a string. * @param val * A Calendar value @@ -448,7 +416,6 @@ public interface DatatypeConverterInterface { public String printDateTime( java.util.Calendar val ); /** - *

                                * Converts an array of bytes into a string. * @param val * an array of bytes @@ -459,7 +426,6 @@ public interface DatatypeConverterInterface { public String printBase64Binary( byte[] val ); /** - *

                                * Converts an array of bytes into a string. * @param val * an array of bytes @@ -470,7 +436,6 @@ public interface DatatypeConverterInterface { public String printHexBinary( byte[] val ); /** - *

                                * Converts a long value into a string. * @param val * A long value @@ -480,7 +445,6 @@ public interface DatatypeConverterInterface { public String printUnsignedInt( long val ); /** - *

                                * Converts an int value into a string. * @param val * An int value @@ -490,7 +454,6 @@ public interface DatatypeConverterInterface { public String printUnsignedShort( int val ); /** - *

                                * Converts a Calendar value into a string. * @param val * A Calendar value @@ -501,7 +464,6 @@ public interface DatatypeConverterInterface { public String printTime( java.util.Calendar val ); /** - *

                                * Converts a Calendar value into a string. * @param val * A Calendar value @@ -512,7 +474,6 @@ public interface DatatypeConverterInterface { public String printDate( java.util.Calendar val ); /** - *

                                * Converts a string value into a string. * @param val * A string value diff --git a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/JAXBPermission.java b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/JAXBPermission.java index 42dedafaaa6..a4d221d1af3 100644 --- a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/JAXBPermission.java +++ b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/JAXBPermission.java @@ -40,7 +40,6 @@ import java.security.BasicPermission; * The following table lists all the possible {@code JAXBPermission} target names, * and for each provides a description of what the permission allows * and a discussion of the risks of granting code the permission. - *

                                * * * diff --git a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/XmlElement.java b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/XmlElement.java index 8f2d881236b..aa752d31040 100644 --- a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/XmlElement.java +++ b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/annotation/XmlElement.java @@ -36,7 +36,7 @@ import static java.lang.annotation.RetentionPolicy.*; /** * Maps a JavaBean property to a XML element derived from property name. * - *

                                Usage

                                + *

                                Usage *

                                * @XmlElement annotation can be used with the following program * elements: @@ -44,8 +44,6 @@ import static java.lang.annotation.RetentionPolicy.*; *

                              • a JavaBean property
                              • *
                              • non static, non transient field
                              • *
                              • within {@link XmlElements} - *

                                - * * * * The usage is subject to the following constraints: @@ -79,7 +77,7 @@ import static java.lang.annotation.RetentionPolicy.*; *

                                  *     //Example: Code fragment
                                  *     public class USPrice {
                                - *         @XmlElement(name="itemprice")
                                + *        {@literal @}XmlElement(name="itemprice")
                                  *         public java.math.BigDecimal price;
                                  *     }
                                  * {@code
                                @@ -95,10 +93,9 @@ import static java.lang.annotation.RetentionPolicy.*;
                                  *
                                  *  Example 2:  Map a field to a nillable element.
                                  *   
                                - *
                                  *     //Example: Code fragment
                                  *     public class USPrice {
                                - *         @XmlElement(nillable=true)
                                + *        {@literal @}XmlElement(nillable=true)
                                  *         public java.math.BigDecimal price;
                                  *     }
                                  * {@code
                                @@ -113,10 +110,9 @@ import static java.lang.annotation.RetentionPolicy.*;
                                  * 

                                * Example 3: Map a field to a nillable, required element. *

                                - *
                                  *     //Example: Code fragment
                                  *     public class USPrice {
                                - *         @XmlElement(nillable=true, required=true)
                                + *        {@literal @}XmlElement(nillable=true, required=true)
                                  *         public java.math.BigDecimal price;
                                  *     }
                                  * {@code
                                @@ -134,7 +130,6 @@ import static java.lang.annotation.RetentionPolicy.*;
                                  * 

                                * See Example 6 in @{@link XmlType}. * - *

                                * @author Sekhar Vajjhala, Sun Microsystems, Inc. * @since 1.6, JAXB 2.0 */ diff --git a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/attachment/AttachmentMarshaller.java b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/attachment/AttachmentMarshaller.java index dd291917a70..8edbc8812eb 100644 --- a/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/attachment/AttachmentMarshaller.java +++ b/jaxws/src/java.xml.bind/share/classes/javax/xml/bind/attachment/AttachmentMarshaller.java @@ -29,22 +29,22 @@ import javax.activation.DataHandler; import javax.xml.bind.Marshaller; /** - *

                                Enable JAXB marshalling to optimize storage of binary data.

                                + *

                                Enable JAXB marshalling to optimize storage of binary data. * *

                                This API enables an efficient cooperative creation of optimized * binary data formats between a JAXB marshalling process and a MIME-based package * processor. A JAXB implementation marshals the root body of a MIME-based package, * delegating the creation of referenceable MIME parts to - * the MIME-based package processor that implements this abstraction.

                                + * the MIME-based package processor that implements this abstraction. * *

                                XOP processing is enabled when {@link #isXOPPackage()} is true. * See {@link #addMtomAttachment(DataHandler, String, String)} for details. - *

                                + * * *

                                WS-I Attachment Profile 1.0 is supported by * {@link #addSwaRefAttachment(DataHandler)} being called by the * marshaller for each JAXB property related to - * {http://ws-i.org/profiles/basic/1.1/xsd}swaRef.

                                + * {http://ws-i.org/profiles/basic/1.1/xsd}swaRef. * * * @author Marc Hadley @@ -60,33 +60,33 @@ import javax.xml.bind.Marshaller; public abstract class AttachmentMarshaller { /** - *

                                Consider MIME content data for optimized binary storage as an attachment. + *

                                Consider MIME content {@code data} for optimized binary storage as an attachment. * *

                                * This method is called by JAXB marshal process when {@link #isXOPPackage()} is - * true, for each element whose datatype is "base64Binary", as described in + * {@code true}, for each element whose datatype is "base64Binary", as described in * Step 3 in * Creating XOP Packages. * *

                                - * The method implementor determines whether data shall be attached separately + * The method implementor determines whether {@code data} shall be attached separately * or inlined as base64Binary data. If the implementation chooses to optimize the storage - * of the binary data as a MIME part, it is responsible for attaching data to the + * of the binary data as a MIME part, it is responsible for attaching {@code data} to the * MIME-based package, and then assigning an unique content-id, cid, that identifies * the MIME part within the MIME message. This method returns the cid, * which enables the JAXB marshaller to marshal a XOP element that refers to that cid in place * of marshalling the binary data. When the method returns null, the JAXB marshaller - * inlines data as base64binary data. + * inlines {@code data} as base64binary data. * *

                                * The caller of this method is required to meet the following constraint. - * If the element infoset item containing data has the attribute - * xmime:contentType or if the JAXB property/field representing - * datais annotated with a known MIME type, - * data.getContentType() should be set to that MIME type. + * If the element infoset item containing {@code data} has the attribute + * {@code xmime:contentType} or if the JAXB property/field representing + * {@code data} is annotated with a known MIME type, + * {@code data.getContentType()} should be set to that MIME type. * *

                                - * The elementNamespace and elementLocalName + * The {@code elementNamespace} and {@code elementLocalName} * parameters provide the * context that contains the binary data. This information could * be used by the MIME-based package processor to determine if the @@ -101,7 +101,7 @@ public abstract class AttachmentMarshaller { * The local name of the element. Always a non-null valid string. * * @return - * a valid content-id URI (see RFC 2387) that identifies the attachment containing data. + * a valid content-id URI (see RFC 2387) that identifies the attachment containing {@code data}. * Otherwise, null if the attachment was not added and should instead be inlined in the message. * * @see XML-binary Optimized Packaging @@ -110,12 +110,12 @@ public abstract class AttachmentMarshaller { public abstract String addMtomAttachment(DataHandler data, String elementNamespace, String elementLocalName); /** - *

                                Consider binary data for optimized binary storage as an attachment. + *

                                Consider binary {@code data} for optimized binary storage as an attachment. * - *

                                Since content type is not known, the attachment's MIME content type must be set to "application/octet-stream".

                                + *

                                Since content type is not known, the attachment's MIME content type must be set to "application/octet-stream". * *

                                - * The elementNamespace and elementLocalName + * The {@code elementNamespace} and {@code elementLocalName} * parameters provide the * context that contains the binary data. This information could * be used by the MIME-based package processor to determine if the @@ -146,21 +146,21 @@ public abstract class AttachmentMarshaller { * The local name of the element. Always a non-null valid string. * * @return content-id URI, cid, to the attachment containing - * data or null if data should be inlined. + * {@code data} or null if data should be inlined. * * @see #addMtomAttachment(DataHandler, String, String) */ public abstract String addMtomAttachment(byte[] data, int offset, int length, String mimeType, String elementNamespace, String elementLocalName); /** - *

                                Read-only property that returns true if JAXB marshaller should enable XOP creation.

                                + *

                                Read-only property that returns true if JAXB marshaller should enable XOP creation. * *

                                This value must not change during the marshalling process. When this - * value is true, the addMtomAttachment(...) method + * value is true, the {@code addMtomAttachment(...)} method * is invoked when the appropriate binary datatypes are encountered by - * the marshal process.

                                + * the marshal process. * - *

                                Marshaller.marshal() must throw IllegalStateException if this value is true + *

                                Marshaller.marshal() must throw IllegalStateException if this value is {@code true} * and the XML content to be marshalled violates Step 1 in * Creating XOP Pacakges * http://www.w3.org/TR/2005/REC-xop10-20050125/#creating_xop_packages. @@ -168,18 +168,18 @@ public abstract class AttachmentMarshaller { * [namespace name] of "http://www.w3.org/2004/08/xop/include" and a [local name] of Include" * *

                                When this method returns true and during the marshal process - * at least one call to addMtomAttachment(...) returns + * at least one call to {@code addMtomAttachment(...)} returns * a content-id, the MIME-based package processor must label the * root part with the application/xop+xml media type as described in * Step 5 of - * Creating XOP Pacakges.

                                + * Creating XOP Pacakges. * * @return true when MIME context is a XOP Package. */ public boolean isXOPPackage() { return false; } /** - *

                                Add MIME data as an attachment and return attachment's content-id, cid.

                                + *

                                Add MIME {@code data} as an attachment and return attachment's content-id, cid. * *

                                * This method is called by JAXB marshal process for each element/attribute typed as @@ -188,7 +188,7 @@ public abstract class AttachmentMarshaller { * MIME attachment, and generating a content-id, cid, that uniquely identifies the attachment * within the MIME-based package. * - *

                                Caller inserts the returned content-id, cid, into the XML content being marshalled.

                                + *

                                Caller inserts the returned content-id, cid, into the XML content being marshalled. * * @param data * represents the data to be attached. Must be non-null. diff --git a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/Engine.java b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/Engine.java index 516f51107c0..29b94bf98c2 100644 --- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/Engine.java +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/Engine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,7 +108,8 @@ public class Engine { } public Thread newThread(Runnable r) { - Thread t = new Thread(null, r, namePrefix + threadNumber.getAndIncrement(), 0); + Thread t = ThreadHelper.createNewThread(r); + t.setName(namePrefix + threadNumber.getAndIncrement()); if (!t.isDaemon()) { t.setDaemon(true); } diff --git a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/ThreadHelper.java b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/ThreadHelper.java new file mode 100644 index 00000000000..1c74d10a220 --- /dev/null +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/pipe/ThreadHelper.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.api.pipe; + +import java.lang.reflect.Constructor; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Simple utility class to instantiate correct Thread instance + * depending on runtime context (jdk/non-jdk usage) + * + * @author miroslav.kos@oracle.com + */ +final class ThreadHelper { + + private static final String SAFE_THREAD_NAME = "sun.misc.ManagedLocalsThread"; + private static final Constructor THREAD_CONSTRUCTOR; + + // no instantiating wanted + private ThreadHelper() { + } + + static { + THREAD_CONSTRUCTOR = AccessController.doPrivileged( + new PrivilegedAction () { + @Override + public Constructor run() { + try { + Class cls = Class.forName(SAFE_THREAD_NAME); + if (cls != null) { + return cls.getConstructor(Runnable.class); + } + } catch (ClassNotFoundException ignored) { + } catch (NoSuchMethodException ignored) { + } + return null; + } + } + ); + } + + static Thread createNewThread(final Runnable r) { + if (isJDKInternal()) { + return AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Thread run() { + try { + return (Thread) THREAD_CONSTRUCTOR.newInstance(r); + } catch (Exception e) { + return new Thread(r); + } + } + } + ); + } else { + return new Thread(r); + } + } + + private static boolean isJDKInternal() { + String className = ThreadHelper.class.getName(); + return className.contains(".internal."); + } +} diff --git a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java index 1c054547a4e..2b384af2919 100644 --- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -894,15 +894,6 @@ public class WSServiceDelegate extends WSService { return wsdlService; } - static class DaemonThreadFactory implements ThreadFactory { - @Override - public Thread newThread(Runnable r) { - Thread daemonThread = new Thread(r); - daemonThread.setDaemon(Boolean.TRUE); - return daemonThread; - } - } - protected static final WebServiceFeature[] EMPTY_FEATURES = new WebServiceFeature[0]; private static ClassLoader getDelegatingLoader(ClassLoader loader1, ClassLoader loader2) { diff --git a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/BindingHelper.java b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/BindingHelper.java index 84047b67d24..a69edb430a5 100644 --- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/BindingHelper.java +++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/BindingHelper.java @@ -36,9 +36,6 @@ import com.sun.xml.internal.bind.marshaller.SAX2DOMEx; //TODO DOMHeader DOMMessage SAAJMessage StatefulInstanceResolver import com.sun.xml.internal.bind.unmarshaller.DOMScanner; -//TODO MtomCodec -import com.sun.xml.internal.bind.v2.runtime.output.Encoded; - //TODO ExceptionBean import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper; diff --git a/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/InitParam.java b/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/InitParam.java index 43088e25e20..15e276d7d0f 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/InitParam.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/InitParam.java @@ -27,7 +27,7 @@ package javax.jws.soap; /** * @since 1.6 - * @Deprecated + * @deprecated */ @Deprecated public @interface InitParam { String name(); diff --git a/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandler.java b/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandler.java index fe974e3e090..79dea42b59e 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandler.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandler.java @@ -27,7 +27,7 @@ package javax.jws.soap; /** * @since 1.6 - * @Deprecated + * @deprecated */ @Deprecated public @interface SOAPMessageHandler { String name() default ""; diff --git a/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandlers.java b/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandlers.java index c255f756c1a..fa104740c44 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandlers.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/jws/soap/SOAPMessageHandlers.java @@ -29,7 +29,7 @@ import static java.lang.annotation.ElementType.*; /** * @since 1.6 - * @Deprecated + * @deprecated */ @Retention(value=RetentionPolicy.RUNTIME) @Target({TYPE}) diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/AttachmentPart.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/AttachmentPart.java index ae3390c82c1..f597e0dc866 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/AttachmentPart.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/AttachmentPart.java @@ -32,54 +32,53 @@ import java.util.Iterator; import javax.activation.DataHandler; /** - * A single attachment to a SOAPMessage object. A SOAPMessage - * object may contain zero, one, or many AttachmentPart objects. - * Each AttachmentPart object consists of two parts, + * A single attachment to a {@code SOAPMessage} object. A {@code SOAPMessage} + * object may contain zero, one, or many {@code AttachmentPart} objects. + * Each {@code AttachmentPart} object consists of two parts, * application-specific content and associated MIME headers. The * MIME headers consists of name/value pairs that can be used to * identify and describe the content. *

                                - * An AttachmentPart object must conform to certain standards. + * An {@code AttachmentPart} object must conform to certain standards. *

                                  *
                                1. It must conform to * MIME [RFC2045] standards *
                                2. It MUST contain content *
                                3. The header portion MUST include the following header: *
                                    - *
                                  • Content-Type
                                    + *
                                  • {@code Content-Type}
                                    * This header identifies the type of data in the content of an - * AttachmentPart object and MUST conform to [RFC2045]. + * {@code AttachmentPart} object and MUST conform to [RFC2045]. * The following is an example of a Content-Type header: *
                                      *       Content-Type:  application/xml
                                      *       
                                    - * The following line of code, in which ap is an - * AttachmentPart object, sets the header shown in + * The following line of code, in which {@code ap} is an + * {@code AttachmentPart} object, sets the header shown in * the previous example. *
                                      *       ap.setMimeHeader("Content-Type", "application/xml");
                                      *       
                                    - *

                                    *

                                  *
                                *

                                - * There are no restrictions on the content portion of an - * AttachmentPart object. The content may be anything from a + * There are no restrictions on the content portion of an {@code + * AttachmentPart} object. The content may be anything from a * simple plain text object to a complex XML document or image file. * *

                                - * An AttachmentPart object is created with the method - * SOAPMessage.createAttachmentPart. After setting its MIME headers, - * the AttachmentPart object is added to the message - * that created it with the method SOAPMessage.addAttachmentPart. + * An {@code AttachmentPart} object is created with the method + * {@code SOAPMessage.createAttachmentPart}. After setting its MIME headers, + * the {@code AttachmentPart} object is added to the message + * that created it with the method {@code SOAPMessage.addAttachmentPart}. * *

                                - * The following code fragment, in which m is a - * SOAPMessage object and contentStringl is a - * String, creates an instance of AttachmentPart, - * sets the AttachmentPart object with some content and - * header information, and adds the AttachmentPart object to - * the SOAPMessage object. + * The following code fragment, in which {@code m} is a + * {@code SOAPMessage} object and {@code contentStringl} is a + * {@code String}, creates an instance of {@code AttachmentPart}, + * sets the {@code AttachmentPart} object with some content and + * header information, and adds the {@code AttachmentPart} object to + * the {@code SOAPMessage} object. *

                                  *     AttachmentPart ap1 = m.createAttachmentPart();
                                  *     ap1.setContent(contentString1, "text/plain");
                                @@ -89,7 +88,7 @@ import javax.activation.DataHandler;
                                  *
                                  * 

                                * The following code fragment creates and adds a second - * AttachmentPart instance to the same message. jpegData + * {@code AttachmentPart} instance to the same message. {@code jpegData} * is a binary byte buffer representing the jpeg file. *

                                  *     AttachmentPart ap2 = m.createAttachmentPart();
                                @@ -98,19 +97,19 @@ import javax.activation.DataHandler;
                                  *     m.addAttachmentPart(ap2);
                                  * 
                                *

                                - * The getContent method retrieves the contents and header from - * an AttachmentPart object. Depending on the - * DataContentHandler objects present, the returned - * Object can either be a typed Java object corresponding - * to the MIME type or an InputStream object that contains the + * The {@code getContent} method retrieves the contents and header from + * an {@code AttachmentPart} object. Depending on the + * {@code DataContentHandler} objects present, the returned + * {@code Object} can either be a typed Java object corresponding + * to the MIME type or an {@code InputStream} object that contains the * content as bytes. *

                                  *     String content1 = ap1.getContent();
                                  *     java.io.InputStream content2 = ap2.getContent();
                                  * 
                                * - * The method clearContent removes all the content from an - * AttachmentPart object but does not affect its header information. + * The method {@code clearContent} removes all the content from an + * {@code AttachmentPart} object but does not affect its header information. *
                                  *     ap1.clearContent();
                                  * 
                                @@ -120,10 +119,10 @@ import javax.activation.DataHandler; public abstract class AttachmentPart { /** - * Returns the number of bytes in this AttachmentPart + * Returns the number of bytes in this {@code AttachmentPart} * object. * - * @return the size of this AttachmentPart object in bytes + * @return the size of this {@code AttachmentPart} object in bytes * or -1 if the size cannot be determined * @exception SOAPException if the content of this attachment is * corrupted of if there was an exception while trying @@ -132,52 +131,52 @@ public abstract class AttachmentPart { public abstract int getSize() throws SOAPException; /** - * Clears out the content of this AttachmentPart object. + * Clears out the content of this {@code AttachmentPart} object. * The MIME header portion is left untouched. */ public abstract void clearContent(); /** - * Gets the content of this AttachmentPart object as a Java + * Gets the content of this {@code AttachmentPart} object as a Java * object. The type of the returned Java object depends on (1) the - * DataContentHandler object that is used to interpret the bytes - * and (2) the Content-Type given in the header. + * {@code DataContentHandler} object that is used to interpret the bytes + * and (2) the {@code Content-Type} given in the header. *

                                * For the MIME content types "text/plain", "text/html" and "text/xml", the - * DataContentHandler object does the conversions to and + * {@code DataContentHandler} object does the conversions to and * from the Java types corresponding to the MIME types. - * For other MIME types,the DataContentHandler object - * can return an InputStream object that contains the content data + * For other MIME types,the {@code DataContentHandler} object + * can return an {@code InputStream} object that contains the content data * as raw bytes. *

                                * A SAAJ-compliant implementation must, as a minimum, return a - * java.lang.String object corresponding to any content - * stream with a Content-Type value of - * text/plain, a - * javax.xml.transform.stream.StreamSource object corresponding to a - * content stream with a Content-Type value of - * text/xml, a java.awt.Image object + * {@code java.lang.String} object corresponding to any content + * stream with a {@code Content-Type} value of + * {@code text/plain}, a + * {@code javax.xml.transform.stream.StreamSource} object corresponding to a + * content stream with a {@code Content-Type} value of + * {@code text/xml}, a {@code java.awt.Image} object * corresponding to a content stream with a - * Content-Type value of image/gif or - * image/jpeg. For those content types that an - * installed DataContentHandler object does not understand, the - * DataContentHandler object is required to return a - * java.io.InputStream object with the raw bytes. + * {@code Content-Type} value of {@code image/gif} or + * {@code image/jpeg}. For those content types that an + * installed {@code DataContentHandler} object does not understand, the + * {@code DataContentHandler} object is required to return a + * {@code java.io.InputStream} object with the raw bytes. * - * @return a Java object with the content of this AttachmentPart + * @return a Java object with the content of this {@code AttachmentPart} * object * * @exception SOAPException if there is no content set into this - * AttachmentPart object or if there was a data + * {@code AttachmentPart} object or if there was a data * transformation error */ public abstract Object getContent() throws SOAPException; /** - * Gets the content of this AttachmentPart object as an - * InputStream as if a call had been made to getContent and no - * DataContentHandler had been registered for the - * content-type of this AttachmentPart. + * Gets the content of this {@code AttachmentPart} object as an + * InputStream as if a call had been made to {@code getContent} and no + * {@code DataContentHandler} had been registered for the + * {@code content-type} of this {@code AttachmentPart}. *

                                * Note that reading from the returned InputStream would result in consuming * the data in the stream. It is the responsibility of the caller to reset @@ -185,11 +184,11 @@ public abstract class AttachmentPart { * of the raw attachment content is required then the {@link #getRawContentBytes} API * should be used instead. * - * @return an InputStream from which the raw data contained by - * the AttachmentPart can be accessed. + * @return an {@code InputStream} from which the raw data contained by + * the {@code AttachmentPart} can be accessed. * * @throws SOAPException if there is no content set into this - * AttachmentPart object or if there was a data + * {@code AttachmentPart} object or if there was a data * transformation error. * * @since 1.6, SAAJ 1.3 @@ -198,16 +197,16 @@ public abstract class AttachmentPart { public abstract InputStream getRawContent() throws SOAPException; /** - * Gets the content of this AttachmentPart object as a - * byte[] array as if a call had been made to getContent and no - * DataContentHandler had been registered for the - * content-type of this AttachmentPart. + * Gets the content of this {@code AttachmentPart} object as a + * byte[] array as if a call had been made to {@code getContent} and no + * {@code DataContentHandler} had been registered for the + * {@code content-type} of this {@code AttachmentPart}. * - * @return a byte[] array containing the raw data of the - * AttachmentPart. + * @return a {@code byte[]} array containing the raw data of the + * {@code AttachmentPart}. * * @throws SOAPException if there is no content set into this - * AttachmentPart object or if there was a data + * {@code AttachmentPart} object or if there was a data * transformation error. * * @since 1.6, SAAJ 1.3 @@ -215,16 +214,16 @@ public abstract class AttachmentPart { public abstract byte[] getRawContentBytes() throws SOAPException; /** - * Returns an InputStream which can be used to obtain the - * content of AttachmentPart as Base64 encoded + * Returns an {@code InputStream} which can be used to obtain the + * content of {@code AttachmentPart} as Base64 encoded * character data, this method would base64 encode the raw bytes * of the attachment and return. * - * @return an InputStream from which the Base64 encoded - * AttachmentPart can be read. + * @return an {@code InputStream} from which the Base64 encoded + * {@code AttachmentPart} can be read. * * @throws SOAPException if there is no content set into this - * AttachmentPart object or if there was a data + * {@code AttachmentPart} object or if there was a data * transformation error. * * @since 1.6, SAAJ 1.3 @@ -233,11 +232,11 @@ public abstract class AttachmentPart { /** * Sets the content of this attachment part to that of the given - * Object and sets the value of the Content-Type + * {@code Object} and sets the value of the {@code Content-Type} * header to the given type. The type of the - * Object should correspond to the value given for the - * Content-Type. This depends on the particular - * set of DataContentHandler objects in use. + * {@code Object} should correspond to the value given for the + * {@code Content-Type}. This depends on the particular + * set of {@code DataContentHandler} objects in use. * * * @param object the Java object that makes up the content for @@ -247,7 +246,7 @@ public abstract class AttachmentPart { * * @exception IllegalArgumentException may be thrown if the contentType * does not match the type of the content object, or if there - * was no DataContentHandler object for this + * was no {@code DataContentHandler} object for this * content object * * @see #getContent @@ -256,31 +255,31 @@ public abstract class AttachmentPart { /** * Sets the content of this attachment part to that contained by the - * InputStream content and sets the value of the - * Content-Type header to the value contained in - * contentType. + * {@code InputStream} {@code content} and sets the value of the + * {@code Content-Type} header to the value contained in + * {@code contentType}. *

                                * A subsequent call to getSize() may not be an exact measure * of the content size. * * @param content the raw data to add to the attachment part - * @param contentType the value to set into the Content-Type + * @param contentType the value to set into the {@code Content-Type} * header * * @exception SOAPException if an there is an error in setting the content - * @exception NullPointerException if content is null + * @exception NullPointerException if {@code content} is null * @since 1.6, SAAJ 1.3 */ public abstract void setRawContent(InputStream content, String contentType) throws SOAPException; /** * Sets the content of this attachment part to that contained by the - * byte[] array content and sets the value of the - * Content-Type header to the value contained in - * contentType. + * {@code byte[]} array {@code content} and sets the value of the + * {@code Content-Type} header to the value contained in + * {@code contentType}. * * @param content the raw data to add to the attachment part - * @param contentType the value to set into the Content-Type + * @param contentType the value to set into the {@code Content-Type} * header * @param offset the offset in the byte array of the content * @param len the number of bytes that form the content @@ -296,20 +295,20 @@ public abstract class AttachmentPart { /** * Sets the content of this attachment part from the Base64 source - * InputStream and sets the value of the - * Content-Type header to the value contained in - * contentType, This method would first decode the base64 + * {@code InputStream} and sets the value of the + * {@code Content-Type} header to the value contained in + * {@code contentType}, This method would first decode the base64 * input and write the resulting raw bytes to the attachment. *

                                * A subsequent call to getSize() may not be an exact measure * of the content size. * * @param content the base64 encoded data to add to the attachment part - * @param contentType the value to set into the Content-Type + * @param contentType the value to set into the {@code Content-Type} * header * * @exception SOAPException if an there is an error in setting the content - * @exception NullPointerException if content is null + * @exception NullPointerException if {@code content} is null * * @since 1.6, SAAJ 1.3 */ @@ -318,30 +317,30 @@ public abstract class AttachmentPart { /** - * Gets the DataHandler object for this AttachmentPart + * Gets the {@code DataHandler} object for this {@code AttachmentPart} * object. * - * @return the DataHandler object associated with this - * AttachmentPart object + * @return the {@code DataHandler} object associated with this + * {@code AttachmentPart} object * * @exception SOAPException if there is no data in - * this AttachmentPart object + * this {@code AttachmentPart} object */ public abstract DataHandler getDataHandler() throws SOAPException; /** - * Sets the given DataHandler object as the data handler - * for this AttachmentPart object. Typically, on an incoming + * Sets the given {@code DataHandler} object as the data handler + * for this {@code AttachmentPart} object. Typically, on an incoming * message, the data handler is automatically set. When * a message is being created and populated with content, the - * setDataHandler method can be used to get data from + * {@code setDataHandler} method can be used to get data from * various data sources into the message. * - * @param dataHandler the DataHandler object to be set + * @param dataHandler the {@code DataHandler} object to be set * * @exception IllegalArgumentException if there was a problem with - * the specified DataHandler object + * the specified {@code DataHandler} object */ public abstract void setDataHandler(DataHandler dataHandler); @@ -349,8 +348,8 @@ public abstract class AttachmentPart { /** * Gets the value of the MIME header whose name is "Content-ID". * - * @return a String giving the value of the - * "Content-ID" header or null if there + * @return a {@code String} giving the value of the + * "Content-ID" header or {@code null} if there * is none * @see #setContentId */ @@ -364,8 +363,8 @@ public abstract class AttachmentPart { /** * Gets the value of the MIME header whose name is "Content-Location". * - * @return a String giving the value of the - * "Content-Location" header or null if there + * @return a {@code String} giving the value of the + * "Content-Location" header or {@code null} if there * is none */ public String getContentLocation() { @@ -378,8 +377,8 @@ public abstract class AttachmentPart { /** * Gets the value of the MIME header whose name is "Content-Type". * - * @return a String giving the value of the - * "Content-Type" header or null if there + * @return a {@code String} giving the value of the + * "Content-Type" header or {@code null} if there * is none */ public String getContentType() { @@ -392,11 +391,11 @@ public abstract class AttachmentPart { /** * Sets the MIME header whose name is "Content-ID" with the given value. * - * @param contentId a String giving the value of the + * @param contentId a {@code String} giving the value of the * "Content-ID" header * * @exception IllegalArgumentException if there was a problem with - * the specified contentId value + * the specified {@code contentId} value * @see #getContentId */ public void setContentId(String contentId) @@ -409,7 +408,7 @@ public abstract class AttachmentPart { * Sets the MIME header whose name is "Content-Location" with the given value. * * - * @param contentLocation a String giving the value of the + * @param contentLocation a {@code String} giving the value of the * "Content-Location" header * @exception IllegalArgumentException if there was a problem with * the specified content location @@ -422,7 +421,7 @@ public abstract class AttachmentPart { /** * Sets the MIME header whose name is "Content-Type" with the given value. * - * @param contentType a String giving the value of the + * @param contentType a {@code String} giving the value of the * "Content-Type" header * * @exception IllegalArgumentException if there was a problem with @@ -449,10 +448,10 @@ public abstract class AttachmentPart { /** * Gets all the values of the header identified by the given - * String. + * {@code String}. * * @param name the name of the header; example: "Content-Type" - * @return a String array giving the value for the + * @return a {@code String} array giving the value for the * specified header * @see #setMimeHeader */ @@ -466,9 +465,9 @@ public abstract class AttachmentPart { * * Note that RFC822 headers can only contain US-ASCII characters. * - * @param name a String giving the name of the header + * @param name a {@code String} giving the name of the header * for which to search - * @param value a String giving the value to be set for + * @param value a {@code String} giving the value to be set for * the header whose name matches the given name * * @exception IllegalArgumentException if there was a problem with @@ -479,13 +478,13 @@ public abstract class AttachmentPart { /** * Adds a MIME header with the specified name and value to this - * AttachmentPart object. + * {@code AttachmentPart} object. *

                                * Note that RFC822 headers can contain only US-ASCII characters. * - * @param name a String giving the name of the header + * @param name a {@code String} giving the name of the header * to be added - * @param value a String giving the value of the header + * @param value a {@code String} giving the value of the header * to be added * * @exception IllegalArgumentException if there was a problem with @@ -494,35 +493,35 @@ public abstract class AttachmentPart { public abstract void addMimeHeader(String name, String value); /** - * Retrieves all the headers for this AttachmentPart object - * as an iterator over the MimeHeader objects. + * Retrieves all the headers for this {@code AttachmentPart} object + * as an iterator over the {@code MimeHeader} objects. * - * @return an Iterator object with all of the Mime - * headers for this AttachmentPart object + * @return an {@code Iterator} object with all of the Mime + * headers for this {@code AttachmentPart} object */ public abstract Iterator getAllMimeHeaders(); /** - * Retrieves all MimeHeader objects that match a name in + * Retrieves all {@code MimeHeader} objects that match a name in * the given array. * - * @param names a String array with the name(s) of the + * @param names a {@code String} array with the name(s) of the * MIME headers to be returned * @return all of the MIME headers that match one of the names in the - * given array as an Iterator object + * given array as an {@code Iterator} object */ public abstract Iterator getMatchingMimeHeaders(String[] names); /** - * Retrieves all MimeHeader objects whose name does + * Retrieves all {@code MimeHeader} objects whose name does * not match a name in the given array. * - * @param names a String array with the name(s) of the + * @param names a {@code String} array with the name(s) of the * MIME headers not to be returned - * @return all of the MIME headers in this AttachmentPart object + * @return all of the MIME headers in this {@code AttachmentPart} object * except those that match one of the names in the * given array. The nonmatching MIME headers are returned as an - * Iterator object. + * {@code Iterator} object. */ public abstract Iterator getNonMatchingMimeHeaders(String[] names); } diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/Name.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/Name.java index 7c227f19eb3..3f0ef4db6a5 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/Name.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/Name.java @@ -32,52 +32,50 @@ package javax.xml.soap; * to get the URI of the namespace. *

                                * The following is an example of a namespace declaration in an element. - *

                                - *   <wombat:GetLastTradePrice xmlns:wombat="http://www.wombat.org/trader">
                                - * 
                                + * {@code } * ("xmlns" stands for "XML namespace".) * The following - * shows what the methods in the Name interface will return. + * shows what the methods in the {@code Name} interface will return. *
                                  - *
                                • getQualifiedName will return "prefix:LocalName" = + *
                                • {@code getQualifiedName} will return "prefix:LocalName" = * "WOMBAT:GetLastTradePrice" - *
                                • getURI will return "http://www.wombat.org/trader" - *
                                • getLocalName will return "GetLastTracePrice" - *
                                • getPrefix will return "WOMBAT" + *
                                • {@code getURI} will return "http://www.wombat.org/trader" + *
                                • {@code getLocalName} will return "GetLastTracePrice" + *
                                • {@code getPrefix} will return "WOMBAT" *
                                *

                                * XML namespaces are used to disambiguate SOAP identifiers from * application-specific identifiers. *

                                - * Name objects are created using the method - * SOAPEnvelope.createName, which has two versions. - * One method creates Name objects with + * {@code Name} objects are created using the method + * {@code SOAPEnvelope.createName}, which has two versions. + * One method creates {@code Name} objects with * a local name, a namespace prefix, and a namespace URI. - * and the second creates Name objects with just a local name. + * and the second creates {@code Name} objects with just a local name. * The following line of - * code, in which se is a SOAPEnvelope object, creates a new - * Name object with all three. + * code, in which se is a {@code SOAPEnvelope} object, creates a new + * {@code Name} object with all three. *

                                  *     Name name = se.createName("GetLastTradePrice", "WOMBAT",
                                  *                                "http://www.wombat.org/trader");
                                  * 
                                - * The following line of code gives an example of how a Name object - * can be used. The variable element is a SOAPElement object. - * This code creates a new SOAPElement object with the given name and + * The following line of code gives an example of how a {@code Name} object + * can be used. The variable element is a {@code SOAPElement} object. + * This code creates a new {@code SOAPElement} object with the given name and * adds it to element. *
                                  *     element.addChildElement(name);
                                  * 
                                *

                                - * The Name interface may be deprecated in a future release of SAAJ - * in favor of javax.xml.namespace.QName + * The {@code Name} interface may be deprecated in a future release of SAAJ + * in favor of {@code javax.xml.namespace.QName} * @see SOAPEnvelope#createName(String, String, String) SOAPEnvelope.createName * @see SOAPFactory#createName(String, String, String) SOAPFactory.createName * @since 1.6 */ public interface Name { /** - * Gets the local name part of the XML name that this Name + * Gets the local name part of the XML name that this {@code Name} * object represents. * * @return a string giving the local name @@ -86,16 +84,16 @@ public interface Name { /** * Gets the namespace-qualified name of the XML name that this - * Name object represents. + * {@code Name} object represents. * * @return the namespace-qualified name as a string */ String getQualifiedName(); /** - * Returns the prefix that was specified when this Name object + * Returns the prefix that was specified when this {@code Name} object * was initialized. This prefix is associated with the namespace for the XML - * name that this Name object represents. + * name that this {@code Name} object represents. * * @return the prefix as a string */ @@ -103,7 +101,7 @@ public interface Name { /** * Returns the URI of the namespace for the XML - * name that this Name object represents. + * name that this {@code Name} object represents. * * @return the URI as a string */ diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPBody.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPBody.java index ca4a9210f30..ba0ddd74ea7 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPBody.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPBody.java @@ -36,10 +36,10 @@ import javax.xml.namespace.QName; * element in a SOAP message. A SOAP body element consists of XML data * that affects the way the application-specific content is processed. *

                                - * A SOAPBody object contains SOAPBodyElement + * A {@code SOAPBody} object contains {@code SOAPBodyElement} * objects, which have the content for the SOAP body. - * A SOAPFault object, which carries status and/or - * error information, is an example of a SOAPBodyElement object. + * A {@code SOAPFault} object, which carries status and/or + * error information, is an example of a {@code SOAPBodyElement} object. * * @see SOAPFault * @since 1.6 @@ -47,47 +47,47 @@ import javax.xml.namespace.QName; public interface SOAPBody extends SOAPElement { /** - * Creates a new SOAPFault object and adds it to - * this SOAPBody object. The new SOAPFault will + * Creates a new {@code SOAPFault} object and adds it to + * this {@code SOAPBody} object. The new {@code SOAPFault} will * have default values set for the mandatory child elements. The type of - * the SOAPFault will be a SOAP 1.1 or a SOAP 1.2 SOAPFault - * depending on the protocol specified while creating the - * MessageFactory instance. + * the {@code SOAPFault} will be a SOAP 1.1 or a SOAP 1.2 {@code SOAPFault} + * depending on the {@code protocol} specified while creating the + * {@code MessageFactory} instance. *

                                - * A SOAPBody may contain at most one SOAPFault + * A {@code SOAPBody} may contain at most one {@code SOAPFault} * child element. * - * @return the new SOAPFault object + * @return the new {@code SOAPFault} object * @exception SOAPException if there is a SOAP error */ public SOAPFault addFault() throws SOAPException; /** - * Creates a new SOAPFault object and adds it to - * this SOAPBody object. The type of the - * SOAPFault will be a SOAP 1.1 or a SOAP 1.2 - * SOAPFault depending on the protocol - * specified while creating the MessageFactory instance. + * Creates a new {@code SOAPFault} object and adds it to + * this {@code SOAPBody} object. The type of the + * {@code SOAPFault} will be a SOAP 1.1 or a SOAP 1.2 + * {@code SOAPFault} depending on the {@code protocol} + * specified while creating the {@code MessageFactory} instance. *

                                - * For SOAP 1.2 the faultCode parameter is the value of the - * Fault/Code/Value element and the faultString parameter + * For SOAP 1.2 the {@code faultCode} parameter is the value of the + * Fault/Code/Value element and the {@code faultString} parameter * is the value of the Fault/Reason/Text element. For SOAP 1.1 - * the faultCode parameter is the value of the faultcode - * element and the faultString parameter is the value of the faultstring + * the {@code faultCode} parameter is the value of the {@code faultcode} + * element and the {@code faultString} parameter is the value of the {@code faultstring} * element. *

                                - * A SOAPBody may contain at most one SOAPFault + * A {@code SOAPBody} may contain at most one {@code SOAPFault} * child element. * - * @param faultCode a Name object giving the fault + * @param faultCode a {@code Name} object giving the fault * code to be set; must be one of the fault codes defined in the Version * of SOAP specification in use - * @param faultString a String giving an explanation of + * @param faultString a {@code String} giving an explanation of * the fault * @param locale a {@link java.util.Locale} object indicating - * the native language of the faultString - * @return the new SOAPFault object + * the native language of the {@code faultString} + * @return the new {@code SOAPFault} object * @exception SOAPException if there is a SOAP error * @see SOAPFault#setFaultCode * @see SOAPFault#setFaultString @@ -96,32 +96,32 @@ public interface SOAPBody extends SOAPElement { public SOAPFault addFault(Name faultCode, String faultString, Locale locale) throws SOAPException; /** - * Creates a new SOAPFault object and adds it to this - * SOAPBody object. The type of the SOAPFault - * will be a SOAP 1.1 or a SOAP 1.2 SOAPFault depending on - * the protocol specified while creating the MessageFactory + * Creates a new {@code SOAPFault} object and adds it to this + * {@code SOAPBody} object. The type of the {@code SOAPFault} + * will be a SOAP 1.1 or a SOAP 1.2 {@code SOAPFault} depending on + * the {@code protocol} specified while creating the {@code MessageFactory} * instance. *

                                - * For SOAP 1.2 the faultCode parameter is the value of the - * Fault/Code/Value element and the faultString parameter + * For SOAP 1.2 the {@code faultCode} parameter is the value of the + * Fault/Code/Value element and the {@code faultString} parameter * is the value of the Fault/Reason/Text element. For SOAP 1.1 - * the faultCode parameter is the value of the faultcode - * element and the faultString parameter is the value of the faultstring + * the {@code faultCode} parameter is the value of the {@code faultcode} + * element and the {@code faultString} parameter is the value of the {@code faultstring} * element. *

                                - * A SOAPBody may contain at most one SOAPFault + * A {@code SOAPBody} may contain at most one {@code SOAPFault} * child element. * * @param faultCode - * a QName object giving the fault code to be + * a {@code QName} object giving the fault code to be * set; must be one of the fault codes defined in the version * of SOAP specification in use. * @param faultString - * a String giving an explanation of the fault + * a {@code String} giving an explanation of the fault * @param locale * a {@link java.util.Locale Locale} object indicating the - * native language of the faultString - * @return the new SOAPFault object + * native language of the {@code faultString} + * @return the new {@code SOAPFault} object * @exception SOAPException * if there is a SOAP error * @see SOAPFault#setFaultCode @@ -134,33 +134,33 @@ public interface SOAPBody extends SOAPElement { throws SOAPException; /** - * Creates a new SOAPFault object and adds it to this - * SOAPBody object. The type of the SOAPFault - * will be a SOAP 1.1 or a SOAP 1.2 SOAPFault depending on - * the protocol specified while creating the MessageFactory + * Creates a new {@code SOAPFault} object and adds it to this + * {@code SOAPBody} object. The type of the {@code SOAPFault} + * will be a SOAP 1.1 or a SOAP 1.2 {@code SOAPFault} depending on + * the {@code protocol} specified while creating the {@code MessageFactory} * instance. *

                                - * For SOAP 1.2 the faultCode parameter is the value of the - * Fault/Code/Value element and the faultString parameter + * For SOAP 1.2 the {@code faultCode} parameter is the value of the + * Fault/Code/Value element and the {@code faultString} parameter * is the value of the Fault/Reason/Text element. For SOAP 1.1 - * the faultCode parameter is the value of the faultcode - * element and the faultString parameter is the value of the faultstring + * the {@code faultCode} parameter is the value of the faultcode + * element and the {@code faultString} parameter is the value of the faultstring * element. *

                                - * In case of a SOAP 1.2 fault, the default value for the mandatory xml:lang + * In case of a SOAP 1.2 fault, the default value for the mandatory {@code xml:lang} * attribute on the Fault/Reason/Text element will be set to - * java.util.Locale.getDefault() + * {@code java.util.Locale.getDefault()} *

                                - * A SOAPBody may contain at most one SOAPFault + * A {@code SOAPBody} may contain at most one {@code SOAPFault} * child element. * * @param faultCode - * a Name object giving the fault code to be set; + * a {@code Name} object giving the fault code to be set; * must be one of the fault codes defined in the version of SOAP * specification in use * @param faultString - * a String giving an explanation of the fault - * @return the new SOAPFault object + * a {@code String} giving an explanation of the fault + * @return the new {@code SOAPFault} object * @exception SOAPException * if there is a SOAP error * @see SOAPFault#setFaultCode @@ -171,33 +171,33 @@ public interface SOAPBody extends SOAPElement { throws SOAPException; /** - * Creates a new SOAPFault object and adds it to this SOAPBody - * object. The type of the SOAPFault - * will be a SOAP 1.1 or a SOAP 1.2 SOAPFault depending on - * the protocol specified while creating the MessageFactory + * Creates a new {@code SOAPFault} object and adds it to this {@code SOAPBody} + * object. The type of the {@code SOAPFault} + * will be a SOAP 1.1 or a SOAP 1.2 {@code SOAPFault} depending on + * the {@code protocol} specified while creating the {@code MessageFactory} * instance. *

                                - * For SOAP 1.2 the faultCode parameter is the value of the - * Fault/Code/Value element and the faultString parameter + * For SOAP 1.2 the {@code faultCode} parameter is the value of the + * Fault/Code/Value element and the {@code faultString} parameter * is the value of the Fault/Reason/Text element. For SOAP 1.1 - * the faultCode parameter is the value of the faultcode - * element and the faultString parameter is the value of the faultstring + * the {@code faultCode} parameter is the value of the faultcode + * element and the {@code faultString} parameter is the value of the faultstring * element. *

                                - * In case of a SOAP 1.2 fault, the default value for the mandatory xml:lang + * In case of a SOAP 1.2 fault, the default value for the mandatory {@code xml:lang} * attribute on the Fault/Reason/Text element will be set to - * java.util.Locale.getDefault() + * {@code java.util.Locale.getDefault()} *

                                - * A SOAPBody may contain at most one SOAPFault + * A {@code SOAPBody} may contain at most one {@code SOAPFault} * child element * * @param faultCode - * a QName object giving the fault code to be + * a {@code QName} object giving the fault code to be * set; must be one of the fault codes defined in the version * of SOAP specification in use * @param faultString - * a String giving an explanation of the fault - * @return the new SOAPFault object + * a {@code String} giving an explanation of the fault + * @return the new {@code SOAPFault} object * @exception SOAPException * if there is a SOAP error * @see SOAPFault#setFaultCode @@ -209,32 +209,32 @@ public interface SOAPBody extends SOAPElement { throws SOAPException; /** - * Indicates whether a SOAPFault object exists in this - * SOAPBody object. + * Indicates whether a {@code SOAPFault} object exists in this + * {@code SOAPBody} object. * - * @return true if a SOAPFault object exists - * in this SOAPBody object; false + * @return {@code true} if a {@code SOAPFault} object exists + * in this {@code SOAPBody} object; {@code false} * otherwise */ public boolean hasFault(); /** - * Returns the SOAPFault object in this SOAPBody + * Returns the {@code SOAPFault} object in this {@code SOAPBody} * object. * - * @return the SOAPFault object in this SOAPBody + * @return the {@code SOAPFault} object in this {@code SOAPBody} * object if present, null otherwise. */ public SOAPFault getFault(); /** - * Creates a new SOAPBodyElement object with the specified - * name and adds it to this SOAPBody object. + * Creates a new {@code SOAPBodyElement} object with the specified + * name and adds it to this {@code SOAPBody} object. * * @param name - * a Name object with the name for the new SOAPBodyElement + * a {@code Name} object with the name for the new {@code SOAPBodyElement} * object - * @return the new SOAPBodyElement object + * @return the new {@code SOAPBodyElement} object * @exception SOAPException * if a SOAP error occurs * @see SOAPBody#addBodyElement(javax.xml.namespace.QName) @@ -243,13 +243,13 @@ public interface SOAPBody extends SOAPElement { /** - * Creates a new SOAPBodyElement object with the specified - * QName and adds it to this SOAPBody object. + * Creates a new {@code SOAPBodyElement} object with the specified + * QName and adds it to this {@code SOAPBody} object. * * @param qname - * a QName object with the qname for the new - * SOAPBodyElement object - * @return the new SOAPBodyElement object + * a {@code QName} object with the qname for the new + * {@code SOAPBodyElement} object + * @return the new {@code SOAPBodyElement} object * @exception SOAPException * if a SOAP error occurs * @see SOAPBody#addBodyElement(Name) @@ -259,20 +259,20 @@ public interface SOAPBody extends SOAPElement { /** * Adds the root node of the DOM {@link org.w3c.dom.Document} - * to this SOAPBody object. + * to this {@code SOAPBody} object. *

                                - * Calling this method invalidates the document parameter. - * The client application should discard all references to this Document - * and its contents upon calling addDocument. The behavior + * Calling this method invalidates the {@code document} parameter. + * The client application should discard all references to this {@code Document} + * and its contents upon calling {@code addDocument}. The behavior * of an application that continues to use such references is undefined. * * @param document - * the Document object whose root node will be - * added to this SOAPBody. - * @return the SOAPBodyElement that represents the root node + * the {@code Document} object whose root node will be + * added to this {@code SOAPBody}. + * @return the {@code SOAPBodyElement} that represents the root node * that was added. * @exception SOAPException - * if the Document cannot be added + * if the {@code Document} cannot be added * @since 1.6, SAAJ 1.2 */ public SOAPBodyElement addDocument(org.w3c.dom.Document document) @@ -280,16 +280,16 @@ public interface SOAPBody extends SOAPElement { /** * Creates a new DOM {@link org.w3c.dom.Document} and sets - * the first child of this SOAPBody as it's document - * element. The child SOAPElement is removed as part of the + * the first child of this {@code SOAPBody} as it's document + * element. The child {@code SOAPElement} is removed as part of the * process. * * @return the {@link org.w3c.dom.Document} representation - * of the SOAPBody content. + * of the {@code SOAPBody} content. * * @exception SOAPException - * if there is not exactly one child SOAPElement of the - * SOAPBody. + * if there is not exactly one child {@code SOAPElement} of the + * {@code SOAPBody}. * * @since 1.6, SAAJ 1.3 */ diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPElement.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPElement.java index b4d8bca6006..d74eb598c24 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPElement.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPElement.java @@ -38,7 +38,7 @@ import javax.xml.namespace.QName; * Methods in this interface that are required to return SAAJ specific objects * may "silently" replace nodes in the tree as required to successfully return * objects of the correct type. See {@link #getChildElements()} and - * {@link javax.xml.soap} + * {@link javax.xml.soap} * for details. * * @since 1.6 @@ -46,115 +46,115 @@ import javax.xml.namespace.QName; public interface SOAPElement extends Node, org.w3c.dom.Element { /** - * Creates a new SOAPElement object initialized with the - * given Name object and adds the new element to this - * SOAPElement object. + * Creates a new {@code SOAPElement} object initialized with the + * given {@code Name} object and adds the new element to this + * {@code SOAPElement} object. *

                                * This method may be deprecated in a future release of SAAJ in favor of * addChildElement(javax.xml.namespace.QName) * - * @param name a Name object with the XML name for the + * @param name a {@code Name} object with the XML name for the * new element * - * @return the new SOAPElement object that was created + * @return the new {@code SOAPElement} object that was created * @exception SOAPException if there is an error in creating the - * SOAPElement object + * {@code SOAPElement} object * @see SOAPElement#addChildElement(javax.xml.namespace.QName) */ public SOAPElement addChildElement(Name name) throws SOAPException; /** - * Creates a new SOAPElement object initialized with the given - * QName object and adds the new element to this SOAPElement + * Creates a new {@code SOAPElement} object initialized with the given + * {@code QName} object and adds the new element to this {@code SOAPElement} * object. The namespace, localname and prefix of the new - * SOAPElement are all taken from the qname argument. + * {@code SOAPElement} are all taken from the {@code qname} argument. * - * @param qname a QName object with the XML name for the + * @param qname a {@code QName} object with the XML name for the * new element * - * @return the new SOAPElement object that was created + * @return the new {@code SOAPElement} object that was created * @exception SOAPException if there is an error in creating the - * SOAPElement object + * {@code SOAPElement} object * @see SOAPElement#addChildElement(Name) * @since 1.6, SAAJ 1.3 */ public SOAPElement addChildElement(QName qname) throws SOAPException; /** - * Creates a new SOAPElement object initialized with the + * Creates a new {@code SOAPElement} object initialized with the * specified local name and adds the new element to this - * SOAPElement object. - * The new SOAPElement inherits any in-scope default namespace. + * {@code SOAPElement} object. + * The new {@code SOAPElement} inherits any in-scope default namespace. * - * @param localName a String giving the local name for + * @param localName a {@code String} giving the local name for * the element - * @return the new SOAPElement object that was created + * @return the new {@code SOAPElement} object that was created * @exception SOAPException if there is an error in creating the - * SOAPElement object + * {@code SOAPElement} object */ public SOAPElement addChildElement(String localName) throws SOAPException; /** - * Creates a new SOAPElement object initialized with the + * Creates a new {@code SOAPElement} object initialized with the * specified local name and prefix and adds the new element to this - * SOAPElement object. + * {@code SOAPElement} object. * - * @param localName a String giving the local name for + * @param localName a {@code String} giving the local name for * the new element - * @param prefix a String giving the namespace prefix for + * @param prefix a {@code String} giving the namespace prefix for * the new element * - * @return the new SOAPElement object that was created - * @exception SOAPException if the prefix is not valid in the - * context of this SOAPElement or if there is an error in creating the - * SOAPElement object + * @return the new {@code SOAPElement} object that was created + * @exception SOAPException if the {@code prefix} is not valid in the + * context of this {@code SOAPElement} or if there is an error in creating the + * {@code SOAPElement} object */ public SOAPElement addChildElement(String localName, String prefix) throws SOAPException; /** - * Creates a new SOAPElement object initialized with the + * Creates a new {@code SOAPElement} object initialized with the * specified local name, prefix, and URI and adds the new element to this - * SOAPElement object. + * {@code SOAPElement} object. * - * @param localName a String giving the local name for + * @param localName a {@code String} giving the local name for * the new element - * @param prefix a String giving the namespace prefix for + * @param prefix a {@code String} giving the namespace prefix for * the new element - * @param uri a String giving the URI of the namespace + * @param uri a {@code String} giving the URI of the namespace * to which the new element belongs * - * @return the new SOAPElement object that was created + * @return the new {@code SOAPElement} object that was created * @exception SOAPException if there is an error in creating the - * SOAPElement object + * {@code SOAPElement} object */ public SOAPElement addChildElement(String localName, String prefix, String uri) throws SOAPException; /** - * Add a SOAPElement as a child of this - * SOAPElement instance. The SOAPElement + * Add a {@code SOAPElement} as a child of this + * {@code SOAPElement} instance. The {@code SOAPElement} * is expected to be created by a - * SOAPFactory. Callers should not rely on the + * {@code SOAPFactory}. Callers should not rely on the * element instance being added as is into the XML * tree. Implementations could end up copying the content - * of the SOAPElement passed into an instance of - * a different SOAPElement implementation. For - * instance if addChildElement() is called on a - * SOAPHeader, element will be copied - * into an instance of a SOAPHeaderElement. + * of the {@code SOAPElement} passed into an instance of + * a different {@code SOAPElement} implementation. For + * instance if {@code addChildElement()} is called on a + * {@code SOAPHeader}, {@code element} will be copied + * into an instance of a {@code SOAPHeaderElement}. * - *

                                The fragment rooted in element is either added + *

                                The fragment rooted in {@code element} is either added * as a whole or not at all, if there was an error. * - *

                                The fragment rooted in element cannot contain + *

                                The fragment rooted in {@code element} cannot contain * elements named "Envelope", "Header" or "Body" and in the SOAP * namespace. Any namespace prefixes present in the fragment * should be fully resolved using appropriate namespace * declarations within the fragment itself. * - * @param element the SOAPElement to be added as a + * @param element the {@code SOAPElement} to be added as a * new child * * @exception SOAPException if there was an error in adding this @@ -167,10 +167,10 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { throws SOAPException; /** - * Detaches all children of this SOAPElement. + * Detaches all children of this {@code SOAPElement}. *

                                * This method is useful for rolling back the construction of partially - * completed SOAPHeaders and SOAPBodys in + * completed {@code SOAPHeaders} and {@code SOAPBodys} in * preparation for sending a fault when an error condition is detected. It * is also useful for recycling portions of a document within a SOAP * message. @@ -180,33 +180,33 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { public abstract void removeContents(); /** - * Creates a new Text object initialized with the given - * String and adds it to this SOAPElement object. + * Creates a new {@code Text} object initialized with the given + * {@code String} and adds it to this {@code SOAPElement} object. * - * @param text a String object with the textual content to be added + * @param text a {@code String} object with the textual content to be added * - * @return the SOAPElement object into which - * the new Text object was inserted + * @return the {@code SOAPElement} object into which + * the new {@code Text} object was inserted * @exception SOAPException if there is an error in creating the - * new Text object or if it is not legal to + * new {@code Text} object or if it is not legal to * attach it as a child to this - * SOAPElement + * {@code SOAPElement} */ public SOAPElement addTextNode(String text) throws SOAPException; /** * Adds an attribute with the specified name and value to this - * SOAPElement object. + * {@code SOAPElement} object. * - * @param name a Name object with the name of the attribute - * @param value a String giving the value of the attribute - * @return the SOAPElement object into which the attribute was + * @param name a {@code Name} object with the name of the attribute + * @param value a {@code String} giving the value of the attribute + * @return the {@code SOAPElement} object into which the attribute was * inserted * * @exception SOAPException if there is an error in creating the * Attribute, or it is invalid to set - an attribute with Name - name on this SOAPElement. + an attribute with {@code Name} + {@code name} on this SOAPElement. * @see SOAPElement#addAttribute(javax.xml.namespace.QName, String) */ public SOAPElement addAttribute(Name name, String value) @@ -214,17 +214,17 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Adds an attribute with the specified name and value to this - * SOAPElement object. + * {@code SOAPElement} object. * - * @param qname a QName object with the name of the attribute - * @param value a String giving the value of the attribute - * @return the SOAPElement object into which the attribute was + * @param qname a {@code QName} object with the name of the attribute + * @param value a {@code String} giving the value of the attribute + * @return the {@code SOAPElement} object into which the attribute was * inserted * * @exception SOAPException if there is an error in creating the * Attribute, or it is invalid to set - an attribute with QName - qname on this SOAPElement. + an attribute with {@code QName} + {@code qname} on this SOAPElement. * @see SOAPElement#addAttribute(Name, String) * @since 1.6, SAAJ 1.3 */ @@ -233,11 +233,11 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Adds a namespace declaration with the specified prefix and URI to this - * SOAPElement object. + * {@code SOAPElement} object. * - * @param prefix a String giving the prefix of the namespace - * @param uri a String giving the uri of the namespace - * @return the SOAPElement object into which this + * @param prefix a {@code String} giving the prefix of the namespace + * @param uri a {@code String} giving the uri of the namespace + * @return the {@code SOAPElement} object into which this * namespace declaration was inserted. * * @exception SOAPException if there is an error in creating the @@ -249,8 +249,8 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Returns the value of the attribute with the specified name. * - * @param name a Name object with the name of the attribute - * @return a String giving the value of the specified + * @param name a {@code Name} object with the name of the attribute + * @return a {@code String} giving the value of the specified * attribute, Null if there is no such attribute * @see SOAPElement#getAttributeValue(javax.xml.namespace.QName) */ @@ -259,8 +259,8 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Returns the value of the attribute with the specified qname. * - * @param qname a QName object with the qname of the attribute - * @return a String giving the value of the specified + * @param qname a {@code QName} object with the qname of the attribute + * @return a {@code String} giving the value of the specified * attribute, Null if there is no such attribute * @see SOAPElement#getAttributeValue(Name) * @since 1.6, SAAJ 1.3 @@ -268,11 +268,11 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { public String getAttributeValue(QName qname); /** - * Returns an Iterator over all of the attribute - * Name objects in this - * SOAPElement object. The iterator can be used to get + * Returns an {@code Iterator} over all of the attribute + * {@code Name} objects in this + * {@code SOAPElement} object. The iterator can be used to get * the attribute names, which can then be passed to the method - * getAttributeValue to retrieve the value of each + * {@code getAttributeValue} to retrieve the value of each * attribute. * * @see SOAPElement#getAllAttributesAsQNames() @@ -281,10 +281,10 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { public Iterator getAllAttributes(); /** - * Returns an Iterator over all of the attributes - * in this SOAPElement as QName objects. + * Returns an {@code Iterator} over all of the attributes + * in this {@code SOAPElement} as {@code QName} objects. * The iterator can be used to get the attribute QName, which can then - * be passed to the method getAttributeValue to retrieve + * be passed to the method {@code getAttributeValue} to retrieve * the value of each attribute. * * @return an iterator over the QNames of the attributes @@ -297,94 +297,94 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Returns the URI of the namespace that has the given prefix. * - * @param prefix a String giving the prefix of the namespace + * @param prefix a {@code String} giving the prefix of the namespace * for which to search - * @return a String with the uri of the namespace that has + * @return a {@code String} with the uri of the namespace that has * the given prefix */ public String getNamespaceURI(String prefix); /** - * Returns an Iterator over the namespace prefix - * Strings declared by this element. The prefixes returned by + * Returns an {@code Iterator} over the namespace prefix + * {@code String}s declared by this element. The prefixes returned by * this iterator can be passed to the method - * getNamespaceURI to retrieve the URI of each namespace. + * {@code getNamespaceURI} to retrieve the URI of each namespace. * * @return an iterator over the namespace prefixes in this - * SOAPElement object + * {@code SOAPElement} object */ public Iterator getNamespacePrefixes(); /** - * Returns an Iterator over the namespace prefix - * Strings visible to this element. The prefixes returned by + * Returns an {@code Iterator} over the namespace prefix + * {@code String}s visible to this element. The prefixes returned by * this iterator can be passed to the method - * getNamespaceURI to retrieve the URI of each namespace. + * {@code getNamespaceURI} to retrieve the URI of each namespace. * * @return an iterator over the namespace prefixes are within scope of this - * SOAPElement object + * {@code SOAPElement} object * * @since 1.6, SAAJ 1.2 */ public Iterator getVisibleNamespacePrefixes(); /** - * Creates a QName whose namespace URI is the one associated - * with the parameter, prefix, in the context of this - * SOAPElement. The remaining elements of the new - * QName are taken directly from the parameters, - * localName and prefix. + * Creates a {@code QName} whose namespace URI is the one associated + * with the parameter, {@code prefix}, in the context of this + * {@code SOAPElement}. The remaining elements of the new + * {@code QName} are taken directly from the parameters, + * {@code localName} and {@code prefix}. * * @param localName - * a String containing the local part of the name. + * a {@code String} containing the local part of the name. * @param prefix - * a String containing the prefix for the name. + * a {@code String} containing the prefix for the name. * - * @return a QName with the specified localName - * and prefix, and with a namespace that is associated - * with the prefix in the context of this - * SOAPElement. This namespace will be the same as + * @return a {@code QName} with the specified {@code localName} + * and {@code prefix}, and with a namespace that is associated + * with the {@code prefix} in the context of this + * {@code SOAPElement}. This namespace will be the same as * the one that would be returned by * {@link #getNamespaceURI(String)} if it were given - * prefix as it's parameter. + * {@code prefix} as it's parameter. * - * @exception SOAPException if the QName cannot be created. + * @exception SOAPException if the {@code QName} cannot be created. * * @since 1.6, SAAJ 1.3 */ public QName createQName(String localName, String prefix) throws SOAPException; /** - * Returns the name of this SOAPElement object. + * Returns the name of this {@code SOAPElement} object. * - * @return a Name object with the name of this - * SOAPElement object + * @return a {@code Name} object with the name of this + * {@code SOAPElement} object */ public Name getElementName(); /** - * Returns the qname of this SOAPElement object. + * Returns the qname of this {@code SOAPElement} object. * - * @return a QName object with the qname of this - * SOAPElement object + * @return a {@code QName} object with the qname of this + * {@code SOAPElement} object * @see SOAPElement#getElementName() * @since 1.6, SAAJ 1.3 */ public QName getElementQName(); /** - * Changes the name of this Element to newName if + * Changes the name of this {@code Element} to {@code newName} if * possible. SOAP Defined elements such as SOAPEnvelope, SOAPHeader, SOAPBody * etc. cannot have their names changed using this method. Any attempt to do * so will result in a SOAPException being thrown. *

                                * Callers should not rely on the element instance being renamed as is. * Implementations could end up copying the content of the - * SOAPElement to a renamed instance. + * {@code SOAPElement} to a renamed instance. * - * @param newName the new name for the Element. + * @param newName the new name for the {@code Element}. * - * @exception SOAPException if changing the name of this Element + * @exception SOAPException if changing the name of this {@code Element} * is not allowed. * @return The renamed Node * @@ -395,10 +395,10 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Removes the attribute with the specified name. * - * @param name the Name object with the name of the + * @param name the {@code Name} object with the name of the * attribute to be removed - * @return true if the attribute was - * removed successfully; false if it was not + * @return {@code true} if the attribute was + * removed successfully; {@code false} if it was not * @see SOAPElement#removeAttribute(javax.xml.namespace.QName) */ public boolean removeAttribute(Name name); @@ -406,10 +406,10 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Removes the attribute with the specified qname. * - * @param qname the QName object with the qname of the + * @param qname the {@code QName} object with the qname of the * attribute to be removed - * @return true if the attribute was - * removed successfully; false if it was not + * @return {@code true} if the attribute was + * removed successfully; {@code false} if it was not * @see SOAPElement#removeAttribute(Name) * @since 1.6, SAAJ 1.3 */ @@ -418,84 +418,84 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { /** * Removes the namespace declaration corresponding to the given prefix. * - * @param prefix a String giving the prefix for which + * @param prefix a {@code String} giving the prefix for which * to search - * @return true if the namespace declaration was - * removed successfully; false if it was not + * @return {@code true} if the namespace declaration was + * removed successfully; {@code false} if it was not */ public boolean removeNamespaceDeclaration(String prefix); /** - * Returns an Iterator over all the immediate child - * {@link Node}s of this element. This includes javax.xml.soap.Text - * objects as well as SOAPElement objects. + * Returns an {@code Iterator} over all the immediate child + * {@link Node}s of this element. This includes {@code javax.xml.soap.Text} + * objects as well as {@code SOAPElement} objects. *

                                - * Calling this method may cause child Element, - * SOAPElement and org.w3c.dom.Text nodes to be - * replaced by SOAPElement, SOAPHeaderElement, - * SOAPBodyElement or javax.xml.soap.Text nodes as + * Calling this method may cause child {@code Element}, + * {@code SOAPElement} and {@code org.w3c.dom.Text} nodes to be + * replaced by {@code SOAPElement}, {@code SOAPHeaderElement}, + * {@code SOAPBodyElement} or {@code javax.xml.soap.Text} nodes as * appropriate for the type of this parent node. As a result the calling * application must treat any existing references to these child nodes that * have been obtained through DOM APIs as invalid and either discard them or - * refresh them with the values returned by this Iterator. This + * refresh them with the values returned by this {@code Iterator}. This * behavior can be avoided by calling the equivalent DOM APIs. See - * {@link javax.xml.soap} + * {@link javax.xml.soap} * for more details. * - * @return an iterator with the content of this SOAPElement + * @return an iterator with the content of this {@code SOAPElement} * object */ public Iterator getChildElements(); /** - * Returns an Iterator over all the immediate child + * Returns an {@code Iterator} over all the immediate child * {@link Node}s of this element with the specified name. All of these - * children will be SOAPElement nodes. + * children will be {@code SOAPElement} nodes. *

                                - * Calling this method may cause child Element, - * SOAPElement and org.w3c.dom.Text nodes to be - * replaced by SOAPElement, SOAPHeaderElement, - * SOAPBodyElement or javax.xml.soap.Text nodes as + * Calling this method may cause child {@code Element}, + * {@code SOAPElement} and {@code org.w3c.dom.Text} nodes to be + * replaced by {@code SOAPElement}, {@code SOAPHeaderElement}, + * {@code SOAPBodyElement} or {@code javax.xml.soap.Text} nodes as * appropriate for the type of this parent node. As a result the calling * application must treat any existing references to these child nodes that * have been obtained through DOM APIs as invalid and either discard them or - * refresh them with the values returned by this Iterator. This + * refresh them with the values returned by this {@code Iterator}. This * behavior can be avoided by calling the equivalent DOM APIs. See - * {@link javax.xml.soap} + * {@link javax.xml.soap} * for more details. * - * @param name a Name object with the name of the child + * @param name a {@code Name} object with the name of the child * elements to be returned * - * @return an Iterator object over all the elements - * in this SOAPElement object with the + * @return an {@code Iterator} object over all the elements + * in this {@code SOAPElement} object with the * specified name * @see SOAPElement#getChildElements(javax.xml.namespace.QName) */ public Iterator getChildElements(Name name); /** - * Returns an Iterator over all the immediate child + * Returns an {@code Iterator} over all the immediate child * {@link Node}s of this element with the specified qname. All of these - * children will be SOAPElement nodes. + * children will be {@code SOAPElement} nodes. *

                                - * Calling this method may cause child Element, - * SOAPElement and org.w3c.dom.Text nodes to be - * replaced by SOAPElement, SOAPHeaderElement, - * SOAPBodyElement or javax.xml.soap.Text nodes as + * Calling this method may cause child {@code Element}, + * {@code SOAPElement} and {@code org.w3c.dom.Text} nodes to be + * replaced by {@code SOAPElement}, {@code SOAPHeaderElement}, + * {@code SOAPBodyElement} or {@code javax.xml.soap.Text} nodes as * appropriate for the type of this parent node. As a result the calling * application must treat any existing references to these child nodes that * have been obtained through DOM APIs as invalid and either discard them or - * refresh them with the values returned by this Iterator. This + * refresh them with the values returned by this {@code Iterator}. This * behavior can be avoided by calling the equivalent DOM APIs. See - * {@link javax.xml.soap} + * {@link javax.xml.soap} * for more details. * - * @param qname a QName object with the qname of the child + * @param qname a {@code QName} object with the qname of the child * elements to be returned * - * @return an Iterator object over all the elements - * in this SOAPElement object with the + * @return an {@code Iterator} object over all the elements + * in this {@code SOAPElement} object with the * specified qname * @see SOAPElement#getChildElements(Name) * @since 1.6, SAAJ 1.3 @@ -503,10 +503,10 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { public Iterator getChildElements(QName qname); /** - * Sets the encoding style for this SOAPElement object + * Sets the encoding style for this {@code SOAPElement} object * to one specified. * - * @param encodingStyle a String giving the encoding style + * @param encodingStyle a {@code String} giving the encoding style * * @exception IllegalArgumentException if there was a problem in the * encoding style being set. @@ -516,9 +516,9 @@ public interface SOAPElement extends Node, org.w3c.dom.Element { public void setEncodingStyle(String encodingStyle) throws SOAPException; /** - * Returns the encoding style for this SOAPElement object. + * Returns the encoding style for this {@code SOAPElement} object. * - * @return a String giving the encoding style + * @return a {@code String} giving the encoding style * * @see #setEncodingStyle */ diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPMessage.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPMessage.java index 821c64817e9..a1fef3d693a 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPMessage.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPMessage.java @@ -36,24 +36,24 @@ import javax.activation.DataHandler; * message is an XML document or a MIME message whose first body part is an * XML/SOAP document. *

                                - * A SOAPMessage object consists of a SOAP part and optionally - * one or more attachment parts. The SOAP part for a SOAPMessage - * object is a SOAPPart object, which contains information used + * A {@code SOAPMessage} object consists of a SOAP part and optionally + * one or more attachment parts. The SOAP part for a {@code SOAPMessage} + * object is a {@code SOAPPart} object, which contains information used * for message routing and identification, and which can contain * application-specific content. All data in the SOAP Part of a message must be * in XML format. *

                                - * A new SOAPMessage object contains the following by default: + * A new {@code SOAPMessage} object contains the following by default: *

                                  - *
                                • A SOAPPart object - *
                                • A SOAPEnvelope object - *
                                • A SOAPBody object - *
                                • A SOAPHeader object + *
                                • A {@code SOAPPart} object + *
                                • A {@code SOAPEnvelope} object + *
                                • A {@code SOAPBody} object + *
                                • A {@code SOAPHeader} object *
                                - * The SOAP part of a message can be retrieved by calling the method SOAPMessage.getSOAPPart(). - * The SOAPEnvelope object is retrieved from the SOAPPart - * object, and the SOAPEnvelope object is used to retrieve the - * SOAPBody and SOAPHeader objects. + * The SOAP part of a message can be retrieved by calling the method {@code SOAPMessage.getSOAPPart()}. + * The {@code SOAPEnvelope} object is retrieved from the {@code SOAPPart} + * object, and the {@code SOAPEnvelope} object is used to retrieve the + * {@code SOAPBody} and {@code SOAPHeader} objects. * *
                                  *     SOAPPart sp = message.getSOAPPart();
                                @@ -63,32 +63,32 @@ import javax.activation.DataHandler;
                                  * 
                                * *

                                - * In addition to the mandatory SOAPPart object, a SOAPMessage - * object may contain zero or more AttachmentPart objects, each - * of which contains application-specific data. The SOAPMessage - * interface provides methods for creating AttachmentPart - * objects and also for adding them to a SOAPMessage object. A - * party that has received a SOAPMessage object can examine its + * In addition to the mandatory {@code SOAPPart} object, a {@code SOAPMessage} + * object may contain zero or more {@code AttachmentPart} objects, each + * of which contains application-specific data. The {@code SOAPMessage} + * interface provides methods for creating {@code AttachmentPart} + * objects and also for adding them to a {@code SOAPMessage} object. A + * party that has received a {@code SOAPMessage} object can examine its * contents by retrieving individual attachment parts. *

                                * Unlike the rest of a SOAP message, an attachment is not required to be in * XML format and can therefore be anything from simple text to an image file. * Consequently, any message content that is not in XML format must be in an - * AttachmentPart object. + * {@code AttachmentPart} object. *

                                - * A MessageFactory object may create SOAPMessage + * A {@code MessageFactory} object may create {@code SOAPMessage} * objects with behavior that is specialized to a particular implementation or - * application of SAAJ. For instance, a MessageFactory object - * may produce SOAPMessage objects that conform to a particular - * Profile such as ebXML. In this case a MessageFactory object - * might produce SOAPMessage objects that are initialized with + * application of SAAJ. For instance, a {@code MessageFactory} object + * may produce {@code SOAPMessage} objects that conform to a particular + * Profile such as ebXML. In this case a {@code MessageFactory} object + * might produce {@code SOAPMessage} objects that are initialized with * ebXML headers. *

                                * In order to ensure backward source compatibility, methods that are added to * this class after version 1.1 of the SAAJ specification are all concrete * instead of abstract and they all have default implementations. Unless * otherwise noted in the JavaDocs for those methods the default - * implementations simply throw an UnsupportedOperationException + * implementations simply throw an {@code UnsupportedOperationException} * and the SAAJ implementation code must override them with methods that * provide the specified behavior. Legacy client code does not have this * restriction, however, so long as there is no claim made that it conforms to @@ -126,41 +126,40 @@ public abstract class SOAPMessage { "javax.xml.soap.write-xml-declaration"; /** - * Sets the description of this SOAPMessage object's + * Sets the description of this {@code SOAPMessage} object's * content with the given description. * - * @param description a String describing the content of this + * @param description a {@code String} describing the content of this * message * @see #getContentDescription */ public abstract void setContentDescription(String description); /** - * Retrieves a description of this SOAPMessage object's + * Retrieves a description of this {@code SOAPMessage} object's * content. * - * @return a String describing the content of this - * message or null if no description has been set + * @return a {@code String} describing the content of this + * message or {@code null} if no description has been set * @see #setContentDescription */ public abstract String getContentDescription(); /** - * Gets the SOAP part of this SOAPMessage object. + * Gets the SOAP part of this {@code SOAPMessage} object. *

                                - * SOAPMessage object contains one or more attachments, the + * {@code SOAPMessage} object contains one or more attachments, the * SOAP Part must be the first MIME body part in the message. * - * @return the SOAPPart object for this SOAPMessage + * @return the {@code SOAPPart} object for this {@code SOAPMessage} * object */ public abstract SOAPPart getSOAPPart(); /** - * Gets the SOAP Body contained in this SOAPMessage object. - *

                                + * Gets the SOAP Body contained in this {@code SOAPMessage} object. * - * @return the SOAPBody object contained by this SOAPMessage + * @return the {@code SOAPBody} object contained by this {@code SOAPMessage} * object * @exception SOAPException * if the SOAP Body does not exist or cannot be retrieved @@ -171,23 +170,21 @@ public abstract class SOAPMessage { } /** - * Gets the SOAP Header contained in this SOAPMessage - * object. - *

                                - * - * @return the SOAPHeader object contained by this SOAPMessage - * object - * @exception SOAPException - * if the SOAP Header does not exist or cannot be retrieved - * @since 1.6, SAAJ 1.2 - */ + * Gets the SOAP Header contained in this {@code SOAPMessage} object. + * + * @return the {@code SOAPHeader} object contained + * by this {@code SOAPMessage} object + * @exception SOAPException + * if the SOAP Header does not exist or cannot be retrieved + * @since 1.6, SAAJ 1.2 + */ public SOAPHeader getSOAPHeader() throws SOAPException { throw new UnsupportedOperationException("getSOAPHeader must be overridden by all subclasses of SOAPMessage"); } /** - * Removes all AttachmentPart objects that have been added - * to this SOAPMessage object. + * Removes all {@code AttachmentPart} objects that have been added + * to this {@code SOAPMessage} object. *

                                * This method does not touch the SOAP part. */ @@ -197,26 +194,26 @@ public abstract class SOAPMessage { * Gets a count of the number of attachments in this message. This count * does not include the SOAP part. * - * @return the number of AttachmentPart objects that are - * part of this SOAPMessage object + * @return the number of {@code AttachmentPart} objects that are + * part of this {@code SOAPMessage} object */ public abstract int countAttachments(); /** - * Retrieves all the AttachmentPart objects that are part of - * this SOAPMessage object. + * Retrieves all the {@code AttachmentPart} objects that are part of + * this {@code SOAPMessage} object. * * @return an iterator over all the attachments in this message */ public abstract Iterator getAttachments(); /** - * Retrieves all the AttachmentPart objects that have header + * Retrieves all the {@code AttachmentPart} objects that have header * entries that match the specified headers. Note that a returned * attachment could have headers in addition to those specified. * * @param headers - * a MimeHeaders object containing the MIME + * a {@code MimeHeaders} object containing the MIME * headers for which to search * @return an iterator over all attachments that have a header that matches * one of the given headers @@ -224,12 +221,12 @@ public abstract class SOAPMessage { public abstract Iterator getAttachments(MimeHeaders headers); /** - * Removes all the AttachmentPart objects that have header + * Removes all the {@code AttachmentPart} objects that have header * entries that match the specified headers. Note that the removed * attachment could have headers in addition to those specified. * * @param headers - * a MimeHeaders object containing the MIME + * a {@code MimeHeaders} object containing the MIME * headers for which to search * @since 1.6, SAAJ 1.3 */ @@ -237,25 +234,26 @@ public abstract class SOAPMessage { /** - * Returns an AttachmentPart object that is associated with an - * attachment that is referenced by this SOAPElement or - * null if no such attachment exists. References can be made - * via an href attribute as described in - * {@link SOAP Messages with Attachments}, - * or via a single Text child node containing a URI as + * Returns an {@code AttachmentPart} object that is associated with an + * attachment that is referenced by this {@code SOAPElement} or + * {@code null} if no such attachment exists. References can be made + * via an {@code href} attribute as described in + * SOAP Messages with Attachments, + * or via a single {@code Text} child node containing a URI as * described in the WS-I Attachments Profile 1.0 for elements of schema - * type {@link ref:swaRef}. These two mechanisms must be supported. - * The support for references via href attribute also implies that + * type ref:swaRef. + * These two mechanisms must be supported. + * The support for references via {@code href} attribute also implies that * this method should also be supported on an element that is an * xop:Include element ( - * {@link XOP}). + * XOP). * other reference mechanisms may be supported by individual * implementations of this standard. Contact your vendor for details. * - * @param element The SOAPElement containing the reference to an Attachment - * @return the referenced AttachmentPart or null if no such - * AttachmentPart exists or no reference can be - * found in this SOAPElement. + * @param element The {@code SOAPElement} containing the reference to an Attachment + * @return the referenced {@code AttachmentPart} or null if no such + * {@code AttachmentPart} exists or no reference can be + * found in this {@code SOAPElement}. * @throws SOAPException if there is an error in the attempt to access the * attachment * @@ -265,40 +263,40 @@ public abstract class SOAPMessage { /** - * Adds the given AttachmentPart object to this SOAPMessage - * object. An AttachmentPart object must be created before + * Adds the given {@code AttachmentPart} object to this {@code SOAPMessage} + * object. An {@code AttachmentPart} object must be created before * it can be added to a message. * * @param AttachmentPart - * an AttachmentPart object that is to become part - * of this SOAPMessage object + * an {@code AttachmentPart} object that is to become part + * of this {@code SOAPMessage} object * @exception IllegalArgumentException */ public abstract void addAttachmentPart(AttachmentPart AttachmentPart); /** - * Creates a new empty AttachmentPart object. Note that the - * method addAttachmentPart must be called with this new - * AttachmentPart object as the parameter in order for it to - * become an attachment to this SOAPMessage object. + * Creates a new empty {@code AttachmentPart} object. Note that the + * method {@code addAttachmentPart} must be called with this new + * {@code AttachmentPart} object as the parameter in order for it to + * become an attachment to this {@code SOAPMessage} object. * - * @return a new AttachmentPart object that can be populated - * and added to this SOAPMessage object + * @return a new {@code AttachmentPart} object that can be populated + * and added to this {@code SOAPMessage} object */ public abstract AttachmentPart createAttachmentPart(); /** - * Creates an AttachmentPart object and populates it using - * the given DataHandler object. + * Creates an {@code AttachmentPart} object and populates it using + * the given {@code DataHandler} object. * * @param dataHandler - * the javax.activation.DataHandler object that - * will generate the content for this SOAPMessage + * the {@code javax.activation.DataHandler} object that + * will generate the content for this {@code SOAPMessage} * object - * @return a new AttachmentPart object that contains data - * generated by the given DataHandler object + * @return a new {@code AttachmentPart} object that contains data + * generated by the given {@code DataHandler} object * @exception IllegalArgumentException - * if there was a problem with the specified DataHandler + * if there was a problem with the specified {@code DataHandler} * object * @see javax.activation.DataHandler * @see javax.activation.DataContentHandler @@ -310,32 +308,32 @@ public abstract class SOAPMessage { } /** - * Returns all the transport-specific MIME headers for this SOAPMessage + * Returns all the transport-specific MIME headers for this {@code SOAPMessage} * object in a transport-independent fashion. * - * @return a MimeHeaders object containing the MimeHeader + * @return a {@code MimeHeaders} object containing the {@code MimeHeader} * objects */ public abstract MimeHeaders getMimeHeaders(); /** - * Creates an AttachmentPart object and populates it with + * Creates an {@code AttachmentPart} object and populates it with * the specified data of the specified content type. The type of the - * Object should correspond to the value given for the - * Content-Type. + * {@code Object} should correspond to the value given for the + * {@code Content-Type}. * * @param content - * an Object containing the content for the - * AttachmentPart object to be created + * an {@code Object} containing the content for the + * {@code AttachmentPart} object to be created * @param contentType - * a String object giving the type of content; + * a {@code String} object giving the type of content; * examples are "text/xml", "text/plain", and "image/jpeg" - * @return a new AttachmentPart object that contains the + * @return a new {@code AttachmentPart} object that contains the * given data * @exception IllegalArgumentException * may be thrown if the contentType does not match the type * of the content object, or if there was no - * DataContentHandler object for the given + * {@code DataContentHandler} object for the given * content object * @see javax.activation.DataHandler * @see javax.activation.DataContentHandler @@ -349,50 +347,49 @@ public abstract class SOAPMessage { } /** - * Updates this SOAPMessage object with all the changes that + * Updates this {@code SOAPMessage} object with all the changes that * have been made to it. This method is called automatically when * {@link SOAPMessage#writeTo(OutputStream)} is called. However, if * changes are made to a message that was received or to one that has - * already been sent, the method saveChanges needs to be - * called explicitly in order to save the changes. The method saveChanges + * already been sent, the method {@code saveChanges} needs to be + * called explicitly in order to save the changes. The method {@code saveChanges} * also generates any changes that can be read back (for example, a * MessageId in profiles that support a message id). All MIME headers in a * message that is created for sending purposes are guaranteed to have - * valid values only after saveChanges has been called. + * valid values only after {@code saveChanges} has been called. *

                                * In addition, this method marks the point at which the data from all - * constituent AttachmentPart objects are pulled into the + * constituent {@code AttachmentPart} objects are pulled into the * message. - *

                                * - * @exception SOAPException if there was a problem saving - * changes to this message. + * @exception SOAPException if there was a problem saving + * changes to this message. */ public abstract void saveChanges() throws SOAPException; /** - * Indicates whether this SOAPMessage object needs to have - * the method saveChanges called on it. + * Indicates whether this {@code SOAPMessage} object needs to have + * the method {@code saveChanges} called on it. * - * @return true if saveChanges needs to be - * called; false otherwise. + * @return {@code true} if {@code saveChanges} needs to be + * called; {@code false} otherwise. */ public abstract boolean saveRequired(); /** - * Writes this SOAPMessage object to the given output + * Writes this {@code SOAPMessage} object to the given output * stream. The externalization format is as defined by the SOAP 1.1 with * Attachments specification. *

                                * If there are no attachments, just an XML stream is written out. For - * those messages that have attachments, writeTo writes a + * those messages that have attachments, {@code writeTo} writes a * MIME-encoded byte stream. *

                                * Note that this method does not write the transport-specific MIME Headers * of the Message * * @param out - * the OutputStream object to which this SOAPMessage + * the {@code OutputStream} object to which this {@code SOAPMessage} * object will be written * @exception IOException * if an I/O error occurs @@ -414,13 +411,13 @@ public abstract class SOAPMessage { * implementation specific properties. These properties must be prefixed * with package names that are unique to the vendor. *

                                - * Setting the property WRITE_XML_DECLARATION to "true" + * Setting the property {@code WRITE_XML_DECLARATION} to {@code "true"} * will cause an XML Declaration to be written out at the start of the SOAP * message. The default value of "false" suppresses this declaration. *

                                - * The property CHARACTER_SET_ENCODING defaults to the value - * "utf-8" which causes the SOAP message to be encoded using - * UTF-8. Setting CHARACTER_SET_ENCODING to "utf-16" + * The property {@code CHARACTER_SET_ENCODING} defaults to the value + * {@code "utf-8"} which causes the SOAP message to be encoded using + * UTF-8. Setting {@code CHARACTER_SET_ENCODING} to {@code "utf-16"} * causes the SOAP message to be encoded using UTF-16. *

                                * Some implementations may allow encodings in addition to UTF-8 and @@ -445,7 +442,7 @@ public abstract class SOAPMessage { * * @param property * the name of the property to retrieve - * @return the value associated with the named property or null + * @return the value associated with the named property or {@code null} * if no such property exists. * @exception SOAPException * if the property name is not recognized. diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPPart.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPPart.java index dc280fab60e..0a109422cf1 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPPart.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/soap/SOAPPart.java @@ -30,52 +30,51 @@ import java.util.Iterator; import javax.xml.transform.Source; /** - * The container for the SOAP-specific portion of a SOAPMessage + * The container for the SOAP-specific portion of a {@code SOAPMessage} * object. All messages are required to have a SOAP part, so when a - * SOAPMessage object is created, it will automatically - * have a SOAPPart object. - *

                                - * A SOAPPart object is a MIME part and has the MIME headers + * {@code SOAPMessage} object is created, it will automatically + * have a {@code SOAPPart} object. + *

                                + * A {@code SOAPPart} object is a MIME part and has the MIME headers * Content-Id, Content-Location, and Content-Type. Because the value of - * Content-Type must be "text/xml", a SOAPPart object automatically + * Content-Type must be "text/xml", a {@code SOAPPart} object automatically * has a MIME header of Content-Type with its value set to "text/xml". * The value must be "text/xml" because content in the SOAP part of a * message must be in XML format. Content that is not of type "text/xml" - * must be in an AttachmentPart object rather than in the - * SOAPPart object. + * must be in an {@code AttachmentPart} object rather than in the + * {@code SOAPPart} object. *

                                * When a message is sent, its SOAP part must have the MIME header Content-Type * set to "text/xml". Or, from the other perspective, the SOAP part of any * message that is received must have the MIME header Content-Type with a * value of "text/xml". *

                                - * A client can access the SOAPPart object of a - * SOAPMessage object by - * calling the method SOAPMessage.getSOAPPart. The - * following line of code, in which message is a - * SOAPMessage object, retrieves the SOAP part of a message. + * A client can access the {@code SOAPPart} object of a + * {@code SOAPMessage} object by + * calling the method {@code SOAPMessage.getSOAPPart}. The + * following line of code, in which {@code message} is a + * {@code SOAPMessage} object, retrieves the SOAP part of a message. *

                                  *   SOAPPart soapPart = message.getSOAPPart();
                                  * 
                                *

                                - * A SOAPPart object contains a SOAPEnvelope object, - * which in turn contains a SOAPBody object and a - * SOAPHeader object. - * The SOAPPart method getEnvelope can be used - * to retrieve the SOAPEnvelope object. - *

                                + * A {@code SOAPPart} object contains a {@code SOAPEnvelope} object, + * which in turn contains a {@code SOAPBody} object and a + * {@code SOAPHeader} object. + * The {@code SOAPPart} method {@code getEnvelope} can be used + * to retrieve the {@code SOAPEnvelope} object. * * @since 1.6 */ public abstract class SOAPPart implements org.w3c.dom.Document, Node { /** - * Gets the SOAPEnvelope object associated with this - * SOAPPart object. Once the SOAP envelope is obtained, it + * Gets the {@code SOAPEnvelope} object associated with this + * {@code SOAPPart} object. Once the SOAP envelope is obtained, it * can be used to get its contents. * - * @return the SOAPEnvelope object for this - * SOAPPart object + * @return the {@code SOAPEnvelope} object for this + * {@code SOAPPart} object * @exception SOAPException if there is a SOAP error */ public abstract SOAPEnvelope getEnvelope() throws SOAPException; @@ -83,7 +82,7 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { /** * Retrieves the value of the MIME header whose name is "Content-Id". * - * @return a String giving the value of the MIME header + * @return a {@code String} giving the value of the MIME header * named "Content-Id" * @see #setContentId */ @@ -97,7 +96,7 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { /** * Retrieves the value of the MIME header whose name is "Content-Location". * - * @return a String giving the value of the MIME header whose + * @return a {@code String} giving the value of the MIME header whose * name is "Content-Location" * @see #setContentLocation */ @@ -110,9 +109,9 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { /** * Sets the value of the MIME header named "Content-Id" - * to the given String. + * to the given {@code String}. * - * @param contentId a String giving the value of the MIME + * @param contentId a {@code String} giving the value of the MIME * header "Content-Id" * * @exception IllegalArgumentException if there is a problem in @@ -125,9 +124,9 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { } /** * Sets the value of the MIME header "Content-Location" - * to the given String. + * to the given {@code String}. * - * @param contentLocation a String giving the value + * @param contentLocation a {@code String} giving the value * of the MIME * header "Content-Location" * @exception IllegalArgumentException if there is a problem in @@ -141,24 +140,24 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { /** * Removes all MIME headers that match the given name. * - * @param header a String giving the name of the MIME header(s) to + * @param header a {@code String} giving the name of the MIME header(s) to * be removed */ public abstract void removeMimeHeader(String header); /** - * Removes all the MimeHeader objects for this - * SOAPEnvelope object. + * Removes all the {@code MimeHeader} objects for this + * {@code SOAPEnvelope} object. */ public abstract void removeAllMimeHeaders(); /** - * Gets all the values of the MimeHeader object - * in this SOAPPart object that - * is identified by the given String. + * Gets all the values of the {@code MimeHeader} object + * in this {@code SOAPPart} object that + * is identified by the given {@code String}. * * @param name the name of the header; example: "Content-Type" - * @return a String array giving all the values for the + * @return a {@code String} array giving all the values for the * specified header * @see #setMimeHeader */ @@ -176,13 +175,13 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { *

                                * Note that RFC822 headers can contain only US-ASCII characters. * - * @param name a String giving the header name + * @param name a {@code String} giving the header name * for which to search - * @param value a String giving the value to be set. + * @param value a {@code String} giving the value to be set. * This value will be substituted for the current value(s) * of the first header that is a match if there is one. * If there is no match, this value will be the value for - * a new MimeHeader object. + * a new {@code MimeHeader} object. * * @exception IllegalArgumentException if there was a problem with * the specified mime header name or value @@ -191,16 +190,16 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { public abstract void setMimeHeader(String name, String value); /** - * Creates a MimeHeader object with the specified - * name and value and adds it to this SOAPPart object. - * If a MimeHeader with the specified name already + * Creates a {@code MimeHeader} object with the specified + * name and value and adds it to this {@code SOAPPart} object. + * If a {@code MimeHeader} with the specified name already * exists, this method adds the specified value to the already * existing value(s). *

                                * Note that RFC822 headers can contain only US-ASCII characters. * - * @param name a String giving the header name - * @param value a String giving the value to be set + * @param name a {@code String} giving the header name + * @param value a {@code String} giving the value to be set * or added * @exception IllegalArgumentException if there was a problem with * the specified mime header name or value @@ -208,44 +207,44 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { public abstract void addMimeHeader(String name, String value); /** - * Retrieves all the headers for this SOAPPart object - * as an iterator over the MimeHeader objects. + * Retrieves all the headers for this {@code SOAPPart} object + * as an iterator over the {@code MimeHeader} objects. * - * @return an Iterator object with all of the Mime - * headers for this SOAPPart object + * @return an {@code Iterator} object with all of the Mime + * headers for this {@code SOAPPart} object */ public abstract Iterator getAllMimeHeaders(); /** - * Retrieves all MimeHeader objects that match a name in + * Retrieves all {@code MimeHeader} objects that match a name in * the given array. * - * @param names a String array with the name(s) of the + * @param names a {@code String} array with the name(s) of the * MIME headers to be returned * @return all of the MIME headers that match one of the names in the - * given array, returned as an Iterator object + * given array, returned as an {@code Iterator} object */ public abstract Iterator getMatchingMimeHeaders(String[] names); /** - * Retrieves all MimeHeader objects whose name does + * Retrieves all {@code MimeHeader} objects whose name does * not match a name in the given array. * - * @param names a String array with the name(s) of the + * @param names a {@code String} array with the name(s) of the * MIME headers not to be returned - * @return all of the MIME headers in this SOAPPart object + * @return all of the MIME headers in this {@code SOAPPart} object * except those that match one of the names in the * given array. The nonmatching MIME headers are returned as an - * Iterator object. + * {@code Iterator} object. */ public abstract Iterator getNonMatchingMimeHeaders(String[] names); /** - * Sets the content of the SOAPEnvelope object with the data - * from the given Source object. This Source + * Sets the content of the {@code SOAPEnvelope} object with the data + * from the given {@code Source} object. This {@code Source} * must contain a valid SOAP document. * - * @param source the javax.xml.transform.Source object with the + * @param source the {@code javax.xml.transform.Source} object with the * data to be set * * @exception SOAPException if there is a problem in setting the source @@ -254,13 +253,13 @@ public abstract class SOAPPart implements org.w3c.dom.Document, Node { public abstract void setContent(Source source) throws SOAPException; /** - * Returns the content of the SOAPEnvelope as a JAXP Source + * Returns the content of the SOAPEnvelope as a JAXP {@code Source} * object. * - * @return the content as a javax.xml.transform.Source object + * @return the content as a {@code javax.xml.transform.Source} object * * @exception SOAPException if the implementation cannot convert - * the specified Source object + * the specified {@code Source} object * @see #setContent */ public abstract Source getContent() throws SOAPException; diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Action.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Action.java index f42190b295e..445f651c893 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Action.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Action.java @@ -32,89 +32,90 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * The Action annotation allows explicit association of a - * WS-Addressing Action message addressing property with - * input, output, and - * fault messages of the mapped WSDL operation. + * The {@code Action} annotation allows explicit association of a + * WS-Addressing {@code Action} message addressing property with + * {@code input}, {@code output}, and + * {@code fault} messages of the mapped WSDL operation. *

                                * This annotation can be specified on each method of a service endpoint interface. * For such a method, the mapped operation in the generated WSDL's - * wsam:Action attribute on the WSDL input, - * output and fault messages of the WSDL operation - * is based upon which attributes of the Action annotation have been specified. - * For the exact computation of wsam:Action values for the messages, refer + * {@code wsam:Action} attribute on the WSDL {@code input}, + * {@code output} and {@code fault} messages of the WSDL {@code operation} + * is based upon which attributes of the {@code Action} annotation have been specified. + * For the exact computation of {@code wsam:Action} values for the messages, refer * to the algorithm in the JAX-WS specification. *

                                - * Example 1: Specify explicit values for Action message addressing property - * for input and output messages. + * Example 1: Specify explicit values for {@code Action} message addressing property + * for {@code input} and {@code output} messages. * *

                                - * @WebService(targetNamespace="http://example.com/numbers")
                                - * public class AddNumbersImpl {
                                - *     @Action(
                                - *         input="http://example.com/inputAction",
                                - *         output="http://example.com/outputAction")
                                - *     public int addNumbers(int number1, int number2) {
                                - *         return number1 + number2;
                                - *     }
                                - * }
                                + * {@literal @}WebService(targetNamespace="http://example.com/numbers")
                                + *  public class AddNumbersImpl {
                                + *     {@literal @}Action(
                                + *          input="http://example.com/inputAction",
                                + *          output="http://example.com/outputAction")
                                + *      public int addNumbers(int number1, int number2) {
                                + *          return number1 + number2;
                                + *      }
                                + *  }
                                  * 
                                * * The generated WSDL looks like: - *
                                - *   <definitions targetNamespace="http://example.com/numbers" ...>
                                + * 
                                 {@code
                                + *   
                                  *     ...
                                - *     <portType name="AddNumbersPortType">
                                - *       <operation name="AddNumbers">
                                - *         <input message="tns:AddNumbersInput" name="foo"
                                + *     
                                + *       
                                + *         wsam:Action="http://example.com/inputAction"/>
                                - *         <output message="tns:AddNumbersOutput" name="bar"
                                + *         wsam:Action="http://example.com/outputAction"/>
                                - *       </operation>
                                - *     </portType>
                                + *       
                                + *     
                                  *     ...
                                - *   </definitions>
                                + *   
                                + * }
                                  * 
                                * *

                                - * Example 2: Specify explicit value for Action message addressing property - * for only the input message. The wsam:Action values for the - * WSDL output message are computed using the algorithm in the JAX-WS specification. + * Example 2: Specify explicit value for {@code Action} message addressing property + * for only the {@code input} message. The {@code wsam:Action} values for the + * WSDL {@code output} message are computed using the algorithm in the JAX-WS specification. * *

                                - * @WebService(targetNamespace="http://example.com/numbers")
                                - * public class AddNumbersImpl {
                                - *     @Action(input="http://example.com/inputAction")
                                - *     public int addNumbers(int number1, int number2) {
                                - *         return number1 + number2;
                                - *     }
                                - * }
                                + * {@literal @}WebService(targetNamespace="http://example.com/numbers")
                                + *  public class AddNumbersImpl {
                                + *     {@literal @}Action(input="http://example.com/inputAction")
                                + *      public int addNumbers(int number1, int number2) {
                                + *          return number1 + number2;
                                + *      }
                                + *  }
                                  * 
                                * * The generated WSDL looks like: - *
                                - *   <definitions targetNamespace="http://example.com/numbers" ...>
                                + * 
                                 {@code
                                + *   
                                  *     ...
                                - *     <portType name="AddNumbersPortType">
                                - *       <operation name="AddNumbers">
                                - *         <input message="tns:AddNumbersInput" name="foo"
                                - *           wsam:Action="http://example.com/inputAction" />
                                - *         <output message="tns:AddNumbersOutput" name="bar"
                                + *     
                                + *       
                                + *         wsam:Action="http://example.com/inputAction"/>
                                + *         wsam:Action="http://example.com/numbers/AddNumbersPortType/AddNumbersResponse"/>
                                - *       </operation>
                                - *     </portType>
                                + *       
                                + *     
                                  *     ...
                                - *   </definitions>
                                - * 
                                + * + * }
                                * - * It is legitimate to specify an explicit value for Action message addressing property for - * output message only. In this case, wsam:Action value for the - * WSDL input message is computed using the algorithm in the JAX-WS specification. + * It is legitimate to specify an explicit value for {@code Action} message addressing property for + * {@code output} message only. In this case, {@code wsam:Action} value for the + * WSDL {@code input} message is computed using the algorithm in the JAX-WS specification. * *

                                * Example 3: See {@link FaultAction} annotation for an example of - * how to specify an explicit value for Action message addressing property for the - * fault message. + * how to specify an explicit value for {@code Action} message addressing property for the + * {@code fault} message. * * @see FaultAction * @@ -126,21 +127,21 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) public @interface Action { /** - * Explicit value of the WS-Addressing Action message addressing property for the input + * Explicit value of the WS-Addressing {@code Action} message addressing property for the {@code input} * message of the operation. */ String input() default ""; /** - * Explicit value of the WS-Addressing Action message addressing property for the output + * Explicit value of the WS-Addressing {@code Action} message addressing property for the {@code output} * message of the operation. */ String output() default ""; /** - * Explicit value of the WS-Addressing Action message addressing property for the fault + * Explicit value of the WS-Addressing {@code Action} message addressing property for the {@code fault} * message(s) of the operation. Each exception that is mapped to a fault and requires an explicit WS-Addressing - * Action message addressing property, needs to be specified as a value in this property + * {@code Action} message addressing property, needs to be specified as a value in this property * using {@link FaultAction} annotation. */ FaultAction[] fault() default { }; diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Binding.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Binding.java index 24be0222c67..f4f8c01d3bb 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Binding.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Binding.java @@ -26,7 +26,7 @@ package javax.xml.ws; -/** The Binding interface is the base interface +/** The {@code Binding} interface is the base interface * for JAX-WS protocol bindings. * * @since 1.6, JAX-WS 2.0 @@ -35,10 +35,10 @@ public interface Binding { /** * Gets a copy of the handler chain for a protocol binding instance. - * If the returned chain is modified a call to setHandlerChain + * If the returned chain is modified a call to {@code setHandlerChain} * is required to configure the binding instance with the new chain. * - * @return java.util.List<Handler> Handler chain + * @return {@code java.util.List} Handler chain */ public java.util.List getHandlerChain(); @@ -59,7 +59,7 @@ public interface Binding { * Get the URI for this binding instance. * * @return String The binding identifier for the port. - * Never returns null + * Never returns {@code null} * * @since 1.6, JAX-WS 2.1 */ diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Dispatch.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Dispatch.java index 7c96bab57d8..8bef4ee4cf5 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Dispatch.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/Dispatch.java @@ -27,10 +27,10 @@ package javax.xml.ws; import java.util.concurrent.Future; -/** The Dispatch interface provides support +/** The {@code Dispatch} interface provides support * for the dynamic invocation of a service endpoint operations. The - * javax.xml.ws.Service - * class acts as a factory for the creation of Dispatch + * {@code javax.xml.ws.Service} + * class acts as a factory for the creation of {@code Dispatch} * instances. * * @since 1.6, JAX-WS 2.0 @@ -39,7 +39,7 @@ public interface Dispatch extends BindingProvider { /** Invoke a service operation synchronously. * - * The client is responsible for ensuring that the msg object + * The client is responsible for ensuring that the {@code msg} object * when marshalled is formed according to the requirements of the protocol * binding in use. * @@ -50,16 +50,16 @@ public interface Dispatch extends BindingProvider { * @throws WebServiceException If a fault occurs during communication with * the service * @throws WebServiceException If there is any error in the configuration of - * the Dispatch instance + * the {@code Dispatch} instance **/ public T invoke(T msg); /** Invoke a service operation asynchronously. The * method returns without waiting for the response to the operation * invocation, the results of the operation are obtained by polling the - * returned Response. + * returned {@code Response}. *

                                - * The client is responsible for ensuring that the msg object + * The client is responsible for ensuring that the {@code msg} object * when marshalled is formed according to the requirements of the protocol * binding in use. * @@ -68,16 +68,16 @@ public interface Dispatch extends BindingProvider { * @return The response message or message payload to the * operation invocation. * @throws WebServiceException If there is any error in the configuration of - * the Dispatch instance + * the {@code Dispatch} instance **/ public Response invokeAsync(T msg); /** Invoke a service operation asynchronously. The * method returns without waiting for the response to the operation * invocation, the results of the operation are communicated to the client - * via the passed in handler. + * via the passed in {@code handler}. *

                                - * The client is responsible for ensuring that the msg object + * The client is responsible for ensuring that the {@code msg} object * when marshalled is formed according to the requirements of the protocol * binding in use. * @@ -85,13 +85,13 @@ public interface Dispatch extends BindingProvider { * the message used to invoke the operation. * @param handler The handler object that will receive the * response to the operation invocation. - * @return A Future object that may be used to check the status + * @return A {@code Future} object that may be used to check the status * of the operation invocation. This object MUST NOT be used to try to * obtain the results of the operation - the object returned from - * Future<?>.get() is implementation dependent + * {@code Future.get()} is implementation dependent * and any use of it will result in non-portable behaviour. * @throws WebServiceException If there is any error in the configuration of - * the Dispatch instance + * the {@code Dispatch} instance **/ public Future invokeAsync(T msg, AsyncHandler handler); @@ -102,14 +102,14 @@ public interface Dispatch extends BindingProvider { * the protocol in use is SOAP/HTTP, this method MUST block until * an HTTP response code has been received or an error occurs. *

                                - * The client is responsible for ensuring that the msg object + * The client is responsible for ensuring that the {@code msg} object * when marshalled is formed according to the requirements of the protocol * binding in use. * * @param msg An object that will form the message or payload of * the message used to invoke the operation. * @throws WebServiceException If there is any error in the configuration of - * the Dispatch instance or if an error occurs during the + * the {@code Dispatch} instance or if an error occurs during the * invocation. **/ public void invokeOneWay(T msg); diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/FaultAction.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/FaultAction.java index 43e37f608ea..7fd4eff7f7e 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/FaultAction.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/FaultAction.java @@ -32,28 +32,28 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * The FaultAction annotation is used inside an {@link Action} + * The {@code FaultAction} annotation is used inside an {@link Action} * annotation to allow an explicit association of a WS-Addressing - * Action message addressing property with the fault + * {@code Action} message addressing property with the {@code fault} * messages of the WSDL operation mapped from the exception class. *

                                - * The wsam:Action attribute value in the fault - * message in the generated WSDL operation mapped for className - * class is equal to the corresponding value in the FaultAction. - * For the exact computation of wsam:Action values for the + * The {@code wsam:Action} attribute value in the {@code fault} + * message in the generated WSDL operation mapped for {@code className} + * class is equal to the corresponding value in the {@code FaultAction}. + * For the exact computation of {@code wsam:Action} values for the * fault messages, refer to the algorithm in the JAX-WS specification. * *

                                - * Example 1: Specify explicit values for Action message addressing - * property for the input, output and fault message + * Example 1: Specify explicit values for {@code Action} message addressing + * property for the {@code input}, {@code output} and {@code fault} message * if the Java method throws only one service specific exception. * *

                                - * @WebService(targetNamespace="http://example.com/numbers")
                                - * public class AddNumbersImpl {
                                - *     @Action(
                                + * {@literal @}WebService(targetNamespace="http://example.com/numbers")
                                + *  public class AddNumbersImpl {
                                + *    {@literal @}Action(
                                  *         fault = {
                                - *             @FaultAction(className=AddNumbersException.class, value="http://example.com/faultAction")
                                + *             {@literal @}FaultAction(className=AddNumbersException.class, value="http://example.com/faultAction")
                                  *         })
                                  *     public int addNumbers(int number1, int number2)
                                  *         throws AddNumbersException {
                                @@ -64,86 +64,86 @@ import java.lang.annotation.Target;
                                  *
                                  * The generated WSDL looks like:
                                  *
                                - * 
                                - *   <definitions targetNamespace="http://example.com/numbers" ...>
                                + * 
                                 {@code
                                + *   
                                  *     ...
                                - *     <portType name="AddNumbersPortType">
                                - *       <operation name="AddNumbers">
                                + *     
                                + *       
                                  *         ...
                                - *         <fault message="tns:AddNumbersException" name="AddNumbersException"
                                - *           wsam:Action="http://example.com/faultAction"/>
                                - *       </operation>
                                - *     </portType>
                                + *         wsam:Action="http://example.com/faultAction"{@code />
                                + *       
                                + *     
                                  *     ...
                                - *   </definitions>
                                + *    }
                                  * 
                                * *

                                - * Example 2: Here is an example that shows if the explicit value for Action + * Example 2: Here is an example that shows if the explicit value for {@code Action} * message addressing property for the service specific exception is not present. * *

                                - * @WebService(targetNamespace="http://example.com/numbers")
                                - * public class AddNumbersImpl {
                                + * {@literal @}WebService(targetNamespace="http://example.com/numbers")
                                + *  public class AddNumbersImpl {
                                  *     public int addNumbers(int number1, int number2)
                                  *         throws AddNumbersException {
                                  *         return number1 + number2;
                                  *     }
                                - * }
                                + *  }
                                  * 
                                * * The generated WSDL looks like: * - *
                                - *   <definitions targetNamespace="http://example.com/numbers" ...>
                                + * 
                                {@code
                                + *   
                                  *     ...
                                - *     <portType name="AddNumbersPortType">
                                - *       <operation name="AddNumbers">
                                + *     
                                + *       
                                  *         ...
                                - *         <fault message="tns:addNumbersFault" name="InvalidNumbers"
                                - *           wsam:Action="http://example.com/numbers/AddNumbersPortType/AddNumbers/Fault/AddNumbersException"/>
                                - *       </operation>
                                - *     </portType>
                                + *         wsam:Action="http://example.com/numbers/AddNumbersPortType/AddNumbers/Fault/AddNumbersException"{@code />
                                + *       
                                + *     
                                  *     ...
                                - *   </definitions>
                                - * 
                                + * + * }
                                * *

                                - * Example 3: Here is an example that shows how to specify explicit values for Action + * Example 3: Here is an example that shows how to specify explicit values for {@code Action} * message addressing property if the Java method throws more than one service specific exception. * *

                                - * @WebService(targetNamespace="http://example.com/numbers")
                                - * public class AddNumbersImpl {
                                - *     @Action(
                                + * {@literal @}WebService(targetNamespace="http://example.com/numbers")
                                + *  public class AddNumbersImpl {
                                + *    {@literal @}Action(
                                  *         fault = {
                                - *             @FaultAction(className=AddNumbersException.class, value="http://example.com/addFaultAction"),
                                - *             @FaultAction(className=TooBigNumbersException.class, value="http://example.com/toobigFaultAction")
                                + *             {@literal @}FaultAction(className=AddNumbersException.class, value="http://example.com/addFaultAction"),
                                + *             {@literal @}FaultAction(className=TooBigNumbersException.class, value="http://example.com/toobigFaultAction")
                                  *         })
                                  *     public int addNumbers(int number1, int number2)
                                  *         throws AddNumbersException, TooBigNumbersException {
                                  *         return number1 + number2;
                                  *     }
                                - * }
                                + *  }
                                  * 
                                * * The generated WSDL looks like: * - *
                                - *   <definitions targetNamespace="http://example.com/numbers" ...>
                                + * 
                                 {@code
                                + *   
                                  *     ...
                                - *     <portType name="AddNumbersPortType">
                                - *       <operation name="AddNumbers">
                                + *     
                                + *       
                                  *         ...
                                - *         <fault message="tns:addNumbersFault" name="AddNumbersException"
                                - *           wsam:Action="http://example.com/addFaultAction"/>
                                - *         <fault message="tns:tooBigNumbersFault" name="TooBigNumbersException"
                                - *           wsam:Action="http://example.com/toobigFaultAction"/>
                                - *       </operation>
                                - *     </portType>
                                + *         wsam:Action="http://example.com/addFaultAction"{@code />
                                + *         wsam:Action="http://example.com/toobigFaultAction"{@code />
                                + *       
                                + *     
                                  *     ...
                                - *   </definitions>
                                - * 
                                + * + * }
                                * * @since 1.6, JAX-WS 2.1 */ @@ -158,7 +158,7 @@ public @interface FaultAction { Class className(); /** - * Value of WS-Addressing Action message addressing property for the exception + * Value of WS-Addressing {@code Action} message addressing property for the exception */ String value() default ""; } diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/WebServicePermission.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/WebServicePermission.java index 743243f22f6..08751c4ea5a 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/WebServicePermission.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/WebServicePermission.java @@ -35,16 +35,14 @@ import java.security.BasicPermission; * with them. *

                                * The following permission target name is defined: - *

                                *

                                *
                                publishEndpoint *
                                + * The {@code publishEndpoint} permission allows publishing a + * web service endpoint using the {@code publish} methods + * defined by the {@code javax.xml.ws.Endpoint} class. *

                                - * The publishEndpoint permission allows publishing a - * web service endpoint using the publish methods - * defined by the javax.xml.ws.Endpoint class. - *

                                - * Granting publishEndpoint allows the application to be + * Granting {@code publishEndpoint} allows the application to be * exposed as a network service. Depending on the security of the runtime and * the security of the application, this may introduce a security hole that * is remotely exploitable. @@ -64,7 +62,7 @@ public final class WebServicePermission extends BasicPermission { /** * Creates a new permission with the specified name. * - * @param name the name of the WebServicePermission + * @param name the name of the {@code WebServicePermission} */ public WebServicePermission(String name) { super(name); @@ -73,11 +71,11 @@ public final class WebServicePermission extends BasicPermission { /** * Creates a new permission with the specified name and actions. * - * The actions parameter is currently unused and - * it should be null. + * The {@code actions} parameter is currently unused and + * it should be {@code null}. * - * @param name the name of the WebServicePermission - * @param actions should be null + * @param name the name of the {@code WebServicePermission} + * @param actions should be {@code null} */ public WebServicePermission(String name, String actions) { super(name, actions); diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/HandlerResolver.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/HandlerResolver.java index c0f2f97361b..7f1358c0e71 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/HandlerResolver.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/HandlerResolver.java @@ -26,15 +26,15 @@ package javax.xml.ws.handler; /** - * HandlerResolver is an interface implemented + * {@code HandlerResolver} is an interface implemented * by an application to get control over the handler chain * set on proxy/dispatch objects at the time of their creation. *

                                - * A HandlerResolver may be set on a Service - * using the setHandlerResolver method. - *

                                - * When the runtime invokes a HandlerResolver, it will - * pass it a PortInfo object containing information + * A {@code HandlerResolver} may be set on a {@code Service} + * using the {@code setHandlerResolver} method. + *

                                + * When the runtime invokes a {@code HandlerResolver}, it will + * pass it a {@code PortInfo} object containing information * about the port that the proxy/dispatch object will be accessing. * * @see javax.xml.ws.Service#setHandlerResolver @@ -47,7 +47,7 @@ public interface HandlerResolver { * Gets the handler chain for the specified port. * * @param portInfo Contains information about the port being accessed. - * @return java.util.List<Handler> chain + * @return {@code java.util.List} chain **/ public java.util.List getHandlerChain(PortInfo portInfo); } diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/MessageContext.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/MessageContext.java index 35525fc0440..aab8550dead 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/MessageContext.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/handler/MessageContext.java @@ -27,12 +27,12 @@ package javax.xml.ws.handler; import java.util.Map; /** - * The interface MessageContext abstracts the message - * context that is processed by a handler in the handle + * The interface {@code MessageContext} abstracts the message + * context that is processed by a handler in the {@code handle} * method. * - *

                                The MessageContext interface provides methods to - * manage a property set. MessageContext properties + *

                                The {@code MessageContext} interface provides methods to + * manage a property set. {@code MessageContext} properties * enable handlers in a handler chain to share processing related * state. * @@ -41,8 +41,8 @@ import java.util.Map; public interface MessageContext extends Map { /** - * Standard property: message direction, true for - * outbound messages, false for inbound. + * Standard property: message direction, {@code true} for + * outbound messages, {@code false} for inbound. *

                                Type: boolean */ public static final String MESSAGE_OUTBOUND_PROPERTY = @@ -51,7 +51,7 @@ public interface MessageContext extends Map { /** * Standard property: Map of attachments to a message for the inbound * message, key is the MIME Content-ID, value is a DataHandler. - *

                                Type: java.util.Map<String,DataHandler> + *

                                Type: {@code java.util.Map} */ public static final String INBOUND_MESSAGE_ATTACHMENTS = "javax.xml.ws.binding.attachments.inbound"; @@ -59,7 +59,7 @@ public interface MessageContext extends Map { /** * Standard property: Map of attachments to a message for the outbound * message, key is the MIME Content-ID, value is a DataHandler. - *

                                Type: java.util.Map<String,DataHandler> + *

                                Type: {@code java.util.Map} */ public static final String OUTBOUND_MESSAGE_ATTACHMENTS = "javax.xml.ws.binding.attachments.outbound"; @@ -108,14 +108,14 @@ public interface MessageContext extends Map { /** * Standard property: HTTP request headers. - *

                                Type: java.util.Map<java.lang.String, java.util.List<java.lang.String>> + *

                                Type: {@code java.util.Map>} */ public static final String HTTP_REQUEST_HEADERS = "javax.xml.ws.http.request.headers"; /** * Standard property: HTTP response headers. - *

                                Type: java.util.Map<java.lang.String, java.util.List<java.lang.String>> + *

                                Type: {@code java.util.Map>} */ public static final String HTTP_RESPONSE_HEADERS = "javax.xml.ws.http.response.headers"; @@ -166,7 +166,7 @@ public interface MessageContext extends Map { * Standard property: WS Addressing Reference Parameters. * The list MUST include all SOAP headers marked with the * wsa:IsReferenceParameter="true" attribute. - *

                                Type: List<Element> + *

                                Type: {@code List} * * @since 1.6, JAX-WS 2.1 */ @@ -174,10 +174,10 @@ public interface MessageContext extends Map { "javax.xml.ws.reference.parameters"; /** - * Property scope. Properties scoped as APPLICATION are + * Property scope. Properties scoped as {@code APPLICATION} are * visible to handlers, * client applications and service endpoints; properties scoped as - * HANDLER + * {@code HANDLER} * are only normally visible to handlers. */ public enum Scope {APPLICATION, HANDLER}; @@ -186,7 +186,7 @@ public interface MessageContext extends Map { * Sets the scope of a property. * * @param name Name of the property associated with the - * MessageContext + * {@code MessageContext} * @param scope Desired scope of the property * @throws java.lang.IllegalArgumentException if an illegal * property name is specified diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/AddressingFeature.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/AddressingFeature.java index 8f9d730d797..2da2aaf14dc 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/AddressingFeature.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/AddressingFeature.java @@ -52,10 +52,10 @@ import javax.xml.ws.Service; * receiver. * *

                                - * If the feature is enabled, the required property determines + * If the feature is enabled, the {@code required} property determines * whether the endpoint requires WS-Addressing. If it is set true, * WS-Addressing headers MUST be present on incoming and outgoing messages. - * By default the required property is false. + * By default the {@code required} property is {@code false}. * *

                                * If the web service developer has not explicitly enabled this feature, @@ -75,31 +75,31 @@ import javax.xml.ws.Service; * *

                                * Example 1: Possible Policy Assertion in the generated WSDL for - * @Addressing - *

                                - *   <wsam:Addressing wsp:Optional="true">
                                - *     <wsp:Policy/>
                                - *   </wsam:Addressing>
                                + * {@code @Addressing}
                                + * 
                                 {@code
                                + *   
                                + *     
                                + *    }
                                  * 
                                * *

                                * Example 2: Possible Policy Assertion in the generated WSDL for - * @Addressing(required=true) - *

                                - *   <wsam:Addressing>
                                - *     <wsp:Policy/>
                                - *   </wsam:Addressing>
                                + * {@code @Addressing(required=true)}
                                + * 
                                 {@code
                                + *   
                                + *     
                                + *    }
                                  * 
                                * *

                                * Example 3: Possible Policy Assertion in the generated WSDL for - * @Addressing(required=true, responses=Responses.ANONYMOUS) - *

                                - *   <wsam:Addressing>
                                - *      <wsp:Policy>
                                - *        <wsam:AnonymousResponses/>
                                - *      </wsp:Policy>
                                - *   </wsam:Addressing>
                                + * {@code @Addressing(required=true, responses=Responses.ANONYMOUS)}
                                + * 
                                 {@code
                                + *   
                                + *      
                                + *        
                                + *      
                                + *    }
                                  * 
                                * *

                                @@ -181,7 +181,7 @@ public final class AddressingFeature extends WebServiceFeature { private final Responses responses; /** - * Creates and configures an AddressingFeature with the + * Creates and configures an {@code AddressingFeature} with the * use of addressing requirements. The created feature enables * ws-addressing i.e. supports ws-addressing but doesn't require * its use. It is also configured to accept all the response types. @@ -191,8 +191,8 @@ public final class AddressingFeature extends WebServiceFeature { } /** - * Creates and configures an AddressingFeature with the - * use of addressing requirements. If enabled is true, + * Creates and configures an {@code AddressingFeature} with the + * use of addressing requirements. If {@code enabled} is true, * it enables ws-addressing i.e. supports ws-addressing but doesn't * require its use. It also configures to accept all the response types. * @@ -204,9 +204,9 @@ public final class AddressingFeature extends WebServiceFeature { } /** - * Creates and configures an AddressingFeature with the - * use of addressing requirements. If enabled and - * required are true, it enables ws-addressing and + * Creates and configures an {@code AddressingFeature} with the + * use of addressing requirements. If {@code enabled} and + * {@code required} are true, it enables ws-addressing and * requires its use. It also configures to accept all the response types. * * @param enabled true enables ws-addressing i.e.ws-addressing @@ -218,11 +218,11 @@ public final class AddressingFeature extends WebServiceFeature { } /** - * Creates and configures an AddressingFeature with the - * use of addressing requirements. If enabled and - * required are true, it enables ws-addressing and + * Creates and configures an {@code AddressingFeature} with the + * use of addressing requirements. If {@code enabled} and + * {@code required} are true, it enables ws-addressing and * requires its use. Also, the response types can be configured using - * responses parameter. + * {@code responses} parameter. * * @param enabled true enables ws-addressing i.e.ws-addressing * is supported but doesn't require its use @@ -260,7 +260,6 @@ public final class AddressingFeature extends WebServiceFeature { * requires the use of anonymous responses, or non-anonymous responses, * or all responses. * - *

                                * @return {@link Responses#ALL} when endpoint supports all types of * responses, * {@link Responses#ANONYMOUS} when endpoint requires the use of diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOM.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOM.java index da6714e9a7e..cd59f0ffcbb 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOM.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOM.java @@ -40,14 +40,14 @@ import javax.xml.ws.WebServiceProvider; * web service. *

                                * This annotation MUST only be used in conjunction the - * javax.jws.WebService, {@link WebServiceProvider}, + * {@code javax.jws.WebService}, {@link WebServiceProvider}, * {@link WebServiceRef} annotations. - * When used with the javax.jws.WebService annotation this + * When used with the {@code javax.jws.WebService} annotation this * annotation MUST only be used on the service endpoint implementation * class. - * When used with a WebServiceRef annotation, this annotation + * When used with a {@code WebServiceRef} annotation, this annotation * MUST only be used when a proxy instance is created. The injected SEI - * proxy, and endpoint MUST honor the values of the MTOM + * proxy, and endpoint MUST honor the values of the {@code MTOM} * annotation. *

                                * @@ -69,7 +69,7 @@ public @interface MTOM { /** * Property for MTOM threshold value. When MTOM is enabled, binary data above this * size in bytes will be XOP encoded or sent as attachment. The value of this property - * MUST always be >= 0. Default value is 0. + * MUST always be {@literal >=} 0. Default value is 0. */ int threshold() default 0; } diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOMFeature.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOMFeature.java index 232f98f91c2..4ffb051a641 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOMFeature.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/MTOMFeature.java @@ -67,14 +67,14 @@ public final class MTOMFeature extends WebServiceFeature { * Property for MTOM threshold value. This property serves as a hint when * MTOM is enabled, binary data above this size in bytes SHOULD be sent * as attachment. - * The value of this property MUST always be >= 0. Default value is 0. + * The value of this property MUST always be {@literal >=} 0. Default value is 0. */ // should be changed to private final, keeping original modifier to keep backwards compatibility protected int threshold; /** - * Create an MTOMFeature. + * Create an {@code MTOMFeature}. * The instance created will be enabled. */ public MTOMFeature() { @@ -83,7 +83,7 @@ public final class MTOMFeature extends WebServiceFeature { } /** - * Creates an MTOMFeature. + * Creates a {@code MTOMFeature}. * * @param enabled specifies if this feature should be enabled or not */ @@ -94,13 +94,13 @@ public final class MTOMFeature extends WebServiceFeature { /** - * Creates an MTOMFeature. + * Creates a {@code MTOMFeature}. * The instance created will be enabled. * * @param threshold the size in bytes that binary data SHOULD be before * being sent as an attachment. * - * @throws WebServiceException if threshold is < 0 + * @throws WebServiceException if threshold is {@literal <} 0 */ public MTOMFeature(int threshold) { if (threshold < 0) @@ -110,13 +110,13 @@ public final class MTOMFeature extends WebServiceFeature { } /** - * Creates an MTOMFeature. + * Creates a {@code MTOMFeature}. * * @param enabled specifies if this feature should be enabled or not * @param threshold the size in bytes that binary data SHOULD be before * being sent as an attachment. * - * @throws WebServiceException if threshold is < 0 + * @throws WebServiceException if threshold is {@literal <} 0 */ public MTOMFeature(boolean enabled, int threshold) { if (threshold < 0) diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/SOAPBinding.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/SOAPBinding.java index 4b9d88887f4..885328b14e1 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/SOAPBinding.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/soap/SOAPBinding.java @@ -31,7 +31,7 @@ import javax.xml.ws.Binding; import javax.xml.soap.SOAPFactory; import javax.xml.soap.MessageFactory; -/** The SOAPBinding interface is an abstraction for +/** The {@code SOAPBinding} interface is an abstraction for * the SOAP binding. * * @since 1.6, JAX-WS 2.0 @@ -63,7 +63,7 @@ public interface SOAPBinding extends Binding { /** Gets the roles played by the SOAP binding instance. * - * @return Set<String> The set of roles played by the binding instance. + * @return {@code Set} The set of roles played by the binding instance. **/ public Set getRoles(); @@ -76,9 +76,9 @@ public interface SOAPBinding extends Binding { public void setRoles(Set roles); /** - * Returns true if the use of MTOM is enabled. + * Returns {@code true} if the use of MTOM is enabled. * - * @return true if and only if the use of MTOM is enabled. + * @return {@code true} if and only if the use of MTOM is enabled. **/ public boolean isMTOMEnabled(); @@ -86,7 +86,7 @@ public interface SOAPBinding extends Binding { /** * Enables or disables use of MTOM. * - * @param flag A boolean specifying whether the use of MTOM should + * @param flag A {@code boolean} specifying whether the use of MTOM should * be enabled or disabled. * @throws WebServiceException If the specified setting is not supported * by this binding instance. @@ -95,14 +95,14 @@ public interface SOAPBinding extends Binding { public void setMTOMEnabled(boolean flag); /** - * Gets the SAAJ SOAPFactory instance used by this SOAP binding. + * Gets the SAAJ {@code SOAPFactory} instance used by this SOAP binding. * * @return SOAPFactory instance used by this SOAP binding. **/ public SOAPFactory getSOAPFactory(); /** - * Gets the SAAJ MessageFactory instance used by this SOAP binding. + * Gets the SAAJ {@code MessageFactory} instance used by this SOAP binding. * * @return MessageFactory instance used by this SOAP binding. **/ diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/Provider.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/Provider.java index 8c8b802130f..785a58a2c6f 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/Provider.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/Provider.java @@ -37,9 +37,8 @@ import javax.xml.ws.wsaddressing.W3CEndpointReference; import org.w3c.dom.Element; /** - * Service provider for ServiceDelegate and - * Endpoint objects. - *

                                + * Service provider for {@code ServiceDelegate} and + * {@code Endpoint} objects. * * @since 1.6, JAX-WS 2.0 */ @@ -47,14 +46,14 @@ public abstract class Provider { /** * A constant representing the property used to lookup the - * name of a Provider implementation + * name of a {@code Provider} implementation * class. */ static public final String JAXWSPROVIDER_PROPERTY = "javax.xml.ws.spi.Provider"; /** * A constant representing the name of the default - * Provider implementation class. + * {@code Provider} implementation class. **/ // Using two strings so that package renaming doesn't change it static final String DEFAULT_JAXWSPROVIDER @@ -72,22 +71,21 @@ public abstract class Provider { *

                                * The algorithm used to locate the provider subclass to use consists * of the following steps: - *

                                *

                                  *
                                • * If a resource with the name of - * META-INF/services/javax.xml.ws.spi.Provider + * {@code META-INF/services/javax.xml.ws.spi.Provider} * exists, then its first line, if present, is used as the UTF-8 encoded * name of the implementation class. *
                                • *
                                • * If the $java.home/lib/jaxws.properties file exists and it is readable by - * the java.util.Properties.load(InputStream) method and it contains - * an entry whose key is javax.xml.ws.spi.Provider, then the value of + * the {@code java.util.Properties.load(InputStream)} method and it contains + * an entry whose key is {@code javax.xml.ws.spi.Provider}, then the value of * that entry is used as the name of the implementation class. *
                                • *
                                • - * If a system property with the name javax.xml.ws.spi.Provider + * If a system property with the name {@code javax.xml.ws.spi.Provider} * is defined, then its value is used as the name of the implementation class. *
                                • *
                                • @@ -136,12 +134,12 @@ public abstract class Provider { /** * Creates a service delegate object. - *

                                  + * * @param wsdlDocumentLocation A URL pointing to the WSDL document - * for the service, or null if there isn't one. + * for the service, or {@code null} if there isn't one. * @param serviceName The qualified name of the service. * @param serviceClass The service class, which MUST be either - * javax.xml.ws.Service or a subclass thereof. + * {@code javax.xml.ws.Service} or a subclass thereof. * @return The newly created service delegate. */ public abstract ServiceDelegate createServiceDelegate( @@ -150,12 +148,12 @@ public abstract class Provider { /** * Creates a service delegate object. - *

                                  + * * @param wsdlDocumentLocation A URL pointing to the WSDL document - * for the service, or null if there isn't one. + * for the service, or {@code null} if there isn't one. * @param serviceName The qualified name of the service. * @param serviceClass The service class, which MUST be either - * javax.xml.ws.Service or a subclass thereof. + * {@code javax.xml.ws.Service} or a subclass thereof. * @param features Web Service features that must be configured on * the service. If the provider doesn't understand a feature, * it must throw a WebServiceException. @@ -205,18 +203,18 @@ public abstract class Provider { /** * read an EndpointReference from the infoset contained in - * eprInfoset. + * {@code eprInfoset}. * * @param eprInfoset infoset for EndpointReference * - * @return the EndpointReference unmarshalled from - * eprInfoset. This method never returns null. + * @return the {@code EndpointReference} unmarshalled from + * {@code eprInfoset}. This method never returns {@code null}. * * @throws WebServiceException If there is an error creating the - * EndpointReference from the specified eprInfoset. + * {@code EndpointReference} from the specified {@code eprInfoset}. * - * @throws NullPointerException If the null - * eprInfoset value is given. + * @throws NullPointerException If the {@code null} + * {@code eprInfoset} value is given. * * @since 1.6, JAX-WS 2.1 **/ @@ -226,31 +224,31 @@ public abstract class Provider { /** * The getPort method returns a proxy. If there * are any reference parameters in the - * endpointReference, then those reference + * {@code endpointReference}, then those reference * parameters MUST appear as SOAP headers, indicating them to be * reference parameters, on all messages sent to the endpoint. - * The parameter serviceEndpointInterface specifies + * The parameter {@code serviceEndpointInterface} specifies * the service endpoint interface that is supported by the * returned proxy. - * The parameter endpointReference specifies the + * The parameter {@code endpointReference} specifies the * endpoint that will be invoked by the returned proxy. * In the implementation of this method, the JAX-WS * runtime system takes the responsibility of selecting a protocol * binding (and a port) and configuring the proxy accordingly from * the WSDL metadata of the - * serviceEndpointInterface and the EndpointReference. + * {@code serviceEndpointInterface} and the {@code EndpointReference}. * For this method * to successfully return a proxy, WSDL metadata MUST be available and the - * endpointReference MUST contain an implementation understood - * serviceName metadata. + * {@code endpointReference} MUST contain an implementation understood + * {@code serviceName} metadata. * * * @param endpointReference the EndpointReference that will * be invoked by the returned proxy. * @param serviceEndpointInterface Service endpoint interface * @param features A list of WebServiceFeatures to configure on the - * proxy. Supported features not in the features - * parameter will have their default values. + * proxy. Supported features not in the {@code features + * } parameter will have their default values. * @return Object Proxy instance that supports the * specified service endpoint interface * @throws WebServiceException @@ -260,10 +258,10 @@ public abstract class Provider { *

                                • If there is any missing WSDL metadata * as required by this method} *
                                • If this - * endpointReference + * {@code endpointReference} * is illegal *
                                • If an illegal - * serviceEndpointInterface + * {@code serviceEndpointInterface} * is specified *
                                • If a feature is enabled that is not compatible with * this port or is unsupported. @@ -278,60 +276,60 @@ public abstract class Provider { WebServiceFeature... features); /** - * Factory method to create a W3CEndpointReference. + * Factory method to create a {@code W3CEndpointReference}. * *

                                  - * This method can be used to create a W3CEndpointReference - * for any endpoint by specifying the address property along + * This method can be used to create a {@code W3CEndpointReference} + * for any endpoint by specifying the {@code address} property along * with any other desired properties. This method - * can also be used to create a W3CEndpointReference for + * can also be used to create a {@code W3CEndpointReference} for * an endpoint that is published by the same Java EE application. - * To do so the address property can be provided or this - * method can automatically determine the address of + * To do so the {@code address} property can be provided or this + * method can automatically determine the {@code address} of * an endpoint that is published by the same Java EE application and is - * identified by the serviceName and - * portName propeties. If the address is - * null and the serviceName and - * portName do not identify an endpoint published by the + * identified by the {@code serviceName} and + * {@code portName} propeties. If the {@code address} is + * {@code null} and the {@code serviceName} and + * {@code portName} do not identify an endpoint published by the * same Java EE application, a - * javax.lang.IllegalStateException MUST be thrown. + * {@code javax.lang.IllegalStateException} MUST be thrown. * * @param address Specifies the address of the target endpoint * @param serviceName Qualified name of the service in the WSDL. * @param portName Qualified name of the endpoint in the WSDL. * @param metadata A list of elements that should be added to the - * W3CEndpointReference instances wsa:metadata + * {@code W3CEndpointReference} instances {@code wsa:metadata} * element. * @param wsdlDocumentLocation URL for the WSDL document location for * the service. * @param referenceParameters Reference parameters to be associated - * with the returned EndpointReference instance. + * with the returned {@code EndpointReference} instance. * - * @return the W3CEndpointReference created from - * serviceName, portName, - * metadata, wsdlDocumentLocation - * and referenceParameters. This method - * never returns null. + * @return the {@code W3CEndpointReference} created from + * {@code serviceName}, {@code portName}, + * {@code metadata}, {@code wsdlDocumentLocation} + * and {@code referenceParameters}. This method + * never returns {@code null}. * * @throws java.lang.IllegalStateException *

                                    - *
                                  • If the address, serviceName and - * portName are all null. - *
                                  • If the serviceName service is null and the - * portName is NOT null. - *
                                  • If the address property is null and - * the serviceName and portName do not + *
                                  • If the {@code address}, {@code serviceName} and + * {@code portName} are all {@code null}. + *
                                  • If the {@code serviceName} service is {@code null} and the + * {@code portName} is NOT {@code null}. + *
                                  • If the {@code address} property is {@code null} and + * the {@code serviceName} and {@code portName} do not * specify a valid endpoint published by the same Java EE * application. - *
                                  • If the serviceNameis NOT null + *
                                  • If the {@code serviceName}is NOT {@code null} * and is not present in the specified WSDL. - *
                                  • If the portName port is not null and it - * is not present in serviceName service in the WSDL. - *
                                  • If the wsdlDocumentLocation is NOT null + *
                                  • If the {@code portName} port is not {@code null} and it + * is not present in {@code serviceName} service in the WSDL. + *
                                  • If the {@code wsdlDocumentLocation} is NOT {@code null} * and does not represent a valid WSDL. *
                                  * @throws WebServiceException If an error occurs while creating the - * W3CEndpointReference. + * {@code W3CEndpointReference}. * * @since 1.6, JAX-WS 2.1 */ @@ -340,73 +338,73 @@ public abstract class Provider { /** - * Factory method to create a W3CEndpointReference. - * Using this method, a W3CEndpointReference instance + * Factory method to create a {@code W3CEndpointReference}. + * Using this method, a {@code W3CEndpointReference} instance * can be created with extension elements, and attributes. - * Provider implementations must override the default + * {@code Provider} implementations must override the default * implementation. * *

                                  - * This method can be used to create a W3CEndpointReference - * for any endpoint by specifying the address property along + * This method can be used to create a {@code W3CEndpointReference} + * for any endpoint by specifying the {@code address} property along * with any other desired properties. This method - * can also be used to create a W3CEndpointReference for + * can also be used to create a {@code W3CEndpointReference} for * an endpoint that is published by the same Java EE application. - * To do so the address property can be provided or this - * method can automatically determine the address of + * To do so the {@code address} property can be provided or this + * method can automatically determine the {@code address} of * an endpoint that is published by the same Java EE application and is - * identified by the serviceName and - * portName propeties. If the address is - * null and the serviceName and - * portName do not identify an endpoint published by the + * identified by the {@code serviceName} and + * {@code portName} propeties. If the {@code address} is + * {@code null} and the {@code serviceName} and + * {@code portName} do not identify an endpoint published by the * same Java EE application, a - * javax.lang.IllegalStateException MUST be thrown. + * {@code javax.lang.IllegalStateException} MUST be thrown. * * @param address Specifies the address of the target endpoint - * @param interfaceName the wsam:InterfaceName element in the - * wsa:Metadata element. + * @param interfaceName the {@code wsam:InterfaceName} element in the + * {@code wsa:Metadata} element. * @param serviceName Qualified name of the service in the WSDL. * @param portName Qualified name of the endpoint in the WSDL. * @param metadata A list of elements that should be added to the - * W3CEndpointReference instances wsa:metadata + * {@code W3CEndpointReference} instances {@code wsa:metadata} * element. * @param wsdlDocumentLocation URL for the WSDL document location for * the service. * @param referenceParameters Reference parameters to be associated - * with the returned EndpointReference instance. + * with the returned {@code EndpointReference} instance. * @param elements extension elements to be associated - * with the returned EndpointReference instance. + * with the returned {@code EndpointReference} instance. * @param attributes extension attributes to be associated - * with the returned EndpointReference instance. + * with the returned {@code EndpointReference} instance. * - * @return the W3CEndpointReference created from - * serviceName, portName, - * metadata, wsdlDocumentLocation - * and referenceParameters. This method - * never returns null. + * @return the {@code W3CEndpointReference} created from + * {@code serviceName}, {@code portName}, + * {@code metadata}, {@code wsdlDocumentLocation} + * and {@code referenceParameters}. This method + * never returns {@code null}. * * @throws java.lang.IllegalStateException *

                                    - *
                                  • If the address, serviceName and - * portName are all null. - *
                                  • If the serviceName service is null and the - * portName is NOT null. - *
                                  • If the address property is null and - * the serviceName and portName do not + *
                                  • If the {@code address}, {@code serviceName} and + * {@code portName} are all {@code null}. + *
                                  • If the {@code serviceName} service is {@code null} and the + * {@code portName} is NOT {@code null}. + *
                                  • If the {@code address} property is {@code null} and + * the {@code serviceName} and {@code portName} do not * specify a valid endpoint published by the same Java EE * application. - *
                                  • If the serviceNameis NOT null + *
                                  • If the {@code serviceName}is NOT {@code null} * and is not present in the specified WSDL. - *
                                  • If the portName port is not null and it - * is not present in serviceName service in the WSDL. - *
                                  • If the wsdlDocumentLocation is NOT null + *
                                  • If the {@code portName} port is not {@code null} and it + * is not present in {@code serviceName} service in the WSDL. + *
                                  • If the {@code wsdlDocumentLocation} is NOT {@code null} * and does not represent a valid WSDL. - *
                                  • If the wsdlDocumentLocation is NOT null but + *
                                  • If the {@code wsdlDocumentLocation} is NOT {@code null} but * wsdli:wsdlLocation's namespace name cannot be got from the available * metadata. *
                                  * @throws WebServiceException If an error occurs while creating the - * W3CEndpointReference. + * {@code W3CEndpointReference}. * @since 1.7, JAX-WS 2.2 */ public W3CEndpointReference createW3CEndpointReference(String address, @@ -419,7 +417,7 @@ public abstract class Provider { /** * Creates and publishes an endpoint object with the specified * address, implementation object and web service features. - * Provider implementations must override the + * {@code Provider} implementations must override the * default implementation. * * @param address A URI specifying the address and transport/protocol @@ -431,8 +429,8 @@ public abstract class Provider { * class MUST be annotated with all the necessary Web service * annotations. * @param features A list of WebServiceFeatures to configure on the - * endpoint. Supported features not in the features - * parameter will have their default values. + * endpoint. Supported features not in the {@code features} + * parameter will have their default values. * @return The newly created endpoint. * @since 1.7, JAX-WS 2.2 */ @@ -443,7 +441,7 @@ public abstract class Provider { /** * Creates an endpoint object with the provided binding, implementation - * object and web service features. Provider implementations + * object and web service features. {@code Provider} implementations * must override the default implementation. * * @param bindingId A URI specifying the desired binding (e.g. SOAP/HTTP) @@ -452,8 +450,8 @@ public abstract class Provider { * class MUST be annotated with all the necessary Web service * annotations. * @param features A list of WebServiceFeatures to configure on the - * endpoint. Supported features not in the features - * parameter will have their default values. + * endpoint. Supported features not in the {@code features} + * parameter will have their default values. * @return The newly created endpoint. * @since 1.7, JAX-WS 2.2 */ @@ -465,7 +463,7 @@ public abstract class Provider { /** * Creates an endpoint object with the provided binding, implementation * class, invoker and web service features. Containers typically use - * this to create Endpoint objects. Provider + * this to create Endpoint objects. {@code Provider} * implementations must override the default implementation. * * @param bindingId A URI specifying the desired binding (e.g. SOAP/HTTP). @@ -475,8 +473,8 @@ public abstract class Provider { * annotations. * @param invoker that does the actual invocation on the service instance. * @param features A list of WebServiceFeatures to configure on the - * endpoint. Supported features not in the features - * parameter will have their default values. + * endpoint. Supported features not in the {@code features + * } parameter will have their default values. * @return The newly created endpoint. * @since 1.7, JAX-WS 2.2 */ diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/WebServiceFeatureAnnotation.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/WebServiceFeatureAnnotation.java index 39c0f25e3c4..74423670e4e 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/WebServiceFeatureAnnotation.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/WebServiceFeatureAnnotation.java @@ -39,27 +39,26 @@ import javax.xml.ws.soap.MTOM; /** * Annotation used to identify other annotations - * as a WebServiceFeature. + * as a {@code WebServiceFeature}. *

                                  - * Each WebServiceFeature annotation annotated with + * Each {@code WebServiceFeature} annotation annotated with * this annotation MUST contain an - * enabled property of type - * boolean with a default value of true. + * {@code enabled} property of type + * {@code boolean} with a default value of {@code true}. *

                                  * JAX-WS defines the following - * WebServiceFeature annotations (Addressing, - * MTOM, RespectBinding), however, an implementation + * {@code WebServiceFeature} annotations ({@code Addressing}, + * {@code MTOM}, {@code RespectBinding}), however, an implementation * may define vendors specific annotations for other features. *

                                  - * Annotations annotated with WebServiceFeatureAnnotation MUST + * Annotations annotated with {@code WebServiceFeatureAnnotation} MUST * have the same @Target of {@link WebServiceRef} annotation, so that the resulting * feature annotation can be used in conjunction with the {@link WebServiceRef} * annotation if necessary. *

                                  * If a JAX-WS implementation encounters an annotation annotated - * with the WebServiceFeatureAnnotation that it does not + * with the {@code WebServiceFeatureAnnotation} that it does not * recognize/support an error MUST be given. - *

                                  * * @see Addressing * @see MTOM @@ -79,8 +78,8 @@ public @interface WebServiceFeatureAnnotation { String id(); /** - * The WebServiceFeature bean that is associated - * with the WebServiceFeature annotation + * The {@code WebServiceFeature} bean that is associated + * with the {@code WebServiceFeature} annotation */ Class bean(); } diff --git a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/http/package-info.java b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/http/package-info.java index d105948e7f4..eed7e5d4a53 100644 --- a/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/http/package-info.java +++ b/jaxws/src/java.xml.ws/share/classes/javax/xml/ws/spi/http/package-info.java @@ -47,7 +47,7 @@ object encapsulates a HTTP request and a response. -

                                  +  
                                  {@literal
                                     Container                               JAX-WS runtime
                                     ---------                               --------------
                                     1. Creates Invoker1, ... InvokerN
                                  @@ -64,10 +64,10 @@
                                    10. EndpointN.publish(HttpContextN)  --> 11. creates HttpHandlerN
                                                                            HttpContextN.setHandler(HttpHandlerN)
                                   
                                  -  
                                  + }
                                  The request processing is done as below(for every request): -
                                  +  
                                  {@literal
                                     Container                               JAX-WS runtime
                                     ---------                               --------------
                                     1. Creates a HttpExchange
                                  @@ -76,14 +76,14 @@
                                                                         <-- 5. Calls Invoker
                                     6. Invokes the actual instance
                                                                             7. Writes the response to HttpExchange
                                  -  
                                  + }

                                  The portable undeployment is done as below:

                                     Container
                                     ---------
                                  -  1. @preDestroy on instances
                                  +  1. {@literal @}preDestroy on instances
                                     2. Endpoint1.stop()
                                     ...
                                     3. EndpointN.stop()
                                  diff --git a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/document/soap/SOAPConstants.java b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/document/soap/SOAPConstants.java
                                  index ee1582ed285..7c6a640bee8 100644
                                  --- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/document/soap/SOAPConstants.java
                                  +++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wsdl/document/soap/SOAPConstants.java
                                  @@ -25,8 +25,6 @@
                                   
                                   package com.sun.tools.internal.ws.wsdl.document.soap;
                                   
                                  -import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
                                  -
                                   import javax.xml.namespace.QName;
                                   
                                   /**
                                  @@ -37,7 +35,9 @@ import javax.xml.namespace.QName;
                                   public interface SOAPConstants {
                                   
                                       // namespace URIs
                                  -    public static final String URI_ENVELOPE = SOAPNamespaceConstants.ENVELOPE;
                                  +    public static final String URI_ENVELOPE =
                                  +        "http://schemas.xmlsoap.org/soap/envelope/";
                                  +
                                       public static final String NS_WSDL_SOAP =
                                           "http://schemas.xmlsoap.org/wsdl/soap/";
                                       public static final String NS_SOAP_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
                                  diff --git a/jdk/.hgtags b/jdk/.hgtags
                                  index 0b955733484..7a547227410 100644
                                  --- a/jdk/.hgtags
                                  +++ b/jdk/.hgtags
                                  @@ -302,3 +302,5 @@ d49e247dade61f29f771f09b2105857492241156 jdk9-b55
                                   c76339e86ea7da5d9ac7856f3fae9ef73eef04a2 jdk9-b57
                                   36fc65e80d811ee43aedfc69284224b86a403662 jdk9-b58
                                   48ee960f29df93a9b2a895621321358a86909086 jdk9-b59
                                  +84c5527f742bc64562e47d3149c16197fe1c4c1a jdk9-b60
                                  +da84dcac1b0b12c5b836b05ac75ecbfadee0cd32 jdk9-b61
                                  diff --git a/jdk/make/CompileDemos.gmk b/jdk/make/CompileDemos.gmk
                                  index 2d10867948f..3328dbc6cf4 100644
                                  --- a/jdk/make/CompileDemos.gmk
                                  +++ b/jdk/make/CompileDemos.gmk
                                  @@ -45,7 +45,7 @@ DEMO_SHARE_SRC := $(JDK_TOPDIR)/src/demo/share
                                   DEMO_CLOSED_SHARE_SRC := $(JDK_TOPDIR)/src/closed/demo/share
                                   DEMO_SOLARIS_SRC := $(JDK_TOPDIR)/src/demo/solaris
                                   DEMO_OS_TYPE_SRC := $(JDK_TOPDIR)/src/demo/$(OPENJDK_TARGET_OS_TYPE)
                                  -VERSION_INFO_RESOURCE := $(JDK_TOPDIR)/src/java.base/windows/native/common/version.rc
                                  +GLOBAL_VERSION_INFO_RESOURCE := $(JDK_TOPDIR)/src/java.base/windows/native/common/version.rc
                                   
                                   ##################################################################################################
                                   
                                  @@ -230,11 +230,8 @@ define SetupJVMTIDemo
                                         $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/README.txt, $2)) \
                                         $$(wildcard $$(patsubst %, $(DEMO_SHARE_SRC)/jvmti/%/sample.makefile.txt, $2))
                                     BUILD_DEMO_JVMTI_$1_EXTRA_INC := $$(addprefix -I, $$(BUILD_DEMO_JVMTI_$1_EXTRA_SRC))
                                  -  BUILD_DEMO_JVMTI_$1_LANG := C
                                  -  ifneq (, $4)
                                  -    BUILD_DEMO_JVMTI_$1_LANG := $4
                                  -  endif
                                     ifeq (C++, $4)
                                  +    BUILD_DEMO_JVMTI_$1_TOOLCHAIN := TOOLCHAIN_LINK_CXX
                                       $1_EXTRA_CXX := $(LDFLAGS_CXX_JDK) $(LIBCXX)
                                     endif
                                   
                                  @@ -254,7 +251,7 @@ define SetupJVMTIDemo
                                     # Remove the -incremental:no setting to get .ilk-files like in the old build.
                                     $$(eval $$(call SetupNativeCompilation,BUILD_DEMO_JVMTI_$1, \
                                         SRC := $(DEMO_SHARE_SRC)/jvmti/$1 $$(BUILD_DEMO_JVMTI_$1_EXTRA_SRC), \
                                  -      LANG := $$(BUILD_DEMO_JVMTI_$1_LANG), \
                                  +      TOOLCHAIN := $$(BUILD_DEMO_JVMTI_$1_TOOLCHAIN), \
                                         OPTIMIZATION := LOW, \
                                         CXXFLAGS := $$($1_CXXFLAGS), \
                                         DISABLED_WARNINGS_gcc := $(10), \
                                  @@ -267,7 +264,7 @@ define SetupJVMTIDemo
                                         LDFLAGS_SUFFIX_windows := $6, \
                                         LDFLAGS_SUFFIX_solaris := $7 -lc, \
                                         LDFLAGS_SUFFIX_linux := $8, \
                                  -      VERSIONINFO_RESOURCE := $(VERSION_INFO_RESOURCE), \
                                  +      VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
                                         RC_FLAGS := $$(RC_FLAGS) \
                                             -D "JDK_FNAME=$1.dll" \
                                             -D "JDK_INTERNAL_NAME=$1" \
                                  @@ -398,7 +395,6 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
                                   
                                     $(eval $(call SetupNativeCompilation,BUILD_LIBPOLLER, \
                                         SRC := $(DEMO_SOLARIS_SRC)/jni/Poller, \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(SHARED_LIBRARY_FLAGS) \
                                             -I$(SUPPORT_OUTPUTDIR)/demo/classes/jni/Poller, \
                                  diff --git a/jdk/make/Tools.gmk b/jdk/make/Tools.gmk
                                  index 07ac66339a0..0d56ccbb827 100644
                                  --- a/jdk/make/Tools.gmk
                                  +++ b/jdk/make/Tools.gmk
                                  @@ -163,9 +163,7 @@ $(eval $(call SetupCopyFiles,COPY_JIMAGE_SERVICE_PROVIDER, \
                                   ifeq ($(OPENJDK_TARGET_OS), solaris)
                                     $(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \
                                         SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \
                                  -      LANG := C, \
                                  -      CC := $(BUILD_CC), \
                                  -      LDEXE := $(BUILD_LD), \
                                  +      TOOLCHAIN := TOOLCHAIN_BUILD, \
                                         LDFLAGS := -lelf, \
                                         OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \
                                         OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
                                  @@ -173,9 +171,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
                                   
                                     $(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \
                                         SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \
                                  -      LANG := C, \
                                  -      CC := $(BUILD_CC), \
                                  -      LDEXE := $(BUILD_LD), \
                                  +      TOOLCHAIN := TOOLCHAIN_BUILD, \
                                         LDFLAGS := -lelf, \
                                         OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
                                         OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
                                  diff --git a/jdk/make/copy/Copy-java.base.gmk b/jdk/make/copy/Copy-java.base.gmk
                                  index f1728f33edb..46687333361 100644
                                  --- a/jdk/make/copy/Copy-java.base.gmk
                                  +++ b/jdk/make/copy/Copy-java.base.gmk
                                  @@ -170,9 +170,6 @@ POLICY_SRC_LIST :=
                                   
                                   ifeq ($(OPENJDK_TARGET_OS), windows)
                                     POLICY_SRC_LIST += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/conf/security/java.policy
                                  -  ifndef OPENJDK
                                  -    POLICY_SRC_LIST += $(JDK_TOPDIR)/src/closed/java.base/$(OPENJDK_TARGET_OS)/conf/security/java.policy
                                  -  endif
                                   endif
                                   
                                   POLICY_SRC_LIST += $(POLICY_SRC)
                                  diff --git a/jdk/make/copy/Copy-jdk.accessibility.gmk b/jdk/make/copy/Copy-jdk.accessibility.gmk
                                  new file mode 100644
                                  index 00000000000..4c089c16883
                                  --- /dev/null
                                  +++ b/jdk/make/copy/Copy-jdk.accessibility.gmk
                                  @@ -0,0 +1,47 @@
                                  +#
                                  +# Copyright (c) 2104, 2015, Oracle and/or its affiliates. All rights reserved.
                                  +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                  +#
                                  +# This code is free software; you can redistribute it and/or modify it
                                  +# under the terms of the GNU General Public License version 2 only, as
                                  +# published by the Free Software Foundation.  Oracle designates this
                                  +# particular file as subject to the "Classpath" exception as provided
                                  +# by Oracle in the LICENSE file that accompanied this code.
                                  +#
                                  +# This code is distributed in the hope that it will be useful, but WITHOUT
                                  +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                  +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                                  +# version 2 for more details (a copy is included in the LICENSE file that
                                  +# accompanied this code).
                                  +#
                                  +# You should have received a copy of the GNU General Public License version
                                  +# 2 along with this work; if not, write to the Free Software Foundation,
                                  +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
                                  +#
                                  +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
                                  +# or visit www.oracle.com if you need additional information or have any
                                  +# questions.
                                  +#
                                  +
                                  +include CopyCommon.gmk
                                  +
                                  +################################################################################
                                  +
                                  +ifeq ($(OPENJDK_TARGET_OS), windows)
                                  +  TARGETS += $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgeCallbacks.h \
                                  +      $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgeCalls.h \
                                  +      $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgePackages.h \
                                  +      $(INCLUDE_DST_OS_DIR)/bridge/AccessBridgeCalls.c \
                                  +      $(CONF_DST_DIR)/accessibility.properties
                                  +
                                  +  $(INCLUDE_DST_OS_DIR)/bridge/%: \
                                  +      $(JDK_TOPDIR)/src/jdk.accessibility/windows/native/include/bridge/%
                                  +		$(install-file)
                                  +
                                  +  $(CONF_DST_DIR)/accessibility.properties: \
                                  +      $(JDK_TOPDIR)/src/jdk.accessibility/windows/conf/accessibility.properties
                                  +		$(install-file)
                                  +
                                  +endif
                                  +
                                  +################################################################################
                                  diff --git a/jdk/make/data/swingbeaninfo/SwingBeanInfo.template b/jdk/make/data/swingbeaninfo/SwingBeanInfo.template
                                  index 9c1a133f67f..e0c83c0e2cf 100644
                                  --- a/jdk/make/data/swingbeaninfo/SwingBeanInfo.template
                                  +++ b/jdk/make/data/swingbeaninfo/SwingBeanInfo.template
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -92,25 +92,38 @@ public class @(BeanClassName)BeanInfo extends javax.swing.SwingBeanInfoBase {
                                       /**
                                        * @return an icon of the specified kind for @(BeanClassName)
                                        */
                                  -    public Image getIcon(int kind) {
                                  +    public Image getIcon(final int kind) {
                                           Image i;
                                           switch (kind){
                                               case ICON_COLOR_32x32:
                                  -                i = loadImage("beaninfo/images/@(BeanClassName)Color32.gif");
                                  -                return ((i == null) ? loadImage("beaninfo/images/JComponentColor32.gif") : i);
                                  +                i = loadStandardImage("beaninfo/images/@(BeanClassName)Color32.gif");
                                  +                return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor32.gif") : i);
                                               case ICON_COLOR_16x16:
                                  -                i = loadImage("beaninfo/images/@(BeanClassName)Color16.gif");
                                  -                return ((i == null) ? loadImage("beaninfo/images/JComponentColor16.gif") : i);
                                  +                i = loadStandardImage("beaninfo/images/@(BeanClassName)Color16.gif");
                                  +                return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor16.gif") : i);
                                               case ICON_MONO_32x32:
                                  -                i = loadImage("beaninfo/images/@(BeanClassName)Mono32.gif");
                                  -                return ((i == null) ? loadImage("beaninfo/images/JComponentMono32.gif") : i);		  
                                  +                i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono32.gif");
                                  +                return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono32.gif") : i);         
                                               case ICON_MONO_16x16:
                                  -                i = loadImage("beaninfo/images/@(BeanClassName)Mono16.gif");
                                  -                return ((i == null) ? loadImage("beaninfo/images/JComponentMono16.gif") : i);		  
                                  +                i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono16.gif");
                                  +                return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono16.gif") : i);         
                                               default:
                                                   return super.getIcon(kind);
                                           }
                                       }
                                  +
                                  +    /**
                                  +     * This is a utility method to help in loading standard icon images.
                                  +     *
                                  +     * @param  resourceName A pathname relative to the directory holding the
                                  +     *         class file of the current class
                                  +     * @return an image object. May be null if the load failed.
                                  +     * @see java.beans.SimpleBeanInfo#loadImage(String)
                                  +     */
                                  +    private Image loadStandardImage(final String resourceName) {
                                  +        return java.security.AccessController.doPrivileged(
                                  +                (java.security.PrivilegedAction) () -> loadImage(resourceName));
                                  +    }
                                   }
                                   
                                   
                                  diff --git a/jdk/make/gensrc/GensrcMisc.gmk b/jdk/make/gensrc/GensrcMisc.gmk
                                  index c0489f3a97d..7762a284952 100644
                                  --- a/jdk/make/gensrc/GensrcMisc.gmk
                                  +++ b/jdk/make/gensrc/GensrcMisc.gmk
                                  @@ -63,9 +63,7 @@ SOR_COPYRIGHT_YEARS = $(shell $(CAT) $(GENSRC_SOR_SRC)/$(GENSRC_SOR_SRC_FILE) |
                                   $(eval $(call SetupNativeCompilation,BUILD_GENSRC_SOR_EXE, \
                                       SRC := $(GENSRC_SOR_SRC), \
                                       INCLUDE_FILES := $(GENSRC_SOR_SRC_FILE), \
                                  -    LANG := C, \
                                  -    CC := $(BUILD_CC), \
                                  -    LDEXE := $(BUILD_LD), \
                                  +    TOOLCHAIN := TOOLCHAIN_BUILD, \
                                       OBJECT_DIR := $(GENSRC_SOR_BIN), \
                                       OUTPUT_DIR := $(GENSRC_SOR_BIN), \
                                       PROGRAM := genSocketOptionRegistry))
                                  @@ -101,9 +99,7 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
                                     $(eval $(call SetupNativeCompilation,BUILD_GENSRC_UC_EXE, \
                                         SRC := $(GENSRC_UC_SRC), \
                                         INCLUDE_FILES := $(GENSRC_UC_SRC_FILE), \
                                  -      LANG := C, \
                                  -      CC := $(BUILD_CC), \
                                  -      LDEXE := $(BUILD_CC), \
                                  +      TOOLCHAIN := TOOLCHAIN_BUILD, \
                                         CFLAGS := $(filter -D%, $(CFLAGS_JDKEXE)), \
                                         OBJECT_DIR := $(GENSRC_UC_BIN), \
                                         OUTPUT_DIR := $(GENSRC_UC_BIN), \
                                  @@ -142,9 +138,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
                                     $(eval $(call SetupNativeCompilation,BUILD_GENSRC_SOL_EXE, \
                                         SRC := $(GENSRC_SOL_SRC), \
                                         INCLUDE_FILES := $(GENSRC_SOL_SRC_FILE), \
                                  -      LANG := C, \
                                  -      CC := $(BUILD_CC), \
                                  -      LDEXE := $(BUILD_CC), \
                                  +      TOOLCHAIN := TOOLCHAIN_BUILD, \
                                         OBJECT_DIR := $(GENSRC_SOL_BIN), \
                                         OUTPUT_DIR := $(GENSRC_SOL_BIN), \
                                         PROGRAM := genSolarisConstants))
                                  diff --git a/jdk/make/launcher/Launcher-java.base.gmk b/jdk/make/launcher/Launcher-java.base.gmk
                                  index d117ad3b2ca..b0defc603f8 100644
                                  --- a/jdk/make/launcher/Launcher-java.base.gmk
                                  +++ b/jdk/make/launcher/Launcher-java.base.gmk
                                  @@ -103,7 +103,6 @@ ifneq ($(BUILD_JEXEC_SRC), )
                                     $(eval $(call SetupNativeCompilation,BUILD_JEXEC, \
                                         SRC := $(BUILD_JEXEC_SRC), \
                                         INCLUDE_FILES := jexec.c, \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKEXE) \
                                             $(BUILD_JEXEC_INC), \
                                  @@ -144,7 +143,6 @@ ifeq ($(BUILD_JSPAWNHELPER), 1)
                                     $(eval $(call SetupNativeCompilation,BUILD_JSPAWNHELPER, \
                                         SRC := $(BUILD_JSPAWNHELPER_SRC), \
                                         INCLUDE_FILES := jspawnhelper.c, \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKEXE) $(JSPAWNHELPER_CFLAGS), \
                                         LDFLAGS := $(LDFLAGS_JDKEXE) $(LINK_JSPAWNHELPER_FLAGS), \
                                  diff --git a/jdk/make/launcher/Launcher-jdk.accessibility.gmk b/jdk/make/launcher/Launcher-jdk.accessibility.gmk
                                  new file mode 100644
                                  index 00000000000..dc34a3fee7b
                                  --- /dev/null
                                  +++ b/jdk/make/launcher/Launcher-jdk.accessibility.gmk
                                  @@ -0,0 +1,61 @@
                                  +#
                                  +# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
                                  +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                  +#
                                  +# This code is free software; you can redistribute it and/or modify it
                                  +# under the terms of the GNU General Public License version 2 only, as
                                  +# published by the Free Software Foundation.  Oracle designates this
                                  +# particular file as subject to the "Classpath" exception as provided
                                  +# by Oracle in the LICENSE file that accompanied this code.
                                  +#
                                  +# This code is distributed in the hope that it will be useful, but WITHOUT
                                  +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                  +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                                  +# version 2 for more details (a copy is included in the LICENSE file that
                                  +# accompanied this code).
                                  +#
                                  +# You should have received a copy of the GNU General Public License version
                                  +# 2 along with this work; if not, write to the Free Software Foundation,
                                  +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
                                  +#
                                  +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
                                  +# or visit www.oracle.com if you need additional information or have any
                                  +# questions.
                                  +#
                                  +
                                  +include LauncherCommon.gmk
                                  +
                                  +################################################################################
                                  +# jabswitch
                                  +
                                  +ifeq ($(OPENJDK_TARGET_OS), windows)
                                  +
                                  +  JABSWITCH_SRC := $(JDK_TOPDIR)/src/jdk.accessibility/windows/native/jabswitch
                                  +  ACCESSBRIDGE_SRC := $(JDK_TOPDIR)/src/jdk.accessibility/windows/native/common
                                  +
                                  +  $(eval $(call SetupNativeCompilation,BUILD_JABSWITCH, \
                                  +      SRC := $(JABSWITCH_SRC), \
                                  +      INCLUDE_FILES := jabswitch.cpp, \
                                  +      CFLAGS := $(filter-out -Zc:wchar_t-, $(CFLAGS_JDKEXE)) -Zc:wchar_t \
                                  +          -analyze- -Od -Gd -D_WINDOWS \
                                  +          -D_UNICODE -DUNICODE -RTC1 -EHsc, \
                                  +      DISABLED_WARNINGS_microsoft := 4267, \
                                  +      LDFLAGS := $(LDFLAGS_JDKEXE) \
                                  +          Advapi32.lib Version.lib User32.lib, \
                                  +      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jabswitch, \
                                  +      OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
                                  +      PROGRAM := jabswitch, \
                                  +      DEBUG_SYMBOLS := true, \
                                  +      VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRC)/AccessBridgeStatusWindow.RC, \
                                  +      RC_FLAGS := $(RC_FLAGS) \
                                  +          -D "JDK_FNAME=jabswitch.exe" \
                                  +          -D "JDK_INTERNAL_NAME=jabswitch" \
                                  +          -D "JDK_FTYPE=0x01L", \
                                  +      MANIFEST := $(JABSWITCH_SRC)/jabswitch.manifest, \
                                  +      MANIFEST_VERSION := $(JDK_VERSION_FOR_MANIFEST), \
                                  +  ))
                                  +
                                  +  TARGETS += $(BUILD_JABSWITCH)
                                  +endif
                                  +
                                  +################################################################################
                                  diff --git a/jdk/make/launcher/Launcher-jdk.pack200.gmk b/jdk/make/launcher/Launcher-jdk.pack200.gmk
                                  index affdbdb26eb..391272a76fb 100644
                                  --- a/jdk/make/launcher/Launcher-jdk.pack200.gmk
                                  +++ b/jdk/make/launcher/Launcher-jdk.pack200.gmk
                                  @@ -56,23 +56,28 @@ else
                                   
                                   endif
                                   
                                  -UNPACKEXE_LANG := C
                                   ifeq ($(OPENJDK_TARGET_OS), solaris)
                                  -  UNPACKEXE_LANG := C++
                                  +  UNPACKEXE_TOOLCHAIN := TOOLCHAIN_LINK_CXX
                                   endif
                                   
                                  +UNPACK_MAPFILE_DIR := $(JDK_TOPDIR)/make/mapfiles/libunpack
                                  +UNPACK_MAPFILE_PLATFORM_FILE := \
                                  +    $(UNPACK_MAPFILE_DIR)/mapfile-vers-unpack200-$(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH)
                                  +
                                   # The linker on older SuSE distros (e.g. on SLES 10) complains with:
                                   # "Invalid version tag `SUNWprivate_1.1'. Only anonymous version tag is allowed in executable."
                                   # if feeded with a version script which contains named tags.
                                   ifeq ($(USING_BROKEN_SUSE_LD), yes)
                                  -  UNPACK_MAPFILE = $(JDK_TOPDIR)/make/mapfiles/libunpack/mapfile-vers-unpack200.anonymous
                                  +  UNPACK_MAPFILE := $(UNPACK_MAPFILE_DIR)/mapfile-vers-unpack200.anonymous
                                  +else ifneq ($(wildcard $(UNPACK_MAPFILE_PLATFORM_FILE)), )
                                  +  UNPACK_MAPFILE := $(UNPACK_MAPFILE_PLATFORM_FILE)
                                   else
                                  -  UNPACK_MAPFILE = $(JDK_TOPDIR)/make/mapfiles/libunpack/mapfile-vers-unpack200
                                  +  UNPACK_MAPFILE := $(UNPACK_MAPFILE_DIR)/mapfile-vers-unpack200
                                   endif
                                   
                                   $(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
                                       SRC := $(UNPACKEXE_SRC), \
                                  -    LANG := $(UNPACKEXE_LANG), \
                                  +    TOOLCHAIN := $(UNPACKEXE_TOOLCHAIN), \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(UNPACKEXE_CFLAGS) $(CXXFLAGS_JDKEXE) -DFULL, \
                                       CFLAGS_release := -DPRODUCT, \
                                  @@ -96,7 +101,9 @@ $(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
                                           -D "JDK_INTERNAL_NAME=unpack200" \
                                           -D "JDK_FTYPE=0x1L", \
                                       DEBUG_SYMBOLS := true, \
                                  -    MANIFEST := $(JDK_TOPDIR)/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest))
                                  +    MANIFEST := $(JDK_TOPDIR)/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest, \
                                  +    MANIFEST_VERSION := $(JDK_VERSION_FOR_MANIFEST), \
                                  +))
                                   
                                   ifneq ($(USE_EXTERNAL_LIBZ), true)
                                   
                                  diff --git a/jdk/make/launcher/LauncherCommon.gmk b/jdk/make/launcher/LauncherCommon.gmk
                                  index 09ffcffdb34..1e504f5231a 100644
                                  --- a/jdk/make/launcher/LauncherCommon.gmk
                                  +++ b/jdk/make/launcher/LauncherCommon.gmk
                                  @@ -1,5 +1,5 @@
                                   #
                                  -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
                                  +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
                                   # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                   #
                                   # This code is free software; you can redistribute it and/or modify it
                                  @@ -161,7 +161,6 @@ define SetupLauncher
                                     $(call SetupNativeCompilation,BUILD_LAUNCHER_$1, \
                                         SRC := $(LAUNCHER_SRC), \
                                         INCLUDE_FILES := main.c, \
                                  -      LANG := C, \
                                         OPTIMIZATION := $$($1_OPTIMIZATION_ARG), \
                                         CFLAGS := $$($1_CFLAGS) \
                                             $(LAUNCHER_CFLAGS) \
                                  @@ -199,7 +198,9 @@ define SetupLauncher
                                             -D "JDK_FTYPE=0x1L" \
                                             $7, \
                                         MANIFEST := $(JAVA_MANIFEST), \
                                  -      CODESIGN := $$($1_CODESIGN))
                                  +      MANIFEST_VERSION := $(JDK_VERSION_FOR_MANIFEST), \
                                  +      CODESIGN := $$($1_CODESIGN), \
                                  +  )
                                   
                                     TARGETS += $$(BUILD_LAUNCHER_$1)
                                   
                                  diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk
                                  index c7ce8d9c202..254f446a000 100644
                                  --- a/jdk/make/lib/Awt2dLibraries.gmk
                                  +++ b/jdk/make/lib/Awt2dLibraries.gmk
                                  @@ -51,7 +51,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBMLIB_IMAGE, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(BUILD_LIBMLIB_SRC), \
                                       EXCLUDE_FILES := mlib_c_ImageBlendTable.c, \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGHEST, \
                                       CFLAGS := $(CFLAGS_JDKLIB) \
                                           $(BUILD_LIBMLIB_CFLAGS), \
                                  @@ -124,7 +123,6 @@ ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
                                         LIBRARY := mlib_image_v, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBMLIB_IMAGE_V_SRC), \
                                  -      LANG := C, \
                                         EXCLUDE_FILES := $(BUILD_LIBMLIB_IMAGE_V_EXFILES), \
                                         OPTIMIZATION := HIGHEST, \
                                         CFLAGS := -xarch=sparcvis \
                                  @@ -204,8 +202,6 @@ ifneq ($(OPENJDK_TARGET_OS), solaris)
                                     LIBAWT_CFLAGS += -DMLIB_NO_LIBSUNMATH
                                   endif
                                   
                                  -LIBAWT_LANG := C
                                  -
                                   ifeq ($(OPENJDK_TARGET_OS), windows)
                                     LIBAWT_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
                                         $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
                                  @@ -222,7 +218,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
                                         awt/image/cvutils/img_colors.c \
                                         #
                                   
                                  -  LIBAWT_LANG := C++
                                     LIBAWT_CFLAGS += -EHsc -DUNICODE -D_UNICODE
                                     ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
                                       LIBAWT_CFLAGS += -DMLIB_OS64BIT
                                  @@ -247,7 +242,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \
                                       SRC := $(LIBAWT_DIRS), \
                                       EXCLUDES := $(LIBAWT_EXCLUDES), \
                                       EXCLUDE_FILES := $(LIBAWT_EXFILES), \
                                  -    LANG := $(LIBAWT_LANG), \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_CFLAGS), \
                                       DISABLED_WARNINGS_gcc := sign-compare unused-result maybe-uninitialized \
                                  @@ -355,7 +349,6 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),)
                                           OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                           SRC := $(LIBAWT_XAWT_DIRS), \
                                           EXCLUDES := $(LIBAWT_XAWT_EXCLUDES), \
                                  -        LANG := C, \
                                           OPTIMIZATION := LOW, \
                                           CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_XAWT_CFLAGS) \
                                               $(X_CFLAGS), \
                                  @@ -413,7 +406,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBLCMS, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBLCMS_SRC), \
                                       INCLUDE_FILES := $(BUILD_LIBLCMS_INCLUDE_FILES), \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGHEST, \
                                       CFLAGS := $(filter-out -xc99=%none, $(CFLAGS_JDKLIB)) \
                                           $(SHARED_LIBRARY_FLAGS) $(LIBLCMS_CPPFLAGS) \
                                  @@ -496,7 +488,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVAJPEG, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJAVAJPEG_SRC), \
                                       INCLUDE_FILES := $(BUILD_LIBJAVAJPEG_INCLUDE_FILES), \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGHEST, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJAVAJPEG_SRC)) \
                                           $(LIBJAVA_HEADER_FLAGS) \
                                  @@ -564,7 +555,6 @@ ifeq ($(BUILD_HEADLESS), true)
                                           OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                           SRC := $(LIBAWT_HEADLESS_DIRS), \
                                           EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \
                                  -        LANG := C, \
                                           OPTIMIZATION := LOW, \
                                           CFLAGS := $(CFLAGS_JDKLIB) \
                                               -DHEADLESS=true \
                                  @@ -651,7 +641,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \
                                       SRC := $(LIBFONTMANAGER_SRC), \
                                       EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \
                                           AccelGlyphCache.c, \
                                  -    LANG := C++, \
                                  +    TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(LIBFONTMANAGER_CFLAGS), \
                                       CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBFONTMANAGER_CFLAGS), \
                                       OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \
                                  @@ -712,7 +702,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBJAWT_SRC), \
                                         INCLUDE_FILES := $(LIBJAWT_INCLUDE_FILES), \
                                  -      LANG := C++, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CXXFLAGS_JDKLIB) \
                                             -EHsc -DUNICODE -D_UNICODE \
                                  @@ -771,7 +760,6 @@ else # OPENJDK_TARGET_OS not windows
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBJAWT_SRC), \
                                         INCLUDE_FILES := $(JAWT_FILES), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             $(LIBJAWT_CFLAGS), \
                                  @@ -889,7 +877,6 @@ ifndef BUILD_HEADLESS_ONLY
                                         SRC := $(LIBSPLASHSCREEN_DIRS), \
                                         EXCLUDE_FILES := imageioJPEG.c jpegdecoder.c pngtest.c, \
                                         EXCLUDES := $(LIBSPLASHSCREEN_EXCLUDES), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(LIBSPLASHSCREEN_CFLAGS) $(CFLAGS_JDKLIB) \
                                                   $(GIFLIB_CFLAGS) $(LIBJPEG_CFLAGS) $(PNG_CFLAGS), \
                                  @@ -958,7 +945,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
                                         LIBRARY := awt_lwawt, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBAWT_LWAWT_DIRS), \
                                  -      LANG := C, \
                                         INCLUDE_FILES := $(LIBAWT_LWAWT_FILES), \
                                         EXCLUDE_FILES := $(LIBAWT_LWAWT_EXFILES), \
                                         EXCLUDES := $(LIBAWT_LWAWT_EXCLUDES), \
                                  @@ -1008,7 +994,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
                                         LIBRARY := osxui, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(JDK_TOPDIR)/src/java.desktop/macosx/native/libosxui, \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             -I$(JDK_TOPDIR)/src/java.desktop/macosx/native/libosxui \
                                  diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk
                                  index 02ea309b107..ed6d75ce2be 100644
                                  --- a/jdk/make/lib/CoreLibraries.gmk
                                  +++ b/jdk/make/lib/CoreLibraries.gmk
                                  @@ -43,7 +43,6 @@ ifneq ($(OPENJDK_TARGET_OS), macosx)
                                         STATIC_LIBRARY := fdlibm, \
                                         OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
                                         SRC := $(LIBFDLIBM_SRC), \
                                  -      LANG := C, \
                                         OPTIMIZATION := $(BUILD_LIBFDLIBM_OPTIMIZATION), \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(LIBFDLIBM_CFLAGS), \
                                         CFLAGS_windows_debug := -DLOGGING, \
                                  @@ -62,7 +61,6 @@ else
                                         LIBRARY := fdlibm, \
                                         OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfdlibm, \
                                         SRC := $(LIBFDLIBM_SRC), \
                                  -      LANG := C, \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(LIBFDLIBM_CFLAGS), \
                                         LDFLAGS := -nostdlib -r -arch x86_64, \
                                         OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfdlibm, \
                                  @@ -93,7 +91,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBVERIFY, \
                                       LIBRARY := verify, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(JDK_TOPDIR)/src/java.base/share/native/libverify, \
                                  -    LANG := C, \
                                       OPTIMIZATION := $(LIBVERIFY_OPTIMIZATION), \
                                       CFLAGS := $(CFLAGS_JDKLIB), \
                                       DISABLED_WARNINGS_microsoft := 4244 4267, \
                                  @@ -146,7 +143,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
                                       LIBRARY := java, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJAVA_SRC_DIRS), \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGH, \
                                       CFLAGS := $(CFLAGS_JDKLIB) \
                                           $(LIBJAVA_CFLAGS), \
                                  @@ -206,7 +202,6 @@ endif
                                   $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
                                       LIBRARY := zip, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       SRC := $(JDK_TOPDIR)/src/java.base/share/native/libzip, \
                                       EXCLUDES := $(LIBZIP_EXCLUDES), \
                                  @@ -314,7 +309,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
                                       SRC := $(LIBJLI_SRC_DIRS), \
                                       EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
                                       EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGH, \
                                       CFLAGS := $(LIBJLI_CFLAGS), \
                                       DISABLED_WARNINGS_solstudio := E_ASM_DISABLES_OPTIMIZATION, \
                                  @@ -363,7 +357,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
                                         SRC := $(LIBJLI_SRC_DIRS), \
                                         EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
                                         EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
                                  -      LANG := C, \
                                         OPTIMIZATION := HIGH, \
                                         CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
                                         ARFLAGS := $(ARFLAGS), \
                                  @@ -383,7 +376,6 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
                                         SRC := $(LIBJLI_SRC_DIRS), \
                                         EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
                                         EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
                                  -      LANG := C, \
                                         OPTIMIZATION := HIGH, \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \
                                         LDFLAGS := -nostdlib -r, \
                                  @@ -403,7 +395,6 @@ else ifeq ($(OPENJDK_TARGET_OS), aix)
                                         SRC := $(LIBJLI_SRC_DIRS), \
                                         EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
                                         EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
                                  -      LANG := C, \
                                         OPTIMIZATION := HIGH, \
                                         CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
                                         ARFLAGS := $(ARFLAGS), \
                                  diff --git a/jdk/make/lib/Lib-java.instrument.gmk b/jdk/make/lib/Lib-java.instrument.gmk
                                  index 4aaec5ce5e2..5b668c87872 100644
                                  --- a/jdk/make/lib/Lib-java.instrument.gmk
                                  +++ b/jdk/make/lib/Lib-java.instrument.gmk
                                  @@ -57,7 +57,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBINSTRUMENT, \
                                       LIBRARY := instrument, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBINSTRUMENT_SRC), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(LIBINSTRUMENT_CFLAGS) $(CFLAGS_WARNINGS_ARE_ERRORS), \
                                       CFLAGS_debug := -DJPLIS_LOGGING, \
                                  diff --git a/jdk/make/lib/Lib-java.management.gmk b/jdk/make/lib/Lib-java.management.gmk
                                  index e0e6f1d9476..29d5c081665 100644
                                  --- a/jdk/make/lib/Lib-java.management.gmk
                                  +++ b/jdk/make/lib/Lib-java.management.gmk
                                  @@ -72,7 +72,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(BUILD_LIBMANAGEMENT_SRC), \
                                       EXCLUDE_FILES := $(BUILD_LIBMANAGEMENT_EXCLUDES), \
                                  -    LANG := C, \
                                       OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(BUILD_LIBMANAGEMENT_CFLAGS), \
                                       MAPFILE := $(LIBMANAGEMENT_MAPFILE), \
                                  diff --git a/jdk/make/lib/Lib-java.prefs.gmk b/jdk/make/lib/Lib-java.prefs.gmk
                                  index 1ed2b6b13a8..d12d7eff7dd 100644
                                  --- a/jdk/make/lib/Lib-java.prefs.gmk
                                  +++ b/jdk/make/lib/Lib-java.prefs.gmk
                                  @@ -37,7 +37,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBPREFS, \
                                       LIBRARY := prefs, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBPREF_SRC_DIRS), \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGH, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBPREF_SRC_DIRS)) \
                                           $(LIBJAVA_HEADER_FLAGS), \
                                  diff --git a/jdk/make/lib/Lib-java.security.jgss.gmk b/jdk/make/lib/Lib-java.security.jgss.gmk
                                  index c2cee4e109b..401d0e7c0e9 100644
                                  --- a/jdk/make/lib/Lib-java.security.jgss.gmk
                                  +++ b/jdk/make/lib/Lib-java.security.jgss.gmk
                                  @@ -36,7 +36,6 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
                                         LIBRARY := j2gss, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBJ2GSS_SRC), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2GSS_SRC)) \
                                             $(LIBJAVA_HEADER_FLAGS) \
                                  @@ -79,7 +78,6 @@ ifneq ($(BUILD_CRYPTO), no)
                                           LIBRARY := $(BUILD_LIBKRB5_NAME), \
                                           OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                           SRC := $(BUILD_LIBKRB5_SRC), \
                                  -        LANG := C, \
                                           OPTIMIZATION := LOW, \
                                           CFLAGS := $(CFLAGS_JDKLIB) \
                                               $(addprefix -I, $(BUILD_LIBKRB5_SRC)) \
                                  diff --git a/jdk/make/lib/Lib-java.smartcardio.gmk b/jdk/make/lib/Lib-java.smartcardio.gmk
                                  index b08fb077819..82dfbfd55c1 100644
                                  --- a/jdk/make/lib/Lib-java.smartcardio.gmk
                                  +++ b/jdk/make/lib/Lib-java.smartcardio.gmk
                                  @@ -37,7 +37,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PCSC, \
                                       LIBRARY := j2pcsc, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJ2PCSC_SRC), \
                                  -    LANG := C, \
                                       CFLAGS_unix := -D__sun_jdk, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(LIBJ2PCSC_CPPFLAGS), \
                                  diff --git a/jdk/make/lib/Lib-jdk.accessibility.gmk b/jdk/make/lib/Lib-jdk.accessibility.gmk
                                  new file mode 100644
                                  index 00000000000..a689c89c65c
                                  --- /dev/null
                                  +++ b/jdk/make/lib/Lib-jdk.accessibility.gmk
                                  @@ -0,0 +1,135 @@
                                  +#
                                  +# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
                                  +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                  +#
                                  +# This code is free software; you can redistribute it and/or modify it
                                  +# under the terms of the GNU General Public License version 2 only, as
                                  +# published by the Free Software Foundation.  Oracle designates this
                                  +# particular file as subject to the "Classpath" exception as provided
                                  +# by Oracle in the LICENSE file that accompanied this code.
                                  +#
                                  +# This code is distributed in the hope that it will be useful, but WITHOUT
                                  +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                  +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                                  +# version 2 for more details (a copy is included in the LICENSE file that
                                  +# accompanied this code).
                                  +#
                                  +# You should have received a copy of the GNU General Public License version
                                  +# 2 along with this work; if not, write to the Free Software Foundation,
                                  +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
                                  +#
                                  +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
                                  +# or visit www.oracle.com if you need additional information or have any
                                  +# questions.
                                  +#
                                  +
                                  +include LibCommon.gmk
                                  +
                                  +################################################################################
                                  +
                                  +ifeq ($(OPENJDK_TARGET_OS), windows)
                                  +
                                  +  ROOT_SRCDIR := $(JDK_TOPDIR)/src/jdk.accessibility/windows/native
                                  +  JAVA_AB_SRCDIR := $(ROOT_SRCDIR)/libjavaaccessbridge $(ROOT_SRCDIR)/common
                                  +  WIN_AB_SRCDIR := $(ROOT_SRCDIR)/libwindowsaccessbridge $(ROOT_SRCDIR)/common
                                  +  SYSINFO_SRCDIR := $(ROOT_SRCDIR)/libjabsysinfo
                                  +  ACCESSBRIDGE_CFLAGS := -I$(SUPPORT_OUTPUTDIR)/headers/jdk.accessibility \
                                  +      -I$(JDK_TOPDIR)/src/java.desktop/windows/native/include \
                                  +      -I$(JDK_TOPDIR)/src/java.desktop/share/native/include
                                  +
                                  +  define SetupJavaDLL
                                  +    # Parameter 1 Suffix
                                  +    # Parameter 2 ACCESSBRIDGE_ARCH_ suffix
                                  +
                                  +    $(call SetupNativeCompilation,BUILD_JAVAACCESSBRIDGE$1, \
                                  +        LIBRARY = javaaccessbridge$1, \
                                  +        OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                  +        SRC := $(JAVA_AB_SRCDIR), \
                                  +        OPTIMIZATION := LOW, \
                                  +        CFLAGS := $(CFLAGS_JDKLIB) $(ACCESSBRIDGE_CFLAGS) \
                                  +            $(addprefix -I,$(JAVA_AB_SRCDIR)) \
                                  +            -I$(JDK_TOPDIR)/src/jdk.accessibility/windows/native/include/bridge \
                                  +            -DACCESSBRIDGE_ARCH_$2, \
                                  +        LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \
                                  +            winspool.lib comdlg32.lib advapi32.lib shell32.lib \
                                  +            $(SUPPORT_OUTPUTDIR)/native/java.desktop/libjawt/jawt.lib \
                                  +            ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
                                  +            -subsystem:windows, \
                                  +        VERSIONINFO_RESOURCE := $(ROOT_SRCDIR)/common/AccessBridgeStatusWindow.rc, \
                                  +        RC_FLAGS := $(RC_FLAGS) \
                                  +            -D "JDK_FNAME=javaaccessbridge$1.dll" \
                                  +            -D "JDK_INTERNAL_NAME=javaaccessbridge$1" \
                                  +            -D "JDK_FTYPE=0x02L", \
                                  +        OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjavaaccessbridge$1, \
                                  +        DEBUG_SYMBOLS := true)
                                  +
                                  +    $$(BUILD_JAVAACCESSBRIDGE$1): $(SUPPORT_OUTPUTDIR)/native/java.desktop/libjawt/jawt.lib
                                  +
                                  +    TARGETS += $$(BUILD_JAVAACCESSBRIDGE$1)
                                  +  endef
                                  +
                                  +  define SetupWinDLL
                                  +    # Parameter 1 Suffix
                                  +    # Parameter 2 ACCESSBRIDGE_ARCH_ suffix
                                  +    $(call SetupNativeCompilation,BUILD_WINDOWSACCESSBRIDGE$1, \
                                  +        LIBRARY = windowsaccessbridge$1, \
                                  +        OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                  +        SRC := $(WIN_AB_SRCDIR), \
                                  +        OPTIMIZATION := LOW, \
                                  +        CFLAGS := $(filter-out -MD, $(CFLAGS_JDKLIB)) -MT $(ACCESSBRIDGE_CFLAGS) \
                                  +            $(addprefix -I,$(WIN_AB_SRCDIR)) \
                                  +            -I$(JDK_TOPDIR)/src/jdk.accessibility/windows/native/include/bridge \
                                  +            -DACCESSBRIDGE_ARCH_$2, \
                                  +        LDFLAGS := $(LDFLAGS_JDKLIB) kernel32.lib user32.lib gdi32.lib \
                                  +            winspool.lib comdlg32.lib advapi32.lib shell32.lib \
                                  +            ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
                                  +            -subsystem:windows \
                                  +            -def:$(ROOT_SRCDIR)/libwindowsaccessbridge/WinAccessBridge.DEF, \
                                  +        VERSIONINFO_RESOURCE := $(ROOT_SRCDIR)/common/AccessBridgeStatusWindow.rc, \
                                  +        RC_FLAGS := $(RC_FLAGS) \
                                  +            -D "JDK_FNAME=windowsaccessbridge$1.dll" \
                                  +            -D "JDK_INTERNAL_NAME=windowsaccessbridge$1" \
                                  +            -D "JDK_FTYPE=0x02L", \
                                  +        OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libwindowsaccessbridge$1, \
                                  +        DEBUG_SYMBOLS := true)
                                  +
                                  +    TARGETS += $$(BUILD_WINDOWSACCESSBRIDGE$1)
                                  +
                                  +  endef
                                  +
                                  +  define SetupAccessBridgeSysInfo
                                  +
                                  +    $(call SetupNativeCompilation,BUILD_ACCESSBRIDGESYSINFO, \
                                  +        LIBRARY = jabsysinfo, \
                                  +        OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                  +        SRC := $(SYSINFO_SRCDIR), \
                                  +        OPTIMIZATION := LOW, \
                                  +        CFLAGS := $(CFLAGS_JDKLIB) $(ACCESSBRIDGE_CFLAGS), \
                                  +        LDFLAGS := $(LDFLAGS_JDKLIB) \
                                  +            -subsystem:windows -machine:I386, \
                                  +        VERSIONINFO_RESOURCE := $(ROOT_SRCDIR)/common/AccessBridgeStatusWindow.rc, \
                                  +        RC_FLAGS := $(RC_FLAGS) \
                                  +            -D "JDK_FNAME=jabsysinfo.dll" \
                                  +            -D "JDK_INTERNAL_NAME=jabsysinfo" \
                                  +            -D "JDK_FTYPE=0x02L", \
                                  +        OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/lib/libjabsysinfo, \
                                  +        DEBUG_SYMBOLS := true)
                                  +
                                  +    TARGETS += $$(BUILD_ACCESSBRIDGESYSINFO)
                                  +
                                  +  endef
                                  +
                                  +  ifeq ($(OPENJDK_TARGET_CPU_BITS), 32)
                                  +    $(eval $(call SetupAccessBridgeSysInfo))
                                  +    $(eval $(call SetupJavaDLL,-32,32))
                                  +    $(eval $(call SetupJavaDLL,,LEGACY))
                                  +    $(eval $(call SetupWinDLL,-32,32))
                                  +    $(eval $(call SetupWinDLL,,LEGACY))
                                  +  else
                                  +    $(eval $(call SetupJavaDLL,,64))
                                  +    $(eval $(call SetupWinDLL,-64,64))
                                  +  endif
                                  +
                                  +endif
                                  +
                                  +################################################################################
                                  diff --git a/jdk/make/lib/Lib-jdk.attach.gmk b/jdk/make/lib/Lib-jdk.attach.gmk
                                  index 3950b4a7474..c64867c070d 100644
                                  --- a/jdk/make/lib/Lib-jdk.attach.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.attach.gmk
                                  @@ -32,7 +32,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
                                       LIBRARY := attach, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
                                           -I$(SUPPORT_OUTPUTDIR)/headers/jdk.attach \
                                  diff --git a/jdk/make/lib/Lib-jdk.crypto.ec.gmk b/jdk/make/lib/Lib-jdk.crypto.ec.gmk
                                  index 564eb402ae0..5781b777d1e 100644
                                  --- a/jdk/make/lib/Lib-jdk.crypto.ec.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.crypto.ec.gmk
                                  @@ -47,7 +47,7 @@ ifeq ($(ENABLE_INTREE_EC), yes)
                                         LIBRARY := sunec, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBSUNEC_SRC), \
                                  -      LANG := C++, \
                                  +      TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(filter-out $(ECC_JNI_SOLSPARC_FILTER), $(CFLAGS_JDKLIB)) \
                                             $(BUILD_LIBSUNEC_FLAGS) \
                                  diff --git a/jdk/make/lib/Lib-jdk.crypto.mscapi.gmk b/jdk/make/lib/Lib-jdk.crypto.mscapi.gmk
                                  index bc7d1a9fe3a..a2816dfc26b 100644
                                  --- a/jdk/make/lib/Lib-jdk.crypto.mscapi.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.crypto.mscapi.gmk
                                  @@ -35,7 +35,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
                                         LIBRARY := sunmscapi, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBSUNMSCAPI_SRC), \
                                  -      LANG := C++, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             -I$(LIBSUNMSCAPI_SRC), \
                                  diff --git a/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk b/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk
                                  index 0672aa3a359..748b131045c 100644
                                  --- a/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.crypto.pkcs11.gmk
                                  @@ -34,7 +34,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
                                       LIBRARY := j2pkcs11, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJ2PKCS11_SRC), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
                                           $(LIBJAVA_HEADER_FLAGS) \
                                  diff --git a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk
                                  index f66bd4554f9..22b865657a3 100644
                                  --- a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk
                                  @@ -35,7 +35,6 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
                                         LIBRARY := j2ucrypto, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBJ2UCRYPTO_SRC), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             $(addprefix -I, $(LIBJ2UCRYPTO_SRC)), \
                                  diff --git a/jdk/make/lib/Lib-jdk.deploy.osx.gmk b/jdk/make/lib/Lib-jdk.deploy.osx.gmk
                                  index f68b9c065e3..51c56355b5b 100644
                                  --- a/jdk/make/lib/Lib-jdk.deploy.osx.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.deploy.osx.gmk
                                  @@ -35,7 +35,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
                                         LIBRARY := AppleScriptEngine, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBAPPLESCRIPTENGINE_SRC), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             -I$(LIBAPPLESCRIPTENGINE_SRC) \
                                  @@ -68,7 +67,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
                                         LIBRARY := osx, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBOSX_DIRS), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             $(LIBOSX_CFLAGS), \
                                  diff --git a/jdk/make/lib/Lib-jdk.hprof.agent.gmk b/jdk/make/lib/Lib-jdk.hprof.agent.gmk
                                  index 040abc35680..7c43331b33c 100644
                                  --- a/jdk/make/lib/Lib-jdk.hprof.agent.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.hprof.agent.gmk
                                  @@ -45,7 +45,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBHPROF, \
                                       LIBRARY := hprof, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(BUILD_LIBHPROF_SRC), \
                                  -    LANG := C, \
                                       OPTIMIZATION := $(LIBHPROF_OPTIMIZATION), \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
                                           $(BUILD_LIBHPROF_CFLAGS), \
                                  @@ -75,7 +74,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA_CRW_DEMO, \
                                       LIBRARY := java_crw_demo, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJAVA_CRW_DEMO_SRC), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
                                           $(addprefix -I, $(LIBJAVA_CRW_DEMO_SRC)), \
                                  diff --git a/jdk/make/lib/Lib-jdk.jdi.gmk b/jdk/make/lib/Lib-jdk.jdi.gmk
                                  index e46a7276b71..eb1de3b43c1 100644
                                  --- a/jdk/make/lib/Lib-jdk.jdi.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.jdi.gmk
                                  @@ -43,7 +43,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
                                         LIBRARY := dt_shmem, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBDT_SHMEM_SRC), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) -DUSE_MMAP \
                                             $(LIBDT_SHMEM_CPPFLAGS), \
                                  diff --git a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk
                                  index 75c5d3b6830..0743ac85a97 100644
                                  --- a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk
                                  @@ -40,7 +40,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBDT_SOCKET, \
                                       LIBRARY := dt_socket, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBDT_SOCKET_SRC), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_CFLAGS_WARNINGS_ARE_ERRORS) -DUSE_MMAP \
                                           $(LIBDT_SOCKET_CPPFLAGS), \
                                  @@ -77,7 +76,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJDWP, \
                                       LIBRARY := jdwp, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJDWP_SRC), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) -DJDWP_LOGGING \
                                           $(LIBJDWP_CPPFLAGS) \
                                  diff --git a/jdk/make/lib/Lib-jdk.pack200.gmk b/jdk/make/lib/Lib-jdk.pack200.gmk
                                  index 105f1f8b713..e9baaa3dbef 100644
                                  --- a/jdk/make/lib/Lib-jdk.pack200.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.pack200.gmk
                                  @@ -32,7 +32,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(JDK_TOPDIR)/src/jdk.pack200/share/native/libunpack \
                                           $(JDK_TOPDIR)/src/jdk.pack200/share/native/common-unpack, \
                                  -    LANG := C++, \
                                  +    TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CXXFLAGS_JDKLIB) \
                                           -DNO_ZLIB -DUNPACK_JNI -DFULL \
                                  diff --git a/jdk/make/lib/Lib-jdk.sctp.gmk b/jdk/make/lib/Lib-jdk.sctp.gmk
                                  index 61e236e94ff..15db8b3b380 100644
                                  --- a/jdk/make/lib/Lib-jdk.sctp.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.sctp.gmk
                                  @@ -41,7 +41,6 @@ ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
                                           LIBRARY := sctp, \
                                           OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                           SRC := $(JDK_TOPDIR)/src/jdk.sctp/$(OPENJDK_TARGET_OS_TYPE)/native/libsctp, \
                                  -        LANG := C, \
                                           OPTIMIZATION := LOW, \
                                           CFLAGS := $(CFLAGS_JDKLIB) \
                                               -I $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnio/ch \
                                  diff --git a/jdk/make/lib/Lib-jdk.security.auth.gmk b/jdk/make/lib/Lib-jdk.security.auth.gmk
                                  index 80f05da0298..61cd9a66d5c 100644
                                  --- a/jdk/make/lib/Lib-jdk.security.auth.gmk
                                  +++ b/jdk/make/lib/Lib-jdk.security.auth.gmk
                                  @@ -42,7 +42,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
                                       LIBRARY := $(LIBJAAS_NAME), \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \
                                       MAPFILE := $(LIBJAAS_MAPFILE), \
                                  diff --git a/jdk/make/lib/NetworkingLibraries.gmk b/jdk/make/lib/NetworkingLibraries.gmk
                                  index 4231121123e..0f4709301f6 100644
                                  --- a/jdk/make/lib/NetworkingLibraries.gmk
                                  +++ b/jdk/make/lib/NetworkingLibraries.gmk
                                  @@ -29,7 +29,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
                                       LIBRARY := net, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBNET_SRC_DIRS), \
                                  -    LANG := C, \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
                                           $(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \
                                  diff --git a/jdk/make/lib/NioLibraries.gmk b/jdk/make/lib/NioLibraries.gmk
                                  index fd973ccc535..71a65138a9d 100644
                                  --- a/jdk/make/lib/NioLibraries.gmk
                                  +++ b/jdk/make/lib/NioLibraries.gmk
                                  @@ -65,7 +65,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNIO, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(BUILD_LIBNIO_SRC), \
                                       EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
                                  -    LANG := C, \
                                       OPTIMIZATION := HIGH, \
                                       CFLAGS := $(CFLAGS_JDKLIB) \
                                           $(BUILD_LIBNIO_CFLAGS), \
                                  diff --git a/jdk/make/lib/PlatformLibraries.gmk b/jdk/make/lib/PlatformLibraries.gmk
                                  index 0035b1dfbbb..74d535d9095 100644
                                  --- a/jdk/make/lib/PlatformLibraries.gmk
                                  +++ b/jdk/make/lib/PlatformLibraries.gmk
                                  @@ -33,7 +33,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
                                         LIBRARY := osxapp, \
                                         OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                         SRC := $(LIBOSXAPP_SRC), \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             $(addprefix -I, $(LIBOSXAPP_SRC)) \
                                  diff --git a/jdk/make/lib/SoundLibraries.gmk b/jdk/make/lib/SoundLibraries.gmk
                                  index f123d179d7a..07bd1f28637 100644
                                  --- a/jdk/make/lib/SoundLibraries.gmk
                                  +++ b/jdk/make/lib/SoundLibraries.gmk
                                  @@ -35,8 +35,6 @@ LIBJSOUND_CFLAGS := \
                                   
                                   LIBJSOUND_SRC_FILES := Utilities.c Platform.c
                                   
                                  -LIBJSOUND_LANG := C
                                  -
                                   EXTRA_SOUND_JNI_LIBS :=
                                   
                                   LIBJSOUND_MIDIFILES := \
                                  @@ -81,7 +79,7 @@ ifeq ($(OPENJDK_TARGET_OS), aix)
                                   endif # OPENJDK_TARGET_OS aix
                                   
                                   ifeq ($(OPENJDK_TARGET_OS), macosx)
                                  -  LIBJSOUND_LANG := C++
                                  +  LIBJSOUND_TOOLCHAIN := TOOLCHAIN_LINK_CXX
                                     LIBJSOUND_CFLAGS += -DX_PLATFORM=X_MACOSX \
                                         -DUSE_PORTS=TRUE \
                                         -DUSE_DAUDIO=TRUE \
                                  @@ -124,7 +122,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \
                                       OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
                                       SRC := $(LIBJSOUND_SRC_DIRS), \
                                       INCLUDE_FILES := $(LIBJSOUND_SRC_FILES), \
                                  -    LANG := $(LIBJSOUND_LANG), \
                                  +    TOOLCHAIN := $(LIBJSOUND_TOOLCHAIN), \
                                       OPTIMIZATION := LOW, \
                                       CFLAGS := $(CFLAGS_JDKLIB) \
                                           $(LIBJSOUND_CFLAGS), \
                                  @@ -169,7 +167,6 @@ ifneq ($(filter jsoundalsa, $(EXTRA_SOUND_JNI_LIBS)), )
                                             PLATFORM_API_LinuxOS_ALSA_MidiOut.c \
                                             PLATFORM_API_LinuxOS_ALSA_MidiUtils.c \
                                             PLATFORM_API_LinuxOS_ALSA_Ports.c, \
                                  -      LANG := C, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) $(ALSA_CFLAGS) \
                                             $(LIBJSOUND_CFLAGS) \
                                  @@ -201,7 +198,6 @@ ifneq ($(filter jsoundds, $(EXTRA_SOUND_JNI_LIBS)), )
                                         SRC := $(LIBJSOUND_SRC_DIRS), \
                                         INCLUDE_FILES := Utilities.c $(LIBJSOUND_DAUDIOFILES) \
                                             PLATFORM_API_WinOS_DirectSound.cpp, \
                                  -      LANG := C++, \
                                         OPTIMIZATION := LOW, \
                                         CFLAGS := $(CFLAGS_JDKLIB) \
                                             $(LIBJSOUND_CFLAGS) \
                                  diff --git a/jdk/make/mapfiles/launchers/mapfile-x86_64 b/jdk/make/mapfiles/launchers/mapfile-x86_64
                                  index 61c2d1cc3f2..5700d67f2a0 100644
                                  --- a/jdk/make/mapfiles/launchers/mapfile-x86_64
                                  +++ b/jdk/make/mapfiles/launchers/mapfile-x86_64
                                  @@ -34,6 +34,14 @@ SUNWprivate_1.1 {
                                   		_environ;
                                   		__environ_lock;
                                   
                                  +		# These are needed by the c runtime in SS12u4
                                  +		___Argv;
                                  +		__xargv;
                                  +		__xargc;
                                  +		_start;
                                  +		__longdouble_used;
                                  +		_lib_version;
                                  +
                                   	local:
                                   		*;
                                   };
                                  diff --git a/jdk/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-sparc b/jdk/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-sparc
                                  new file mode 100644
                                  index 00000000000..63f2a41a478
                                  --- /dev/null
                                  +++ b/jdk/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-sparc
                                  @@ -0,0 +1,41 @@
                                  +#
                                  +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
                                  +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                  +#
                                  +# This code is free software; you can redistribute it and/or modify it
                                  +# under the terms of the GNU General Public License version 2 only, as
                                  +# published by the Free Software Foundation.  Oracle designates this
                                  +# particular file as subject to the "Classpath" exception as provided
                                  +# by Oracle in the LICENSE file that accompanied this code.
                                  +#
                                  +# This code is distributed in the hope that it will be useful, but WITHOUT
                                  +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                  +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                                  +# version 2 for more details (a copy is included in the LICENSE file that
                                  +# accompanied this code).
                                  +#
                                  +# You should have received a copy of the GNU General Public License version
                                  +# 2 along with this work; if not, write to the Free Software Foundation,
                                  +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
                                  +#
                                  +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
                                  +# or visit www.oracle.com if you need additional information or have any
                                  +# questions.
                                  +#
                                  +
                                  +# Define library interface.
                                  +
                                  +SUNWprivate_1.1 {
                                  +	global:
                                  +		# These are needed by the c runtime in SS12u4
                                  +		_environ;
                                  +		__environ_lock;
                                  +		___Argv;
                                  +		__xargv;
                                  +		__xargc;
                                  +		_start;
                                  +		_lib_version;
                                  +
                                  +	local:
                                  +	    *;
                                  +};
                                  diff --git a/jdk/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-x86 b/jdk/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-x86
                                  new file mode 100644
                                  index 00000000000..60220b18ad3
                                  --- /dev/null
                                  +++ b/jdk/make/mapfiles/libunpack/mapfile-vers-unpack200-solaris-x86
                                  @@ -0,0 +1,42 @@
                                  +#
                                  +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
                                  +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                  +#
                                  +# This code is free software; you can redistribute it and/or modify it
                                  +# under the terms of the GNU General Public License version 2 only, as
                                  +# published by the Free Software Foundation.  Oracle designates this
                                  +# particular file as subject to the "Classpath" exception as provided
                                  +# by Oracle in the LICENSE file that accompanied this code.
                                  +#
                                  +# This code is distributed in the hope that it will be useful, but WITHOUT
                                  +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                                  +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                                  +# version 2 for more details (a copy is included in the LICENSE file that
                                  +# accompanied this code).
                                  +#
                                  +# You should have received a copy of the GNU General Public License version
                                  +# 2 along with this work; if not, write to the Free Software Foundation,
                                  +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
                                  +#
                                  +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
                                  +# or visit www.oracle.com if you need additional information or have any
                                  +# questions.
                                  +#
                                  +
                                  +# Define library interface.
                                  +
                                  +SUNWprivate_1.1 {
                                  +	global:
                                  +		# These are needed by the c runtime in SS12u4
                                  +		_environ;
                                  +		__environ_lock;
                                  +		___Argv;
                                  +		__xargv;
                                  +		__xargc;
                                  +		_start;
                                  +		__longdouble_used;
                                  +		_lib_version;
                                  +
                                  +	local:
                                  +	    *;
                                  +};
                                  diff --git a/jdk/make/src/classes/build/tools/module/ext.modules b/jdk/make/src/classes/build/tools/module/ext.modules
                                  index 934d4e9ba16..15c2e9d6ae0 100644
                                  --- a/jdk/make/src/classes/build/tools/module/ext.modules
                                  +++ b/jdk/make/src/classes/build/tools/module/ext.modules
                                  @@ -4,7 +4,7 @@ java.corba
                                   java.transaction
                                   java.xml.bind
                                   java.xml.ws
                                  -jdk.accessbridge
                                  +jdk.accessibility
                                   jdk.crypto.ec
                                   jdk.crypto.mscapi
                                   jdk.crypto.pkcs11
                                  @@ -12,4 +12,5 @@ jdk.crypto.ucrypto
                                   jdk.localedata
                                   jdk.naming.dns
                                   jdk.scripting.nashorn
                                  +jdk.xml.dom
                                   jdk.zipfs
                                  diff --git a/jdk/src/java.base/linux/classes/sun/nio/ch/EPollPort.java b/jdk/src/java.base/linux/classes/sun/nio/ch/EPollPort.java
                                  index 651457e98df..27f2c7b76d1 100644
                                  --- a/jdk/src/java.base/linux/classes/sun/nio/ch/EPollPort.java
                                  +++ b/jdk/src/java.base/linux/classes/sun/nio/ch/EPollPort.java
                                  @@ -105,7 +105,7 @@ final class EPollPort
                                   
                                           // create the queue and offer the special event to ensure that the first
                                           // threads polls
                                  -        this.queue = new ArrayBlockingQueue(MAX_EPOLL_EVENTS);
                                  +        this.queue = new ArrayBlockingQueue<>(MAX_EPOLL_EVENTS);
                                           this.queue.offer(NEED_TO_POLL);
                                       }
                                   
                                  diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java
                                  index e8d8dc8d6e2..5dbb331631f 100644
                                  --- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java
                                  +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java
                                  @@ -121,7 +121,7 @@ class LinuxNativeDispatcher extends UnixNativeDispatcher {
                                       private static native void init();
                                   
                                       static {
                                  -        AccessController.doPrivileged(new PrivilegedAction() {
                                  +        AccessController.doPrivileged(new PrivilegedAction<>() {
                                               public Void run() {
                                                   System.loadLibrary("nio");
                                                   return null;
                                  diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java
                                  index 123fab5b3ea..19079d72878 100644
                                  --- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java
                                  +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java
                                  @@ -190,7 +190,7 @@ class LinuxWatchService
                                               this.watcher = watcher;
                                               this.ifd = ifd;
                                               this.socketpair = sp;
                                  -            this.wdToKey = new HashMap();
                                  +            this.wdToKey = new HashMap<>();
                                               this.address = unsafe.allocateMemory(BUFFER_SIZE);
                                           }
                                   
                                  @@ -457,7 +457,7 @@ class LinuxWatchService
                                       private static native int poll(int fd1, int fd2) throws UnixException;
                                   
                                       static {
                                  -        AccessController.doPrivileged(new PrivilegedAction() {
                                  +        AccessController.doPrivileged(new PrivilegedAction<>() {
                                               public Void run() {
                                                   System.loadLibrary("nio");
                                                   return null;
                                  diff --git a/jdk/src/java.base/linux/classes/sun/nio/fs/MagicFileTypeDetector.java b/jdk/src/java.base/linux/classes/sun/nio/fs/MagicFileTypeDetector.java
                                  index 801bd626724..2798c960f87 100644
                                  --- a/jdk/src/java.base/linux/classes/sun/nio/fs/MagicFileTypeDetector.java
                                  +++ b/jdk/src/java.base/linux/classes/sun/nio/fs/MagicFileTypeDetector.java
                                  @@ -68,7 +68,7 @@ class MagicFileTypeDetector extends AbstractFileTypeDetector {
                                       private static native byte[] probe0(long pathAddress);
                                   
                                       static {
                                  -        AccessController.doPrivileged(new PrivilegedAction() {
                                  +        AccessController.doPrivileged(new PrivilegedAction<>() {
                                               @Override
                                               public Void run() {
                                                   System.loadLibrary("nio");
                                  diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
                                  index 0ce3358aaad..c912a3f04f0 100644
                                  --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
                                  +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -350,7 +350,7 @@ public final class RSACipher extends CipherSpi {
                                               switch (mode) {
                                               case MODE_SIGN:
                                                   data = padding.pad(buffer, 0, bufOfs);
                                  -                return RSACore.rsa(data, privateKey);
                                  +                return RSACore.rsa(data, privateKey, true);
                                               case MODE_VERIFY:
                                                   byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs);
                                                   data = RSACore.rsa(verifyBuffer, publicKey);
                                  @@ -360,7 +360,7 @@ public final class RSACipher extends CipherSpi {
                                                   return RSACore.rsa(data, publicKey);
                                               case MODE_DECRYPT:
                                                   byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
                                  -                data = RSACore.rsa(decryptBuffer, privateKey);
                                  +                data = RSACore.rsa(decryptBuffer, privateKey, false);
                                                   return padding.unpad(data);
                                               default:
                                                   throw new AssertionError("Internal error");
                                  diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
                                  index 52864dfb02f..d254cb8d5d2 100644
                                  --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
                                  +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
                                  @@ -87,7 +87,7 @@ class NativeUnpack {
                                           // If loading from stand alone build uncomment this.
                                           // System.loadLibrary("unpack");
                                           java.security.AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       System.loadLibrary("unpack");
                                                       return null;
                                  diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java
                                  index af78754e06b..002d88197cb 100644
                                  --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java
                                  +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/Package.java
                                  @@ -1210,7 +1210,7 @@ class Package {
                                           // This keeps files of similar format near each other.
                                           // Put class files at the end, keeping their fixed order.
                                           // Be sure the JAR file's required manifest stays at the front. (4893051)
                                  -        Collections.sort(files, new Comparator() {
                                  +        Collections.sort(files, new Comparator<>() {
                                                   public int compare(File r0, File r1) {
                                                       // Get the file name.
                                                       String f0 = r0.nameString;
                                  diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java
                                  index 000a643f873..018c33f6fd0 100644
                                  --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java
                                  +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageReader.java
                                  @@ -1151,7 +1151,7 @@ class PackageReader extends BandStructure {
                                           return -1;
                                       }
                                   
                                  -    Comparator entryOutputOrder = new Comparator() {
                                  +    Comparator entryOutputOrder = new Comparator<>() {
                                           public int compare(Entry e0, Entry e1) {
                                               int k0 = getOutputIndex(e0);
                                               int k1 = getOutputIndex(e1);
                                  diff --git a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
                                  index bca629f8008..bd3c89951ee 100644
                                  --- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
                                  +++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
                                  @@ -829,7 +829,7 @@ class PackageWriter extends BandStructure {
                                           maxFlags = new int[ATTR_CONTEXT_LIMIT];
                                           allLayouts = new FixedList<>(ATTR_CONTEXT_LIMIT);
                                           for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
                                  -            allLayouts.set(i, new HashMap());
                                  +            allLayouts.set(i, new HashMap<>());
                                           }
                                           // Collect maxFlags and allLayouts.
                                           for (Class cls : pkg.classes) {
                                  @@ -892,7 +892,7 @@ class PackageWriter extends BandStructure {
                                               // Sort by count, most frequent first.
                                               // Predefs. participate in this sort, though it does not matter.
                                               Arrays.sort(layoutsAndCounts,
                                  -                        new Comparator>() {
                                  +                        new Comparator<>() {
                                                   public int compare(Map.Entry e0,
                                                                      Map.Entry e1) {
                                                       // Primary sort key is count, reversed.
                                  @@ -1010,7 +1010,7 @@ class PackageWriter extends BandStructure {
                                           int numAttrDefs = defList.size();
                                           Object[][] defs = new Object[numAttrDefs][];
                                           defList.toArray(defs);
                                  -        Arrays.sort(defs, new Comparator() {
                                  +        Arrays.sort(defs, new Comparator<>() {
                                               public int compare(Object[] a0, Object[] a1) {
                                                   // Primary sort key is attr def header.
                                                   @SuppressWarnings("unchecked")
                                  diff --git a/jdk/src/java.base/share/classes/java/io/ExpiringCache.java b/jdk/src/java.base/share/classes/java/io/ExpiringCache.java
                                  index 5f16877313a..3cd295bda16 100644
                                  --- a/jdk/src/java.base/share/classes/java/io/ExpiringCache.java
                                  +++ b/jdk/src/java.base/share/classes/java/io/ExpiringCache.java
                                  @@ -64,7 +64,7 @@ class ExpiringCache {
                                       @SuppressWarnings("serial")
                                       ExpiringCache(long millisUntilExpiration) {
                                           this.millisUntilExpiration = millisUntilExpiration;
                                  -        map = new LinkedHashMap() {
                                  +        map = new LinkedHashMap<>() {
                                               protected boolean removeEldestEntry(Map.Entry eldest) {
                                                 return size() > MAX_ENTRIES;
                                               }
                                  diff --git a/jdk/src/java.base/share/classes/java/io/FilePermission.java b/jdk/src/java.base/share/classes/java/io/FilePermission.java
                                  index b008d4f933a..0c5bcf35178 100644
                                  --- a/jdk/src/java.base/share/classes/java/io/FilePermission.java
                                  +++ b/jdk/src/java.base/share/classes/java/io/FilePermission.java
                                  @@ -201,7 +201,7 @@ public final class FilePermission extends Permission implements Serializable {
                                           }
                                   
                                           // store only the canonical cpath if possible
                                  -        cpath = AccessController.doPrivileged(new PrivilegedAction() {
                                  +        cpath = AccessController.doPrivileged(new PrivilegedAction<>() {
                                               public String run() {
                                                   try {
                                                       String path = cpath;
                                  diff --git a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java
                                  index 6ae3a542c10..3f098418207 100644
                                  --- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java
                                  +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java
                                  @@ -1263,7 +1263,7 @@ public class ObjectInputStream
                                        */
                                       private static boolean auditSubclass(final Class subcl) {
                                           Boolean result = AccessController.doPrivileged(
                                  -            new PrivilegedAction() {
                                  +            new PrivilegedAction<>() {
                                                   public Boolean run() {
                                                       for (Class cl = subcl;
                                                            cl != ObjectInputStream.class;
                                  @@ -2255,7 +2255,7 @@ public class ObjectInputStream
                                               try {
                                                   while (list != null) {
                                                       AccessController.doPrivileged(
                                  -                        new PrivilegedExceptionAction()
                                  +                        new PrivilegedExceptionAction<>()
                                                       {
                                                           public Void run() throws InvalidObjectException {
                                                               list.obj.validateObject();
                                  diff --git a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java
                                  index e99e0257f31..861b201aae8 100644
                                  --- a/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java
                                  +++ b/jdk/src/java.base/share/classes/java/io/ObjectOutputStream.java
                                  @@ -1066,7 +1066,7 @@ public class ObjectOutputStream
                                        */
                                       private static boolean auditSubclass(final Class subcl) {
                                           Boolean result = AccessController.doPrivileged(
                                  -            new PrivilegedAction() {
                                  +            new PrivilegedAction<>() {
                                                   public Boolean run() {
                                                       for (Class cl = subcl;
                                                            cl != ObjectOutputStream.class;
                                  diff --git a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java
                                  index 1e8a4342390..7220eb3ab0b 100644
                                  --- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java
                                  +++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java
                                  @@ -367,7 +367,7 @@ public class ObjectStreamClass implements Serializable {
                                                   entry = th;
                                               }
                                               if (future.set(entry)) {
                                  -                Caches.localDescs.put(key, new SoftReference(entry));
                                  +                Caches.localDescs.put(key, new SoftReference<>(entry));
                                               } else {
                                                   // nested lookup call already set future
                                                   entry = future.get();
                                  @@ -430,7 +430,7 @@ public class ObjectStreamClass implements Serializable {
                                               }
                                               if (interrupted) {
                                                   AccessController.doPrivileged(
                                  -                    new PrivilegedAction() {
                                  +                    new PrivilegedAction<>() {
                                                           public Void run() {
                                                               Thread.currentThread().interrupt();
                                                               return null;
                                  @@ -465,7 +465,7 @@ public class ObjectStreamClass implements Serializable {
                                           localDesc = this;
                                   
                                           if (serializable) {
                                  -            AccessController.doPrivileged(new PrivilegedAction() {
                                  +            AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public Void run() {
                                                       if (isEnum) {
                                                           suid = Long.valueOf(0);
                                  @@ -1733,7 +1733,7 @@ public class ObjectStreamClass implements Serializable {
                                               for (int i = 0; i < fields.length; i++) {
                                                   fieldSigs[i] = new MemberSignature(fields[i]);
                                               }
                                  -            Arrays.sort(fieldSigs, new Comparator() {
                                  +            Arrays.sort(fieldSigs, new Comparator<>() {
                                                   public int compare(MemberSignature ms1, MemberSignature ms2) {
                                                       return ms1.name.compareTo(ms2.name);
                                                   }
                                  @@ -1764,7 +1764,7 @@ public class ObjectStreamClass implements Serializable {
                                               for (int i = 0; i < cons.length; i++) {
                                                   consSigs[i] = new MemberSignature(cons[i]);
                                               }
                                  -            Arrays.sort(consSigs, new Comparator() {
                                  +            Arrays.sort(consSigs, new Comparator<>() {
                                                   public int compare(MemberSignature ms1, MemberSignature ms2) {
                                                       return ms1.signature.compareTo(ms2.signature);
                                                   }
                                  @@ -1787,7 +1787,7 @@ public class ObjectStreamClass implements Serializable {
                                               for (int i = 0; i < methods.length; i++) {
                                                   methSigs[i] = new MemberSignature(methods[i]);
                                               }
                                  -            Arrays.sort(methSigs, new Comparator() {
                                  +            Arrays.sort(methSigs, new Comparator<>() {
                                                   public int compare(MemberSignature ms1, MemberSignature ms2) {
                                                       int comp = ms1.name.compareTo(ms2.name);
                                                       if (comp == 0) {
                                  @@ -2164,7 +2164,7 @@ public class ObjectStreamClass implements Serializable {
                                                   entry = th;
                                               }
                                               future.set(entry);
                                  -            Caches.reflectors.put(key, new SoftReference(entry));
                                  +            Caches.reflectors.put(key, new SoftReference<>(entry));
                                           }
                                   
                                           if (entry instanceof FieldReflector) {
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/CharacterName.java b/jdk/src/java.base/share/classes/java/lang/CharacterName.java
                                  index 9dbbffc7299..bcc715180d0 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/CharacterName.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/CharacterName.java
                                  @@ -45,7 +45,7 @@ class CharacterName {
                                           DataInputStream dis = null;
                                           try {
                                               dis = new DataInputStream(new InflaterInputStream(
                                  -                AccessController.doPrivileged(new PrivilegedAction()
                                  +                AccessController.doPrivileged(new PrivilegedAction<>()
                                                   {
                                                       public InputStream run() {
                                                           return getClass().getResourceAsStream("uniName.dat");
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java
                                  index 258ec369ce5..9748cc6c804 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/Class.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/Class.java
                                  @@ -437,7 +437,7 @@ public final class Class implements java.io.Serializable,
                                                   // (the stack depth is wrong for the Constructor's
                                                   // security check to work)
                                                   java.security.AccessController.doPrivileged(
                                  -                    new java.security.PrivilegedAction() {
                                  +                    new java.security.PrivilegedAction<>() {
                                                           public Void run() {
                                                                   c.setAccessible(true);
                                                                   return null;
                                  @@ -1068,7 +1068,7 @@ public final class Class implements java.io.Serializable,
                                                                                    Reflection.getCallerClass(), true);
                                               // Client is ok to access declared methods but j.l.Class might not be.
                                               Method[] candidates = AccessController.doPrivileged(
                                  -                    new PrivilegedAction() {
                                  +                    new PrivilegedAction<>() {
                                                           @Override
                                                           public Method[] run() {
                                                               return enclosingCandidate.getDeclaredMethods();
                                  @@ -1228,7 +1228,7 @@ public final class Class implements java.io.Serializable,
                                                                                    Reflection.getCallerClass(), true);
                                               // Client is ok to access declared methods but j.l.Class might not be.
                                               Constructor[] candidates = AccessController.doPrivileged(
                                  -                    new PrivilegedAction[]>() {
                                  +                    new PrivilegedAction<>() {
                                                           @Override
                                                           public Constructor[] run() {
                                                               return enclosingCandidate.getDeclaredConstructors();
                                  @@ -1542,7 +1542,7 @@ public final class Class implements java.io.Serializable,
                                           // has already been ok'd by the SecurityManager.
                                   
                                           return java.security.AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction[]>() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Class[] run() {
                                                       List> list = new ArrayList<>();
                                                       Class currentClass = Class.this;
                                  @@ -3293,7 +3293,7 @@ public final class Class implements java.io.Serializable,
                                       private static boolean initted = false;
                                       private static void checkInitted() {
                                           if (initted) return;
                                  -        AccessController.doPrivileged(new PrivilegedAction() {
                                  +        AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public Void run() {
                                                       // Tests to ensure the system properties table is fully
                                                       // initialized. This is needed because reflection code is
                                  @@ -3349,7 +3349,7 @@ public final class Class implements java.io.Serializable,
                                               try {
                                                   final Method values = getMethod("values");
                                                   java.security.AccessController.doPrivileged(
                                  -                    new java.security.PrivilegedAction() {
                                  +                    new java.security.PrivilegedAction<>() {
                                                           public Void run() {
                                                                   values.setAccessible(true);
                                                                   return null;
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
                                  index 3eb5819473e..295955847ca 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
                                  @@ -496,7 +496,7 @@ public abstract class ClassLoader {
                                               final String name = cls.getName();
                                               final int i = name.lastIndexOf('.');
                                               if (i != -1) {
                                  -                AccessController.doPrivileged(new PrivilegedAction() {
                                  +                AccessController.doPrivileged(new PrivilegedAction<>() {
                                                       public Void run() {
                                                           sm.checkPackageAccess(name.substring(0, i));
                                                           return null;
                                  @@ -1265,7 +1265,7 @@ public abstract class ClassLoader {
                                       {
                                           final Enumeration e =
                                               getBootstrapClassPath().getResources(name);
                                  -        return new Enumeration () {
                                  +        return new Enumeration<> () {
                                               public URL nextElement() {
                                                   return e.nextElement().getURL();
                                               }
                                  @@ -1867,7 +1867,7 @@ public abstract class ClassLoader {
                                           boolean isBuiltin = (name != null);
                                           if (!isBuiltin) {
                                               name = AccessController.doPrivileged(
                                  -                new PrivilegedAction() {
                                  +                new PrivilegedAction<>() {
                                                       public String run() {
                                                           try {
                                                               return file.exists() ? file.getCanonicalPath() : null;
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/Package.java b/jdk/src/java.base/share/classes/java/lang/Package.java
                                  index 725429d4b2e..9cd63274b65 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/Package.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/Package.java
                                  @@ -595,7 +595,7 @@ public class Package implements java.lang.reflect.AnnotatedElement {
                                   
                                           CachedManifest(final String fileName) {
                                               this.fileName = fileName;
                                  -            this.url = AccessController.doPrivileged(new PrivilegedAction() {
                                  +            this.url = AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public URL run() {
                                                       final File file = new File(fileName);
                                                       if (file.isFile()) {
                                  @@ -626,7 +626,7 @@ public class Package implements java.lang.reflect.AnnotatedElement {
                                                   if (m != null) {
                                                       return m;
                                                   }
                                  -                m = AccessController.doPrivileged(new PrivilegedAction() {
                                  +                m = AccessController.doPrivileged(new PrivilegedAction<>() {
                                                       public Manifest run() {
                                                           try (FileInputStream fis = new FileInputStream(fileName);
                                                                JarInputStream jis = new JarInputStream(fis, false)) {
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java
                                  index 1714cf03b23..7f1e90d6c04 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java
                                  @@ -1455,7 +1455,7 @@ class SecurityManager {
                                               if (!packageAccessValid) {
                                                   String tmpPropertyStr =
                                                       AccessController.doPrivileged(
                                  -                        new PrivilegedAction() {
                                  +                        new PrivilegedAction<>() {
                                                               public String run() {
                                                                   return java.security.Security.getProperty(
                                                                       "package.access");
                                  @@ -1524,7 +1524,7 @@ class SecurityManager {
                                               if (!packageDefinitionValid) {
                                                   String tmpPropertyStr =
                                                       AccessController.doPrivileged(
                                  -                        new PrivilegedAction() {
                                  +                        new PrivilegedAction<>() {
                                                               public String run() {
                                                                   return java.security.Security.getProperty(
                                                                       "package.definition");
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java
                                  index a53c7c4c2bb..80d6718399f 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java
                                  @@ -206,6 +206,7 @@ import java.util.Arrays;
                                       }
                                   
                                       /**
                                  +     * @throws IndexOutOfBoundsException {@inheritDoc}
                                        * @since      1.5
                                        */
                                       @Override
                                  @@ -214,6 +215,7 @@ import java.util.Arrays;
                                       }
                                   
                                       /**
                                  +     * @throws IndexOutOfBoundsException {@inheritDoc}
                                        * @since     1.5
                                        */
                                       @Override
                                  @@ -222,6 +224,7 @@ import java.util.Arrays;
                                       }
                                   
                                       /**
                                  +     * @throws IndexOutOfBoundsException {@inheritDoc}
                                        * @since     1.5
                                        */
                                       @Override
                                  @@ -230,6 +233,7 @@ import java.util.Arrays;
                                       }
                                   
                                       /**
                                  +     * @throws IndexOutOfBoundsException {@inheritDoc}
                                        * @since     1.5
                                        */
                                       @Override
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/System.java b/jdk/src/java.base/share/classes/java/lang/System.java
                                  index ee6588491f9..699467ca5a4 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/System.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/System.java
                                  @@ -309,7 +309,7 @@ public final class System {
                                               // calls the installed security manager's checkPermission method
                                               // which will loop infinitely if there is a non-system class
                                               // (in this case: the new security manager class) on the stack).
                                  -            AccessController.doPrivileged(new PrivilegedAction() {
                                  +            AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public Object run() {
                                                       s.getClass().getProtectionDomain().implies
                                                           (SecurityConstants.ALL_PERMISSION);
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java
                                  index e7477416ecb..af2a2a2b049 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/Thread.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/Thread.java
                                  @@ -1661,7 +1661,7 @@ class Thread implements Runnable {
                                        */
                                       private static boolean auditSubclass(final Class subcl) {
                                           Boolean result = AccessController.doPrivileged(
                                  -            new PrivilegedAction() {
                                  +            new PrivilegedAction<>() {
                                                   public Boolean run() {
                                                       for (Class cl = subcl;
                                                            cl != Thread.class;
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java b/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java
                                  index 0ecd005a8d3..6e9e1de81ee 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java
                                  @@ -87,7 +87,7 @@ class InfoFromMemberName implements MethodHandleInfo {
                                               // For more information see comments on {@link MethodHandleNatives#linkMethod}.
                                               throw new IllegalArgumentException("cannot reflect signature polymorphic method");
                                           }
                                  -        Member mem = AccessController.doPrivileged(new PrivilegedAction() {
                                  +        Member mem = AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public Member run() {
                                                       try {
                                                           return reflectUnchecked();
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
                                  index 421db68b464..69d80ec0e61 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
                                  @@ -194,7 +194,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
                                           final Class innerClass = spinInnerClass();
                                           if (invokedType.parameterCount() == 0) {
                                               final Constructor[] ctrs = AccessController.doPrivileged(
                                  -                    new PrivilegedAction[]>() {
                                  +                    new PrivilegedAction<>() {
                                                   @Override
                                                   public Constructor[] run() {
                                                       Constructor[] ctrs = innerClass.getDeclaredConstructors();
                                  @@ -311,7 +311,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
                                   
                                           // If requested, dump out to a file for debugging purposes
                                           if (dumper != null) {
                                  -            AccessController.doPrivileged(new PrivilegedAction() {
                                  +            AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   @Override
                                                   public Void run() {
                                                       dumper.dumpClass(lambdaClassName, classBytes);
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
                                  index a29eed9417a..b44f9adf62f 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
                                  @@ -167,7 +167,7 @@ class InvokerBytecodeGenerator {
                                       static void maybeDump(final String className, final byte[] classFile) {
                                           if (DUMP_CLASS_FILES) {
                                               java.security.AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       try {
                                                           String dumpName = className;
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
                                  index 57568ece696..c138676a8fb 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
                                  @@ -51,7 +51,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
                                       private static final int MAX_ARITY;
                                       static {
                                           final Object[] values = { 255 };
                                  -        AccessController.doPrivileged(new PrivilegedAction() {
                                  +        AccessController.doPrivileged(new PrivilegedAction<>() {
                                               @Override
                                               public Void run() {
                                                   values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
                                  @@ -1234,7 +1234,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
                                           private static final byte[] T_BYTES;
                                           static {
                                               final Object[] values = {null};
                                  -            AccessController.doPrivileged(new PrivilegedAction() {
                                  +            AccessController.doPrivileged(new PrivilegedAction<>() {
                                                       public Void run() {
                                                           try {
                                                               Class tClass = T.class;
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
                                  index 1167eeb4a2b..37373de1a59 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
                                  @@ -199,7 +199,7 @@ public class MethodHandleProxies {
                                               // sun.invoke.WrapperInstance is a restricted interface not accessible
                                               // by any non-null class loader.
                                               final ClassLoader loader = proxyLoader;
                                  -            proxy = AccessController.doPrivileged(new PrivilegedAction() {
                                  +            proxy = AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public Object run() {
                                                       return Proxy.newProxyInstance(
                                                               loader,
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java
                                  index 144de11094f..092a5135879 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java
                                  @@ -53,7 +53,7 @@ import sun.misc.Unsafe;
                                   
                                       static {
                                           final Object[] values = new Object[9];
                                  -        AccessController.doPrivileged(new PrivilegedAction() {
                                  +        AccessController.doPrivileged(new PrivilegedAction<>() {
                                                   public Void run() {
                                                       values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
                                                       values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java b/jdk/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java
                                  index 463f1ff286c..3f143765925 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/ProxyClassesDumper.java
                                  @@ -64,7 +64,7 @@ final class ProxyClassesDumper {
                                           try {
                                               path = path.trim();
                                               final Path dir = Paths.get(path.length() == 0 ? "." : path);
                                  -            AccessController.doPrivileged(new PrivilegedAction() {
                                  +            AccessController.doPrivileged(new PrivilegedAction<>() {
                                                       @Override
                                                       public Void run() {
                                                           validateDumpDir(dir);
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java b/jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java
                                  index e6412012721..d9f94f39e77 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java
                                  @@ -218,7 +218,7 @@ public final class SerializedLambda implements Serializable {
                                   
                                       private Object readResolve() throws ReflectiveOperationException {
                                           try {
                                  -            Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction() {
                                  +            Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
                                                   @Override
                                                   public Method run() throws Exception {
                                                       Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java b/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java
                                  index 6ae2262c5aa..d9cabe61543 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/ref/Finalizer.java
                                  @@ -28,6 +28,7 @@ package java.lang.ref;
                                   import java.security.PrivilegedAction;
                                   import java.security.AccessController;
                                   import sun.misc.JavaLangAccess;
                                  +import sun.misc.ManagedLocalsThread;
                                   import sun.misc.SharedSecrets;
                                   import sun.misc.VM;
                                   
                                  @@ -120,13 +121,13 @@ final class Finalizer extends FinalReference { /* Package-private; must
                                        */
                                       private static void forkSecondaryFinalizer(final Runnable proc) {
                                           AccessController.doPrivileged(
                                  -            new PrivilegedAction() {
                                  +            new PrivilegedAction<>() {
                                                   public Void run() {
                                                       ThreadGroup tg = Thread.currentThread().getThreadGroup();
                                                       for (ThreadGroup tgn = tg;
                                                            tgn != null;
                                                            tg = tgn, tgn = tg.getParent());
                                  -                    Thread sft = new Thread(tg, proc, "Secondary finalizer");
                                  +                    Thread sft = new ManagedLocalsThread(tg, proc, "Secondary finalizer");
                                                       sft.start();
                                                       try {
                                                           sft.join();
                                  @@ -185,7 +186,7 @@ final class Finalizer extends FinalReference { /* Package-private; must
                                                   }}});
                                       }
                                   
                                  -    private static class FinalizerThread extends Thread {
                                  +    private static class FinalizerThread extends ManagedLocalsThread {
                                           private volatile boolean running;
                                           FinalizerThread(ThreadGroup g) {
                                               super(g, "Finalizer");
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java
                                  index 5febcae0299..2bab588f1f4 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java
                                  @@ -27,6 +27,7 @@ package java.lang.ref;
                                   
                                   import sun.misc.Cleaner;
                                   import sun.misc.JavaLangRefAccess;
                                  +import sun.misc.ManagedLocalsThread;
                                   import sun.misc.SharedSecrets;
                                   
                                   /**
                                  @@ -126,7 +127,7 @@ public abstract class Reference {
                                   
                                       /* High-priority thread to enqueue pending References
                                        */
                                  -    private static class ReferenceHandler extends Thread {
                                  +    private static class ReferenceHandler extends ManagedLocalsThread {
                                   
                                           private static void ensureClassInitialized(Class clazz) {
                                               try {
                                  diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java
                                  index 34f0d4c3c01..99b39ce9c76 100644
                                  --- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java
                                  +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java
                                  @@ -728,7 +728,7 @@ public class Proxy implements java.io.Serializable {
                                   
                                               final Constructor cons = cl.getConstructor(constructorParams);
                                               if (!Modifier.isPublic(cl.getModifiers())) {
                                  -                AccessController.doPrivileged(new PrivilegedAction() {
                                  +                AccessController.doPrivileged(new PrivilegedAction<>() {
                                                       public Void run() {
                                                           cons.setAccessible(true);
                                                           return null;
                                  diff --git a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
                                  index 0ffe37f8d9f..1331df397d2 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
                                  @@ -62,7 +62,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
                                        */
                                       static {
                                           java.security.AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       System.loadLibrary("net");
                                                       return null;
                                  diff --git a/jdk/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java
                                  index 2220533459b..b611273f958 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java
                                  @@ -79,7 +79,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
                                        */
                                       static {
                                           java.security.AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       System.loadLibrary("net");
                                                       return null;
                                  diff --git a/jdk/src/java.base/share/classes/java/net/CookieManager.java b/jdk/src/java.base/share/classes/java/net/CookieManager.java
                                  index 4dbc9aa2dfa..74216eb4de0 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/CookieManager.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/CookieManager.java
                                  @@ -201,14 +201,13 @@ public class CookieManager extends CookieHandler
                                               throw new IllegalArgumentException("Argument is null");
                                           }
                                   
                                  -        Map> cookieMap =
                                  -                        new java.util.HashMap>();
                                  +        Map> cookieMap = new java.util.HashMap<>();
                                           // if there's no default CookieStore, no way for us to get any cookie
                                           if (cookieJar == null)
                                               return Collections.unmodifiableMap(cookieMap);
                                   
                                           boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
                                  -        List cookies = new java.util.ArrayList();
                                  +        List cookies = new java.util.ArrayList<>();
                                           String path = uri.getPath();
                                           if (path == null || path.isEmpty()) {
                                               path = "/";
                                  @@ -411,7 +410,7 @@ public class CookieManager extends CookieHandler
                                       private List sortByPath(List cookies) {
                                           Collections.sort(cookies, new CookiePathComparator());
                                   
                                  -        List cookieHeader = new java.util.ArrayList();
                                  +        List cookieHeader = new java.util.ArrayList<>();
                                           for (HttpCookie cookie : cookies) {
                                               // Netscape cookie spec and RFC 2965 have different format of Cookie
                                               // header; RFC 2965 requires a leading $Version="1" string while Netscape
                                  diff --git a/jdk/src/java.base/share/classes/java/net/DatagramPacket.java b/jdk/src/java.base/share/classes/java/net/DatagramPacket.java
                                  index eb8e4000173..2fb419db282 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/DatagramPacket.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/DatagramPacket.java
                                  @@ -47,7 +47,7 @@ class DatagramPacket {
                                        */
                                       static {
                                           java.security.AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       System.loadLibrary("net");
                                                       return null;
                                  diff --git a/jdk/src/java.base/share/classes/java/net/DatagramSocket.java b/jdk/src/java.base/share/classes/java/net/DatagramSocket.java
                                  index 77a12f247a0..f2120eaef04 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/DatagramSocket.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/DatagramSocket.java
                                  @@ -308,7 +308,7 @@ class DatagramSocket implements java.io.Closeable {
                                           // getDeclaredMethod, therefore we need permission to access the member
                                           try {
                                               AccessController.doPrivileged(
                                  -                new PrivilegedExceptionAction() {
                                  +                new PrivilegedExceptionAction<>() {
                                                       public Void run() throws NoSuchMethodException {
                                                           Class[] cl = new Class[1];
                                                           cl[0] = DatagramPacket.class;
                                  diff --git a/jdk/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java b/jdk/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java
                                  index b6e70cafd94..eb6eb13a8bb 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java
                                  @@ -64,7 +64,7 @@ import java.util.Set;
                                               serverSocketField = netClientClazz.getDeclaredField("serverSocket");
                                   
                                               java.security.AccessController.doPrivileged(
                                  -                new java.security.PrivilegedAction() {
                                  +                new java.security.PrivilegedAction<>() {
                                                       public Void run() {
                                                           httpField.setAccessible(true);
                                                           serverSocketField.setAccessible(true);
                                  @@ -146,7 +146,7 @@ import java.util.Set;
                                       {
                                           try {
                                               return java.security.AccessController.doPrivileged(
                                  -                new java.security.PrivilegedExceptionAction() {
                                  +                new java.security.PrivilegedExceptionAction<>() {
                                                       public Socket run() throws IOException {
                                                           return doTunnel(urlString, timeout);
                                                   }
                                  diff --git a/jdk/src/java.base/share/classes/java/net/HttpCookie.java b/jdk/src/java.base/share/classes/java/net/HttpCookie.java
                                  index ff6f0ab70a9..92dcd68c0b5 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/HttpCookie.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/HttpCookie.java
                                  @@ -1125,7 +1125,7 @@ public final class HttpCookie implements Cloneable {
                                        * @return  list of strings; never null
                                        */
                                       private static List splitMultiCookies(String header) {
                                  -        List cookies = new java.util.ArrayList();
                                  +        List cookies = new java.util.ArrayList<>();
                                           int quoteCount = 0;
                                           int p, q;
                                   
                                  diff --git a/jdk/src/java.base/share/classes/java/net/IDN.java b/jdk/src/java.base/share/classes/java/net/IDN.java
                                  index d4c8f5e426d..5d3ae15dc62 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/IDN.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/IDN.java
                                  @@ -228,7 +228,7 @@ public final class IDN {
                                           try {
                                               final String IDN_PROFILE = "uidna.spp";
                                               if (System.getSecurityManager() != null) {
                                  -                stream = AccessController.doPrivileged(new PrivilegedAction() {
                                  +                stream = AccessController.doPrivileged(new PrivilegedAction<>() {
                                                       public InputStream run() {
                                                           return StringPrep.class.getResourceAsStream(IDN_PROFILE);
                                                       }
                                  diff --git a/jdk/src/java.base/share/classes/java/net/InMemoryCookieStore.java b/jdk/src/java.base/share/classes/java/net/InMemoryCookieStore.java
                                  index 487c9eb2a89..a08be4a1c2c 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/InMemoryCookieStore.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/InMemoryCookieStore.java
                                  @@ -62,9 +62,9 @@ class InMemoryCookieStore implements CookieStore {
                                        * The default ctor
                                        */
                                       public InMemoryCookieStore() {
                                  -        cookieJar = new ArrayList();
                                  -        domainIndex = new HashMap>();
                                  -        uriIndex = new HashMap>();
                                  +        cookieJar = new ArrayList<>();
                                  +        domainIndex = new HashMap<>();
                                  +        uriIndex = new HashMap<>();
                                   
                                           lock = new ReentrantLock(false);
                                       }
                                  @@ -115,7 +115,7 @@ class InMemoryCookieStore implements CookieStore {
                                               throw new NullPointerException("uri is null");
                                           }
                                   
                                  -        List cookies = new ArrayList();
                                  +        List cookies = new ArrayList<>();
                                           boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
                                           lock.lock();
                                           try {
                                  @@ -157,7 +157,7 @@ class InMemoryCookieStore implements CookieStore {
                                        * of this cookie store.
                                        */
                                       public List getURIs() {
                                  -        List uris = new ArrayList();
                                  +        List uris = new ArrayList<>();
                                   
                                           lock.lock();
                                           try {
                                  @@ -281,7 +281,7 @@ class InMemoryCookieStore implements CookieStore {
                                               String host, boolean secureLink) {
                                           // Use a separate list to handle cookies that need to be removed so
                                           // that there is no conflict with iterators.
                                  -        ArrayList toRemove = new ArrayList();
                                  +        ArrayList toRemove = new ArrayList<>();
                                           for (Map.Entry> entry : cookieIndex.entrySet()) {
                                               String domain = entry.getKey();
                                               List lst = entry.getValue();
                                  @@ -368,7 +368,7 @@ class InMemoryCookieStore implements CookieStore {
                                   
                                                   cookies.add(cookie);
                                               } else {
                                  -                cookies = new ArrayList();
                                  +                cookies = new ArrayList<>();
                                                   cookies.add(cookie);
                                                   indexStore.put(index, cookies);
                                               }
                                  diff --git a/jdk/src/java.base/share/classes/java/net/InetAddress.java b/jdk/src/java.base/share/classes/java/net/InetAddress.java
                                  index eb72c091285..b39fa5dc2d6 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/InetAddress.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java
                                  @@ -270,7 +270,7 @@ class InetAddress implements java.io.Serializable {
                                           preferIPv6Address = java.security.AccessController.doPrivileged(
                                               new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();
                                           AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       System.loadLibrary("net");
                                                       return null;
                                  @@ -852,7 +852,7 @@ class InetAddress implements java.io.Serializable {
                                               final String providerName = provider;
                                               try {
                                                   nameService = java.security.AccessController.doPrivileged(
                                  -                    new java.security.PrivilegedExceptionAction() {
                                  +                    new java.security.PrivilegedExceptionAction<>() {
                                                           public NameService run() {
                                                               Iterator itr =
                                                                   ServiceLoader.load(NameServiceDescriptor.class)
                                  @@ -892,7 +892,7 @@ class InetAddress implements java.io.Serializable {
                                           String provider = null;;
                                           String propPrefix = "sun.net.spi.nameservice.provider.";
                                           int n = 1;
                                  -        nameServices = new ArrayList();
                                  +        nameServices = new ArrayList<>();
                                           provider = AccessController.doPrivileged(
                                                   new GetPropertyAction(propPrefix + n));
                                           while (provider != null) {
                                  diff --git a/jdk/src/java.base/share/classes/java/net/NetworkInterface.java b/jdk/src/java.base/share/classes/java/net/NetworkInterface.java
                                  index 411d8df14b9..3376bafdf20 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/NetworkInterface.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/NetworkInterface.java
                                  @@ -54,7 +54,7 @@ public final class NetworkInterface {
                                   
                                       static {
                                           AccessController.doPrivileged(
                                  -            new java.security.PrivilegedAction() {
                                  +            new java.security.PrivilegedAction<>() {
                                                   public Void run() {
                                                       System.loadLibrary("net");
                                                       return null;
                                  @@ -167,7 +167,7 @@ public final class NetworkInterface {
                                        * @since 1.6
                                        */
                                       public java.util.List getInterfaceAddresses() {
                                  -        java.util.List lst = new java.util.ArrayList(1);
                                  +        java.util.List lst = new java.util.ArrayList<>(1);
                                           SecurityManager sec = System.getSecurityManager();
                                           for (int j=0; j() {
                                  +        return new Enumeration<>() {
                                               private int i = 0;
                                               public NetworkInterface nextElement() {
                                                   if (netifs != null && i < netifs.length) {
                                  diff --git a/jdk/src/java.base/share/classes/java/net/Socket.java b/jdk/src/java.base/share/classes/java/net/Socket.java
                                  index a0ca24e5224..a94d2ef9994 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/Socket.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/Socket.java
                                  @@ -470,7 +470,7 @@ class Socket implements java.io.Closeable {
                                           // getDeclaredMethod, therefore we need permission to access the member
                                   
                                           oldImpl = AccessController.doPrivileged
                                  -                                (new PrivilegedAction() {
                                  +                                (new PrivilegedAction<>() {
                                               public Boolean run() {
                                                   Class clazz = impl.getClass();
                                                   while (true) {
                                  @@ -911,7 +911,7 @@ class Socket implements java.io.Closeable {
                                           InputStream is = null;
                                           try {
                                               is = AccessController.doPrivileged(
                                  -                new PrivilegedExceptionAction() {
                                  +                new PrivilegedExceptionAction<>() {
                                                       public InputStream run() throws IOException {
                                                           return impl.getInputStream();
                                                       }
                                  @@ -951,7 +951,7 @@ class Socket implements java.io.Closeable {
                                           OutputStream os = null;
                                           try {
                                               os = AccessController.doPrivileged(
                                  -                new PrivilegedExceptionAction() {
                                  +                new PrivilegedExceptionAction<>() {
                                                       public OutputStream run() throws IOException {
                                                           return impl.getOutputStream();
                                                       }
                                  diff --git a/jdk/src/java.base/share/classes/java/net/SocketPermission.java b/jdk/src/java.base/share/classes/java/net/SocketPermission.java
                                  index 8894152512b..52c71b0f7a3 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/SocketPermission.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/SocketPermission.java
                                  @@ -1194,7 +1194,7 @@ public final class SocketPermission extends Permission
                                        */
                                       private static int initEphemeralPorts(String suffix, int defval) {
                                           return AccessController.doPrivileged(
                                  -            new PrivilegedAction(){
                                  +            new PrivilegedAction<>(){
                                                   public Integer run() {
                                                       int val = Integer.getInteger(
                                                               "jdk.net.ephemeralPortRange."+suffix, -1
                                  @@ -1328,7 +1328,7 @@ final class SocketPermissionCollection extends PermissionCollection
                                        */
                                   
                                       public SocketPermissionCollection() {
                                  -        perms = new ArrayList();
                                  +        perms = new ArrayList<>();
                                       }
                                   
                                       /**
                                  @@ -1466,7 +1466,7 @@ final class SocketPermissionCollection extends PermissionCollection
                                           // Get the one we want
                                           @SuppressWarnings("unchecked")
                                           Vector permissions = (Vector)gfields.get("permissions", null);
                                  -        perms = new ArrayList(permissions.size());
                                  +        perms = new ArrayList<>(permissions.size());
                                           perms.addAll(permissions);
                                       }
                                   }
                                  diff --git a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java
                                  index 3dd4259cd9a..573945b9632 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java
                                  @@ -82,7 +82,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                       {
                                           try {
                                               AccessController.doPrivileged(
                                  -                new java.security.PrivilegedExceptionAction() {
                                  +                new java.security.PrivilegedExceptionAction<>() {
                                                       public Void run() throws IOException {
                                                                 superConnectServer(host, port, timeout);
                                                                 cmdIn = getInputStream();
                                  @@ -157,7 +157,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                               final InetAddress addr = InetAddress.getByName(server);
                                               PasswordAuthentication pw =
                                                   java.security.AccessController.doPrivileged(
                                  -                    new java.security.PrivilegedAction() {
                                  +                    new java.security.PrivilegedAction<>() {
                                                           public PasswordAuthentication run() {
                                                                   return Authenticator.requestPasswordAuthentication(
                                                                          server, addr, serverPort, "SOCKS5", "SOCKS authentication", null);
                                  @@ -351,7 +351,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                               // server is not null only when the socket was created with a
                                               // specified proxy in which case it does bypass the ProxySelector
                                               ProxySelector sel = java.security.AccessController.doPrivileged(
                                  -                new java.security.PrivilegedAction() {
                                  +                new java.security.PrivilegedAction<>() {
                                                       public ProxySelector run() {
                                                               return ProxySelector.getDefault();
                                                           }
                                  @@ -595,7 +595,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                           InetAddress naddr = baddr;
                                           if (naddr.isAnyLocalAddress()) {
                                               naddr = AccessController.doPrivileged(
                                  -                        new PrivilegedAction() {
                                  +                        new PrivilegedAction<>() {
                                                               public InetAddress run() {
                                                                   return cmdsock.getLocalAddress();
                                   
                                  @@ -671,7 +671,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                               // server is not null only when the socket was created with a
                                               // specified proxy in which case it does bypass the ProxySelector
                                               ProxySelector sel = java.security.AccessController.doPrivileged(
                                  -                new java.security.PrivilegedAction() {
                                  +                new java.security.PrivilegedAction<>() {
                                                       public ProxySelector run() {
                                                               return ProxySelector.getDefault();
                                                           }
                                  @@ -724,7 +724,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                                   // Connects to the SOCKS server
                                                   try {
                                                       AccessController.doPrivileged(
                                  -                        new PrivilegedExceptionAction() {
                                  +                        new PrivilegedExceptionAction<>() {
                                                               public Void run() throws Exception {
                                                                   cmdsock = new Socket(new PlainSocketImpl());
                                                                   cmdsock.connect(new InetSocketAddress(server, serverPort));
                                  @@ -755,7 +755,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
                                           } else {
                                               try {
                                                   AccessController.doPrivileged(
                                  -                    new PrivilegedExceptionAction() {
                                  +                    new PrivilegedExceptionAction<>() {
                                                           public Void run() throws Exception {
                                                               cmdsock = new Socket(new PlainSocketImpl());
                                                               cmdsock.connect(new InetSocketAddress(server, serverPort));
                                  diff --git a/jdk/src/java.base/share/classes/java/net/URL.java b/jdk/src/java.base/share/classes/java/net/URL.java
                                  index fc7ecb513bb..1a32a236ba0 100644
                                  --- a/jdk/src/java.base/share/classes/java/net/URL.java
                                  +++ b/jdk/src/java.base/share/classes/java/net/URL.java
                                  @@ -268,6 +268,23 @@ public final class URL implements java.io.Serializable {
                                        *     createURLStreamHandler} method of each provider, if instantiated, is
                                        *     invoked, with the protocol string, until a provider returns non-null,
                                        *     or all providers have been exhausted.
                                  +     * 
                                • If the previous step fails to find a protocol handler, the + * constructor reads the value of the system property: + *
                                  {@code + * java.protocol.handler.pkgs + * }
                                  + * If the value of that system property is not {@code null}, + * it is interpreted as a list of packages separated by a vertical + * slash character '{@code |}'. The constructor tries to load + * the class named: + *
                                  {@code + * ..Handler + * }
                                  + * where {@code } is replaced by the name of the package + * and {@code } is replaced by the name of the protocol. + * If this class does not exist, or if the class exists but it is not + * a subclass of {@code URLStreamHandler}, then the next package + * in the list is tried. *
                                • If the previous step fails to find a protocol handler, then the * constructor tries to load a built-in protocol handler. * If this class does not exist, or if the class exists but it is not a @@ -1139,8 +1156,41 @@ public final class URL implements java.io.Serializable { } } + private static URLStreamHandler lookupViaProperty(String protocol) { + String packagePrefixList = java.security.AccessController.doPrivileged( + new PrivilegedAction<>() { + public String run() { + return System.getProperty(protocolPathProp, ""); + } + }); + String[] packagePrefixes = packagePrefixList.split("\\|"); + + URLStreamHandler handler = null; + for (int i=0; handler == null && i cls = null; + try { + cls = Class.forName(clsName); + } catch (ClassNotFoundException e) { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + if (cl != null) { + cls = cl.loadClass(clsName); + } + } + if (cls != null) { + handler = (URLStreamHandler)cls.newInstance(); + } + } catch (Exception e) { + // any number of exceptions can get thrown here + } + } + return handler; + } + private static Iterator providers() { - return new Iterator() { + return new Iterator<>() { ClassLoader cl = ClassLoader.getSystemClassLoader(); ServiceLoader sl = @@ -1193,7 +1243,7 @@ public final class URL implements java.io.Serializable { gate.set(gate); try { return AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public URLStreamHandler run() { Iterator itr = providers(); while (itr.hasNext()) { @@ -1251,6 +1301,10 @@ public final class URL implements java.io.Serializable { if (handler == null && !protocol.equalsIgnoreCase("jar")) { handler = lookupViaProviders(protocol); } + + if (handler == null) { + handler = lookupViaProperty(protocol); + } } synchronized (streamHandlerLock) { diff --git a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java index 7bb5fc54a9e..3b5c1e264ff 100644 --- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java @@ -359,7 +359,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { final Class result; try { result = AccessController.doPrivileged( - new PrivilegedExceptionAction>() { + new PrivilegedExceptionAction<>() { public Class run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); Resource res = ucp.getResource(path, false); @@ -564,7 +564,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { * The same restriction to finding classes applies to resources */ URL url = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public URL run() { return ucp.findResource(name, true); } @@ -587,7 +587,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { { final Enumeration e = ucp.findResources(name, true); - return new Enumeration() { + return new Enumeration<>() { private URL url = null; private boolean next() { @@ -596,7 +596,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { } do { URL u = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public URL run() { if (!e.hasMoreElements()) return null; @@ -704,7 +704,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { final Permission fp = p; - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() throws SecurityException { sm.checkPermission(fp); return null; @@ -735,7 +735,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { final AccessControlContext acc = AccessController.getContext(); // Need a privileged block to create the class loader URLClassLoader ucl = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public URLClassLoader run() { return new FactoryURLClassLoader(urls, parent, acc); } @@ -760,7 +760,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { final AccessControlContext acc = AccessController.getContext(); // Need a privileged block to create the class loader URLClassLoader ucl = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public URLClassLoader run() { return new FactoryURLClassLoader(urls, acc); } diff --git a/jdk/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java b/jdk/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java index b985d775748..4b5548e79e5 100644 --- a/jdk/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java +++ b/jdk/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java @@ -296,7 +296,7 @@ public abstract class AsynchronousFileChannel public static AsynchronousFileChannel open(Path file, OpenOption... options) throws IOException { - Set set = new HashSet(options.length); + Set set = new HashSet<>(options.length); Collections.addAll(set, options); return open(file, set, null, NO_ATTRIBUTES); } diff --git a/jdk/src/java.base/share/classes/java/nio/channels/FileChannel.java b/jdk/src/java.base/share/classes/java/nio/channels/FileChannel.java index a23f1c3c336..eb3934d3dea 100644 --- a/jdk/src/java.base/share/classes/java/nio/channels/FileChannel.java +++ b/jdk/src/java.base/share/classes/java/nio/channels/FileChannel.java @@ -330,7 +330,7 @@ public abstract class FileChannel public static FileChannel open(Path path, OpenOption... options) throws IOException { - Set set = new HashSet(options.length); + Set set = new HashSet<>(options.length); Collections.addAll(set, options); return open(path, set, NO_ATTRIBUTES); } diff --git a/jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java b/jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java index 464b4fc435d..d14c853522b 100644 --- a/jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java +++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java @@ -76,7 +76,7 @@ public abstract class AsynchronousChannelProvider { private static AsynchronousChannelProvider load() { return AccessController - .doPrivileged(new PrivilegedAction() { + .doPrivileged(new PrivilegedAction<>() { public AsynchronousChannelProvider run() { AsynchronousChannelProvider p; p = loadProviderFromProperty(); diff --git a/jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java b/jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java index ae876005bac..ca704a8e5a5 100644 --- a/jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java +++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java @@ -172,7 +172,7 @@ public abstract class SelectorProvider { if (provider != null) return provider; return AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public SelectorProvider run() { if (loadProviderFromProperty()) return provider; diff --git a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java index ae0566174b5..8d67ebbc8d6 100644 --- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java +++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java @@ -335,7 +335,7 @@ public abstract class Charset // thrown. Should be invoked with full privileges. // private static Iterator providers() { - return new Iterator() { + return new Iterator<>() { ClassLoader cl = ClassLoader.getSystemClassLoader(); ServiceLoader sl = @@ -404,7 +404,7 @@ public abstract class Charset gate.set(gate); return AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public Charset run() { for (Iterator i = providers(); i.hasNext();) { @@ -428,7 +428,7 @@ public abstract class Charset // returns ExtendedProvider, if installed private static CharsetProvider extendedProvider() { return AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public CharsetProvider run() { try { Class epc @@ -570,10 +570,10 @@ public abstract class Charset */ public static SortedMap availableCharsets() { return AccessController.doPrivileged( - new PrivilegedAction>() { + new PrivilegedAction<>() { public SortedMap run() { TreeMap m = - new TreeMap( + new TreeMap<>( ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); put(standardProvider.charsets(), m); CharsetProvider ecp = ExtendedProviderHolder.extendedProvider; @@ -663,7 +663,7 @@ public abstract class Charset if (aliasSet != null) return aliasSet; int n = aliases.length; - HashSet hs = new HashSet(n); + HashSet hs = new HashSet<>(n); for (int i = 0; i < n; i++) hs.add(aliases[i]); aliasSet = Collections.unmodifiableSet(hs); diff --git a/jdk/src/java.base/share/classes/java/nio/charset/CoderResult.java b/jdk/src/java.base/share/classes/java/nio/charset/CoderResult.java index 1c9250cf19f..79d4843e2de 100644 --- a/jdk/src/java.base/share/classes/java/nio/charset/CoderResult.java +++ b/jdk/src/java.base/share/classes/java/nio/charset/CoderResult.java @@ -204,13 +204,13 @@ public class CoderResult { WeakReference w; CoderResult e = null; if (cache == null) { - cache = new HashMap>(); + cache = new HashMap<>(); } else if ((w = cache.get(k)) != null) { e = w.get(); } if (e == null) { e = create(len); - cache.put(k, new WeakReference(e)); + cache.put(k, new WeakReference<>(e)); } return e; } diff --git a/jdk/src/java.base/share/classes/java/nio/file/FileSystems.java b/jdk/src/java.base/share/classes/java/nio/file/FileSystems.java index 17c295e95ef..8524518f9f3 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/FileSystems.java +++ b/jdk/src/java.base/share/classes/java/nio/file/FileSystems.java @@ -93,7 +93,7 @@ public final class FileSystems { private static FileSystem defaultFileSystem() { // load default provider FileSystemProvider provider = AccessController - .doPrivileged(new PrivilegedAction() { + .doPrivileged(new PrivilegedAction<>() { public FileSystemProvider run() { return getDefaultProvider(); } diff --git a/jdk/src/java.base/share/classes/java/nio/file/Files.java b/jdk/src/java.base/share/classes/java/nio/file/Files.java index 0c7891458b8..80c76a2f571 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/Files.java +++ b/jdk/src/java.base/share/classes/java/nio/file/Files.java @@ -402,7 +402,7 @@ public final class Files { public static SeekableByteChannel newByteChannel(Path path, OpenOption... options) throws IOException { - Set set = new HashSet(options.length); + Set set = new HashSet<>(options.length); Collections.addAll(set, options); return newByteChannel(path, set); } @@ -516,7 +516,7 @@ public final class Files { // create a matcher and return a filter that uses it. FileSystem fs = dir.getFileSystem(); final PathMatcher matcher = fs.getPathMatcher("glob:" + glob); - DirectoryStream.Filter filter = new DirectoryStream.Filter() { + DirectoryStream.Filter filter = new DirectoryStream.Filter<>() { @Override public boolean accept(Path entry) { return matcher.matches(entry.getFileName()); @@ -1541,7 +1541,7 @@ public final class Files { // creates the default file type detector private static FileTypeDetector createDefaultFileTypeDetector() { return AccessController - .doPrivileged(new PrivilegedAction() { + .doPrivileged(new PrivilegedAction<>() { @Override public FileTypeDetector run() { return sun.nio.fs.DefaultFileTypeDetector.create(); }}); @@ -1550,7 +1550,7 @@ public final class Files { // loads all installed file type detectors private static List loadInstalledDetectors() { return AccessController - .doPrivileged(new PrivilegedAction>() { + .doPrivileged(new PrivilegedAction<>() { @Override public List run() { List list = new ArrayList<>(); ServiceLoader loader = ServiceLoader @@ -3468,7 +3468,7 @@ public final class Files { final Iterator delegate = ds.iterator(); // Re-wrap DirectoryIteratorException to UncheckedIOException - Iterator iterator = new Iterator() { + Iterator iterator = new Iterator<>() { @Override public boolean hasNext() { try { diff --git a/jdk/src/java.base/share/classes/java/nio/file/Path.java b/jdk/src/java.base/share/classes/java/nio/file/Path.java index fdb28cfd716..8387a8e9597 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/Path.java +++ b/jdk/src/java.base/share/classes/java/nio/file/Path.java @@ -801,7 +801,7 @@ public interface Path */ @Override default Iterator iterator() { - return new Iterator() { + return new Iterator<>() { private int i = 0; @Override diff --git a/jdk/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java b/jdk/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java index b0084946283..26818be4219 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java +++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java @@ -306,7 +306,7 @@ public final class AclEntry { * @return the permissions component */ public Set permissions() { - return new HashSet(perms); + return new HashSet<>(perms); } /** @@ -317,7 +317,7 @@ public final class AclEntry { * @return the flags component */ public Set flags() { - return new HashSet(flags); + return new HashSet<>(flags); } /** diff --git a/jdk/src/java.base/share/classes/java/nio/file/attribute/PosixFilePermissions.java b/jdk/src/java.base/share/classes/java/nio/file/attribute/PosixFilePermissions.java index 45a866a5f1d..c98b69deaba 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/attribute/PosixFilePermissions.java +++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/PosixFilePermissions.java @@ -160,13 +160,13 @@ public final class PosixFilePermissions { { // copy set and check for nulls (CCE will be thrown if an element is not // a PosixFilePermission) - perms = new HashSet(perms); + perms = new HashSet<>(perms); for (PosixFilePermission p: perms) { if (p == null) throw new NullPointerException(); } final Set value = perms; - return new FileAttribute>() { + return new FileAttribute<>() { @Override public String name() { return "posix:permissions"; diff --git a/jdk/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java b/jdk/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java index def1cca7a57..dad51083401 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java +++ b/jdk/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java @@ -110,7 +110,7 @@ public abstract class FileSystemProvider { // loads all installed providers private static List loadInstalledProviders() { - List list = new ArrayList(); + List list = new ArrayList<>(); ServiceLoader sl = ServiceLoader .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader()); @@ -163,7 +163,7 @@ public abstract class FileSystemProvider { loadingProviders = true; List list = AccessController - .doPrivileged(new PrivilegedAction>() { + .doPrivileged(new PrivilegedAction<>() { @Override public List run() { return loadInstalledProviders(); @@ -419,7 +419,7 @@ public abstract class FileSystemProvider { throws IOException { int len = options.length; - Set opts = new HashSet(len + 3); + Set opts = new HashSet<>(len + 3); if (len == 0) { opts.add(StandardOpenOption.CREATE); opts.add(StandardOpenOption.TRUNCATE_EXISTING); diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index a8f70915012..90c6108c244 100644 --- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -70,6 +70,7 @@ import static java.time.temporal.ChronoField.NANO_OF_SECOND; import static java.time.temporal.ChronoField.OFFSET_SECONDS; import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.ERA; import java.lang.ref.SoftReference; import java.math.BigDecimal; @@ -84,6 +85,7 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; +import java.time.chrono.Era; import java.time.chrono.IsoChronology; import java.time.format.DateTimeTextProvider.LocaleStore; import java.time.temporal.ChronoField; @@ -3131,6 +3133,16 @@ public final class DateTimeFormatterBuilder { return context.setParsedField(field, entry.getValue(), position, position + itText.length()); } } + if (field == ERA && !context.isStrict()) { + // parse the possible era name from era.toString() + List eras = chrono.eras(); + for (Era era : eras) { + String name = era.toString(); + if (context.subSequenceEquals(name, 0, parseText, position, name.length())) { + return context.setParsedField(field, era.getValue(), position, position + name.length()); + } + } + } if (context.isStrict()) { return ~position; } diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeParseContext.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeParseContext.java index e3ca5e981a5..6b8dd98501c 100644 --- a/jdk/src/java.base/share/classes/java/time/format/DateTimeParseContext.java +++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeParseContext.java @@ -399,7 +399,7 @@ final class DateTimeParseContext { */ void addChronoChangedListener(Consumer listener) { if (chronoListeners == null) { - chronoListeners = new ArrayList>(); + chronoListeners = new ArrayList<>(); } chronoListeners.add(listener); } diff --git a/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java b/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java index 9523664d169..0905d9c3957 100644 --- a/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java +++ b/jdk/src/java.base/share/classes/java/time/zone/ZoneRulesProvider.java @@ -141,7 +141,7 @@ public abstract class ZoneRulesProvider { // if the property java.time.zone.DefaultZoneRulesProvider is // set then its value is the class name of the default provider final List loaded = new ArrayList<>(); - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Object run() { String prop = System.getProperty("java.time.zone.DefaultZoneRulesProvider"); if (prop != null) { diff --git a/jdk/src/java.base/share/classes/java/util/Calendar.java b/jdk/src/java.base/share/classes/java/util/Calendar.java index 68deb16d4d5..80849001e74 100644 --- a/jdk/src/java.base/share/classes/java/util/Calendar.java +++ b/jdk/src/java.base/share/classes/java/util/Calendar.java @@ -3579,7 +3579,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable() { + new PrivilegedExceptionAction<>() { @Override public ZoneInfo run() throws Exception { return (ZoneInfo) input.readObject(); diff --git a/jdk/src/java.base/share/classes/java/util/Currency.java b/jdk/src/java.base/share/classes/java/util/Currency.java index 1ba8cc93e07..c244bb73d8d 100644 --- a/jdk/src/java.base/share/classes/java/util/Currency.java +++ b/jdk/src/java.base/share/classes/java/util/Currency.java @@ -212,7 +212,7 @@ public final class Currency implements Serializable { private static final int VALID_FORMAT_VERSION = 2; static { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Void run() { try { diff --git a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java index 1b55a97b6ad..d6d79f5160d 100644 --- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java +++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java @@ -2655,7 +2655,7 @@ public abstract class ResourceBundle { InputStream stream = null; try { stream = AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public InputStream run() throws IOException { InputStream is = null; if (reloadFlag) { diff --git a/jdk/src/java.base/share/classes/java/util/TimeZone.java b/jdk/src/java.base/share/classes/java/util/TimeZone.java index 6847a80876f..adc6ad349df 100644 --- a/jdk/src/java.base/share/classes/java/util/TimeZone.java +++ b/jdk/src/java.base/share/classes/java/util/TimeZone.java @@ -678,7 +678,7 @@ abstract public class TimeZone implements Serializable, Cloneable { assert tz != null; final String id = zoneID; - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Void run() { System.setProperty("user.timezone", id); diff --git a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java index f04a86ee3b8..3c01aacecc2 100644 --- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java @@ -593,7 +593,7 @@ class JarFile extends ZipFile { if (includeUnsigned) { return unsignedEntryNames(); } else { - return new Enumeration() { + return new Enumeration<>() { public boolean hasMoreElements() { return false; @@ -619,7 +619,7 @@ class JarFile extends ZipFile { // screen out entries which are never signed final Enumeration enum_ = super.entries(); - return new Enumeration() { + return new Enumeration<>() { ZipEntry entry; @@ -669,7 +669,7 @@ class JarFile extends ZipFile { private Enumeration unsignedEntryNames() { final Enumeration entries = entries(); - return new Enumeration() { + return new Enumeration<>() { String name; diff --git a/jdk/src/java.base/share/classes/java/util/jar/JarVerifier.java b/jdk/src/java.base/share/classes/java/util/jar/JarVerifier.java index c1468a1be1c..6e978e41278 100644 --- a/jdk/src/java.base/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/java.base/share/classes/java/util/jar/JarVerifier.java @@ -684,7 +684,7 @@ class JarVerifier { final List signersReq = req; final Enumeration enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration; - return new Enumeration() { + return new Enumeration<>() { String name; @@ -726,7 +726,7 @@ class JarVerifier { final Map map = new HashMap<>(); map.putAll(signerMap()); final Enumeration enum_ = e; - return new Enumeration() { + return new Enumeration<>() { Enumeration signers = null; JarEntry entry; @@ -786,7 +786,7 @@ class JarVerifier { private Enumeration unsignedEntryNames(JarFile jar) { final Map map = signerMap(); final Enumeration entries = jar.entries(); - return new Enumeration() { + return new Enumeration<>() { String name; diff --git a/jdk/src/java.base/share/classes/sun/misc/Cleaner.java b/jdk/src/java.base/share/classes/sun/misc/Cleaner.java index 5e92f35d616..6cc90a74760 100644 --- a/jdk/src/java.base/share/classes/sun/misc/Cleaner.java +++ b/jdk/src/java.base/share/classes/sun/misc/Cleaner.java @@ -142,7 +142,7 @@ public class Cleaner try { thunk.run(); } catch (final Throwable x) { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { if (System.err != null) new Error("Cleaner terminated abnormally", x) diff --git a/jdk/src/java.base/share/classes/sun/misc/GC.java b/jdk/src/java.base/share/classes/sun/misc/GC.java index c77bf1d055b..4cfd9781274 100644 --- a/jdk/src/java.base/share/classes/sun/misc/GC.java +++ b/jdk/src/java.base/share/classes/sun/misc/GC.java @@ -82,8 +82,7 @@ public class GC { */ public static native long maxObjectInspectionAge(); - - private static class Daemon extends Thread { + private static class Daemon extends ManagedLocalsThread { public void run() { for (;;) { diff --git a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java index db431029484..78a0a185f0a 100644 --- a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java +++ b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java @@ -26,32 +26,37 @@ package sun.misc; import java.security.AccessControlContext; +import java.security.AccessController; import java.security.ProtectionDomain; +import java.security.PrivilegedAction; +import java.util.concurrent.atomic.AtomicInteger; /** * A thread that has no permissions, is not a member of any user-defined * ThreadGroup and supports the ability to erase ThreadLocals. - * - * @implNote Based on the implementation of InnocuousForkJoinWorkerThread. */ -public final class InnocuousThread extends Thread { +public final class InnocuousThread extends ManagedLocalsThread { private static final Unsafe UNSAFE; - private static final ThreadGroup THREADGROUP; + private static final ThreadGroup INNOCUOUSTHREADGROUP; private static final AccessControlContext ACC; - private static final long THREADLOCALS; - private static final long INHERITABLETHREADLOCALS; private static final long INHERITEDACCESSCONTROLCONTEXT; + private static final long CONTEXTCLASSLOADER; + + private static final AtomicInteger threadNumber = new AtomicInteger(1); public InnocuousThread(Runnable target) { - super(THREADGROUP, target, "anInnocuousThread"); - UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); - eraseThreadLocals(); + this(INNOCUOUSTHREADGROUP, target, + "InnocuousThread-" + threadNumber.getAndIncrement()); } - @Override - public ClassLoader getContextClassLoader() { - // always report system class loader - return ClassLoader.getSystemClassLoader(); + public InnocuousThread(Runnable target, String name) { + this(INNOCUOUSTHREADGROUP, target, name); + } + + public InnocuousThread(ThreadGroup group, Runnable target, String name) { + super(group, target, name); + UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); + UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader()); } @Override @@ -61,7 +66,11 @@ public final class InnocuousThread extends Thread { @Override public void setContextClassLoader(ClassLoader cl) { - throw new SecurityException("setContextClassLoader"); + // Allow clearing of the TCCL to remove the reference to the system classloader. + if (cl == null) + super.setContextClassLoader(null); + else + throw new SecurityException("setContextClassLoader"); } // ensure run method is run only once @@ -75,14 +84,6 @@ public final class InnocuousThread extends Thread { } } - /** - * Drops all thread locals (and inherited thread locals). - */ - public void eraseThreadLocals() { - UNSAFE.putObject(this, THREADLOCALS, null); - UNSAFE.putObject(this, INHERITABLETHREADLOCALS, null); - } - // Use Unsafe to access Thread group and ThreadGroup parent fields static { try { @@ -95,12 +96,10 @@ public final class InnocuousThread extends Thread { Class tk = Thread.class; Class gk = ThreadGroup.class; - THREADLOCALS = UNSAFE.objectFieldOffset - (tk.getDeclaredField("threadLocals")); - INHERITABLETHREADLOCALS = UNSAFE.objectFieldOffset - (tk.getDeclaredField("inheritableThreadLocals")); INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset (tk.getDeclaredField("inheritedAccessControlContext")); + CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset + (tk.getDeclaredField("contextClassLoader")); long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group")); long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent")); @@ -113,7 +112,10 @@ public final class InnocuousThread extends Thread { break; group = parent; } - THREADGROUP = new ThreadGroup(group, "InnocuousThreadGroup"); + final ThreadGroup root = group; + INNOCUOUSTHREADGROUP = AccessController.doPrivileged( + (PrivilegedAction) () -> + { return new ThreadGroup(root, "InnocuousThreadGroup"); }); } catch (Exception e) { throw new Error(e); } diff --git a/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java b/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java new file mode 100644 index 00000000000..cd75ef237ce --- /dev/null +++ b/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +/** + * A thread that has it's thread locals, and inheritable thread + * locals erased on construction. + */ +public class ManagedLocalsThread extends Thread { + private static final Unsafe UNSAFE; + private static final long THREAD_LOCALS; + private static final long INHERITABLE_THREAD_LOCALS; + + public ManagedLocalsThread() { + eraseThreadLocals(); + } + + public ManagedLocalsThread(Runnable target) { + super(target); + eraseThreadLocals(); + } + + public ManagedLocalsThread(String name) { + super(name); + eraseThreadLocals(); + } + + public ManagedLocalsThread(Runnable target, String name) { + super(target, name); + eraseThreadLocals(); + } + + public ManagedLocalsThread(ThreadGroup group, String name) { + super(group, name); + eraseThreadLocals(); + } + + public ManagedLocalsThread(ThreadGroup group, Runnable target, String name) { + super(group, target, name); + eraseThreadLocals(); + } + + /** + * Drops all thread locals (and inherited thread locals). + */ + public final void eraseThreadLocals() { + UNSAFE.putObject(this, THREAD_LOCALS, null); + UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null); + } + + static { + UNSAFE = Unsafe.getUnsafe(); + Class t = Thread.class; + try { + THREAD_LOCALS = UNSAFE.objectFieldOffset + (t.getDeclaredField("threadLocals")); + INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset + (t.getDeclaredField("inheritableThreadLocals")); + } catch (Exception e) { + throw new Error(e); + } + } +} + diff --git a/jdk/src/java.base/share/classes/sun/misc/RequestProcessor.java b/jdk/src/java.base/share/classes/sun/misc/RequestProcessor.java index 54a62724de0..30131f42b29 100644 --- a/jdk/src/java.base/share/classes/sun/misc/RequestProcessor.java +++ b/jdk/src/java.base/share/classes/sun/misc/RequestProcessor.java @@ -77,7 +77,7 @@ public class RequestProcessor implements Runnable { */ public static synchronized void startProcessing() { if (dispatcher == null) { - dispatcher = new Thread(new RequestProcessor(), "Request Processor"); + dispatcher = new ManagedLocalsThread(new RequestProcessor(), "Request Processor"); dispatcher.setPriority(Thread.NORM_PRIORITY + 2); dispatcher.start(); } diff --git a/jdk/src/java.base/share/classes/sun/misc/Signal.java b/jdk/src/java.base/share/classes/sun/misc/Signal.java index 07557a8d78f..a00ee9f089d 100644 --- a/jdk/src/java.base/share/classes/sun/misc/Signal.java +++ b/jdk/src/java.base/share/classes/sun/misc/Signal.java @@ -213,7 +213,7 @@ public final class Signal { } }; if (handler != null) { - new Thread(runnable, sig + " handler").start(); + new ManagedLocalsThread(runnable, sig + " handler").start(); } } diff --git a/jdk/src/java.base/share/classes/sun/misc/URLClassPath.java b/jdk/src/java.base/share/classes/sun/misc/URLClassPath.java index 04321d65512..56482db0a23 100644 --- a/jdk/src/java.base/share/classes/sun/misc/URLClassPath.java +++ b/jdk/src/java.base/share/classes/sun/misc/URLClassPath.java @@ -97,16 +97,16 @@ public class URLClassPath { } /* The original search path of URLs. */ - private ArrayList path = new ArrayList(); + private ArrayList path = new ArrayList<>(); /* The stack of unopened URLs */ - Stack urls = new Stack(); + Stack urls = new Stack<>(); /* The resulting search path of Loaders */ - ArrayList loaders = new ArrayList(); + ArrayList loaders = new ArrayList<>(); /* Map of each URL opened to its corresponding Loader */ - HashMap lmap = new HashMap(); + HashMap lmap = new HashMap<>(); /* The jar protocol handler to use when creating new URLs */ private URLStreamHandler jarHandler; @@ -142,7 +142,7 @@ public class URLClassPath { if (closed) { return Collections.emptyList(); } - List result = new LinkedList(); + List result = new LinkedList<>(); for (Loader loader : loaders) { try { loader.close(); @@ -234,7 +234,7 @@ public class URLClassPath { */ public Enumeration findResources(final String name, final boolean check) { - return new Enumeration() { + return new Enumeration<>() { private int index = 0; private URL url = null; @@ -281,7 +281,7 @@ public class URLClassPath { */ public Enumeration getResources(final String name, final boolean check) { - return new Enumeration() { + return new Enumeration<>() { private int index = 0; private Resource res = null; @@ -374,7 +374,7 @@ public class URLClassPath { private Loader getLoader(final URL url) throws IOException { try { return java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { + new java.security.PrivilegedExceptionAction<>() { public Loader run() throws IOException { String file = url.getFile(); if (file != null && file.endsWith("/")) { @@ -689,7 +689,7 @@ public class URLClassPath { if (jar == null) { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { + new java.security.PrivilegedExceptionAction<>() { public Void run() throws IOException { if (DEBUG) { System.err.println("Opening " + csu); @@ -870,7 +870,7 @@ public class URLClassPath { if (index == null) return null; - HashSet visited = new HashSet(); + HashSet visited = new HashSet<>(); return getResource(name, check, visited); } @@ -912,7 +912,7 @@ public class URLClassPath { * before */ newLoader = AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public JarLoader run() throws IOException { return new JarLoader(url, handler, lmap); diff --git a/jdk/src/java.base/share/classes/sun/net/NetworkClient.java b/jdk/src/java.base/share/classes/sun/net/NetworkClient.java index 0f76bf62398..f5cd53c295e 100644 --- a/jdk/src/java.base/share/classes/sun/net/NetworkClient.java +++ b/jdk/src/java.base/share/classes/sun/net/NetworkClient.java @@ -69,7 +69,7 @@ public class NetworkClient { final String encs[] = { null }; AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public Void run() { vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue(); vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue(); @@ -154,7 +154,7 @@ public class NetworkClient { if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { s = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public Socket run() { return new Socket(proxy); }}); @@ -201,7 +201,7 @@ public class NetworkClient { if (serverSocket == null) throw new IOException("not connected"); return AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public InetAddress run() { return serverSocket.getLocalAddress(); diff --git a/jdk/src/java.base/share/classes/sun/net/NetworkServer.java b/jdk/src/java.base/share/classes/sun/net/NetworkServer.java index d4a9cc78e5b..6937775d40e 100644 --- a/jdk/src/java.base/share/classes/sun/net/NetworkServer.java +++ b/jdk/src/java.base/share/classes/sun/net/NetworkServer.java @@ -27,6 +27,7 @@ package sun.net; import java.io.*; import java.net.Socket; import java.net.ServerSocket; +import sun.misc.ManagedLocalsThread; /** * This is the base class for network servers. To define a new type @@ -72,7 +73,7 @@ public class NetworkServer implements Runnable, Cloneable { NetworkServer n = (NetworkServer)clone(); n.serverSocket = null; n.clientSocket = ns; - new Thread(n).start(); + new ManagedLocalsThread(n).start(); } catch(Exception e) { System.out.print("Server failure\n"); e.printStackTrace(); @@ -107,7 +108,7 @@ public class NetworkServer implements Runnable, Cloneable { for each new connection. */ final public void startServer(int port) throws IOException { serverSocket = new ServerSocket(port, 50); - serverInstance = new Thread(this); + serverInstance = new ManagedLocalsThread(this); serverInstance.start(); } diff --git a/jdk/src/java.base/share/classes/sun/net/ProgressMonitor.java b/jdk/src/java.base/share/classes/sun/net/ProgressMonitor.java index e9ddce85df6..6aa7b351bad 100644 --- a/jdk/src/java.base/share/classes/sun/net/ProgressMonitor.java +++ b/jdk/src/java.base/share/classes/sun/net/ProgressMonitor.java @@ -64,7 +64,7 @@ public class ProgressMonitor * Return a snapshot of the ProgressSource list */ public ArrayList getProgressSources() { - ArrayList snapshot = new ArrayList(); + ArrayList snapshot = new ArrayList<>(); try { synchronized(progressSourceList) { @@ -114,7 +114,7 @@ public class ProgressMonitor if (progressListenerList.size() > 0) { // Notify progress listener if there is progress change - ArrayList listeners = new ArrayList(); + ArrayList listeners = new ArrayList<>(); // Copy progress listeners to another list to avoid holding locks synchronized(progressListenerList) { @@ -151,7 +151,7 @@ public class ProgressMonitor if (progressListenerList.size() > 0) { // Notify progress listener if there is progress change - ArrayList listeners = new ArrayList(); + ArrayList listeners = new ArrayList<>(); // Copy progress listeners to another list to avoid holding locks synchronized(progressListenerList) { @@ -183,7 +183,7 @@ public class ProgressMonitor if (progressListenerList.size() > 0) { // Notify progress listener if there is progress change - ArrayList listeners = new ArrayList(); + ArrayList listeners = new ArrayList<>(); // Copy progress listeners to another list to avoid holding locks synchronized(progressListenerList) { diff --git a/jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java b/jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java index 34b6307826f..c4ab99ac34c 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java +++ b/jdk/src/java.base/share/classes/sun/net/www/MessageHeader.java @@ -244,7 +244,7 @@ class MessageHeader { public synchronized Map> filterAndAddHeaders( String[] excludeList, Map> include) { boolean skipIt = false; - Map> m = new HashMap>(); + Map> m = new HashMap<>(); for (int i = nkeys; --i >= 0;) { if (excludeList != null) { // check if the key is in the excludeList. @@ -260,7 +260,7 @@ class MessageHeader { if (!skipIt) { List l = m.get(keys[i]); if (l == null) { - l = new ArrayList(); + l = new ArrayList<>(); m.put(keys[i], l); } l.add(values[i]); @@ -274,7 +274,7 @@ class MessageHeader { for (Map.Entry> entry: include.entrySet()) { List l = m.get(entry.getKey()); if (l == null) { - l = new ArrayList(); + l = new ArrayList<>(); m.put(entry.getKey(), l); } l.addAll(entry.getValue()); diff --git a/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java b/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java index ee4fb40eeca..32b3603de82 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java +++ b/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java @@ -27,8 +27,9 @@ package sun.net.www; import java.net.URL; import java.io.*; import java.util.StringTokenizer; +import sun.misc.ManagedLocalsThread; -class MimeLauncher extends Thread { +class MimeLauncher extends ManagedLocalsThread { java.net.URLConnection uc; MimeEntry m; String genericTempFileTemplate; diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java b/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java index 7035295a372..43eff0435f4 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java +++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java @@ -64,7 +64,7 @@ public class HttpCapture { private static synchronized void init() { initialized = true; String rulesFile = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public String run() { return NetProperties.get("sun.net.http.captureRules"); } @@ -85,8 +85,8 @@ public class HttpCapture { String[] s = line.split(","); if (s.length == 2) { if (patterns == null) { - patterns = new ArrayList(); - capFiles = new ArrayList(); + patterns = new ArrayList<>(); + capFiles = new ArrayList<>(); } patterns.add(Pattern.compile(s[0].trim())); capFiles.add(s[1].trim()); diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java index fcdd50943ab..0d7f09c6132 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -479,7 +479,7 @@ public class HttpClient extends NetworkClient { { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { + new java.security.PrivilegedExceptionAction<>() { public Void run() throws IOException { openServer(server.getHostString(), server.getPort()); return null; diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java b/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java index 16f02d7cdde..42902b0148b 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java +++ b/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java @@ -30,6 +30,7 @@ import java.io.NotSerializableException; import java.util.ArrayList; import java.util.HashMap; import java.net.URL; +import sun.misc.InnocuousThread; /** * A class that implements a cache of idle Http connections for keep-alive @@ -93,17 +94,9 @@ public class KeepAliveCache */ final KeepAliveCache cache = this; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public Void run() { - // We want to create the Keep-Alive-Timer in the - // system threadgroup - ThreadGroup grp = Thread.currentThread().getThreadGroup(); - ThreadGroup parent = null; - while ((parent = grp.getParent()) != null) { - grp = parent; - } - - keepAliveTimer = new Thread(grp, cache, "Keep-Alive-Timer"); + keepAliveTimer = new InnocuousThread(cache, "Keep-Alive-Timer"); keepAliveTimer.setDaemon(true); keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2); // Set the context class loader to null in order to avoid @@ -185,7 +178,7 @@ public class KeepAliveCache long currentTime = System.currentTimeMillis(); ArrayList keysToRemove - = new ArrayList(); + = new ArrayList<>(); for (KeepAliveKey key : keySet()) { ClientVector v = get(key); diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java b/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java index 9155c4ae8c5..53835df7f6a 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java +++ b/jdk/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java @@ -26,6 +26,8 @@ package sun.net.www.http; import java.io.*; + +import sun.misc.InnocuousThread; import sun.net.ProgressSource; import sun.net.www.MeteredStream; @@ -171,15 +173,7 @@ class KeepAliveStream extends MeteredStream implements Hurryable { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Void run() { - // We want to create the Keep-Alive-SocketCleaner in the - // system threadgroup - ThreadGroup grp = Thread.currentThread().getThreadGroup(); - ThreadGroup parent = null; - while ((parent = grp.getParent()) != null) { - grp = parent; - } - - cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner"); + cleanerThread = new InnocuousThread(queue, "Keep-Alive-SocketCleaner"); cleanerThread.setDaemon(true); cleanerThread.setPriority(Thread.MAX_PRIORITY - 2); // Set the context class loader to null in order to avoid diff --git a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java index 89b4d991ea8..42f692c3738 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java @@ -122,7 +122,7 @@ public class AuthenticationHeader { this.dontUseNegotiate = dontUseNegotiate; rsp = response; this.hdrname = hdrname; - schemes = new HashMap(); + schemes = new HashMap<>(); parse(); } diff --git a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java index 5f0ee771a91..5ad27159253 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java @@ -62,7 +62,7 @@ class DigestAuthentication extends AuthenticationInfo { static { Boolean b = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public Boolean run() { return NetProperties.getBoolean(compatPropName); } diff --git a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 2cc199c16f0..a012c3b6a1c 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -244,7 +244,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { new sun.security.action.GetBooleanAction( "sun.net.http.allowRestrictedHeaders")).booleanValue(); if (!allowRestrictedHeaders) { - restrictedHeaderSet = new HashSet(restrictedHeaders.length); + restrictedHeaderSet = new HashSet<>(restrictedHeaders.length); for (int i=0; i < restrictedHeaders.length; i++) { restrictedHeaderSet.add(restrictedHeaders[i].toLowerCase()); } @@ -413,7 +413,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final URL url, final RequestorType authType) { return java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public PasswordAuthentication run() { if (logger.isLoggable(PlatformLogger.Level.FINEST)) { logger.finest("Requesting Authentication: host =" + host + " url = " + url); @@ -817,14 +817,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } catch (SecurityException se) { /* swallow exception */ } } else { cookieHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public CookieHandler run() { return CookieHandler.getDefault(); } }); } cacheHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public ResponseCache run() { return ResponseCache.getDefault(); } @@ -909,7 +909,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final boolean result[] = {false}; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public Void run() { try { InetAddress a1 = InetAddress.getByName(h1); @@ -954,7 +954,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { try { // lookup hostname and use IP address if available host = AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public String run() throws IOException { InetAddress addr = InetAddress.getByName(hostarg); return addr.getHostAddress(); @@ -984,7 +984,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (p != null) { try { AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public Void run() throws IOException { plainConnect0(); return null; @@ -1086,7 +1086,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { */ ProxySelector sel = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public ProxySelector run() { return ProxySelector.getDefault(); } @@ -1245,7 +1245,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (p != null) { try { return AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public OutputStream run() throws IOException { return getOutputStream0(); } @@ -1423,7 +1423,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (p != null) { try { return AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public InputStream run() throws IOException { return getInputStream0(); } @@ -1877,7 +1877,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final Object[] args = { rememberedException.getMessage() }; IOException chainedException = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { + new java.security.PrivilegedExceptionAction<>() { public IOException run() throws Exception { return (IOException) rememberedException.getClass() @@ -2204,7 +2204,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { try { final String finalHost = host; addr = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { + new java.security.PrivilegedExceptionAction<>() { public InetAddress run() throws java.net.UnknownHostException { return InetAddress.getByName(finalHost); @@ -2566,7 +2566,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (p != null) { try { return AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public Boolean run() throws IOException { return followRedirect0(loc, stat, locUrl0); } diff --git a/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java b/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java index e7e6ad05ad6..f78e1d28b19 100644 --- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java +++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java @@ -213,7 +213,7 @@ public class URLJarFile extends JarFile { /* get the stream before asserting privileges */ try (final InputStream in = url.openConnection().getInputStream()) { result = AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction<>() { public JarFile run() throws IOException { Path tmpFile = Files.createTempFile("jar_cache", null); try { diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java index a584ce9dbf5..117df2452dc 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java @@ -76,7 +76,7 @@ abstract class AsynchronousChannelGroupImpl this.pool = pool; if (pool.isFixedThreadPool()) { - taskQueue = new ConcurrentLinkedQueue(); + taskQueue = new ConcurrentLinkedQueue<>(); } else { taskQueue = null; // not used } @@ -115,7 +115,7 @@ abstract class AsynchronousChannelGroupImpl } private void startInternalThread(final Runnable task) { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Void run() { // internal threads should not be visible to application so @@ -246,7 +246,7 @@ abstract class AsynchronousChannelGroupImpl abstract void shutdownHandlerTasks(); private void shutdownExecutors() { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { pool.executor().shutdown(); timeoutExecutor.shutdown(); @@ -323,7 +323,7 @@ abstract class AsynchronousChannelGroupImpl task = new Runnable() { @Override public void run() { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Void run() { delegate.run(); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java index e9521ea4e5b..2d0ef217e3c 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java @@ -228,7 +228,7 @@ abstract class AsynchronousServerSocketChannelImpl static final Set> defaultOptions = defaultOptions(); private static Set> defaultOptions() { - HashSet> set = new HashSet>(2); + HashSet> set = new HashSet<>(2); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_REUSEADDR); return Collections.unmodifiableSet(set); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java index 9899d759b71..16a4d391881 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java @@ -503,7 +503,7 @@ abstract class AsynchronousSocketChannelImpl static final Set> defaultOptions = defaultOptions(); private static Set> defaultOptions() { - HashSet> set = new HashSet>(5); + HashSet> set = new HashSet<>(5); set.add(StandardSocketOptions.SO_SNDBUF); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_KEEPALIVE); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index e316facf491..9d4a2e828c1 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -294,7 +294,7 @@ class DatagramChannelImpl static final Set> defaultOptions = defaultOptions(); private static Set> defaultOptions() { - HashSet> set = new HashSet>(8); + HashSet> set = new HashSet<>(8); set.add(StandardSocketOptions.SO_SNDBUF); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_REUSEADDR); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java index 5ecc39608e4..4d47b41ad9b 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java @@ -184,7 +184,7 @@ class MembershipKeyImpl // created blocked set if required and add source address if (blockedSet == null) - blockedSet = new HashSet(); + blockedSet = new HashSet<>(); blockedSet.add(toBlock); } return this; diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java index 6607fc841d0..9f01c51601f 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipRegistry.java @@ -84,13 +84,13 @@ class MembershipRegistry { InetAddress group = key.group(); List keys; if (groups == null) { - groups = new HashMap>(); + groups = new HashMap<>(); keys = null; } else { keys = groups.get(group); } if (keys == null) { - keys = new LinkedList(); + keys = new LinkedList<>(); groups.put(group, keys); } keys.add(key); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java index db8ce1fd0e1..1693c0cdec6 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java @@ -52,8 +52,8 @@ public abstract class SelectorImpl protected SelectorImpl(SelectorProvider sp) { super(sp); - keys = new HashSet(); - selectedKeys = new HashSet(); + keys = new HashSet<>(); + selectedKeys = new HashSet<>(); if (Util.atBugLevel("1.4")) { publicKeys = keys; publicSelectedKeys = selectedKeys; diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java index b5b8b05d36f..0274c2e0753 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java @@ -182,7 +182,7 @@ class ServerSocketChannelImpl static final Set> defaultOptions = defaultOptions(); private static Set> defaultOptions() { - HashSet> set = new HashSet>(2); + HashSet> set = new HashSet<>(2); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_REUSEADDR); set.add(StandardSocketOptions.IP_TOS); diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index a72fe07e4a1..0b3a3828ef3 100644 --- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -229,7 +229,7 @@ class SocketChannelImpl static final Set> defaultOptions = defaultOptions(); private static Set> defaultOptions() { - HashSet> set = new HashSet>(8); + HashSet> set = new HashSet<>(8); set.add(StandardSocketOptions.SO_SNDBUF); set.add(StandardSocketOptions.SO_RCVBUF); set.add(StandardSocketOptions.SO_KEEPALIVE); diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java b/jdk/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java index c5586f0abe5..2d1358c92c7 100644 --- a/jdk/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java +++ b/jdk/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java @@ -135,7 +135,7 @@ public class CharsetMapping { // init the CharsetMapping object from the .dat binary file public static CharsetMapping get(final InputStream is) { - return AccessController.doPrivileged(new PrivilegedAction() { + return AccessController.doPrivileged(new PrivilegedAction<>() { public CharsetMapping run() { return new CharsetMapping().load(is); } diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java index 34d4ea4e3bc..039f5b74c2d 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java @@ -30,6 +30,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.io.IOException; import java.util.*; +import sun.misc.ManagedLocalsThread; /** * Base implementation of background poller thread used in watch service @@ -47,7 +48,7 @@ abstract class AbstractPoller implements Runnable { private boolean shutdown; protected AbstractPoller() { - this.requestList = new LinkedList(); + this.requestList = new LinkedList<>(); this.shutdown = false; } @@ -56,10 +57,10 @@ abstract class AbstractPoller implements Runnable { */ public void start() { final Runnable thisRunnable = this; - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Object run() { - Thread thr = new Thread(thisRunnable); + Thread thr = new ManagedLocalsThread(thisRunnable); thr.setDaemon(true); thr.start(); return null; diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java index 132b6e5d845..710e38fc607 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java @@ -70,8 +70,8 @@ abstract class AbstractWatchKey implements WatchKey { this.watcher = watcher; this.dir = dir; this.state = State.READY; - this.events = new ArrayList>(); - this.lastModifyEvents = new HashMap>(); + this.events = new ArrayList<>(); + this.lastModifyEvents = new HashMap<>(); } final AbstractWatchService watcher() { @@ -146,7 +146,7 @@ abstract class AbstractWatchKey implements WatchKey { // non-repeated event Event ev = - new Event((WatchEvent.Kind)kind, context); + new Event<>((WatchEvent.Kind)kind, context); if (isModify) { lastModifyEvents.put(context, ev); } else if (kind == StandardWatchEventKinds.OVERFLOW) { @@ -163,7 +163,7 @@ abstract class AbstractWatchKey implements WatchKey { public final List> pollEvents() { synchronized (this) { List> result = events; - events = new ArrayList>(); + events = new ArrayList<>(); lastModifyEvents.clear(); return result; } diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java b/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java index 0aa6521f19b..648d4089ce8 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java @@ -25,6 +25,7 @@ package sun.nio.fs; +import sun.misc.ManagedLocalsThread; import sun.misc.Unsafe; import java.util.concurrent.ExecutionException; @@ -117,7 +118,7 @@ abstract class Cancellable implements Runnable { * thread by writing into the memory location that it polls cooperatively. */ static void runInterruptibly(Cancellable task) throws ExecutionException { - Thread t = new Thread(task); + Thread t = new ManagedLocalsThread(task); t.start(); boolean cancelledByInterrupt = false; while (t.isAlive()) { diff --git a/jdk/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java b/jdk/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java index d3d9891223d..bc4af73e762 100644 --- a/jdk/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java +++ b/jdk/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.util.*; import java.util.concurrent.*; import com.sun.nio.file.SensitivityWatchEventModifier; +import sun.misc.ManagedLocalsThread; /** * Simple WatchService implementation that uses periodic tasks to poll @@ -58,7 +59,7 @@ class PollingWatchService .newSingleThreadScheduledExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { - Thread t = new Thread(r); + Thread t = new ManagedLocalsThread(r); t.setDaemon(true); return t; }}); diff --git a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java index 34c1da25908..3d10f9b18c2 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java +++ b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java @@ -375,7 +375,7 @@ public class ReflectionFactory { private static void checkInitted() { if (initted) return; AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public Void run() { // Tests to ensure the system properties table is fully // initialized. This is needed because reflection code is diff --git a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java index 669099019f1..7bef3e6541e 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java +++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java @@ -106,16 +106,16 @@ public class AnnotationType { throw new IllegalArgumentException("Not an annotation type"); Method[] methods = - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Method[] run() { // Initialize memberTypes and defaultValues return annotationClass.getDeclaredMethods(); } }); - memberTypes = new HashMap>(methods.length+1, 1.0f); - memberDefaults = new HashMap(0); - members = new HashMap(methods.length+1, 1.0f); + memberTypes = new HashMap<>(methods.length+1, 1.0f); + memberDefaults = new HashMap<>(0); + members = new HashMap<>(methods.length+1, 1.0f); for (Method method : methods) { if (method.getParameterTypes().length != 0) diff --git a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index 354a644e37e..1f52015392c 100644 --- a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -716,6 +716,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { entry.protectedPrivKey = key.clone(); if (chain != null) { + // validate cert-chain + if ((chain.length > 1) && (!validateChain(chain))) { + throw new KeyStoreException("Certificate chain is " + + "not valid"); + } entry.chain = chain.clone(); certificateCount += chain.length; @@ -1490,7 +1495,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi { if (!(issuerDN.equals(subjectDN))) return false; } - return true; + + // Check for loops in the chain. If there are repeated certs, + // the Set of certs in the chain will contain fewer certs than + // the chain + Set set = new HashSet<>(Arrays.asList(certChain)); + return set.size() == certChain.length; } @@ -2070,7 +2080,24 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ArrayList chain = new ArrayList(); X509Certificate cert = findMatchedCertificate(entry); + + mainloop: while (cert != null) { + // Check for loops in the certificate chain + if (!chain.isEmpty()) { + for (X509Certificate chainCert : chain) { + if (cert.equals(chainCert)) { + if (debug != null) { + debug.println("Loop detected in " + + "certificate chain. Skip adding " + + "repeated cert to chain. Subject: " + + cert.getSubjectX500Principal() + .toString()); + } + break mainloop; + } + } + } chain.add(cert); X500Principal issuerDN = cert.getIssuerX500Principal(); if (issuerDN.equals(cert.getSubjectX500Principal())) { diff --git a/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java b/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java index 474e20ed433..fd08fa3f8ee 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Random; +import sun.misc.ManagedLocalsThread; import sun.security.util.Debug; abstract class SeedGenerator { @@ -304,7 +305,7 @@ abstract class SeedGenerator { } finalsg[0] = new ThreadGroup (group, "SeedGenerator ThreadGroup"); - Thread newT = new Thread(finalsg[0], + Thread newT = new ManagedLocalsThread(finalsg[0], ThreadedSeedGenerator.this, "SeedGenerator Thread"); newT.setPriority(Thread.MIN_PRIORITY); @@ -341,7 +342,7 @@ abstract class SeedGenerator { // Start some noisy threads try { BogusThread bt = new BogusThread(); - Thread t = new Thread + Thread t = new ManagedLocalsThread (seedGroup, bt, "SeedGenerator Thread"); t.start(); } catch (Exception e) { diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java index 84cbe66ee09..e6b5fc05582 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java @@ -102,8 +102,8 @@ public abstract class Builder { /** * Verifies whether the input certificate completes the path. - * When building forward, a trust anchor will complete the path. - * When building reverse, the target certificate will complete the path. + * When building in the forward direction, a trust anchor will + * complete the path. * * @param cert the certificate to test * @return a boolean value indicating whether the cert completes the path. diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java index 890d1a825ba..8f6b0a33670 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java @@ -551,10 +551,10 @@ public class DistributionPointFetcher { // set interim reasons mask to the intersection of // reasons in the DP and onlySomeReasons in the IDP boolean[] idpReasonFlags = reasons.getFlags(); - for (int i = 0; i < idpReasonFlags.length; i++) { - if (idpReasonFlags[i] && pointReasonFlags[i]) { - interimReasonsMask[i] = true; - } + for (int i = 0; i < interimReasonsMask.length; i++) { + interimReasonsMask[i] = + (i < idpReasonFlags.length && idpReasonFlags[i]) && + (i < pointReasonFlags.length && pointReasonFlags[i]); } } else { // set interim reasons mask to the value of @@ -568,7 +568,6 @@ public class DistributionPointFetcher { interimReasonsMask = pointReasonFlags.clone(); } else { // set interim reasons mask to the special value all-reasons - interimReasonsMask = new boolean[9]; Arrays.fill(interimReasonsMask, true); } } @@ -577,7 +576,9 @@ public class DistributionPointFetcher { // not included in the reasons mask boolean oneOrMore = false; for (int i = 0; i < interimReasonsMask.length && !oneOrMore; i++) { - if (!reasonsMask[i] && interimReasonsMask[i]) { + if (interimReasonsMask[i] && + !(i < reasonsMask.length && reasonsMask[i])) + { oneOrMore = true; } } @@ -703,11 +704,11 @@ public class DistributionPointFetcher { } // update reasonsMask - for (int i = 0; i < interimReasonsMask.length; i++) { - if (!reasonsMask[i] && interimReasonsMask[i]) { - reasonsMask[i] = true; - } + for (int i = 0; i < reasonsMask.length; i++) { + reasonsMask[i] = reasonsMask[i] || + (i < interimReasonsMask.length && interimReasonsMask[i]); } + return true; } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java index 98c88348adf..e33d4a21a5c 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package sun.security.provider.certpath; import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; import java.security.PublicKey; import java.security.cert.*; import java.security.interfaces.DSAPublicKey; @@ -194,7 +193,6 @@ class PKIX { static class BuilderParams extends ValidatorParams { private PKIXBuilderParameters params; - private boolean buildForward = true; private List stores; private X500Principal targetSubject; @@ -213,10 +211,6 @@ class PKIX { + "targetCertConstraints parameter must be an " + "X509CertSelector"); } - if (params instanceof SunCertPathBuilderParameters) { - buildForward = - ((SunCertPathBuilderParameters)params).getBuildForward(); - } this.params = params; this.targetSubject = getTargetSubject( certStores(), (X509CertSelector)targetCertConstraints()); @@ -230,7 +224,6 @@ class PKIX { return stores; } int maxPathLength() { return params.getMaxPathLength(); } - boolean buildForward() { return buildForward; } PKIXBuilderParameters params() { return params; } X500Principal targetSubject() { return targetSubject; } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ReverseBuilder.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ReverseBuilder.java deleted file mode 100644 index a70945d65f5..00000000000 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ReverseBuilder.java +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.provider.certpath; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.Principal; -import java.security.cert.CertificateException; -import java.security.cert.CertPathValidatorException; -import java.security.cert.CertStore; -import java.security.cert.CertStoreException; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.PKIXCertPathChecker; -import java.security.cert.PKIXParameters; -import java.security.cert.PKIXReason; -import java.security.cert.TrustAnchor; -import java.security.cert.X509Certificate; -import java.security.cert.X509CertSelector; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.LinkedList; -import java.util.Set; - -import javax.security.auth.x500.X500Principal; - -import sun.security.provider.certpath.PKIX.BuilderParams; -import sun.security.util.Debug; -import sun.security.x509.Extension; -import static sun.security.x509.PKIXExtensions.*; -import sun.security.x509.X500Name; -import sun.security.x509.X509CertImpl; -import sun.security.x509.PolicyMappingsExtension; - -/** - * This class represents a reverse builder, which is able to retrieve - * matching certificates from CertStores and verify a particular certificate - * against a ReverseState. - * - * @since 1.4 - * @author Sean Mullan - * @author Yassir Elley - */ - -class ReverseBuilder extends Builder { - - private Debug debug = Debug.getInstance("certpath"); - - private final Set initPolicies; - - /** - * Initialize the builder with the input parameters. - * - * @param params the parameter set used to build a certification path - */ - ReverseBuilder(BuilderParams buildParams) { - super(buildParams); - - Set initialPolicies = buildParams.initialPolicies(); - initPolicies = new HashSet(); - if (initialPolicies.isEmpty()) { - // if no initialPolicies are specified by user, set - // initPolicies to be anyPolicy by default - initPolicies.add(PolicyChecker.ANY_POLICY); - } else { - initPolicies.addAll(initialPolicies); - } - } - - /** - * Retrieves all certs from the specified CertStores that satisfy the - * requirements specified in the parameters and the current - * PKIX state (name constraints, policy constraints, etc). - * - * @param currentState the current state. - * Must be an instance of ReverseState - * @param certStores list of CertStores - */ - @Override - Collection getMatchingCerts - (State currState, List certStores) - throws CertStoreException, CertificateException, IOException - { - ReverseState currentState = (ReverseState) currState; - - if (debug != null) - debug.println("In ReverseBuilder.getMatchingCerts."); - - /* - * The last certificate could be an EE or a CA certificate - * (we may be building a partial certification path or - * establishing trust in a CA). - * - * Try the EE certs before the CA certs. It will be more - * common to build a path to an end entity. - */ - Collection certs = - getMatchingEECerts(currentState, certStores); - certs.addAll(getMatchingCACerts(currentState, certStores)); - - return certs; - } - - /* - * Retrieves all end-entity certificates which satisfy constraints - * and requirements specified in the parameters and PKIX state. - */ - private Collection getMatchingEECerts - (ReverseState currentState, List certStores) - throws CertStoreException, CertificateException, IOException { - - /* - * Compose a CertSelector to filter out - * certs which do not satisfy requirements. - * - * First, retrieve clone of current target cert constraints, and - * then add more selection criteria based on current validation state. - */ - X509CertSelector sel = (X509CertSelector) targetCertConstraints.clone(); - - /* - * Match on issuer (subject of previous cert) - */ - sel.setIssuer(currentState.subjectDN); - - /* - * Match on certificate validity date. - */ - sel.setCertificateValid(buildParams.date()); - - /* - * Policy processing optimizations - */ - if (currentState.explicitPolicy == 0) - sel.setPolicy(getMatchingPolicies()); - - /* - * If previous cert has a subject key identifier extension, - * use it to match on authority key identifier extension. - */ - /*if (currentState.subjKeyId != null) { - AuthorityKeyIdentifierExtension authKeyId = new AuthorityKeyIdentifierExtension( - (KeyIdentifier) currentState.subjKeyId.get(SubjectKeyIdentifierExtension.KEY_ID), - null, null); - sel.setAuthorityKeyIdentifier(authKeyId.getExtensionValue()); - }*/ - - /* - * Require EE certs - */ - sel.setBasicConstraints(-2); - - /* Retrieve matching certs from CertStores */ - HashSet eeCerts = new HashSet<>(); - addMatchingCerts(sel, certStores, eeCerts, true); - - if (debug != null) { - debug.println("ReverseBuilder.getMatchingEECerts got " - + eeCerts.size() + " certs."); - } - return eeCerts; - } - - /* - * Retrieves all CA certificates which satisfy constraints - * and requirements specified in the parameters and PKIX state. - */ - private Collection getMatchingCACerts - (ReverseState currentState, List certStores) - throws CertificateException, CertStoreException, IOException { - - /* - * Compose a CertSelector to filter out - * certs which do not satisfy requirements. - */ - X509CertSelector sel = new X509CertSelector(); - - /* - * Match on issuer (subject of previous cert) - */ - sel.setIssuer(currentState.subjectDN); - - /* - * Match on certificate validity date. - */ - sel.setCertificateValid(buildParams.date()); - - /* - * Match on target subject name (checks that current cert's - * name constraints permit it to certify target). - * (4 is the integer type for DIRECTORY name). - */ - byte[] subject = targetCertConstraints.getSubjectAsBytes(); - if (subject != null) { - sel.addPathToName(4, subject); - } else { - X509Certificate cert = targetCertConstraints.getCertificate(); - if (cert != null) { - sel.addPathToName(4, - cert.getSubjectX500Principal().getEncoded()); - } - } - - /* - * Policy processing optimizations - */ - if (currentState.explicitPolicy == 0) - sel.setPolicy(getMatchingPolicies()); - - /* - * If previous cert has a subject key identifier extension, - * use it to match on authority key identifier extension. - */ - /*if (currentState.subjKeyId != null) { - AuthorityKeyIdentifierExtension authKeyId = new AuthorityKeyIdentifierExtension( - (KeyIdentifier) currentState.subjKeyId.get(SubjectKeyIdentifierExtension.KEY_ID), - null, null); - sel.setAuthorityKeyIdentifier(authKeyId.getExtensionValue()); - }*/ - - /* - * Require CA certs - */ - sel.setBasicConstraints(0); - - /* Retrieve matching certs from CertStores */ - ArrayList reverseCerts = new ArrayList<>(); - addMatchingCerts(sel, certStores, reverseCerts, true); - - /* Sort remaining certs using name constraints */ - Collections.sort(reverseCerts, new PKIXCertComparator()); - - if (debug != null) - debug.println("ReverseBuilder.getMatchingCACerts got " + - reverseCerts.size() + " certs."); - return reverseCerts; - } - - /* - * This inner class compares 2 PKIX certificates according to which - * should be tried first when building a path to the target. For - * now, the algorithm is to look at name constraints in each cert and those - * which constrain the path closer to the target should be - * ranked higher. Later, we may want to consider other components, - * such as key identifiers. - */ - class PKIXCertComparator implements Comparator { - - private Debug debug = Debug.getInstance("certpath"); - - @Override - public int compare(X509Certificate cert1, X509Certificate cert2) { - - /* - * if either cert certifies the target, always - * put at head of list. - */ - X500Principal targetSubject = buildParams.targetSubject(); - if (cert1.getSubjectX500Principal().equals(targetSubject)) { - return -1; - } - if (cert2.getSubjectX500Principal().equals(targetSubject)) { - return 1; - } - - int targetDist1; - int targetDist2; - try { - X500Name targetSubjectName = X500Name.asX500Name(targetSubject); - targetDist1 = Builder.targetDistance( - null, cert1, targetSubjectName); - targetDist2 = Builder.targetDistance( - null, cert2, targetSubjectName); - } catch (IOException e) { - if (debug != null) { - debug.println("IOException in call to Builder.targetDistance"); - e.printStackTrace(); - } - throw new ClassCastException - ("Invalid target subject distinguished name"); - } - - if (targetDist1 == targetDist2) - return 0; - - if (targetDist1 == -1) - return 1; - - if (targetDist1 < targetDist2) - return -1; - - return 1; - } - } - - /** - * Verifies a matching certificate. - * - * This method executes any of the validation steps in the PKIX path validation - * algorithm which were not satisfied via filtering out non-compliant - * certificates with certificate matching rules. - * - * If the last certificate is being verified (the one whose subject - * matches the target subject, then the steps in Section 6.1.4 of the - * Certification Path Validation algorithm are NOT executed, - * regardless of whether or not the last cert is an end-entity - * cert or not. This allows callers to certify CA certs as - * well as EE certs. - * - * @param cert the certificate to be verified - * @param currentState the current state against which the cert is verified - * @param certPathList the certPathList generated thus far - */ - @Override - void verifyCert(X509Certificate cert, State currState, - List certPathList) - throws GeneralSecurityException - { - if (debug != null) { - debug.println("ReverseBuilder.verifyCert(SN: " - + Debug.toHexString(cert.getSerialNumber()) - + "\n Subject: " + cert.getSubjectX500Principal() + ")"); - } - - ReverseState currentState = (ReverseState) currState; - - /* we don't perform any validation of the trusted cert */ - if (currentState.isInitial()) { - return; - } - - // Don't bother to verify untrusted certificate more. - currentState.untrustedChecker.check(cert, - Collections.emptySet()); - - /* - * check for looping - abort a loop if - * ((we encounter the same certificate twice) AND - * ((policyMappingInhibited = true) OR (no policy mapping - * extensions can be found between the occurrences of the same - * certificate))) - * in order to facilitate the check to see if there are - * any policy mapping extensions found between the occurrences - * of the same certificate, we reverse the certpathlist first - */ - if ((certPathList != null) && (!certPathList.isEmpty())) { - List reverseCertList = new ArrayList<>(); - for (X509Certificate c : certPathList) { - reverseCertList.add(0, c); - } - - boolean policyMappingFound = false; - for (X509Certificate cpListCert : reverseCertList) { - X509CertImpl cpListCertImpl = X509CertImpl.toImpl(cpListCert); - PolicyMappingsExtension policyMappingsExt = - cpListCertImpl.getPolicyMappingsExtension(); - if (policyMappingsExt != null) { - policyMappingFound = true; - } - if (debug != null) - debug.println("policyMappingFound = " + policyMappingFound); - if (cert.equals(cpListCert)) { - if ((buildParams.policyMappingInhibited()) || - (!policyMappingFound)){ - if (debug != null) - debug.println("loop detected!!"); - throw new CertPathValidatorException("loop detected"); - } - } - } - } - - /* check if target cert */ - boolean finalCert = cert.getSubjectX500Principal().equals(buildParams.targetSubject()); - - /* check if CA cert */ - boolean caCert = (cert.getBasicConstraints() != -1 ? true : false); - - /* if there are more certs to follow, verify certain constraints */ - if (!finalCert) { - - /* check if CA cert */ - if (!caCert) - throw new CertPathValidatorException("cert is NOT a CA cert"); - - /* If the certificate was not self-issued, verify that - * remainingCerts is greater than zero - */ - if ((currentState.remainingCACerts <= 0) && !X509CertImpl.isSelfIssued(cert)) { - throw new CertPathValidatorException - ("pathLenConstraint violated, path too long", null, - null, -1, PKIXReason.PATH_TOO_LONG); - } - - /* - * Check keyUsage extension (only if CA cert and not final cert) - */ - KeyChecker.verifyCAKeyUsage(cert); - - } else { - - /* - * If final cert, check that it satisfies specified target - * constraints - */ - if (targetCertConstraints.match(cert) == false) { - throw new CertPathValidatorException("target certificate " + - "constraints check failed"); - } - } - - /* - * Check revocation. - */ - if (buildParams.revocationEnabled() && currentState.revChecker != null) { - currentState.revChecker.check(cert, Collections.emptySet()); - } - - /* Check name constraints if this is not a self-issued cert */ - if (finalCert || !X509CertImpl.isSelfIssued(cert)){ - if (currentState.nc != null) { - try { - if (!currentState.nc.verify(cert)){ - throw new CertPathValidatorException - ("name constraints check failed", null, null, -1, - PKIXReason.INVALID_NAME); - } - } catch (IOException ioe) { - throw new CertPathValidatorException(ioe); - } - } - } - - /* - * Check policy - */ - X509CertImpl certImpl = X509CertImpl.toImpl(cert); - currentState.rootNode = PolicyChecker.processPolicies - (currentState.certIndex, initPolicies, - currentState.explicitPolicy, currentState.policyMapping, - currentState.inhibitAnyPolicy, - buildParams.policyQualifiersRejected(), currentState.rootNode, - certImpl, finalCert); - - /* - * Check CRITICAL private extensions - */ - Set unresolvedCritExts = cert.getCriticalExtensionOIDs(); - if (unresolvedCritExts == null) { - unresolvedCritExts = Collections.emptySet(); - } - - /* - * Check that the signature algorithm is not disabled. - */ - currentState.algorithmChecker.check(cert, unresolvedCritExts); - - for (PKIXCertPathChecker checker : currentState.userCheckers) { - checker.check(cert, unresolvedCritExts); - } - - /* - * Look at the remaining extensions and remove any ones we have - * already checked. If there are any left, throw an exception! - */ - if (!unresolvedCritExts.isEmpty()) { - unresolvedCritExts.remove(BasicConstraints_Id.toString()); - unresolvedCritExts.remove(NameConstraints_Id.toString()); - unresolvedCritExts.remove(CertificatePolicies_Id.toString()); - unresolvedCritExts.remove(PolicyMappings_Id.toString()); - unresolvedCritExts.remove(PolicyConstraints_Id.toString()); - unresolvedCritExts.remove(InhibitAnyPolicy_Id.toString()); - unresolvedCritExts.remove(SubjectAlternativeName_Id.toString()); - unresolvedCritExts.remove(KeyUsage_Id.toString()); - unresolvedCritExts.remove(ExtendedKeyUsage_Id.toString()); - - if (!unresolvedCritExts.isEmpty()) - throw new CertPathValidatorException - ("Unrecognized critical extension(s)", null, null, -1, - PKIXReason.UNRECOGNIZED_CRIT_EXT); - } - - /* - * Check signature. - */ - if (buildParams.sigProvider() != null) { - cert.verify(currentState.pubKey, buildParams.sigProvider()); - } else { - cert.verify(currentState.pubKey); - } - } - - /** - * Verifies whether the input certificate completes the path. - * This checks whether the cert is the target certificate. - * - * @param cert the certificate to test - * @return a boolean value indicating whether the cert completes the path. - */ - @Override - boolean isPathCompleted(X509Certificate cert) { - return cert.getSubjectX500Principal().equals(buildParams.targetSubject()); - } - - /** Adds the certificate to the certPathList - * - * @param cert the certificate to be added - * @param certPathList the certification path list - */ - @Override - void addCertToPath(X509Certificate cert, - LinkedList certPathList) { - certPathList.addLast(cert); - } - - /** Removes final certificate from the certPathList - * - * @param certPathList the certification path list - */ - @Override - void removeFinalCertFromPath(LinkedList certPathList) { - certPathList.removeLast(); - } -} diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ReverseState.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ReverseState.java deleted file mode 100644 index c51500308ae..00000000000 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ReverseState.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.provider.certpath; - -import java.io.IOException; -import java.security.PublicKey; -import java.security.cert.CertificateException; -import java.security.cert.CertPathValidatorException; -import java.security.cert.PKIXCertPathChecker; -import java.security.cert.PKIXRevocationChecker; -import java.security.cert.TrustAnchor; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Set; -import javax.security.auth.x500.X500Principal; - -import sun.security.provider.certpath.PKIX.BuilderParams; -import sun.security.util.Debug; -import sun.security.x509.NameConstraintsExtension; -import sun.security.x509.SubjectKeyIdentifierExtension; -import sun.security.x509.X509CertImpl; - -/** - * A specification of a reverse PKIX validation state - * which is initialized by each build and updated each time a - * certificate is added to the current path. - * @since 1.4 - * @author Sean Mullan - * @author Yassir Elley - */ - -class ReverseState implements State { - - private static final Debug debug = Debug.getInstance("certpath"); - - /* The subject DN of the last cert in the path */ - X500Principal subjectDN; - - /* The subject public key of the last cert */ - PublicKey pubKey; - - /* The subject key identifier extension (if any) of the last cert */ - SubjectKeyIdentifierExtension subjKeyId; - - /* The PKIX constrained/excluded subtrees state variable */ - NameConstraintsExtension nc; - - /* The PKIX explicit policy, policy mapping, and inhibit_any-policy - state variables */ - int explicitPolicy; - int policyMapping; - int inhibitAnyPolicy; - int certIndex; - PolicyNodeImpl rootNode; - - /* The number of remaining CA certs which may follow in the path. - * -1: previous cert was an EE cert - * 0: only EE certs may follow. - * >0 and userCheckers; - - /* Flag indicating if state is initial (path is just starting) */ - private boolean init = true; - - /* the checker used for revocation status */ - RevocationChecker revChecker; - - /* the algorithm checker */ - AlgorithmChecker algorithmChecker; - - /* the untrusted certificates checker */ - UntrustedChecker untrustedChecker; - - /* the trust anchor used to validate the path */ - TrustAnchor trustAnchor; - - /* Flag indicating if current cert can vouch for the CRL for - * the next cert - */ - boolean crlSign = true; - - /** - * Returns a boolean flag indicating if the state is initial - * (just starting) - * - * @return boolean flag indicating if the state is initial (just starting) - */ - @Override - public boolean isInitial() { - return init; - } - - /** - * Display state for debugging purposes - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("State ["); - sb.append("\n subjectDN of last cert: ").append(subjectDN); - sb.append("\n subjectKeyIdentifier: ").append - (String.valueOf(subjKeyId)); - sb.append("\n nameConstraints: ").append(String.valueOf(nc)); - sb.append("\n certIndex: ").append(certIndex); - sb.append("\n explicitPolicy: ").append(explicitPolicy); - sb.append("\n policyMapping: ").append(policyMapping); - sb.append("\n inhibitAnyPolicy: ").append(inhibitAnyPolicy); - sb.append("\n rootNode: ").append(rootNode); - sb.append("\n remainingCACerts: ").append(remainingCACerts); - sb.append("\n crlSign: ").append(crlSign); - sb.append("\n init: ").append(init); - sb.append("\n]\n"); - return sb.toString(); - } - - /** - * Initialize the state. - * - * @param buildParams builder parameters - */ - public void initState(BuilderParams buildParams) - throws CertPathValidatorException - { - /* - * Initialize number of remainingCACerts. - * Note that -1 maxPathLen implies unlimited. - * 0 implies only an EE cert is acceptable. - */ - int maxPathLen = buildParams.maxPathLength(); - remainingCACerts = (maxPathLen == -1) ? Integer.MAX_VALUE - : maxPathLen; - - /* Initialize explicit policy state variable */ - if (buildParams.explicitPolicyRequired()) { - explicitPolicy = 0; - } else { - // unconstrained if maxPathLen is -1, - // otherwise, we want to initialize this to the value of the - // longest possible path + 1 (i.e. maxpathlen + finalcert + 1) - explicitPolicy = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2; - } - - /* Initialize policy mapping state variable */ - if (buildParams.policyMappingInhibited()) { - policyMapping = 0; - } else { - policyMapping = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2; - } - - /* Initialize inhibit any policy state variable */ - if (buildParams.anyPolicyInhibited()) { - inhibitAnyPolicy = 0; - } else { - inhibitAnyPolicy = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2; - } - - /* Initialize certIndex */ - certIndex = 1; - - /* Initialize policy tree */ - Set initExpPolSet = new HashSet<>(1); - initExpPolSet.add(PolicyChecker.ANY_POLICY); - - rootNode = new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null, - false, initExpPolSet, false); - - /* - * Initialize each user-defined checker - * Shallow copy the checkers - */ - userCheckers = new ArrayList<>(buildParams.certPathCheckers()); - /* initialize each checker (just in case) */ - for (PKIXCertPathChecker checker : userCheckers) { - checker.init(false); - } - - /* Start by trusting the cert to sign CRLs */ - crlSign = true; - - init = true; - } - - /** - * Update the state with the specified trust anchor. - * - * @param anchor the most-trusted CA - * @param buildParams builder parameters - */ - public void updateState(TrustAnchor anchor, BuilderParams buildParams) - throws CertificateException, IOException, CertPathValidatorException - { - trustAnchor = anchor; - X509Certificate trustedCert = anchor.getTrustedCert(); - if (trustedCert != null) { - updateState(trustedCert); - } else { - X500Principal caName = anchor.getCA(); - updateState(anchor.getCAPublicKey(), caName); - } - - // The user specified AlgorithmChecker and RevocationChecker may not be - // able to set the trust anchor until now. - boolean revCheckerAdded = false; - for (PKIXCertPathChecker checker : userCheckers) { - if (checker instanceof AlgorithmChecker) { - ((AlgorithmChecker)checker).trySetTrustAnchor(anchor); - } else if (checker instanceof PKIXRevocationChecker) { - if (revCheckerAdded) { - throw new CertPathValidatorException( - "Only one PKIXRevocationChecker can be specified"); - } - // if it's our own, initialize it - if (checker instanceof RevocationChecker) { - ((RevocationChecker)checker).init(anchor, buildParams); - } - ((PKIXRevocationChecker)checker).init(false); - revCheckerAdded = true; - } - } - - // only create a RevocationChecker if revocation is enabled and - // a PKIXRevocationChecker has not already been added - if (buildParams.revocationEnabled() && !revCheckerAdded) { - revChecker = new RevocationChecker(anchor, buildParams); - revChecker.init(false); - } - - init = false; - } - - /** - * Update the state. This method is used when the most-trusted CA is - * a trusted public-key and caName, instead of a trusted cert. - * - * @param pubKey the public key of the trusted CA - * @param subjectDN the subject distinguished name of the trusted CA - */ - private void updateState(PublicKey pubKey, X500Principal subjectDN) { - - /* update subject DN */ - this.subjectDN = subjectDN; - - /* update subject public key */ - this.pubKey = pubKey; - } - - /** - * Update the state with the next certificate added to the path. - * - * @param cert the certificate which is used to update the state - */ - public void updateState(X509Certificate cert) - throws CertificateException, IOException, CertPathValidatorException { - - if (cert == null) { - return; - } - - /* update subject DN */ - subjectDN = cert.getSubjectX500Principal(); - - /* check for key needing to inherit alg parameters */ - X509CertImpl icert = X509CertImpl.toImpl(cert); - PublicKey newKey = cert.getPublicKey(); - if (PKIX.isDSAPublicKeyWithoutParams(newKey)) { - newKey = BasicChecker.makeInheritedParamsKey(newKey, pubKey); - } - - /* update subject public key */ - pubKey = newKey; - - /* - * if this is a trusted cert (init == true), then we - * don't update any of the remaining fields - */ - if (init) { - init = false; - return; - } - - /* update subject key identifier */ - subjKeyId = icert.getSubjectKeyIdentifierExtension(); - - /* update crlSign */ - crlSign = RevocationChecker.certCanSignCrl(cert); - - /* update current name constraints */ - if (nc != null) { - nc.merge(icert.getNameConstraintsExtension()); - } else { - nc = icert.getNameConstraintsExtension(); - if (nc != null) { - // Make sure we do a clone here, because we're probably - // going to modify this object later and we don't want to - // be sharing it with a Certificate object! - nc = (NameConstraintsExtension) nc.clone(); - } - } - - /* update policy state variables */ - explicitPolicy = - PolicyChecker.mergeExplicitPolicy(explicitPolicy, icert, false); - policyMapping = - PolicyChecker.mergePolicyMapping(policyMapping, icert); - inhibitAnyPolicy = - PolicyChecker.mergeInhibitAnyPolicy(inhibitAnyPolicy, icert); - certIndex++; - - /* - * Update remaining CA certs - */ - remainingCACerts = - ConstraintsChecker.mergeBasicConstraints(cert, remainingCACerts); - - init = false; - } - - /** - * Returns a boolean flag indicating if a key lacking necessary key - * algorithm parameters has been encountered. - * - * @return boolean flag indicating if key lacking parameters encountered. - */ - @Override - public boolean keyParamsNeeded() { - /* when building in reverse, we immediately get parameters needed - * or else throw an exception - */ - return false; - } - - /* - * Clone current state. The state is cloned as each cert is - * added to the path. This is necessary if backtracking occurs, - * and a prior state needs to be restored. - * - * Note that this is a SMART clone. Not all fields are fully copied, - * because some of them (e.g., subjKeyId) will - * not have their contents modified by subsequent calls to updateState. - */ - @Override - @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly - public Object clone() { - try { - ReverseState clonedState = (ReverseState) super.clone(); - - /* clone checkers, if cloneable */ - clonedState.userCheckers = - (ArrayList)userCheckers.clone(); - ListIterator li = - clonedState.userCheckers.listIterator(); - while (li.hasNext()) { - PKIXCertPathChecker checker = li.next(); - if (checker instanceof Cloneable) { - li.set((PKIXCertPathChecker)checker.clone()); - } - } - - /* make copy of name constraints */ - if (nc != null) { - clonedState.nc = (NameConstraintsExtension) nc.clone(); - } - - /* make copy of policy tree */ - if (rootNode != null) { - clonedState.rootNode = rootNode.copyTree(); - } - - return clonedState; - } catch (CloneNotSupportedException e) { - throw new InternalError(e.toString(), e); - } - } -} diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java index 161f565df56..a0c058e795e 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java @@ -35,8 +35,6 @@ import java.security.cert.PKIXReason; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.LinkedList; import java.util.Set; @@ -47,8 +45,7 @@ import static sun.security.x509.PKIXExtensions.*; import sun.security.util.Debug; /** - * This class is able to build certification paths in either the forward - * or reverse directions. + * This class builds certification paths in the forward direction. * *

                                  If successful, it returns a certification path which has successfully * satisfied all the constraints and requirements specified in the @@ -102,10 +99,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { /** * Attempts to build a certification path using the Sun build * algorithm from a trusted anchor(s) to a target subject, which must both - * be specified in the input parameter set. By default, this method will - * attempt to build in the forward direction. In order to build in the - * reverse direction, the caller needs to pass in an instance of - * SunCertPathBuilderParameters with the buildForward flag set to false. + * be specified in the input parameter set. This method will + * attempt to build in the forward direction: from the target to the CA. * *

                                  The certification path that is constructed is validated * according to the PKIX specification. @@ -162,11 +157,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { policyTreeResult = null; LinkedList certPathList = new LinkedList<>(); try { - if (buildParams.buildForward()) { - buildForward(adjList, certPathList, searchAllCertStores); - } else { - buildReverse(adjList, certPathList); - } + buildForward(adjList, certPathList, searchAllCertStores); } catch (GeneralSecurityException | IOException e) { if (debug != null) { debug.println("SunCertPathBuilder.engineBuild() exception in " @@ -209,81 +200,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { return null; } - /* - * Private build reverse method. - */ - private void buildReverse(List> adjacencyList, - LinkedList certPathList) - throws GeneralSecurityException, IOException - { - if (debug != null) { - debug.println("SunCertPathBuilder.buildReverse()..."); - debug.println("SunCertPathBuilder.buildReverse() InitialPolicies: " - + buildParams.initialPolicies()); - } - - ReverseState currentState = new ReverseState(); - /* Initialize adjacency list */ - adjacencyList.clear(); - adjacencyList.add(new LinkedList()); - - /* - * Perform a search using each trust anchor, until a valid - * path is found - */ - Iterator iter = buildParams.trustAnchors().iterator(); - while (iter.hasNext()) { - TrustAnchor anchor = iter.next(); - - /* check if anchor satisfies target constraints */ - if (anchorIsTarget(anchor, buildParams.targetCertConstraints())) { - this.trustAnchor = anchor; - this.pathCompleted = true; - this.finalPublicKey = anchor.getTrustedCert().getPublicKey(); - break; - } - - // skip anchor if it contains a DSA key with no DSA params - X509Certificate trustedCert = anchor.getTrustedCert(); - PublicKey pubKey = trustedCert != null ? trustedCert.getPublicKey() - : anchor.getCAPublicKey(); - - if (PKIX.isDSAPublicKeyWithoutParams(pubKey)) { - continue; - } - - /* Initialize current state */ - currentState.initState(buildParams); - currentState.updateState(anchor, buildParams); - - currentState.algorithmChecker = new AlgorithmChecker(anchor); - currentState.untrustedChecker = new UntrustedChecker(); - try { - depthFirstSearchReverse(null, currentState, - new ReverseBuilder(buildParams), - adjacencyList, certPathList); - } catch (GeneralSecurityException | IOException e) { - // continue on error if more anchors to try - if (iter.hasNext()) - continue; - else - throw e; - } - - // break out of loop if search is successful - if (pathCompleted) { - break; - } - } - - if (debug != null) { - debug.println("SunCertPathBuilder.buildReverse() returned from " - + "depthFirstSearchReverse()"); - debug.println("SunCertPathBuilder.buildReverse() " - + "certPathList.size: " + certPathList.size()); - } - } - /* * Private build forward method. */ @@ -631,147 +547,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { } } - /* - * This method performs a depth first search for a certification - * path while building reverse which meets the requirements set in - * the parameters object. - * It uses an adjacency list to store all certificates which were - * tried (i.e. at one time added to the path - they may not end up in - * the final path if backtracking occurs). This information can - * be used later to debug or demo the build. - * - * See "Data Structure and Algorithms, by Aho, Hopcroft, and Ullman" - * for an explanation of the DFS algorithm. - * - * @param dN the distinguished name being currently searched for certs - * @param currentState the current PKIX validation state - */ - private void depthFirstSearchReverse(X500Principal dN, - ReverseState currentState, - ReverseBuilder builder, - List> adjList, - LinkedList cpList) - throws GeneralSecurityException, IOException - { - if (debug != null) - debug.println("SunCertPathBuilder.depthFirstSearchReverse(" + dN - + ", " + currentState.toString() + ")"); - - /* - * Find all the certificates issued by dN which - * satisfy the PKIX certification path constraints. - */ - Collection certs = - builder.getMatchingCerts(currentState, buildParams.certStores()); - List vertices = addVertices(certs, adjList); - if (debug != null) - debug.println("SunCertPathBuilder.depthFirstSearchReverse(): " - + "certs.size=" + vertices.size()); - - /* - * For each cert in the collection, verify anything - * that hasn't been checked yet (signature, revocation, etc) - * and check for loops. Call depthFirstSearchReverse() - * recursively for each good cert. - */ - for (Vertex vertex : vertices) { - /** - * Restore state to currentState each time through the loop. - * This is important because some of the user-defined - * checkers modify the state, which MUST be restored if - * the cert eventually fails to lead to the target and - * the next matching cert is tried. - */ - ReverseState nextState = (ReverseState) currentState.clone(); - X509Certificate cert = vertex.getCertificate(); - try { - builder.verifyCert(cert, nextState, cpList); - } catch (GeneralSecurityException gse) { - if (debug != null) - debug.println("SunCertPathBuilder.depthFirstSearchReverse()" - + ": validation failed: " + gse); - vertex.setThrowable(gse); - continue; - } - - /* - * Certificate is good, add it to the path (if it isn't a - * self-signed cert) and update state - */ - if (!currentState.isInitial()) - builder.addCertToPath(cert, cpList); - // save trust anchor - this.trustAnchor = currentState.trustAnchor; - - /* - * Check if path is completed, return ASAP if so. - */ - if (builder.isPathCompleted(cert)) { - if (debug != null) - debug.println("SunCertPathBuilder.depthFirstSearchReverse()" - + ": path completed!"); - pathCompleted = true; - - PolicyNodeImpl rootNode = nextState.rootNode; - - if (rootNode == null) - policyTreeResult = null; - else { - policyTreeResult = rootNode.copyTree(); - ((PolicyNodeImpl)policyTreeResult).setImmutable(); - } - - /* - * Extract and save the final target public key - */ - finalPublicKey = cert.getPublicKey(); - if (PKIX.isDSAPublicKeyWithoutParams(finalPublicKey)) { - finalPublicKey = - BasicChecker.makeInheritedParamsKey - (finalPublicKey, currentState.pubKey); - } - - return; - } - - /* Update the PKIX state */ - nextState.updateState(cert); - - /* - * Append an entry for cert in adjacency list and - * set index for current vertex. - */ - adjList.add(new LinkedList()); - vertex.setIndex(adjList.size() - 1); - - /* recursively search for matching certs at next dN */ - depthFirstSearchReverse(cert.getSubjectX500Principal(), nextState, - builder, adjList, cpList); - - /* - * If path has been completed, return ASAP! - */ - if (pathCompleted) { - return; - } else { - /* - * If we get here, it means we have searched all possible - * certs issued by the dN w/o finding any matching certs. This - * means we have to backtrack to the previous cert in the path - * and try some other paths. - */ - if (debug != null) - debug.println("SunCertPathBuilder.depthFirstSearchReverse()" - + ": backtracking"); - if (!currentState.isInitial()) - builder.removeFinalCertFromPath(cpList); - } - } - if (debug != null) - debug.println("SunCertPathBuilder.depthFirstSearchReverse() all " - + "certs in this adjacency list checked"); - } - /* * Adds a collection of matching certificates to the * adjacency list. diff --git a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilderParameters.java b/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilderParameters.java deleted file mode 100644 index 186e2527328..00000000000 --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilderParameters.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.provider.certpath; - -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.cert.*; -import java.util.Set; - -/** - * This class specifies the set of parameters used as input for the Sun - * certification path build algorithm. It is identical to PKIXBuilderParameters - * with the addition of a buildForward parameter which allows - * the caller to specify whether or not the path should be constructed in - * the forward direction. - * - * The default for the buildForward parameter is - * true, which means that the build algorithm should construct paths - * from the target subject back to the trusted anchor. - * - * @since 1.4 - * @author Sean Mullan - * @author Yassir Elley - */ -public class SunCertPathBuilderParameters extends PKIXBuilderParameters { - - private boolean buildForward = true; - - /** - * Creates an instance of SunCertPathBuilderParameters with the - * specified parameter values. - * - * @param trustAnchors a Set of TrustAnchors - * @param targetConstraints a CertSelector specifying the - * constraints on the target certificate - * @throws InvalidAlgorithmParameterException if the specified - * Set is empty (trustAnchors.isEmpty() == true) - * @throws NullPointerException if the specified Set is - * null - * @throws ClassCastException if any of the elements in the Set - * are not of type java.security.cert.TrustAnchor - */ - public SunCertPathBuilderParameters(Set trustAnchors, - CertSelector targetConstraints) throws InvalidAlgorithmParameterException - { - super(trustAnchors, targetConstraints); - setBuildForward(true); - } - - /** - * Creates an instance of SunCertPathBuilderParameters that - * uses the specified KeyStore to populate the set - * of most-trusted CA certificates. - * - * @param keystore A keystore from which the set of most-trusted - * CA certificates will be populated. - * @param targetConstraints a CertSelector specifying the - * constraints on the target certificate - * @throws KeyStoreException if the keystore has not been initialized. - * @throws InvalidAlgorithmParameterException if the keystore does - * not contain at least one trusted certificate entry - * @throws NullPointerException if the keystore is null - */ - public SunCertPathBuilderParameters(KeyStore keystore, - CertSelector targetConstraints) - throws KeyStoreException, InvalidAlgorithmParameterException - { - super(keystore, targetConstraints); - setBuildForward(true); - } - - /** - * Returns the value of the buildForward flag. - * - * @return the value of the buildForward flag - */ - public boolean getBuildForward() { - return this.buildForward; - } - - /** - * Sets the value of the buildForward flag. If true, paths - * are built from the target subject to the trusted anchor. - * If false, paths are built from the trusted anchor to the - * target subject. The default value if not specified is true. - * - * @param buildForward the value of the buildForward flag - */ - public void setBuildForward(boolean buildForward) { - this.buildForward = buildForward; - } - - /** - * Returns a formatted string describing the parameters. - * - * @return a formatted string describing the parameters. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[\n"); - sb.append(super.toString()); - sb.append(" Build Forward Flag: " + String.valueOf(buildForward) + "\n"); - sb.append("]\n"); - return sb.toString(); - } -} diff --git a/jdk/src/java.base/share/classes/sun/security/rsa/RSACore.java b/jdk/src/java.base/share/classes/sun/security/rsa/RSACore.java index 81b4e3f986d..7e933e5b758 100644 --- a/jdk/src/java.base/share/classes/sun/security/rsa/RSACore.java +++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSACore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,12 +102,24 @@ public final class RSACore { /** * Perform an RSA private key operation. Uses CRT if the key is a - * CRT key. + * CRT key with additional verification check after the signature + * is computed. */ + @Deprecated public static byte[] rsa(byte[] msg, RSAPrivateKey key) throws BadPaddingException { + return rsa(msg, key, true); + } + + /** + * Perform an RSA private key operation. Uses CRT if the key is a + * CRT key. Set 'verify' to true if this function is used for + * generating a signature. + */ + public static byte[] rsa(byte[] msg, RSAPrivateKey key, boolean verify) + throws BadPaddingException { if (key instanceof RSAPrivateCrtKey) { - return crtCrypt(msg, (RSAPrivateCrtKey)key); + return crtCrypt(msg, (RSAPrivateCrtKey)key, verify); } else { return priCrypt(msg, key.getModulus(), key.getPrivateExponent()); } @@ -148,10 +160,11 @@ public final class RSACore { * RSA private key operations with CRT. Algorithm and variable naming * are taken from PKCS#1 v2.1, section 5.1.2. */ - private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key) - throws BadPaddingException { + private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key, + boolean verify) throws BadPaddingException { BigInteger n = key.getModulus(); - BigInteger c = parseMsg(msg, n); + BigInteger c0 = parseMsg(msg, n); + BigInteger c = c0; BigInteger p = key.getPrimeP(); BigInteger q = key.getPrimeQ(); BigInteger dP = key.getPrimeExponentP(); @@ -184,6 +197,9 @@ public final class RSACore { if (ENABLE_BLINDING) { m = m.multiply(brp.v).mod(n); } + if (verify && !c0.equals(m.modPow(e, n))) { + throw new BadPaddingException("RSA private key operation failed"); + } return toByteArray(m, getByteLength(n)); } diff --git a/jdk/src/java.base/share/classes/sun/security/rsa/RSASignature.java b/jdk/src/java.base/share/classes/sun/security/rsa/RSASignature.java index 959700f22cd..d5ba1f82621 100644 --- a/jdk/src/java.base/share/classes/sun/security/rsa/RSASignature.java +++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSASignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,7 +173,7 @@ public abstract class RSASignature extends SignatureSpi { try { byte[] encoded = encodeSignature(digestOID, digest); byte[] padded = padding.pad(encoded); - byte[] encrypted = RSACore.rsa(padded, privateKey); + byte[] encrypted = RSACore.rsa(padded, privateKey, true); return encrypted; } catch (GeneralSecurityException e) { throw new SignatureException("Could not sign data", e); diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java index cb4f54eb125..ea4d2a404fc 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java @@ -293,7 +293,7 @@ final class ClientHandshaker extends Handshaker { case K_ECDH_RSA: throw new SSLProtocolException( "Protocol violation: server sent a server key exchange" - + "message for key exchange " + keyExchange); + + " message for key exchange " + keyExchange); case K_KRB5: case K_KRB5_EXPORT: throw new SSLProtocolException( diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java index 8cf95a81eed..104d40ddb83 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -39,6 +39,7 @@ import java.util.concurrent.locks.ReentrantLock; import javax.crypto.BadPaddingException; import javax.net.ssl.*; +import sun.misc.ManagedLocalsThread; /** * Implementation of an SSL socket. This is a normal connection type @@ -1078,8 +1079,10 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { HandshakeCompletedEvent event = new HandshakeCompletedEvent(this, sess); - Thread t = new NotifyHandshakeThread( - handshakeListeners.entrySet(), event); + Thread t = new ManagedLocalsThread( + new NotifyHandshake( + handshakeListeners.entrySet(), event), + "HandshakeCompletedNotify-Thread"); t.start(); } } @@ -2575,17 +2578,16 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { // events. This ensures that the notifications don't block the // protocol state machine. // - private static class NotifyHandshakeThread extends Thread { + private static class NotifyHandshake implements Runnable { private Set> targets; // who gets notified private HandshakeCompletedEvent event; // the notification - NotifyHandshakeThread( + NotifyHandshake( Set> entrySet, HandshakeCompletedEvent e) { - super("HandshakeCompletedNotify-Thread"); targets = new HashSet<>(entrySet); // clone the entry set event = e; } diff --git a/jdk/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java b/jdk/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java index 4ca79f086b1..0ecdaa18b54 100644 --- a/jdk/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java +++ b/jdk/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,26 +132,33 @@ class EndEntityChecker { return new EndEntityChecker(type, variant); } - void check(X509Certificate cert, Object parameter) - throws CertificateException { + void check(X509Certificate cert, Object parameter, + boolean checkUnresolvedCritExts) throws CertificateException { if (variant.equals(Validator.VAR_GENERIC)) { - // no checks - return; - } else if (variant.equals(Validator.VAR_TLS_SERVER)) { - checkTLSServer(cert, (String)parameter); + return; // no checks + } + + Set exts = getCriticalExtensions(cert); + if (variant.equals(Validator.VAR_TLS_SERVER)) { + checkTLSServer(cert, (String)parameter, exts); } else if (variant.equals(Validator.VAR_TLS_CLIENT)) { - checkTLSClient(cert); + checkTLSClient(cert, exts); } else if (variant.equals(Validator.VAR_CODE_SIGNING)) { - checkCodeSigning(cert); + checkCodeSigning(cert, exts); } else if (variant.equals(Validator.VAR_JCE_SIGNING)) { - checkCodeSigning(cert); + checkCodeSigning(cert, exts); } else if (variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING)) { - checkCodeSigning(cert); + checkCodeSigning(cert, exts); } else if (variant.equals(Validator.VAR_TSA_SERVER)) { - checkTSAServer(cert); + checkTSAServer(cert, exts); } else { throw new CertificateException("Unknown variant: " + variant); } + + // if neither VAR_GENERIC variant nor unknown variant + if (checkUnresolvedCritExts) { + checkRemainingExtensions(exts); + } } /** @@ -219,10 +226,8 @@ class EndEntityChecker { * authentication. * @throws CertificateException if not. */ - private void checkTLSClient(X509Certificate cert) + private void checkTLSClient(X509Certificate cert, Set exts) throws CertificateException { - Set exts = getCriticalExtensions(cert); - if (checkKeyUsage(cert, KU_SIGNATURE) == false) { throw new ValidatorException ("KeyUsage does not allow digital signatures", @@ -245,8 +250,6 @@ class EndEntityChecker { exts.remove(SimpleValidator.OID_KEY_USAGE); exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE); exts.remove(SimpleValidator.OID_NETSCAPE_CERT_TYPE); - - checkRemainingExtensions(exts); } /** @@ -255,10 +258,8 @@ class EndEntityChecker { * specification for details. * @throws CertificateException if not. */ - private void checkTLSServer(X509Certificate cert, String parameter) - throws CertificateException { - Set exts = getCriticalExtensions(cert); - + private void checkTLSServer(X509Certificate cert, String parameter, + Set exts) throws CertificateException { if (KU_SERVER_ENCRYPTION.contains(parameter)) { if (checkKeyUsage(cert, KU_KEY_ENCIPHERMENT) == false) { throw new ValidatorException @@ -303,18 +304,14 @@ class EndEntityChecker { exts.remove(SimpleValidator.OID_KEY_USAGE); exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE); exts.remove(SimpleValidator.OID_NETSCAPE_CERT_TYPE); - - checkRemainingExtensions(exts); } /** * Check whether this certificate can be used for code signing. * @throws CertificateException if not. */ - private void checkCodeSigning(X509Certificate cert) + private void checkCodeSigning(X509Certificate cert, Set exts) throws CertificateException { - Set exts = getCriticalExtensions(cert); - if (checkKeyUsage(cert, KU_SIGNATURE) == false) { throw new ValidatorException ("KeyUsage does not allow digital signatures", @@ -341,8 +338,6 @@ class EndEntityChecker { // remove extensions we checked exts.remove(SimpleValidator.OID_KEY_USAGE); exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE); - - checkRemainingExtensions(exts); } /** @@ -350,10 +345,8 @@ class EndEntityChecker { * server (see RFC 3161, section 2.3). * @throws CertificateException if not. */ - private void checkTSAServer(X509Certificate cert) + private void checkTSAServer(X509Certificate cert, Set exts) throws CertificateException { - Set exts = getCriticalExtensions(cert); - if (checkKeyUsage(cert, KU_SIGNATURE) == false) { throw new ValidatorException ("KeyUsage does not allow digital signatures", @@ -376,7 +369,5 @@ class EndEntityChecker { // remove extensions we checked exts.remove(SimpleValidator.OID_KEY_USAGE); exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE); - - checkRemainingExtensions(exts); } } diff --git a/jdk/src/java.base/share/classes/sun/security/validator/Validator.java b/jdk/src/java.base/share/classes/sun/security/validator/Validator.java index 863566c7357..dd880a7b2dd 100644 --- a/jdk/src/java.base/share/classes/sun/security/validator/Validator.java +++ b/jdk/src/java.base/share/classes/sun/security/validator/Validator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,6 +143,7 @@ public abstract class Validator { */ public final static String VAR_PLUGIN_CODE_SIGNING = "plugin code signing"; + private final String type; final EndEntityChecker endEntityChecker; final String variant; @@ -154,6 +155,7 @@ public abstract class Validator { volatile Date validationDate; Validator(String type, String variant) { + this.type = type; this.variant = variant; endEntityChecker = EndEntityChecker.getInstance(type, variant); } @@ -261,7 +263,16 @@ public abstract class Validator { // omit EE extension check if EE cert is also trust anchor if (chain.length > 1) { - endEntityChecker.check(chain[0], parameter); + // EndEntityChecker does not need to check unresolved critical + // extensions when validating with a TYPE_PKIX Validator. + // A TYPE_PKIX Validator will already have run checks on all + // certs' extensions, including checks by any PKIXCertPathCheckers + // included in the PKIXParameters, so the extra checks would be + // redundant. + boolean checkUnresolvedCritExts = + (type == TYPE_PKIX) ? false : true; + endEntityChecker.check(chain[0], parameter, + checkUnresolvedCritExts); } return chain; diff --git a/jdk/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java b/jdk/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java index 0f1242d63d9..f02d8eeb636 100644 --- a/jdk/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java +++ b/jdk/src/java.base/share/classes/sun/security/x509/KeyUsageExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,7 +83,8 @@ implements CertAttrSet { * @param position the position in the bit string to check. */ private boolean isSet(int position) { - return bitString[position]; + return (position < bitString.length) && + bitString[position]; } /** @@ -275,41 +276,40 @@ implements CertAttrSet { * Returns a printable representation of the KeyUsage. */ public String toString() { - String s = super.toString() + "KeyUsage [\n"; + StringBuilder sb = new StringBuilder(); + sb.append(super.toString()); + sb.append("KeyUsage [\n"); - try { - if (isSet(0)) { - s += " DigitalSignature\n"; - } - if (isSet(1)) { - s += " Non_repudiation\n"; - } - if (isSet(2)) { - s += " Key_Encipherment\n"; - } - if (isSet(3)) { - s += " Data_Encipherment\n"; - } - if (isSet(4)) { - s += " Key_Agreement\n"; - } - if (isSet(5)) { - s += " Key_CertSign\n"; - } - if (isSet(6)) { - s += " Crl_Sign\n"; - } - if (isSet(7)) { - s += " Encipher_Only\n"; - } - if (isSet(8)) { - s += " Decipher_Only\n"; - } - } catch (ArrayIndexOutOfBoundsException ex) {} + if (isSet(0)) { + sb.append(" DigitalSignature\n"); + } + if (isSet(1)) { + sb.append(" Non_repudiation\n"); + } + if (isSet(2)) { + sb.append(" Key_Encipherment\n"); + } + if (isSet(3)) { + sb.append(" Data_Encipherment\n"); + } + if (isSet(4)) { + sb.append(" Key_Agreement\n"); + } + if (isSet(5)) { + sb.append(" Key_CertSign\n"); + } + if (isSet(6)) { + sb.append(" Crl_Sign\n"); + } + if (isSet(7)) { + sb.append(" Encipher_Only\n"); + } + if (isSet(8)) { + sb.append(" Decipher_Only\n"); + } + sb.append("]\n"); - s += "]\n"; - - return (s); + return sb.toString(); } /** diff --git a/jdk/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java b/jdk/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java index d6d4efd34cf..735efddfc3a 100644 --- a/jdk/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java +++ b/jdk/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,7 +136,8 @@ implements CertAttrSet { * @param position the position in the bit string to check. */ private boolean isSet(int position) { - return bitString[position]; + return (position < bitString.length) && + bitString[position]; } /** @@ -236,27 +237,34 @@ implements CertAttrSet { * Returns a printable representation of the NetscapeCertType. */ public String toString() { - String s = super.toString() + "NetscapeCertType [\n"; + StringBuilder sb = new StringBuilder(); + sb.append(super.toString()); + sb.append("NetscapeCertType [\n"); - try { - if (isSet(getPosition(SSL_CLIENT))) - s += " SSL client\n"; - if (isSet(getPosition(SSL_SERVER))) - s += " SSL server\n"; - if (isSet(getPosition(S_MIME))) - s += " S/MIME\n"; - if (isSet(getPosition(OBJECT_SIGNING))) - s += " Object Signing\n"; - if (isSet(getPosition(SSL_CA))) - s += " SSL CA\n"; - if (isSet(getPosition(S_MIME_CA))) - s += " S/MIME CA\n"; - if (isSet(getPosition(OBJECT_SIGNING_CA))) - s += " Object Signing CA" ; - } catch (Exception e) { } + if (isSet(0)) { + sb.append(" SSL client\n"); + } + if (isSet(1)) { + sb.append(" SSL server\n"); + } + if (isSet(2)) { + sb.append(" S/MIME\n"); + } + if (isSet(3)) { + sb.append(" Object Signing\n"); + } + if (isSet(5)) { + sb.append(" SSL CA\n"); + } + if (isSet(6)) { + sb.append(" S/MIME CA\n"); + } + if (isSet(7)) { + sb.append(" Object Signing CA"); + } - s += "]\n"; - return (s); + sb.append("]\n"); + return sb.toString(); } /** diff --git a/jdk/src/java.base/share/classes/sun/security/x509/ReasonFlags.java b/jdk/src/java.base/share/classes/sun/security/x509/ReasonFlags.java index 4549ad4544f..6a42046205c 100644 --- a/jdk/src/java.base/share/classes/sun/security/x509/ReasonFlags.java +++ b/jdk/src/java.base/share/classes/sun/security/x509/ReasonFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,8 @@ public class ReasonFlags { * @param position the position in the bit string to check. */ private boolean isSet(int position) { - return bitString[position]; + return (position < bitString.length) && + bitString[position]; } /** @@ -199,23 +200,38 @@ public class ReasonFlags { * Returns a printable representation of the ReasonFlags. */ public String toString() { - String s = "Reason Flags [\n"; + StringBuilder sb = new StringBuilder("Reason Flags [\n"); - try { - if (isSet(0)) s += " Unused\n"; - if (isSet(1)) s += " Key Compromise\n"; - if (isSet(2)) s += " CA Compromise\n"; - if (isSet(3)) s += " Affiliation_Changed\n"; - if (isSet(4)) s += " Superseded\n"; - if (isSet(5)) s += " Cessation Of Operation\n"; - if (isSet(6)) s += " Certificate Hold\n"; - if (isSet(7)) s += " Privilege Withdrawn\n"; - if (isSet(8)) s += " AA Compromise\n"; - } catch (ArrayIndexOutOfBoundsException ex) {} + if (isSet(0)) { + sb.append(" Unused\n"); + } + if (isSet(1)) { + sb.append(" Key Compromise\n"); + } + if (isSet(2)) { + sb.append(" CA Compromise\n"); + } + if (isSet(3)) { + sb.append(" Affiliation_Changed\n"); + } + if (isSet(4)) { + sb.append(" Superseded\n"); + } + if (isSet(5)) { + sb.append(" Cessation Of Operation\n"); + } + if (isSet(6)) { + sb.append(" Certificate Hold\n"); + } + if (isSet(7)) { + sb.append(" Privilege Withdrawn\n"); + } + if (isSet(8)) { + sb.append(" AA Compromise\n"); + } + sb.append("]\n"); - s += "]\n"; - - return (s); + return sb.toString(); } /** diff --git a/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java b/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java index d0a8ed90597..9c83984e099 100644 --- a/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java +++ b/jdk/src/java.base/share/classes/sun/util/PreHashedMap.java @@ -166,14 +166,14 @@ public abstract class PreHashedMap } public Set keySet() { - return new AbstractSet () { + return new AbstractSet<> () { public int size() { return size; } public Iterator iterator() { - return new Iterator() { + return new Iterator<>() { private int i = -1; Object[] a = null; String cur = null; diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java index d89a8856bea..5622078fbeb 100644 --- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java @@ -47,6 +47,7 @@ import java.util.Calendar; import java.util.LinkedHashSet; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.ResourceBundle; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -250,17 +251,17 @@ public class LocaleResources { return (String) localeName; } - String[] getTimeZoneNames(String key, int size) { + String[] getTimeZoneNames(String key) { String[] names = null; - String cacheKey = TIME_ZONE_NAMES + size + '.' + key; + String cacheKey = TIME_ZONE_NAMES + '.' + key; removeEmptyReferences(); ResourceReference data = cache.get(cacheKey); - if (data == null || ((names = (String[]) data.get()) == null)) { + if (Objects.isNull(data) || Objects.isNull((names = (String[]) data.get()))) { TimeZoneNamesBundle tznb = localeData.getTimeZoneNames(locale); if (tznb.containsKey(key)) { - names = tznb.getStringArray(key, size); + names = tznb.getStringArray(key); cache.put(cacheKey, new ResourceReference(cacheKey, (Object) names, referenceQueue)); } diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java index 105af9cb8f7..cf609658e01 100644 --- a/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameProviderImpl.java @@ -26,6 +26,7 @@ package sun.util.locale.provider; import java.util.Locale; +import java.util.Objects; import java.util.Set; import java.util.TimeZone; import java.util.spi.TimeZoneNameProvider; @@ -95,8 +96,9 @@ public class TimeZoneNameProviderImpl extends TimeZoneNameProvider { */ @Override public String getDisplayName(String id, boolean daylight, int style, Locale locale) { - String[] names = getDisplayNameArray(id, 5, locale); - if (names != null) { + String[] names = getDisplayNameArray(id, locale); + if (Objects.nonNull(names)) { + assert names.length >= 7; int index = daylight ? 3 : 1; if (style == TimeZone.SHORT) { index++; @@ -108,18 +110,18 @@ public class TimeZoneNameProviderImpl extends TimeZoneNameProvider { @Override public String getGenericDisplayName(String id, int style, Locale locale) { - String[] names = getDisplayNameArray(id, 7, locale); - if (names != null && names.length >= 7) { + String[] names = getDisplayNameArray(id, locale); + if (Objects.nonNull(names)) { + assert names.length >= 7; return names[(style == TimeZone.LONG) ? 5 : 6]; } return null; } - private String[] getDisplayNameArray(String id, int n, Locale locale) { - if (id == null || locale == null) { - throw new NullPointerException(); - } - return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id, n); + private String[] getDisplayNameArray(String id, Locale locale) { + Objects.requireNonNull(id); + Objects.requireNonNull(locale); + return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id); } /** diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java index c99978082b4..688fb2ed21b 100644 --- a/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java +++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/TimeZoneNameUtility.java @@ -30,6 +30,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.spi.TimeZoneNameProvider; @@ -100,9 +101,9 @@ public final class TimeZoneNameUtility { * Retrieve display names for a time zone ID. */ public static String[] retrieveDisplayNames(String id, Locale locale) { - if (id == null || locale == null) { - throw new NullPointerException(); - } + Objects.requireNonNull(id); + Objects.requireNonNull(locale); + return retrieveDisplayNamesImpl(id, locale); } @@ -115,9 +116,12 @@ public final class TimeZoneNameUtility { * @return the requested generic time zone display name, or null if not found. */ public static String retrieveGenericDisplayName(String id, int style, Locale locale) { - LocaleServiceProviderPool pool = - LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class); - return pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, "generic", style, id); + String[] names = retrieveDisplayNamesImpl(id, locale); + if (Objects.nonNull(names)) { + return names[6 - style]; + } else { + return null; + } } /** @@ -130,140 +134,53 @@ public final class TimeZoneNameUtility { * @return the requested time zone name, or null if not found. */ public static String retrieveDisplayName(String id, boolean daylight, int style, Locale locale) { - LocaleServiceProviderPool pool = - LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class); - return pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, daylight ? "dst" : "std", style, id); + String[] names = retrieveDisplayNamesImpl(id, locale); + if (Objects.nonNull(names)) { + return names[(daylight ? 4 : 2) - style]; + } else { + return null; + } } private static String[] retrieveDisplayNamesImpl(String id, Locale locale) { LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class); + String[] names; + Map perLocale = null; SoftReference> ref = cachedDisplayNames.get(id); - if (ref != null) { - Map perLocale = ref.get(); - if (perLocale != null) { - String[] names = perLocale.get(locale); - if (names != null) { + if (Objects.nonNull(ref)) { + perLocale = ref.get(); + if (Objects.nonNull(perLocale)) { + names = perLocale.get(locale); + if (Objects.nonNull(names)) { return names; } - names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); - if (names != null) { - perLocale.put(locale, names); - } - return names; } } - String[] names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id); - if (names != null) { - Map perLocale = new ConcurrentHashMap<>(); - perLocale.put(locale, names); - ref = new SoftReference<>(perLocale); - cachedDisplayNames.put(id, ref); + // build names array + names = new String[7]; + names[0] = id; + for (int i = 1; i <= 6; i ++) { + names[i] = pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, + i<5 ? (i<3 ? "std" : "dst") : "generic", i%2, id); } + + if (Objects.isNull(perLocale)) { + perLocale = new ConcurrentHashMap<>(); + } + perLocale.put(locale, names); + ref = new SoftReference<>(perLocale); + cachedDisplayNames.put(id, ref); return names; } + /** * Obtains a localized time zone strings from a TimeZoneNameProvider * implementation. */ - private static class TimeZoneNameArrayGetter - implements LocaleServiceProviderPool.LocalizedObjectGetter{ - private static final TimeZoneNameArrayGetter INSTANCE = - new TimeZoneNameArrayGetter(); - - @Override - public String[] getObject(TimeZoneNameProvider timeZoneNameProvider, - Locale locale, - String requestID, - Object... params) { - assert params.length == 0; - - // First, try to get names with the request ID - String[] names = buildZoneStrings(timeZoneNameProvider, locale, requestID); - - if (names == null) { - Map aliases = ZoneInfo.getAliasTable(); - - if (aliases != null) { - // Check whether this id is an alias, if so, - // look for the standard id. - String canonicalID = aliases.get(requestID); - if (canonicalID != null) { - names = buildZoneStrings(timeZoneNameProvider, locale, canonicalID); - } - if (names == null) { - // There may be a case that a standard id has become an - // alias. so, check the aliases backward. - names = examineAliases(timeZoneNameProvider, locale, - canonicalID == null ? requestID : canonicalID, aliases); - } - } - } - - if (names != null) { - names[0] = requestID; - } - - return names; - } - - private static String[] examineAliases(TimeZoneNameProvider tznp, Locale locale, - String id, - Map aliases) { - if (aliases.containsValue(id)) { - for (Map.Entry entry : aliases.entrySet()) { - if (entry.getValue().equals(id)) { - String alias = entry.getKey(); - String[] names = buildZoneStrings(tznp, locale, alias); - if (names != null) { - return names; - } - names = examineAliases(tznp, locale, alias, aliases); - if (names != null) { - return names; - } - } - } - } - - return null; - } - - private static String[] buildZoneStrings(TimeZoneNameProvider tznp, - Locale locale, String id) { - String[] names = new String[5]; - - for (int i = 1; i <= 4; i ++) { - names[i] = tznp.getDisplayName(id, i>=3, i%2, locale); - - if (names[i] == null) { - switch (i) { - case 1: - // this id seems not localized by this provider - return null; - case 2: - case 4: - // If the display name for SHORT is not supplied, - // copy the LONG name. - names[i] = names[i-1]; - break; - case 3: - // If the display name for DST is not supplied, - // copy the "standard" name. - names[3] = names[1]; - break; - } - } - } - - return names; - } - } - private static class TimeZoneNameGetter implements LocaleServiceProviderPool.LocalizedObjectGetter { @@ -299,18 +216,16 @@ public final class TimeZoneNameUtility { private static String examineAliases(TimeZoneNameProvider tznp, Locale locale, String requestID, String tzid, int style, Map aliases) { - if (aliases.containsValue(tzid)) { - for (Map.Entry entry : aliases.entrySet()) { - if (entry.getValue().equals(tzid)) { - String alias = entry.getKey(); - String name = getName(tznp, locale, requestID, style, alias); - if (name != null) { - return name; - } - name = examineAliases(tznp, locale, requestID, alias, style, aliases); - if (name != null) { - return name; - } + for (Map.Entry entry : aliases.entrySet()) { + if (entry.getValue().equals(tzid)) { + String alias = entry.getKey(); + String name = getName(tznp, locale, requestID, style, alias); + if (name != null) { + return name; + } + name = examineAliases(tznp, locale, requestID, alias, style, aliases); + if (name != null) { + return name; } } } diff --git a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java index 03c48a4ffec..b81269d3fa8 100644 --- a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java +++ b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java @@ -161,7 +161,7 @@ public class PlatformLogger { private static boolean loggingEnabled; static { loggingEnabled = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { public Boolean run() { String cname = System.getProperty("java.util.logging.config.class"); String fname = System.getProperty("java.util.logging.config.file"); diff --git a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java index 75ee2f018ba..60ddfefe134 100644 --- a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java +++ b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java @@ -159,7 +159,7 @@ public class LocaleData { } public static ResourceBundle getBundle(final String baseName, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction() { + return AccessController.doPrivileged(new PrivilegedAction<>() { @Override public ResourceBundle run() { return ResourceBundle @@ -169,7 +169,7 @@ public class LocaleData { } private static OpenListResourceBundle getSupplementary(final String baseName, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction() { + return AccessController.doPrivileged(new PrivilegedAction<>() { @Override public OpenListResourceBundle run() { OpenListResourceBundle rb = null; diff --git a/jdk/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java b/jdk/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java index 862143c9745..35319575010 100644 --- a/jdk/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java +++ b/jdk/src/java.base/share/classes/sun/util/resources/ParallelListResourceBundle.java @@ -213,7 +213,7 @@ public abstract class ParallelListResourceBundle extends ResourceBundle { if (parent == null) { return set.iterator(); } - return new Iterator() { + return new Iterator<>() { private Iterator itr = set.iterator(); private boolean usingParent; diff --git a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java index ab2d10a676e..3385887596e 100644 --- a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java +++ b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNamesBundle.java @@ -44,6 +44,7 @@ import java.util.Map; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.MissingResourceException; +import java.util.Objects; import java.util.Set; /** @@ -60,26 +61,6 @@ import java.util.Set; */ public abstract class TimeZoneNamesBundle extends OpenListResourceBundle { - /** - * Returns a String array containing time zone names. The String array has - * at most size elements. - * - * @param key the time zone ID for which names are obtained - * @param size the requested size of array for names - * @return a String array containing names - */ - public String[] getStringArray(String key, int size) { - String[] names = handleGetObject(key, size); - if ((names == null || names.length != size) && parent != null) { - names = ((TimeZoneNamesBundle)parent).getStringArray(key, size); - } - if (names == null) { - throw new MissingResourceException("no time zone names", getClass().getName(), key); - } - return names; - - } - /** * Maps time zone IDs to locale-specific names. * The value returned is an array of five strings: @@ -89,6 +70,8 @@ public abstract class TimeZoneNamesBundle extends OpenListResourceBundle { *

                                • The short name of the time zone in standard time (localized). *
                                • The long name of the time zone in daylight savings time (localized). *
                                • The short name of the time zone in daylight savings time (localized). + *
                                • The long name of the time zone in generic form (localized). + *
                                • The short name of the time zone in generic form (localized). * * The localized names come from the subclasses's * getContents implementations, while the time zone @@ -96,16 +79,12 @@ public abstract class TimeZoneNamesBundle extends OpenListResourceBundle { */ @Override public Object handleGetObject(String key) { - return handleGetObject(key, 5); - } - - private String[] handleGetObject(String key, int n) { String[] contents = (String[]) super.handleGetObject(key); - if (contents == null) { + if (Objects.isNull(contents)) { return null; } - int clen = Math.min(n - 1, contents.length); - String[] tmpobj = new String[clen+1]; + int clen = contents.length; + String[] tmpobj = new String[7]; tmpobj[0] = key; System.arraycopy(contents, 0, tmpobj, 1, clen); return tmpobj; diff --git a/jdk/src/java.base/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java b/jdk/src/java.base/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java index ce91613f6ba..14a74e860ad 100644 --- a/jdk/src/java.base/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java +++ b/jdk/src/java.base/share/classes/sun/util/resources/en/TimeZoneNames_en_IE.java @@ -47,7 +47,8 @@ public final class TimeZoneNames_en_IE extends TimeZoneNamesBundle { protected final Object[][] getContents() { return new Object[][] { {"Europe/London", new String[] {"Greenwich Mean Time", "GMT", - "Irish Summer Time", "IST" /*Dublin*/}}, + "Irish Summer Time", "IST", /*Dublin*/ + "Irish Time", "IT" /*Dublin*/}}, }; } } diff --git a/jdk/src/java.base/share/conf/security/java.security b/jdk/src/java.base/share/conf/security/java.security index 1d05aae8eba..b863516a481 100644 --- a/jdk/src/java.base/share/conf/security/java.security +++ b/jdk/src/java.base/share/conf/security/java.security @@ -533,4 +533,4 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024 # # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 -jdk.tls.disabledAlgorithms=SSLv3 +jdk.tls.disabledAlgorithms=SSLv3, RC4 diff --git a/jdk/src/java.base/unix/classes/java/lang/ProcessEnvironment.java b/jdk/src/java.base/unix/classes/java/lang/ProcessEnvironment.java index 08d260cf4a3..08e0ce4e053 100644 --- a/jdk/src/java.base/unix/classes/java/lang/ProcessEnvironment.java +++ b/jdk/src/java.base/unix/classes/java/lang/ProcessEnvironment.java @@ -99,7 +99,7 @@ final class ProcessEnvironment /* Only for use by Runtime.exec(...String[]envp...) */ static Map emptyEnvironment(int capacity) { - return new StringEnvironment(new HashMap(capacity)); + return new StringEnvironment(new HashMap<>(capacity)); } private static native byte[][] environ(); diff --git a/jdk/src/java.base/unix/classes/sun/net/PortConfig.java b/jdk/src/java.base/unix/classes/sun/net/PortConfig.java index 1825b0b59a0..eb2e4d57865 100644 --- a/jdk/src/java.base/unix/classes/sun/net/PortConfig.java +++ b/jdk/src/java.base/unix/classes/sun/net/PortConfig.java @@ -42,7 +42,7 @@ public final class PortConfig { static { AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public Void run() { System.loadLibrary("net"); String os = System.getProperty("os.name"); diff --git a/jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java b/jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java index 5af3d445e09..46fd008681e 100644 --- a/jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java +++ b/jdk/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java @@ -85,6 +85,15 @@ public class ResolverConfigurationImpl if (val.charAt(0) == '#' || val.charAt(0) == ';') { break; } + if ("nameserver".equals(keyword)) { + if (val.indexOf(':') >= 0 && + val.indexOf('.') < 0 && // skip for IPv4 literals with port + val.indexOf('[') < 0 && + val.indexOf(']') < 0 ) { + // IPv6 literal, in non-BSD-style. + val = "[" + val + "]"; + } + } ll.add(val); if (--maxvalues == 0) { break; @@ -122,7 +131,7 @@ public class ResolverConfigurationImpl // get the name servers from /etc/resolv.conf nameservers = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction>() { + new java.security.PrivilegedAction<>() { public LinkedList run() { // typically MAXNS is 3 but we've picked 5 here // to allow for additional servers if required. @@ -147,7 +156,7 @@ public class ResolverConfigurationImpl // first try the search keyword in /etc/resolv.conf sl = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction>() { + new java.security.PrivilegedAction<>() { public LinkedList run() { LinkedList ll; @@ -173,7 +182,7 @@ public class ResolverConfigurationImpl String localDomain = localDomain0(); if (localDomain != null && localDomain.length() > 0) { - sl = new LinkedList(); + sl = new LinkedList<>(); sl.add(localDomain); return sl; } @@ -181,7 +190,7 @@ public class ResolverConfigurationImpl // try domain keyword in /etc/resolv.conf sl = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction>() { + new java.security.PrivilegedAction<>() { public LinkedList run() { LinkedList ll; @@ -251,7 +260,7 @@ public class ResolverConfigurationImpl static { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public Void run() { System.loadLibrary("net"); return null; diff --git a/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java b/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java index ec974744419..2b1c3fd841e 100644 --- a/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java +++ b/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java @@ -198,7 +198,7 @@ public class SdpProvider extends NetHooks.Provider { { Scanner scanner = new Scanner(new File(file)); try { - List result = new ArrayList(); + List result = new ArrayList<>(); while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); diff --git a/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index 6211811e512..0c4523c19f1 100644 --- a/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -95,7 +95,7 @@ public class NTLMAuthentication extends AuthenticationInfo { private void init0() { hostname = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction<>() { public String run() { String localhost; try { diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java index 8c7cfd2291d..8dec1a3553d 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java @@ -216,7 +216,7 @@ class UnixAsynchronousServerSocketChannelImpl // permission check must always be in initiator's context try { if (acc != null) { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -287,7 +287,7 @@ class UnixAsynchronousServerSocketChannelImpl synchronized (updateLock) { if (handler == null) { this.acceptHandler = null; - result = new PendingFuture(this); + result = new PendingFuture<>(this); this.acceptFuture = result; } else { this.acceptHandler = handler; diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/GnomeFileTypeDetector.java b/jdk/src/java.base/unix/classes/sun/nio/fs/GnomeFileTypeDetector.java index f455afe2381..e579f176e2b 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/GnomeFileTypeDetector.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/GnomeFileTypeDetector.java @@ -93,7 +93,7 @@ public class GnomeFileTypeDetector private static native byte[] probeUsingGnomeVfs(long pathAddress); static { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { System.loadLibrary("nio"); return null; diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java b/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java index 8878703a343..b742b3f626f 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java @@ -106,7 +106,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector { synchronized (this) { if (!loaded) { List lines = AccessController.doPrivileged( - new PrivilegedAction>() { + new PrivilegedAction<>() { @Override public List run() { try { diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java index 399259c18c4..7a31ab186a6 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixCopyFile.java @@ -606,7 +606,7 @@ class UnixCopyFile { throws UnixException; static { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Void run() { System.loadLibrary("nio"); diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java index 98fc9abe054..e9c8fe110b0 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java @@ -222,7 +222,7 @@ abstract class UnixFileStore synchronized (loadLock) { if (props == null) { props = AccessController.doPrivileged( - new PrivilegedAction() { + new PrivilegedAction<>() { @Override public Properties run() { return loadProperties(); diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java index 3cdcd595f7f..d394ac10173 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java @@ -152,7 +152,7 @@ abstract class UnixFileSystem public final Iterable getRootDirectories() { final List allowedList = Collections.unmodifiableList(Arrays.asList((Path)rootDirectory)); - return new Iterable() { + return new Iterable<>() { public Iterator iterator() { try { SecurityManager sm = System.getSecurityManager(); @@ -254,7 +254,7 @@ abstract class UnixFileSystem return Collections.emptyList(); } } - return new Iterable() { + return new Iterable<>() { public Iterator iterator() { return new FileStoreIterator(); } diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java index 7a676d1863f..b84fa5c3861 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java @@ -568,7 +568,7 @@ class UnixNativeDispatcher { private static native int init(); static { - AccessController.doPrivileged(new PrivilegedAction() { + AccessController.doPrivileged(new PrivilegedAction<>() { public Void run() { System.loadLibrary("nio"); return null; diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java index b74a393e9b2..b219764d3e7 100644 --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixPath.java @@ -121,7 +121,7 @@ class UnixPath implements Path { ce = Util.jnuEncoding().newEncoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); - encoder.set(new SoftReference(ce)); + encoder.set(new SoftReference<>(ce)); } char[] ca = fs.normalizeNativePath(input.toCharArray()); diff --git a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java index eec35ea9518..28fc83a0b31 100644 --- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java +++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java @@ -40,6 +40,7 @@ import java.util.List; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import sun.misc.ManagedLocalsThread; /** * A multi-threaded implementation of Selector for Windows. @@ -403,7 +404,7 @@ final class WindowsSelectorImpl extends SelectorImpl { } // Represents a helper thread used for select. - private final class SelectThread extends Thread { + private final class SelectThread extends ManagedLocalsThread { private final int index; // index of this thread final SubSelector subSelector; private long lastRun = 0; // last run number diff --git a/jdk/src/java.base/windows/conf/security/java.policy b/jdk/src/java.base/windows/conf/security/java.policy index 01d7bef3f43..cff0be5af98 100644 --- a/jdk/src/java.base/windows/conf/security/java.policy +++ b/jdk/src/java.base/windows/conf/security/java.policy @@ -6,3 +6,7 @@ grant codeBase "jrt:/jdk.crypto.mscapi" { permission java.security.SecurityPermission "clearProviderProperties.SunMSCAPI"; permission java.security.SecurityPermission "removeProviderProperty.SunMSCAPI"; }; + +grant codeBase "jrt:/jdk.accessibility" { + permission java.security.AllPermission; +}; diff --git a/jdk/src/java.base/windows/native/launcher/java.manifest b/jdk/src/java.base/windows/native/launcher/java.manifest index 52f997e8b39..906624bd6fa 100644 --- a/jdk/src/java.base/windows/native/launcher/java.manifest +++ b/jdk/src/java.base/windows/native/launcher/java.manifest @@ -4,12 +4,12 @@ xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" > -Java(TM) SE PROGRAM process +Java(TM) SE process = 6; + if (dtzi.TimeZoneKeyName[0] != 0) { + if (dtzi.DynamicDaylightTimeDisabled) { + customZoneName(dtzi.Bias, winZoneName); + return VALUE_GMTOFFSET; + } + wcstombs(winZoneName, dtzi.TimeZoneKeyName, MAX_ZONE_CHAR); + return VALUE_KEY; + } - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0, - KEY_READ, (PHKEY)&hKey); - if (ret == ERROR_SUCCESS) { - DWORD val; - DWORD bufSize; + /* + * If TimeZoneKeyName is not available, check whether StandardName + * is available to fall back to the older API GetTimeZoneInformation. + * If not, directly read the value from registry keys. + */ + if (dtzi.StandardName[0] == 0) { + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0, + KEY_READ, (PHKEY)&hKey); + if (ret != ERROR_SUCCESS) { + goto err; + } /* * Determine if auto-daylight time adjustment is turned off. */ - valueType = 0; bufSize = sizeof(val); - ret = RegQueryValueExA(hKey, "DisableAutoDaylightTimeSet", - NULL, &valueType, (LPBYTE) &val, &bufSize); - /* - * Vista uses the different key name. - */ + ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL, + &valueType, (LPBYTE) &val, &bufSize); if (ret != ERROR_SUCCESS) { - bufSize = sizeof(val); - ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", - NULL, &valueType, (LPBYTE) &val, &bufSize); + goto err; } - - if (ret == ERROR_SUCCESS) { - int daylightSavingsUpdateDisabledOther = val == 1 && tzi.DaylightDate.wMonth != 0; - int daylightSavingsUpdateDisabledVista = val == 1; - int daylightSavingsUpdateDisabled = isVista ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther; - - if (daylightSavingsUpdateDisabled) { - (void) RegCloseKey(hKey); - customZoneName(tzi.Bias, winZoneName); - return VALUE_GMTOFFSET; - } - } - /* - * Vista has the key for the current "Time Zones" entry. + * Return a custom time zone name if auto-daylight time adjustment + * is disabled. */ - if (isVista) { - valueType = 0; - bufSize = MAX_ZONE_CHAR; - ret = RegQueryValueExA(hKey, "TimeZoneKeyName", NULL, - &valueType, (LPBYTE) winZoneName, &bufSize); - if (ret != ERROR_SUCCESS) { - goto err; - } + if (val == 1) { + customZoneName(dtzi.Bias, winZoneName); (void) RegCloseKey(hKey); - return VALUE_KEY; + return VALUE_GMTOFFSET; } - /* - * Win32 problem: If the length of the standard time name is equal - * to (or probably longer than) 32 in the registry, - * GetTimeZoneInformation() on NT returns a null string as its - * standard time name. We need to work around this problem by - * getting the same information from the TimeZoneInformation - * registry. The function on Win98 seems to return its key name. - * We can't do anything in that case. - */ - if (tzi.StandardName[0] == 0) { - bufSize = sizeof(stdNameInReg); - ret = getValueInRegistry(hKey, STANDARD_NAME, &valueType, - (LPBYTE) stdNameInReg, &bufSize); - if (ret != ERROR_SUCCESS) { - goto err; - } - stdNamePtr = stdNameInReg; + bufSize = MAX_ZONE_CHAR; + ret = RegQueryValueExA(hKey, "TimeZoneKeyName", NULL, + &valueType, (LPBYTE) winZoneName, &bufSize); + if (ret != ERROR_SUCCESS) { + goto err; } (void) RegCloseKey(hKey); - } - - /* - * Open the "Time Zones" registry. - */ - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NT_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey); - if (ret != ERROR_SUCCESS) { - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey); + return VALUE_KEY; + } else { /* - * If both failed, then give up. + * Fall back to GetTimeZoneInformation */ - if (ret != ERROR_SUCCESS) { - return VALUE_UNKNOWN; - } - } + TIME_ZONE_INFORMATION tzi; + HANDLE hSubKey = NULL; + DWORD nSubKeys, i; + ULONG valueType; + TCHAR subKeyName[MAX_ZONE_CHAR]; + TCHAR szValue[MAX_ZONE_CHAR]; + WCHAR stdNameInReg[MAX_ZONE_CHAR]; + TziValue tempTzi; + WCHAR *stdNamePtr = tzi.StandardName; + DWORD valueSize; + int onlyMapID; - /* - * Get the number of subkeys of the "Time Zones" registry for - * enumeration. - */ - ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, &nSubKeys, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if (ret != ERROR_SUCCESS) { - goto err; - } - - /* - * Compare to the "Std" value of each subkey and find the entry that - * matches the current control panel setting. - */ - onlyMapID = 0; - for (i = 0; i < nSubKeys; ++i) { - DWORD size = sizeof(subKeyName); - ret = RegEnumKeyEx(hKey, i, subKeyName, &size, NULL, NULL, NULL, NULL); - if (ret != ERROR_SUCCESS) { - goto err; - } - ret = RegOpenKeyEx(hKey, subKeyName, 0, KEY_READ, (PHKEY)&hSubKey); - if (ret != ERROR_SUCCESS) { + timeType = GetTimeZoneInformation(&tzi); + if (timeType == TIME_ZONE_ID_INVALID) { goto err; } - size = sizeof(szValue); - ret = getValueInRegistry(hSubKey, STD_NAME, &valueType, - szValue, &size); - if (ret != ERROR_SUCCESS) { + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0, + KEY_READ, (PHKEY)&hKey); + if (ret == ERROR_SUCCESS) { /* - * NT 4.0 SP3 fails here since it doesn't have the "Std" - * entry in the Time Zones registry. + * Determine if auto-daylight time adjustment is turned off. */ - RegCloseKey(hSubKey); - onlyMapID = 1; - ret = RegOpenKeyExW(hKey, stdNamePtr, 0, KEY_READ, (PHKEY)&hSubKey); + bufSize = sizeof(val); + ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL, + &valueType, (LPBYTE) &val, &bufSize); + if (ret == ERROR_SUCCESS) { + if (val == 1 && tzi.DaylightDate.wMonth != 0) { + (void) RegCloseKey(hKey); + customZoneName(tzi.Bias, winZoneName); + return VALUE_GMTOFFSET; + } + } + + /* + * Win32 problem: If the length of the standard time name is equal + * to (or probably longer than) 32 in the registry, + * GetTimeZoneInformation() on NT returns a null string as its + * standard time name. We need to work around this problem by + * getting the same information from the TimeZoneInformation + * registry. + */ + if (tzi.StandardName[0] == 0) { + bufSize = sizeof(stdNameInReg); + ret = getValueInRegistry(hKey, STANDARD_NAME, &valueType, + (LPBYTE) stdNameInReg, &bufSize); + if (ret != ERROR_SUCCESS) { + goto err; + } + stdNamePtr = stdNameInReg; + } + (void) RegCloseKey(hKey); + } + + /* + * Open the "Time Zones" registry. + */ + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NT_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey); + if (ret != ERROR_SUCCESS) { + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_TZ_KEY, 0, KEY_READ, (PHKEY)&hKey); + /* + * If both failed, then give up. + */ + if (ret != ERROR_SUCCESS) { + return VALUE_UNKNOWN; + } + } + + /* + * Get the number of subkeys of the "Time Zones" registry for + * enumeration. + */ + ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, &nSubKeys, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) { + goto err; + } + + /* + * Compare to the "Std" value of each subkey and find the entry that + * matches the current control panel setting. + */ + onlyMapID = 0; + for (i = 0; i < nSubKeys; ++i) { + DWORD size = sizeof(subKeyName); + ret = RegEnumKeyEx(hKey, i, subKeyName, &size, NULL, NULL, NULL, NULL); + if (ret != ERROR_SUCCESS) { + goto err; + } + ret = RegOpenKeyEx(hKey, subKeyName, 0, KEY_READ, (PHKEY)&hSubKey); if (ret != ERROR_SUCCESS) { goto err; } - break; - } - if (wcscmp((WCHAR *)szValue, stdNamePtr) == 0) { - /* - * Some localized Win32 platforms use a same name to - * different time zones. So, we can't rely only on the name - * here. We need to check GMT offsets and transition dates - * to make sure it's the registry of the current time - * zone. - */ - DWORD tziValueSize = sizeof(tempTzi); - ret = RegQueryValueEx(hSubKey, "TZI", NULL, &valueType, - (unsigned char *) &tempTzi, &tziValueSize); - if (ret == ERROR_SUCCESS) { - if ((tzi.Bias != tempTzi.bias) || - (memcmp((const void *) &tzi.StandardDate, - (const void *) &tempTzi.stdDate, - sizeof(SYSTEMTIME)) != 0)) { - goto out; + size = sizeof(szValue); + ret = getValueInRegistry(hSubKey, STD_NAME, &valueType, + szValue, &size); + if (ret != ERROR_SUCCESS) { + /* + * NT 4.0 SP3 fails here since it doesn't have the "Std" + * entry in the Time Zones registry. + */ + RegCloseKey(hSubKey); + onlyMapID = 1; + ret = RegOpenKeyExW(hKey, stdNamePtr, 0, KEY_READ, (PHKEY)&hSubKey); + if (ret != ERROR_SUCCESS) { + goto err; } + break; + } - if (tzi.DaylightBias != 0) { - if ((tzi.DaylightBias != tempTzi.dstBias) || - (memcmp((const void *) &tzi.DaylightDate, - (const void *) &tempTzi.dstDate, + if (wcscmp((WCHAR *)szValue, stdNamePtr) == 0) { + /* + * Some localized Win32 platforms use a same name to + * different time zones. So, we can't rely only on the name + * here. We need to check GMT offsets and transition dates + * to make sure it's the registry of the current time + * zone. + */ + DWORD tziValueSize = sizeof(tempTzi); + ret = RegQueryValueEx(hSubKey, "TZI", NULL, &valueType, + (unsigned char *) &tempTzi, &tziValueSize); + if (ret == ERROR_SUCCESS) { + if ((tzi.Bias != tempTzi.bias) || + (memcmp((const void *) &tzi.StandardDate, + (const void *) &tempTzi.stdDate, sizeof(SYSTEMTIME)) != 0)) { goto out; } + + if (tzi.DaylightBias != 0) { + if ((tzi.DaylightBias != tempTzi.dstBias) || + (memcmp((const void *) &tzi.DaylightDate, + (const void *) &tempTzi.dstDate, + sizeof(SYSTEMTIME)) != 0)) { + goto out; + } + } } + + /* + * found matched record, terminate search + */ + strcpy(winZoneName, subKeyName); + break; } - - /* - * found matched record, terminate search - */ - strcpy(winZoneName, subKeyName); - break; + out: + (void) RegCloseKey(hSubKey); } - out: - (void) RegCloseKey(hSubKey); - } - /* - * Get the "MapID" value of the registry to be able to eliminate - * duplicated key names later. - */ - valueSize = MAX_MAPID_LENGTH; - ret = RegQueryValueExA(hSubKey, "MapID", NULL, &valueType, winMapID, &valueSize); - (void) RegCloseKey(hSubKey); - (void) RegCloseKey(hKey); - - if (ret != ERROR_SUCCESS) { /* - * Vista doesn't have mapID. VALUE_UNKNOWN should be returned - * only for Windows NT. + * Get the "MapID" value of the registry to be able to eliminate + * duplicated key names later. */ - if (onlyMapID == 1) { - return VALUE_UNKNOWN; + valueSize = MAX_MAPID_LENGTH; + ret = RegQueryValueExA(hSubKey, "MapID", NULL, &valueType, winMapID, &valueSize); + (void) RegCloseKey(hSubKey); + (void) RegCloseKey(hKey); + + if (ret != ERROR_SUCCESS) { + /* + * Vista doesn't have mapID. VALUE_UNKNOWN should be returned + * only for Windows NT. + */ + if (onlyMapID == 1) { + return VALUE_UNKNOWN; + } } } diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java index b0713215077..7aa82f51a9e 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java @@ -25,15 +25,16 @@ package com.apple.laf; + import java.beans.*; import java.io.File; import java.util.*; - import javax.swing.*; import javax.swing.event.ListDataEvent; import javax.swing.filechooser.FileSystemView; import javax.swing.table.AbstractTableModel; +import sun.misc.ManagedLocalsThread; /** * NavServices-like implementation of a file Table * @@ -42,7 +43,7 @@ import javax.swing.table.AbstractTableModel; @SuppressWarnings("serial") // Superclass is not serializable across versions class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeListener { private final JTable fFileList; - private LoadFilesThread loadThread = null; + private FilesLoader filesLoader = null; private Vector files = null; JFileChooser filechooser = null; @@ -141,9 +142,9 @@ class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeLi public void runWhenDone(final Runnable runnable){ synchronized (fileCacheLock) { - if (loadThread != null) { - if (loadThread.isAlive()) { - loadThread.queuedTasks.add(runnable); + if (filesLoader != null) { + if (filesLoader.loadThread.isAlive()) { + filesLoader.queuedTasks.add(runnable); return; } } @@ -160,9 +161,9 @@ class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeLi return; } - if (loadThread != null) { + if (filesLoader != null) { // interrupt - loadThread.interrupt(); + filesLoader.loadThread.interrupt(); } fetchID++; @@ -173,8 +174,7 @@ class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeLi fileCache = new Vector(50); } - loadThread = new LoadFilesThread(currentDirectory, fetchID); - loadThread.start(); + filesLoader = new FilesLoader(currentDirectory, fetchID); } public int getColumnCount() { @@ -373,17 +373,25 @@ class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeLi } } - class LoadFilesThread extends Thread { - Vector queuedTasks = new Vector(); + class FilesLoader implements Runnable { + Vector queuedTasks = new Vector<>(); File currentDirectory = null; int fid; + Thread loadThread; - public LoadFilesThread(final File currentDirectory, final int fid) { - super("Aqua L&F File Loading Thread"); + public FilesLoader(final File currentDirectory, final int fid) { this.currentDirectory = currentDirectory; this.fid = fid; + String name = "Aqua L&F File Loading Thread"; + if (System.getSecurityManager() == null) { + this.loadThread = new Thread(FilesLoader.this, name); + } else { + this.loadThread = new ManagedLocalsThread(FilesLoader.this, name); + } + this.loadThread.start(); } + @Override public void run() { final Vector runnables = new Vector(10); final FileSystemView fileSystem = filechooser.getFileSystemView(); @@ -415,7 +423,7 @@ class AquaFileSystemModel extends AbstractTableModel implements PropertyChangeLi runnables.addElement(runnable); SwingUtilities.invokeLater(runnable); chunk = new Vector(10); - if (isInterrupted()) { + if (loadThread.isInterrupted()) { // interrupted, cancel all runnables cancelRunnables(runnables); return; diff --git a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollPaneUI.java b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollPaneUI.java index ee0bf7cdf54..0729321552d 100644 --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollPaneUI.java +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaScrollPaneUI.java @@ -29,6 +29,7 @@ import java.awt.event.*; import javax.swing.*; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicScrollPaneUI; public class AquaScrollPaneUI extends javax.swing.plaf.basic.BasicScrollPaneUI { public static ComponentUI createUI(final JComponent x) { @@ -39,28 +40,9 @@ public class AquaScrollPaneUI extends javax.swing.plaf.basic.BasicScrollPaneUI { return new XYMouseWheelHandler(); } - // This is a grody hack to trick BasicScrollPaneUI into scrolling horizontally - // when we notice that the shift key is down. This should be removed when AWT/Swing - // becomes aware of multi-axis scroll wheels. - protected class XYMouseWheelHandler extends javax.swing.plaf.basic.BasicScrollPaneUI.MouseWheelHandler { + protected class XYMouseWheelHandler extends BasicScrollPaneUI.MouseWheelHandler { public void mouseWheelMoved(final MouseWheelEvent e) { - JScrollBar vScrollBar = null; - boolean wasVisible = false; - - if (e.isShiftDown()) { - vScrollBar = scrollpane.getVerticalScrollBar(); - if (vScrollBar != null) { - wasVisible = vScrollBar.isVisible(); - vScrollBar.setVisible(false); - } - } - super.mouseWheelMoved(e); - - if (wasVisible) { - vScrollBar.setVisible(true); - } - // Consume the event even when the scrollBar is invisible // see #7124320 e.consume(); diff --git a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java index 272999ee6b9..341af9ff347 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java +++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java @@ -42,6 +42,7 @@ import sun.awt.FontConfiguration; import sun.awt.HeadlessToolkit; import sun.awt.util.ThreadGroupUtils; import sun.lwawt.macosx.*; +import sun.misc.InnocuousThread; public final class CFontManager extends SunFontManager { private static Hashtable genericFonts = new Hashtable(); @@ -211,14 +212,18 @@ public final class CFontManager extends SunFontManager { }); } }; - AccessController.doPrivileged( - (PrivilegedAction) () -> { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - fileCloser = new Thread(rootTG, fileCloserRunnable); + AccessController.doPrivileged((PrivilegedAction) () -> { + if (System.getSecurityManager() == null) { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + fileCloser = new Thread(rootTG, fileCloserRunnable); + } else { + /* InnocuousThread is a member of a correct TG by default */ + fileCloser = new InnocuousThread(fileCloserRunnable); + } fileCloser.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(fileCloser); return null; diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWCheckboxPeer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWCheckboxPeer.java index c3b91a2fa86..fe85cce8081 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWCheckboxPeer.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWCheckboxPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,7 +132,9 @@ final class LWCheckboxPeer @Override public void setState(final boolean state) { synchronized (getDelegateLock()) { + getDelegate().getCurrentButton().removeItemListener(this); getDelegate().setSelected(state); + getDelegate().getCurrentButton().addItemListener(this); } repaintPeer(); } diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java index 315a19a7ff3..9aea94cdc6c 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java @@ -35,6 +35,7 @@ import java.security.*; import java.util.*; import sun.awt.*; +import sun.misc.InnocuousThread; import sun.print.*; import sun.awt.util.ThreadGroupUtils; @@ -71,22 +72,32 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { */ protected final void init() { AWTAutoShutdown.notifyToolkitThreadBusy(); - - ThreadGroup rootTG = AccessController.doPrivileged( - (PrivilegedAction) ThreadGroupUtils::getRootThreadGroup); - - Runtime.getRuntime().addShutdownHook( - new Thread(rootTG, () -> { + AccessController.doPrivileged((PrivilegedAction) () -> { + Runnable shutdownRunnable = () -> { shutdown(); waitForRunState(STATE_CLEANUP); - }) - ); - - Thread toolkitThread = new Thread(rootTG, this, "AWT-LW"); - toolkitThread.setDaemon(true); - toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); - toolkitThread.start(); + }; + Thread shutdown; + if (System.getSecurityManager() == null) { + shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable); + } else { + shutdown = new InnocuousThread(shutdownRunnable); + } + shutdown.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdown); + String name = "AWT-LW"; + Thread toolkitThread; + if (System.getSecurityManager() == null) { + toolkitThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), LWToolkit.this, name); + } else { + toolkitThread = new InnocuousThread(LWToolkit.this, name); + } + toolkitThread.setDaemon(true); + toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); + toolkitThread.start(); + return null; + }); waitForRunState(STATE_MESSAGELOOP); } diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java index 386c8c7bb7f..d8656c58750 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -1296,6 +1296,12 @@ public class LWWindowPeer } KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); + + if (!becomesFocused && kfmPeer.getCurrentFocusedWindow() != getTarget()) { + // late window focus lost event - ingoring + return; + } + kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null); int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS; diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CClipboard.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CClipboard.java index b657aee8ed9..19f9a408220 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CClipboard.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CClipboard.java @@ -56,6 +56,18 @@ final class CClipboard extends SunClipboard { // Leaving Empty, as WClipboard.clearNativeContext is empty as well. } + @Override + public synchronized Transferable getContents(Object requestor) { + checkPasteboardAndNotify(); + return super.getContents(requestor); + } + + @Override + protected synchronized Transferable getContextContents() { + checkPasteboardAndNotify(); + return super.getContextContents(); + } + @Override protected void setContentsNative(Transferable contents) { FlavorTable flavorMap = getDefaultFlavorTable(); @@ -116,13 +128,20 @@ final class CClipboard extends SunClipboard { private native void declareTypes(long[] formats, SunClipboard newOwner); private native void setData(byte[] data, long format); + void checkPasteboardAndNotify() { + if (checkPasteboardWithoutNotification()) { + notifyChanged(); + lostOwnershipNow(null); + } + } + /** * Invokes native check whether a change count on the general pasteboard is different * than when we set it. The different count value means the current owner lost * pasteboard ownership and someone else put data on the clipboard. * @since 1.7 */ - native void checkPasteboard(); + native boolean checkPasteboardWithoutNotification(); /*** Native Callbacks ***/ private void notifyLostOwnership() { diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java index 20c48cd4133..0f4224bb803 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java @@ -31,7 +31,6 @@ import java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.event.*; import java.awt.image.*; -import java.awt.peer.*; import javax.swing.*; import javax.swing.text.*; @@ -44,6 +43,7 @@ import sun.awt.dnd.*; import sun.lwawt.LWComponentPeer; import sun.lwawt.LWWindowPeer; import sun.lwawt.PlatformWindow; +import sun.misc.ManagedLocalsThread; public final class CDragSourceContextPeer extends SunDragSourceContextPeer { @@ -164,28 +164,29 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { // are posted during dragging by native event handlers. try { - Thread dragThread = new Thread() { - public void run() { - final long nativeDragSource = getNativeContext(); - try { - doDragging(nativeDragSource); - } catch (Exception e) { - e.printStackTrace(); - } finally { - releaseNativeDragSource(nativeDragSource); - fDragImage = null; - if (fDragCImage != null) { - fDragCImage.dispose(); - fDragCImage = null; - } + Runnable dragRunnable = () -> { + final long nativeDragSource = getNativeContext(); + try { + doDragging(nativeDragSource); + } catch (Exception e) { + e.printStackTrace(); + } finally { + releaseNativeDragSource(nativeDragSource); + fDragImage = null; + if (fDragCImage != null) { + fDragCImage.dispose(); + fDragCImage = null; } } }; - + Thread dragThread; + if (System.getSecurityManager() == null) { + dragThread = new Thread(dragRunnable); + } else { + dragThread = new ManagedLocalsThread(dragRunnable); + } dragThread.start(); - } - - catch (Exception e) { + } catch (Exception e) { final long nativeDragSource = getNativeContext(); setNativeContext(0); releaseNativeDragSource(nativeDragSource); diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java index fed9957502a..e1895c2e2f0 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java @@ -123,7 +123,7 @@ public class CEmbeddedFrame extends EmbeddedFrame { // it won't be invoced if focuse is moved to a html element // on the same page. CClipboard clipboard = (CClipboard) Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.checkPasteboard(); + clipboard.checkPasteboardAndNotify(); } if (parentWindowActive) { responder.handleWindowFocusEvent(focused, null); @@ -164,7 +164,7 @@ public class CEmbeddedFrame extends EmbeddedFrame { } // ignore focus "lost" native request as it may mistakenly // deactivate active window (see 8001161) - if (globalFocusedWindow == this && parentWindowActive) { + if (globalFocusedWindow == this) { responder.handleWindowFocusEvent(parentWindowActive, null); } } diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java index cc31b532f76..0e8ee1e1fc4 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java @@ -37,6 +37,7 @@ import java.io.*; import sun.awt.CausedFocusEvent.Cause; import sun.awt.AWTAccessor; import sun.java2d.pipe.Region; +import sun.misc.ManagedLocalsThread; import sun.security.action.GetBooleanAction; class CFileDialog implements FileDialogPeer { @@ -119,7 +120,11 @@ class CFileDialog implements FileDialogPeer { if (visible) { // Java2 Dialog class requires peer to run code in a separate thread // and handles keeping the call modal - new Thread(new Task()).start(); // invokes my 'run' method, below... + if (System.getSecurityManager() == null) { + new Thread(new Task()).start(); + } else { + new ManagedLocalsThread(new Task()).start(); + } } // We hide ourself before "show" returns - setVisible(false) // doesn't apply diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java index 8dfe7e1e51e..6ff3ec01e0e 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java @@ -29,6 +29,7 @@ import java.awt.*; import java.awt.dnd.*; import sun.lwawt.*; +import sun.misc.ManagedLocalsThread; public class CPrinterDialogPeer extends LWWindowPeer { static { @@ -53,13 +54,16 @@ public class CPrinterDialogPeer extends LWWindowPeer { public void setVisible(boolean visible) { if (visible) { - new Thread(new Runnable() { - public void run() { - CPrinterDialog printerDialog = (CPrinterDialog)fTarget; - printerDialog.setRetVal(printerDialog.showDialog()); - printerDialog.setVisible(false); - } - }).start(); + Runnable task = () -> { + CPrinterDialog printerDialog = (CPrinterDialog)fTarget; + printerDialog.setRetVal(printerDialog.showDialog()); + printerDialog.setVisible(false); + }; + if (System.getSecurityManager() == null) { + new Thread(task).start(); + } else { + new ManagedLocalsThread(task).start(); + } } } diff --git a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index ede3bec7b73..b82094d5b7d 100644 --- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -39,6 +39,7 @@ import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.standard.PageRanges; import sun.java2d.*; +import sun.misc.ManagedLocalsThread; import sun.print.*; public final class CPrinterJob extends RasterPrinterJob { @@ -731,9 +732,12 @@ public final class CPrinterJob extends RasterPrinterJob { // upcall from native private static void detachPrintLoop(final long target, final long arg) { - new Thread() { public void run() { - _safePrintLoop(target, arg); - }}.start(); + Runnable task = () -> _safePrintLoop(target, arg); + if (System.getSecurityManager() == null) { + new Thread(task).start(); + } else { + new ManagedLocalsThread(task).start(); + } } private static native void _safePrintLoop(long target, long arg); diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m index 15ae6db79dc..fceb2d72682 100644 --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m @@ -107,6 +107,19 @@ } } +- (BOOL) checkPasteboardWithoutNotification:(id)application { + AWT_ASSERT_APPKIT_THREAD; + + NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount]; + + if (self.changeCount != newChangeCount) { + self.changeCount = newChangeCount; + return YES; + } else { + return NO; + } +} + @end /* @@ -260,21 +273,20 @@ JNF_COCOA_EXIT(env); return returnValue; } -/* - * Class: sun_lwawt_macosx_CClipboard - * Method: checkPasteboard - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard -(JNIEnv *env, jobject inObject ) -{ -JNF_COCOA_ENTER(env); - - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - [[CClipboard sharedClipboard] checkPasteboard:nil]; - }]; - -JNF_COCOA_EXIT(env); -} - - +/* + * Class: sun_lwawt_macosx_CClipboard + * Method: checkPasteboard + * Signature: ()V + */ +JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboardWithoutNotification +(JNIEnv *env, jobject inObject) +{ + __block BOOL ret = NO; + JNF_COCOA_ENTER(env); + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + ret = [[CClipboard sharedClipboard] checkPasteboardWithoutNotification:nil]; + }]; + + JNF_COCOA_EXIT(env); + return ret; +} \ No newline at end of file diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java index 356c0c092f9..b660f272e2c 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java +++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java @@ -25,7 +25,12 @@ package com.sun.imageio.stream; +import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; + import java.io.IOException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Set; import java.util.WeakHashMap; import javax.imageio.stream.ImageInputStream; @@ -81,27 +86,25 @@ public class StreamCloser { } }; - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup tg = - Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - streamCloser = new Thread(tg, streamCloserRunnable); - /* Set context class loader to null in order to avoid - * keeping a strong reference to an application classloader. - */ - streamCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(streamCloser); - return null; - } - }); + AccessController.doPrivileged((PrivilegedAction) () -> { + if (System.getSecurityManager() == null) { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup tg = ThreadGroupUtils.getRootThreadGroup(); + streamCloser = new Thread(tg, streamCloserRunnable); + } else { + /* InnocuousThread is a member of a correct TG by default */ + streamCloser = new InnocuousThread(streamCloserRunnable); + } + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + streamCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(streamCloser); + return null; + }); } } } diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java index 16eef680706..82708f571e5 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsDesktopManager.java @@ -68,7 +68,7 @@ public class WindowsDesktopManager extends DefaultDesktopManager if (currentFrame != null && f != currentFrame) { // If the current frame is maximized, transfer that // attribute to the frame being activated. - if (currentFrame.isMaximum() && + if (!currentFrame.isClosed() && currentFrame.isMaximum() && (f.getClientProperty("JInternalFrame.frameType") != "optionDialog") ) { //Special case. If key binding was used to select next diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java index ee81a15f637..0a666b12e25 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java @@ -64,6 +64,7 @@ import sun.awt.SunToolkit; import sun.awt.OSInfo; import sun.awt.shell.ShellFolder; import sun.font.FontUtilities; +import sun.misc.ManagedLocalsThread; import sun.security.action.GetPropertyAction; import sun.swing.DefaultLayoutStyle; @@ -2037,7 +2038,11 @@ public class WindowsLookAndFeel extends BasicLookAndFeel if (audioRunnable != null) { // Runnable appears to block until completed playing, hence // start up another thread to handle playing. - new Thread(audioRunnable).start(); + if (System.getSecurityManager() == null) { + new Thread(audioRunnable).start(); + } else { + new ManagedLocalsThread(audioRunnable).start(); + } } } } diff --git a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java index ec505959a31..347f2943155 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java +++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java @@ -197,6 +197,10 @@ public class WindowsRootPaneUI extends BasicRootPaneUI { root = null; winAncestor = null; } else { + if (WindowsLookAndFeel.isMnemonicHidden() && ev.isAltDown()) { + WindowsLookAndFeel.setMnemonicHidden(false); + WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); + } altKeyPressed = false; } return false; diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java index 8382f15e8c2..63eaba1c4ec 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -25,6 +25,9 @@ package com.sun.media.sound; +import sun.misc.InnocuousThread; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedInputStream; import java.io.InputStream; import java.io.File; @@ -144,7 +147,13 @@ final class JSSecurityManager { final String threadName, final boolean isDaemon, final int priority, final boolean doStart) { - Thread thread = new Thread(runnable); + Thread thread; + if (System.getSecurityManager() == null) { + thread = new Thread(runnable); + } else { + thread = new ManagedLocalsThread(runnable); + } + if (threadName != null) { thread.setName(threadName); } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java index 1a07a23ec6f..a5fdd4e9f86 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java @@ -24,6 +24,8 @@ */ package com.sun.media.sound; +import sun.misc.ManagedLocalsThread; + import java.io.IOException; import javax.sound.sampled.AudioInputStream; @@ -53,7 +55,11 @@ public final class SoftAudioPusher implements Runnable { if (active) return; active = true; - audiothread = new Thread(this); + if (System.getSecurityManager() == null) { + audiothread = new Thread(this); + } else { + audiothread = new ManagedLocalsThread(this); + } audiothread.setDaemon(true); audiothread.setPriority(Thread.MAX_PRIORITY); audiothread.start(); diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java index 0f5ff294574..85c615e1801 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java @@ -24,12 +24,13 @@ */ package com.sun.media.sound; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; +import sun.misc.ManagedLocalsThread; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; /** * A jitter corrector to be used with SoftAudioPusher. @@ -215,7 +216,11 @@ public final class SoftJitterCorrector extends AudioInputStream { } }; - thread = new Thread(runnable); + if (System.getSecurityManager() == null) { + thread = new Thread(runnable); + } else { + thread = new ManagedLocalsThread(runnable); + } thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); thread.start(); diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java index e895ead074f..81c33ff788b 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java @@ -25,6 +25,8 @@ package com.sun.media.sound; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -139,7 +141,11 @@ public final class SoftSynthesizer implements AudioSynthesizer, pusher = null; jitter_stream = null; sourceDataLine = null; - new Thread(runnable).start(); + if (System.getSecurityManager() == null) { + new Thread(runnable).start(); + } else { + new ManagedLocalsThread(runnable).start(); + } } return len; } diff --git a/jdk/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java b/jdk/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java index 01e42428a73..8297188f1f9 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java +++ b/jdk/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1088,6 +1088,7 @@ public class AWTEventMulticaster implements * contains only the specified listener. If no such listeners are chained, * this method returns an empty array. * + * @param the listener type * @param l the specified java.util.EventListener * @param listenerType the type of listeners requested; this parameter * should specify an interface that descends from diff --git a/jdk/src/java.desktop/share/classes/java/awt/Component.java b/jdk/src/java.desktop/share/classes/java/awt/Component.java index a5e8dfee50c..72e473d8465 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Component.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java @@ -4316,9 +4316,12 @@ public abstract class Component implements ImageObserver, MenuContainer, */ protected boolean validatedContents; // = false /** - * Size of the back buffers + * Width of the back buffers */ protected int width; + /** + * Height of the back buffers + */ protected int height; /** @@ -6013,6 +6016,7 @@ public abstract class Component implements ImageObserver, MenuContainer, * * If no such listeners exist, this method returns an empty array. * + * @param the type of the listeners * @param listenerType the type of listeners requested; this parameter * should specify an interface that descends from * java.util.EventListener diff --git a/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java b/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java index 5bf91e6ab8c..dd9ea860ec2 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java +++ b/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java @@ -30,6 +30,8 @@ import java.awt.event.ActionEvent; import java.awt.event.WindowEvent; import java.util.ArrayList; + +import sun.misc.ManagedLocalsThread; import sun.util.logging.PlatformLogger; import sun.awt.dnd.SunDragSourceContextPeer; @@ -53,7 +55,7 @@ import sun.awt.dnd.SunDragSourceContextPeer; * * @since 1.1 */ -class EventDispatchThread extends Thread { +class EventDispatchThread extends ManagedLocalsThread { private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread"); @@ -65,7 +67,7 @@ class EventDispatchThread extends Thread { private ArrayList eventFilters = new ArrayList(); EventDispatchThread(ThreadGroup group, String name, EventQueue queue) { - super(group, name); + super(group, null, name); setEventQueue(queue); } diff --git a/jdk/src/java.desktop/share/classes/java/awt/GridBagLayout.java b/jdk/src/java.desktop/share/classes/java/awt/GridBagLayout.java index 1624700353f..7c86dcc1f67 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/GridBagLayout.java +++ b/jdk/src/java.desktop/share/classes/java/awt/GridBagLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -353,7 +353,7 @@ import java.util.Arrays; * } * } *
                                  - *

                                  + * * @author Doug Stein * @author Bill Spitzak (orignial NeWS & OLIT implementation) * @see java.awt.GridBagConstraints @@ -770,7 +770,7 @@ java.io.Serializable { * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered, etc. - *

                                  + * * @return the value 0.5f to indicate centered */ public float getLayoutAlignmentX(Container parent) { @@ -783,7 +783,7 @@ java.io.Serializable { * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered, etc. - *

                                  + * * @return the value 0.5f to indicate centered */ public float getLayoutAlignmentY(Container parent) { diff --git a/jdk/src/java.desktop/share/classes/java/awt/MenuComponent.java b/jdk/src/java.desktop/share/classes/java/awt/MenuComponent.java index 64b1db9bf06..f9f9f28da0d 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/MenuComponent.java +++ b/jdk/src/java.desktop/share/classes/java/awt/MenuComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -328,6 +328,7 @@ public abstract class MenuComponent implements java.io.Serializable { * Its use is discouraged, and it may not be supported * in the future. * @param evt the event which is to take place + * @return unconditionally returns false * @deprecated As of JDK version 1.1, replaced by {@link * #dispatchEvent(AWTEvent) dispatchEvent}. */ diff --git a/jdk/src/java.desktop/share/classes/java/awt/MenuContainer.java b/jdk/src/java.desktop/share/classes/java/awt/MenuContainer.java index 8ba5e70245b..995c7d4ceb6 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/MenuContainer.java +++ b/jdk/src/java.desktop/share/classes/java/awt/MenuContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,6 +50,7 @@ public interface MenuContainer { * Posts an event to the listeners. * * @param evt the event to dispatch + * @return the results of posting the event * @deprecated As of JDK version 1.1 * replaced by dispatchEvent(AWTEvent). */ diff --git a/jdk/src/java.desktop/share/classes/java/awt/MenuItem.java b/jdk/src/java.desktop/share/classes/java/awt/MenuItem.java index ab797f4dd1a..e70ec305cdf 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/MenuItem.java +++ b/jdk/src/java.desktop/share/classes/java/awt/MenuItem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -595,6 +595,7 @@ public class MenuItem extends MenuComponent implements Accessible { * * If no such listeners exist, this method returns an empty array. * + * @param the type of the listeners * @param listenerType the type of listeners requested; this parameter * should specify an interface that descends from * java.util.EventListener diff --git a/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java b/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java index 985c946f422..9b3ad9b5777 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1766,6 +1766,7 @@ public abstract class Toolkit { * * subclasses should override this to provide their own implementation * + * @param the type of DragGestureRecognizer to create * @param abstractRecognizerClass The abstract class of the required recognizer * @param ds The DragSource * @param c The Component target for the DragGestureRecognizer @@ -1867,7 +1868,9 @@ public abstract class Toolkit { } /** - * an opportunity to lazily evaluate desktop property values. + * An opportunity to lazily evaluate desktop property values. + * @return the desktop property or null + * @param name the name */ protected Object lazilyLoadDesktopProperty(String name) { return null; @@ -1947,8 +1950,14 @@ public abstract class Toolkit { return desktopPropsSupport.getPropertyChangeListeners(propertyName); } + /** + * The desktop properties. + */ protected final Map desktopProperties = new HashMap(); + /** + * The desktop properties change support. + */ protected final PropertyChangeSupport desktopPropsSupport = Toolkit.createPropertyChangeSupport(this); diff --git a/jdk/src/java.desktop/share/classes/java/awt/Window.java b/jdk/src/java.desktop/share/classes/java/awt/Window.java index 5f819cda87a..56ca461a90b 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/Window.java +++ b/jdk/src/java.desktop/share/classes/java/awt/Window.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2789,6 +2789,7 @@ public class Window extends Container implements Accessible { /** * @deprecated As of J2SE 1.4, replaced by * {@link Component#applyComponentOrientation Component.applyComponentOrientation}. + * @param rb the resource bundle */ @Deprecated public void applyResourceBundle(ResourceBundle rb) { @@ -2798,6 +2799,7 @@ public class Window extends Container implements Accessible { /** * @deprecated As of J2SE 1.4, replaced by * {@link Component#applyComponentOrientation Component.applyComponentOrientation}. + * @param rbName the resource name */ @Deprecated public void applyResourceBundle(String rbName) { diff --git a/jdk/src/java.desktop/share/classes/java/awt/doc-files/Modality.html b/jdk/src/java.desktop/share/classes/java/awt/doc-files/Modality.html index 19695f00177..242e96b914f 100644 --- a/jdk/src/java.desktop/share/classes/java/awt/doc-files/Modality.html +++ b/jdk/src/java.desktop/share/classes/java/awt/doc-files/Modality.html @@ -1,5 +1,5 @@ RGB case. * @@ -1426,23 +1462,23 @@ png_init_read_transformations(png_structp png_ptr) * png_set_background, along with the bit depth, then the code has a record * of exactly what color space the background is currently in. */ - if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) { /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if - * the file was greyscale the background value is gray. + * the file was grayscale the background value is gray. */ - if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; } - else if (png_ptr->transformations & PNG_COMPOSE) + else if ((png_ptr->transformations & PNG_COMPOSE) != 0) { /* PNG_COMPOSE: png_set_background was called with need_expand false, * so the color is in the color space of the output or png_set_alpha_mode * was called and the color is black. Ignore RGB_TO_GRAY because that * happens before GRAY_TO_RGB. */ - if (png_ptr->transformations & PNG_GRAY_TO_RGB) + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) { if (png_ptr->background.red == png_ptr->background.green && png_ptr->background.red == png_ptr->background.blue) @@ -1452,7 +1488,8 @@ png_init_read_transformations(png_structp png_ptr) } } } -#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ +#endif /* READ_EXPAND && READ_BACKGROUND */ +#endif /* READ_GRAY_TO_RGB */ /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations * can be performed directly on the palette, and some (such as rgb to gray) @@ -1473,10 +1510,10 @@ png_init_read_transformations(png_structp png_ptr) #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ defined(PNG_READ_EXPAND_16_SUPPORTED) - if ((png_ptr->transformations & PNG_EXPAND_16) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth != 16) + if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && + png_ptr->bit_depth != 16) { /* TODO: fix this. Because the expand_16 operation is after the compose * handling the background color must be 8, not 16, bits deep, but the @@ -1488,14 +1525,36 @@ png_init_read_transformations(png_structp png_ptr) * NOTE: this discards the low 16 bits of the user supplied background * color, but until expand_16 works properly there is no choice! */ -# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) +# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) CHOP(png_ptr->background.red); CHOP(png_ptr->background.green); CHOP(png_ptr->background.blue); CHOP(png_ptr->background.gray); # undef CHOP } -#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ +#endif /* READ_BACKGROUND && READ_EXPAND_16 */ + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ + defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) + if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && + png_ptr->bit_depth == 16) + { + /* On the other hand, if a 16-bit file is to be reduced to 8-bits per + * component this will also happen after PNG_COMPOSE and so the background + * color must be pre-expanded here. + * + * TODO: fix this too. + */ + png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); + png_ptr->background.green = + (png_uint_16)(png_ptr->background.green * 257); + png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); + png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); + } +#endif /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the * background support (see the comments in scripts/pnglibconf.dfa), this @@ -1524,27 +1583,36 @@ png_init_read_transformations(png_structp png_ptr) * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the * tables. */ - if ((png_ptr->transformations & PNG_GAMMA) - || ((png_ptr->transformations & PNG_RGB_TO_GRAY) - && (png_gamma_significant(png_ptr->gamma) || - png_gamma_significant(png_ptr->screen_gamma))) - || ((png_ptr->transformations & PNG_COMPOSE) - && (png_gamma_significant(png_ptr->gamma) - || png_gamma_significant(png_ptr->screen_gamma) + if ((png_ptr->transformations & PNG_GAMMA) != 0 || + ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && + (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || + png_gamma_significant(png_ptr->screen_gamma) != 0)) || + ((png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || + png_gamma_significant(png_ptr->screen_gamma) != 0 # ifdef PNG_READ_BACKGROUND_SUPPORTED - || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE - && png_gamma_significant(png_ptr->background_gamma)) + || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && + png_gamma_significant(png_ptr->background_gamma) != 0) # endif - )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) - && png_gamma_significant(png_ptr->screen_gamma)) - ) + )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && + png_gamma_significant(png_ptr->screen_gamma) != 0)) { png_build_gamma_table(png_ptr, png_ptr->bit_depth); #ifdef PNG_READ_BACKGROUND_SUPPORTED - if (png_ptr->transformations & PNG_COMPOSE) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + /* Issue a warning about this combination: because RGB_TO_GRAY is + * optimized to do the gamma transform if present yet do_background has + * to do the same thing if both options are set a + * double-gamma-correction happens. This is true in all versions of + * libpng to date. + */ + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + png_warning(png_ptr, + "libpng does not support gamma+background+rgb_to_gray"); + + if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) { /* We don't get to here unless there is a tRNS chunk with non-opaque * entries - see the checking code at the start of this function. @@ -1576,8 +1644,8 @@ png_init_read_transformations(png_structp png_ptr) break; case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->gamma); - gs = png_reciprocal2(png_ptr->gamma, + g = png_reciprocal(png_ptr->colorspace.gamma); + gs = png_reciprocal2(png_ptr->colorspace.gamma, png_ptr->screen_gamma); break; @@ -1592,7 +1660,7 @@ png_init_read_transformations(png_structp png_ptr) break; } - if (png_gamma_significant(gs)) + if (png_gamma_significant(gs) != 0) { back.red = png_gamma_8bit_correct(png_ptr->background.red, gs); @@ -1609,7 +1677,7 @@ png_init_read_transformations(png_structp png_ptr) back.blue = (png_byte)png_ptr->background.blue; } - if (png_gamma_significant(g)) + if (png_gamma_significant(g) != 0) { back_1.red = png_gamma_8bit_correct(png_ptr->background.red, g); @@ -1663,7 +1731,7 @@ png_init_read_transformations(png_structp png_ptr) /* Prevent the transformations being done again. * - * NOTE: this is highly dubious; it zaps the transformations in + * NOTE: this is highly dubious; it removes the transformations in * place. This seems inconsistent with the general treatment of the * transformations elsewhere. */ @@ -1673,8 +1741,9 @@ png_init_read_transformations(png_structp png_ptr) /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ else /* color_type != PNG_COLOR_TYPE_PALETTE */ { - png_fixed_point g = PNG_FP_1; - png_fixed_point gs = PNG_FP_1; + int gs_sig, g_sig; + png_fixed_point g = PNG_FP_1; /* Correction to linear */ + png_fixed_point gs = PNG_FP_1; /* Correction to screen */ switch (png_ptr->background_gamma_type) { @@ -1684,8 +1753,9 @@ png_init_read_transformations(png_structp png_ptr) break; case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->gamma); - gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->colorspace.gamma); + gs = png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: @@ -1698,34 +1768,45 @@ png_init_read_transformations(png_structp png_ptr) png_error(png_ptr, "invalid background gamma type"); } - png_ptr->background_1.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, g); + g_sig = png_gamma_significant(g); + gs_sig = png_gamma_significant(gs); - png_ptr->background.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, gs); + if (g_sig != 0) + png_ptr->background_1.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, g); + + if (gs_sig != 0) + png_ptr->background.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, gs); if ((png_ptr->background.red != png_ptr->background.green) || (png_ptr->background.red != png_ptr->background.blue) || (png_ptr->background.red != png_ptr->background.gray)) { /* RGB or RGBA with color background */ - png_ptr->background_1.red = png_gamma_correct(png_ptr, - png_ptr->background.red, g); + if (g_sig != 0) + { + png_ptr->background_1.red = png_gamma_correct(png_ptr, + png_ptr->background.red, g); - png_ptr->background_1.green = png_gamma_correct(png_ptr, - png_ptr->background.green, g); + png_ptr->background_1.green = png_gamma_correct(png_ptr, + png_ptr->background.green, g); - png_ptr->background_1.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, g); + png_ptr->background_1.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, g); + } - png_ptr->background.red = png_gamma_correct(png_ptr, - png_ptr->background.red, gs); + if (gs_sig != 0) + { + png_ptr->background.red = png_gamma_correct(png_ptr, + png_ptr->background.red, gs); - png_ptr->background.green = png_gamma_correct(png_ptr, - png_ptr->background.green, gs); + png_ptr->background.green = png_gamma_correct(png_ptr, + png_ptr->background.green, gs); - png_ptr->background.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, gs); + png_ptr->background.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, gs); + } } else @@ -1737,20 +1818,29 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; } + + /* The background is now in screen gamma: */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; } /* color_type != PNG_COLOR_TYPE_PALETTE */ }/* png_ptr->transformations & PNG_BACKGROUND */ else /* Transformation does not include PNG_BACKGROUND */ -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#endif /* READ_BACKGROUND */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ + && ((png_ptr->transformations & PNG_EXPAND) == 0 || + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) +#endif + ) { png_colorp palette = png_ptr->palette; int num_palette = png_ptr->num_palette; int i; - /*NOTE: there are other transformations that should probably be in here - * too. + /* NOTE: there are other transformations that should probably be in + * here too. */ for (i = 0; i < num_palette; i++) { @@ -1766,11 +1856,11 @@ png_init_read_transformations(png_structp png_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED else #endif -#endif /* PNG_READ_GAMMA_SUPPORTED */ +#endif /* READ_GAMMA */ #ifdef PNG_READ_BACKGROUND_SUPPORTED /* No GAMMA transformation (see the hanging else 4 lines above) */ - if ((png_ptr->transformations & PNG_COMPOSE) && + if ((png_ptr->transformations & PNG_COMPOSE) != 0 && (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) { int i; @@ -1805,35 +1895,53 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->transformations &= ~PNG_COMPOSE; } -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ +#endif /* READ_BACKGROUND */ #ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) && + if ((png_ptr->transformations & PNG_SHIFT) != 0 && + (png_ptr->transformations & PNG_EXPAND) == 0 && (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) { - png_uint_16 i; - png_uint_16 istop = png_ptr->num_palette; - int sr = 8 - png_ptr->sig_bit.red; - int sg = 8 - png_ptr->sig_bit.green; - int sb = 8 - png_ptr->sig_bit.blue; + int i; + int istop = png_ptr->num_palette; + int shift = 8 - png_ptr->sig_bit.red; - if (sr < 0 || sr > 8) - sr = 0; + png_ptr->transformations &= ~PNG_SHIFT; - if (sg < 0 || sg > 8) - sg = 0; + /* significant bits can be in the range 1 to 7 for a meaninful result, if + * the number of significant bits is 0 then no shift is done (this is an + * error condition which is silently ignored.) + */ + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].red; - if (sb < 0 || sb > 8) - sb = 0; + component >>= shift; + png_ptr->palette[i].red = (png_byte)component; + } - for (i = 0; i < istop; i++) - { - png_ptr->palette[i].red >>= sr; - png_ptr->palette[i].green >>= sg; - png_ptr->palette[i].blue >>= sb; - } + shift = 8 - png_ptr->sig_bit.green; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].green; + + component >>= shift; + png_ptr->palette[i].green = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.blue; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].blue; + + component >>= shift; + png_ptr->palette[i].blue = (png_byte)component; + } } -#endif /* PNG_READ_SHIFT_SUPPORTED */ +#endif /* READ_SHIFT */ } /* Modify the info structure to reflect the transformations. The @@ -1841,12 +1949,12 @@ png_init_read_transformations(png_structp png_ptr) * assuming the transformations result in valid PNG data. */ void /* PRIVATE */ -png_read_transform_info(png_structp png_ptr, png_infop info_ptr) +png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) { png_debug(1, "in png_read_transform_info"); #ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) + if ((png_ptr->transformations & PNG_EXPAND) != 0) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { @@ -1868,9 +1976,9 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) } else { - if (png_ptr->num_trans) + if (png_ptr->num_trans != 0) { - if (png_ptr->transformations & PNG_EXPAND_tRNS) + if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; } if (info_ptr->bit_depth < 8) @@ -1886,7 +1994,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) /* The following is almost certainly wrong unless the background value is in * the screen space! */ - if (png_ptr->transformations & PNG_COMPOSE) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) info_ptr->background = png_ptr->background; #endif @@ -1895,20 +2003,24 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) * however it seems that the code in png_init_read_transformations, which has * been called before this from png_read_update_info->png_read_start_row * sometimes does the gamma transform and cancels the flag. + * + * TODO: this looks wrong; the info_ptr should end up with a gamma equal to + * the screen_gamma value. The following probably results in weirdness if + * the info_ptr is used by the app after the rows have been read. */ - info_ptr->gamma = png_ptr->gamma; + info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; #endif if (info_ptr->bit_depth == 16) { # ifdef PNG_READ_16BIT_SUPPORTED # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_SCALE_16_TO_8) + if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) info_ptr->bit_depth = 8; # endif # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_16_TO_8) + if ((png_ptr->transformations & PNG_16_TO_8) != 0) info_ptr->bit_depth = 8; # endif @@ -1926,7 +2038,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) info_ptr->bit_depth = 8; # else -# if PNG_READ_SCALE_16_TO_8_SUPPORTED +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED png_ptr->transformations |= PNG_SCALE_16_TO_8; info_ptr->bit_depth = 8; # else @@ -1934,25 +2046,27 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) CONFIGURATION ERROR: you must enable at least one 16 to 8 method # endif # endif -#endif /* !READ_16BIT_SUPPORTED */ +#endif /* !READ_16BIT */ } #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if (png_ptr->transformations & PNG_GRAY_TO_RGB) - info_ptr->color_type |= PNG_COLOR_MASK_COLOR; + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) + info_ptr->color_type = (png_byte)(info_ptr->color_type | + PNG_COLOR_MASK_COLOR); #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if (png_ptr->transformations & PNG_RGB_TO_GRAY) - info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_COLOR); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED - if (png_ptr->transformations & PNG_QUANTIZE) + if ((png_ptr->transformations & PNG_QUANTIZE) != 0) { if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - png_ptr->palette_lookup && info_ptr->bit_depth == 8) + png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) { info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; } @@ -1960,54 +2074,57 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_EXPAND_16_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && - info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && + info_ptr->bit_depth == 8 && + info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) { info_ptr->bit_depth = 16; } #endif #ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) + if ((png_ptr->transformations & PNG_PACK) != 0 && + (info_ptr->bit_depth < 8)) info_ptr->bit_depth = 8; #endif if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; - else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) info_ptr->channels = 3; else info_ptr->channels = 1; #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_STRIP_ALPHA) + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) { - info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); info_ptr->num_trans = 0; } #endif - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) info_ptr->channels++; #ifdef PNG_READ_FILLER_SUPPORTED /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ - if ((png_ptr->transformations & PNG_FILLER) && - ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) + if ((png_ptr->transformations & PNG_FILLER) != 0 && + (info_ptr->color_type == PNG_COLOR_TYPE_RGB || + info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) { info_ptr->channels++; /* If adding a true alpha channel not just filler */ - if (png_ptr->transformations & PNG_ADD_ALPHA) + if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; } #endif #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - if (png_ptr->transformations & PNG_USER_TRANSFORM) + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) { if (info_ptr->bit_depth < png_ptr->user_transform_depth) info_ptr->bit_depth = png_ptr->user_transform_depth; @@ -2031,291 +2148,11 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_ptr->info_rowbytes = info_ptr->rowbytes; #ifndef PNG_READ_EXPAND_SUPPORTED - if (png_ptr) + if (png_ptr != NULL) return; #endif } -/* Transform the row. The order of transformations is significant, - * and is very touchy. If you add a transformation, take care to - * decide how it fits in with the other transformations here. - */ -void /* PRIVATE */ -png_do_read_transformations(png_structp png_ptr) -{ - png_debug(1, "in png_do_read_transformations"); - - if (png_ptr->row_buf == NULL) - { - /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this - * error is incredibly rare and incredibly easy to debug without this - * information. - */ - png_error(png_ptr, "NULL row buffer"); - } - - /* The following is debugging; prior to 1.5.4 the code was never compiled in; - * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro - * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for - * selected new APIs to ensure that there is no API change. - */ - if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && - !(png_ptr->flags & PNG_FLAG_ROW_INIT)) - { - /* Application has failed to call either png_read_start_image() or - * png_read_update_info() after setting transforms that expand pixels. - * This check added to libpng-1.2.19 (but not enabled until 1.5.4). - */ - png_error(png_ptr, "Uninitialized row"); - } - -#ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) - { - if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) - { - png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); - } - - else - { - if (png_ptr->num_trans && - (png_ptr->transformations & PNG_EXPAND_tRNS)) - png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->trans_color)); - - else - png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, - NULL); - } - } -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - !(png_ptr->transformations & PNG_COMPOSE) && - (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if (png_ptr->transformations & PNG_RGB_TO_GRAY) - { - int rgb_error = - png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), - png_ptr->row_buf + 1); - - if (rgb_error) - { - png_ptr->rgb_to_gray_status=1; - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_WARN) - png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_ERR) - png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - } - } -#endif - -/* From Andreas Dilger e-mail to png-implement, 26 March 1998: - * - * In most cases, the "simple transparency" should be done prior to doing - * gray-to-RGB, or you will have to test 3x as many bytes to check if a - * pixel is transparent. You would also need to make sure that the - * transparency information is upgraded to RGB. - * - * To summarize, the current flow is: - * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite - * with background "in place" if transparent, - * convert to RGB if necessary - * - Gray + alpha -> composite with gray background and remove alpha bytes, - * convert to RGB if necessary - * - * To support RGB backgrounds for gray images we need: - * - Gray + simple transparency -> convert to RGB + simple transparency, - * compare 3 or 6 bytes and composite with - * background "in place" if transparent - * (3x compare/pixel compared to doing - * composite with gray bkgrnd) - * - Gray + alpha -> convert to RGB + alpha, composite with background and - * remove alpha bytes (3x float - * operations/pixel compared with composite - * on gray background) - * - * Greg's change will do this. The reason it wasn't done before is for - * performance, as this increases the per-pixel operations. If we would check - * in advance if the background was gray or RGB, and position the gray-to-RGB - * transform appropriately, then it would save a lot of work/time. - */ - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* If gray -> RGB, do so now only if background is non-gray; else do later - * for performance reasons - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) - if (png_ptr->transformations & PNG_COMPOSE) - png_do_compose(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - if ((png_ptr->transformations & PNG_GAMMA) && -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) - !((png_ptr->transformations & PNG_COMPOSE) && - ((png_ptr->num_trans != 0) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && -#endif - (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) - png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - (png_ptr->transformations & PNG_COMPOSE) && - (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && - (png_ptr->row_info.color_type & PNG_COLOR_MASK_ALPHA)) - png_do_encode_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_SCALE_16_TO_8) - png_do_scale_16_to_8(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* There is no harm in doing both of these because only one has any effect, - * by putting the 'scale' option first if the app asks for scale (either by - * calling the API or in a TRANSFORM flag) this is what happens. - */ - if (png_ptr->transformations & PNG_16_TO_8) - png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if (png_ptr->transformations & PNG_QUANTIZE) - { - png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->quantize_index); - - if (png_ptr->row_info.rowbytes == 0) - png_error(png_ptr, "png_do_quantize returned rowbytes=0"); - } -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Do the expansion now, after all the arithmetic has been done. Notice - * that previous transformations can handle the PNG_EXPAND_16 flag if this - * is efficient (particularly true in the case of gamma correction, where - * better accuracy results faster!) - */ - if (png_ptr->transformations & PNG_EXPAND_16) - png_do_expand_16(&png_ptr->row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /*NOTE: moved here in 1.5.4 (from much later in this list.) */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED - if (png_ptr->transformations & PNG_SHIFT) - png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if (png_ptr->transformations & PNG_PACK) - png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_BGR_SUPPORTED - if (png_ptr->transformations & PNG_BGR) - png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if (png_ptr->transformations & PNG_FILLER) - png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, - (png_uint_32)png_ptr->filler, png_ptr->flags); -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_ALPHA) - png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_16BIT_SUPPORTED -#ifdef PNG_READ_SWAP_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - if (png_ptr->read_user_transform_fn != NULL) - (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - &(png_ptr->row_info), /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - if (png_ptr->user_transform_depth) - png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels) - png_ptr->row_info.channels = png_ptr->user_transform_channels; -#endif - png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * - png_ptr->row_info.channels); - - png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); - } -#endif -} - #ifdef PNG_READ_PACK_SUPPORTED /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, * without changing the actual values. Thus, if you had a row with @@ -2323,7 +2160,7 @@ png_do_read_transformations(png_structp png_ptr) * the numbers 0 or 1. If you would rather they contain 0 and 255, use * png_do_shift() after this. */ -void /* PRIVATE */ +static void png_do_unpack(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_unpack"); @@ -2421,109 +2258,132 @@ png_do_unpack(png_row_infop row_info, png_bytep row) * a row of bit depth 8, but only 5 are significant, this will shift * the values back to 0 through 31. */ -void /* PRIVATE */ +static void png_do_unshift(png_row_infop row_info, png_bytep row, png_const_color_8p sig_bits) { + int color_type; + png_debug(1, "in png_do_unshift"); - if ( - row_info->color_type != PNG_COLOR_TYPE_PALETTE) + /* The palette case has already been handled in the _init routine. */ + color_type = row_info->color_type; + + if (color_type != PNG_COLOR_TYPE_PALETTE) { int shift[4]; int channels = 0; - int c; - png_uint_16 value = 0; - png_uint_32 row_width = row_info->width; + int bit_depth = row_info->bit_depth; - if (row_info->color_type & PNG_COLOR_MASK_COLOR) + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) { - shift[channels++] = row_info->bit_depth - sig_bits->red; - shift[channels++] = row_info->bit_depth - sig_bits->green; - shift[channels++] = row_info->bit_depth - sig_bits->blue; + shift[channels++] = bit_depth - sig_bits->red; + shift[channels++] = bit_depth - sig_bits->green; + shift[channels++] = bit_depth - sig_bits->blue; } else { - shift[channels++] = row_info->bit_depth - sig_bits->gray; + shift[channels++] = bit_depth - sig_bits->gray; } - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) { - shift[channels++] = row_info->bit_depth - sig_bits->alpha; + shift[channels++] = bit_depth - sig_bits->alpha; } - for (c = 0; c < channels; c++) { - if (shift[c] <= 0) - shift[c] = 0; + int c, have_shift; - else - value = 1; + for (c = have_shift = 0; c < channels; ++c) + { + /* A shift of more than the bit depth is an error condition but it + * gets ignored here. + */ + if (shift[c] <= 0 || shift[c] >= bit_depth) + shift[c] = 0; + + else + have_shift = 1; + } + + if (have_shift == 0) + return; } - if (!value) - return; - - switch (row_info->bit_depth) + switch (bit_depth) { default: + /* Must be 1bpp gray: should not be here! */ + /* NOTREACHED */ break; case 2: + /* Must be 2bpp gray */ + /* assert(channels == 1 && shift[0] == 1) */ { - png_bytep bp; - png_size_t i; - png_size_t istop = row_info->rowbytes; + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; - for (bp = row, i = 0; i < istop; i++) + while (bp < bp_end) { - *bp >>= 1; - *bp++ &= 0x55; + int b = (*bp >> 1) & 0x55; + *bp++ = (png_byte)b; } break; } case 4: + /* Must be 4bpp gray */ + /* assert(channels == 1) */ { png_bytep bp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; - png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | - (png_byte)((int)0xf >> shift[0])); + png_bytep bp_end = bp + row_info->rowbytes; + int gray_shift = shift[0]; + int mask = 0xf >> gray_shift; - for (i = 0; i < istop; i++) + mask |= mask << 4; + + while (bp < bp_end) { - *bp >>= shift[0]; - *bp++ &= mask; + int b = (*bp >> gray_shift) & mask; + *bp++ = (png_byte)b; } break; } case 8: + /* Single byte components, G, GA, RGB, RGBA */ { png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = row_width * channels; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; - for (i = 0; i < istop; i++) + while (bp < bp_end) { - *bp++ >>= shift[i%channels]; + int b = *bp >> shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)b; } break; } #ifdef PNG_READ_16BIT_SUPPORTED case 16: + /* Double byte components, G, GA, RGB, RGBA */ { png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = channels * row_width; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; - for (i = 0; i < istop; i++) + while (bp < bp_end) { - value = (png_uint_16)((*bp << 8) + *(bp + 1)); - value >>= shift[i%channels]; + int value = (bp[0] << 8) + bp[1]; + + value >>= shift[channel]; + if (++channel >= channels) + channel = 0; *bp++ = (png_byte)(value >> 8); *bp++ = (png_byte)(value & 0xff); } @@ -2537,7 +2397,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* Scale rows of bit depth 16 down to 8 accurately */ -void /* PRIVATE */ +static void png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_scale_16_to_8"); @@ -2545,7 +2405,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) if (row_info->bit_depth == 16) { png_bytep sp = row; /* source */ - png_bytep dp = row; /* destinaton */ + png_bytep dp = row; /* destination */ png_bytep ep = sp + row_info->rowbytes; /* end+1 */ while (sp < ep) @@ -2595,7 +2455,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -void /* PRIVATE */ +static void /* Simply discard the low byte. This was the default behavior prior * to libpng-1.5.4. */ @@ -2606,7 +2466,7 @@ png_do_chop(png_row_infop row_info, png_bytep row) if (row_info->bit_depth == 16) { png_bytep sp = row; /* source */ - png_bytep dp = row; /* destinaton */ + png_bytep dp = row; /* destination */ png_bytep ep = sp + row_info->rowbytes; /* end+1 */ while (sp < ep) @@ -2623,7 +2483,7 @@ png_do_chop(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -void /* PRIVATE */ +static void png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_read_swap_alpha"); @@ -2720,7 +2580,7 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -void /* PRIVATE */ +static void png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) { png_uint_32 row_width; @@ -2822,7 +2682,7 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) #ifdef PNG_READ_FILLER_SUPPORTED /* Add filler channel if we have RGB color */ -void /* PRIVATE */ +static void png_do_read_filler(png_row_infop row_info, png_bytep row, png_uint_32 filler, png_uint_32 flags) { @@ -2841,7 +2701,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from G to GX */ png_bytep sp = row + (png_size_t)row_width; @@ -2876,7 +2736,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from GG to GGXX */ png_bytep sp = row + (png_size_t)row_width * 2; @@ -2918,7 +2778,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from RGB to RGBX */ png_bytep sp = row + (png_size_t)row_width * 3; @@ -2957,7 +2817,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from RRGGBB to RRGGBBXX */ png_bytep sp = row + (png_size_t)row_width * 6; @@ -3009,7 +2869,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED /* Expand grayscale files to RGB, with or without alpha */ -void /* PRIVATE */ +static void png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) { png_uint_32 i; @@ -3018,7 +2878,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) png_debug(1, "in png_do_gray_to_rgb"); if (row_info->bit_depth >= 8 && - !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { @@ -3086,7 +2946,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) } } } - row_info->channels += (png_byte)2; + row_info->channels = (png_byte)(row_info->channels + 2); row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); @@ -3097,269 +2957,242 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED /* Reduce RGB files to grayscale, with or without alpha - * using the equation given in Poynton's ColorFAQ at - * (THIS LINK IS DEAD June 2008) - * New link: - * + * using the equation given in Poynton's ColorFAQ of 1998-01-04 at + * (THIS LINK IS DEAD June 2008 but + * versions dated 1998 through November 2002 have been archived at + * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ + * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) * Charles Poynton poynton at poynton.com * * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B * - * We approximate this with - * - * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B - * * which can be expressed with integers as * * Y = (6969 * R + 23434 * G + 2365 * B)/32768 * - * The calculation is to be done in a linear colorspace. + * Poynton's current link (as of January 2003 through July 2011): + * + * has changed the numbers slightly: * - * Other integer coefficents can be used via png_set_rgb_to_gray(). + * Y = 0.2126*R + 0.7152*G + 0.0722*B + * + * which can be expressed with integers as + * + * Y = (6966 * R + 23436 * G + 2366 * B)/32768 + * + * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 + * end point chromaticities and the D65 white point. Depending on the + * precision used for the D65 white point this produces a variety of different + * numbers, however if the four decimal place value used in ITU-R Rec 709 is + * used (0.3127,0.3290) the Y calculation would be: + * + * Y = (6968 * R + 23435 * G + 2366 * B)/32768 + * + * While this is correct the rounding results in an overflow for white, because + * the sum of the rounded coefficients is 32769, not 32768. Consequently + * libpng uses, instead, the closest non-overflowing approximation: + * + * Y = (6968 * R + 23434 * G + 2366 * B)/32768 + * + * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk + * (including an sRGB chunk) then the chromaticities are used to calculate the + * coefficients. See the chunk handling in pngrutil.c for more information. + * + * In all cases the calculation is to be done in a linear colorspace. If no + * gamma information is available to correct the encoding of the original RGB + * values this results in an implicit assumption that the original PNG RGB + * values were linear. + * + * Other integer coefficents can be used via png_set_rgb_to_gray(). Because + * the API takes just red and green coefficients the blue coefficient is + * calculated to make the sum 32768. This will result in different rounding + * to that used above. */ -int /* PRIVATE */ -png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) +static int +png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) { - png_uint_32 i; - - png_uint_32 row_width = row_info->width; int rgb_error = 0; png_debug(1, "in png_do_rgb_to_gray"); - if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && + (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { - png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; - png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; - png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; + PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + PNG_CONST png_uint_32 bc = 32768 - rc - gc; + PNG_CONST png_uint_32 row_width = row_info->width; + PNG_CONST int have_alpha = + (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; - if (row_info->color_type == PNG_COLOR_TYPE_RGB) + if (row_info->bit_depth == 8) { - if (row_info->bit_depth == 8) +#ifdef PNG_READ_GAMMA_SUPPORTED + /* Notice that gamma to/from 1 are not necessarily inverses (if + * there is an overall gamma correction). Prior to 1.5.5 this code + * checked the linearized values for equality; this doesn't match + * the documentation, the original values must be checked. + */ + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) { - png_bytep sp = row; - png_bytep dp = row; + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); - for (i = 0; i < row_width; i++) + if (red != green || red != blue) { - png_byte red = png_ptr->gamma_to_1[*(sp++)]; - png_byte green = png_ptr->gamma_to_1[*(sp++)]; - png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + red = png_ptr->gamma_to_1[red]; + green = png_ptr->gamma_to_1[green]; + blue = png_ptr->gamma_to_1[blue]; - if (red != green || red != blue) - { - rgb_error |= 1; - *(dp++) = png_ptr->gamma_from_1[ - (rc*red + gc*green + bc*blue)>>15]; - } - - else - *(dp++) = *(sp - 1); + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1[ + (rc*red + gc*green + bc*blue + 16384)>>15]; } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) + + else { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); + /* If there is no overall correction the table will not be + * set. + */ + if (png_ptr->gamma_table != NULL) + red = png_ptr->gamma_table[red]; - if (red != green || red != blue) - { - rgb_error |= 1; - *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); - } - - else - *(dp++) = *(sp - 1); + *(dp++) = red; } + + if (have_alpha != 0) + *(dp++) = *(sp++); } } - - else /* RGB bit_depth == 16 */ - { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if (png_ptr->gamma_16_to_1 != NULL && - png_ptr->gamma_16_from_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, w; - - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - - if (red == green && red == blue) - w = red; - - else - { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) - >> png_ptr->gamma_shift][red>>8]; - png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green&0xff) >> - png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) - >> png_ptr->gamma_shift][blue>>8]; - png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 - + bc*blue_1)>>15); - w = png_ptr->gamma_16_from_1[(gray16&0xff) >> - png_ptr->gamma_shift][gray16 >> 8]; - rgb_error |= 1; - } - - *(dp++) = (png_byte)((w>>8) & 0xff); - *(dp++) = (png_byte)(w & 0xff); - } - } - else + else #endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + + if (red != green || red != blue) { - png_uint_16 red, green, blue, gray16; - - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - - if (red != green || red != blue) - rgb_error |= 1; - - gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); - *(dp++) = (png_byte)((gray16>>8) & 0xff); - *(dp++) = (png_byte)(gray16 & 0xff); + rgb_error |= 1; + /* NOTE: this is the historical approach which simply + * truncates the results. + */ + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); } + + else + *(dp++) = red; + + if (have_alpha != 0) + *(dp++) = *(sp++); } } } - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + + else /* RGB bit_depth == 16 */ { - if (row_info->bit_depth == 8) +#ifdef PNG_READ_GAMMA_SUPPORTED + if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) + png_uint_16 red, green, blue, w; + + red = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; + + if (red == green && red == blue) { - png_byte red = png_ptr->gamma_to_1[*(sp++)]; - png_byte green = png_ptr->gamma_to_1[*(sp++)]; - png_byte blue = png_ptr->gamma_to_1[*(sp++)]; - - if (red != green || red != blue) - rgb_error |= 1; - - *(dp++) = png_ptr->gamma_from_1 - [(rc*red + gc*green + bc*blue)>>15]; - - *(dp++) = *(sp++); /* alpha */ - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - if (red != green || red != blue) - rgb_error |= 1; - - *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); - *(dp++) = *(sp++); /* alpha */ - } - } - } - else /* RGBA bit_depth == 16 */ - { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if (png_ptr->gamma_16_to_1 != NULL && - png_ptr->gamma_16_from_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, w; - - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - - if (red == green && red == blue) - w = red; + if (png_ptr->gamma_16_table != NULL) + w = png_ptr->gamma_16_table[(red & 0xff) + >> png_ptr->gamma_shift][red >> 8]; else - { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> - png_ptr->gamma_shift][red>>8]; + w = red; + } - png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green&0xff) >> - png_ptr->gamma_shift][green>>8]; + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) + >> png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = + png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) + >> png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + + bc*blue_1 + 16384)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> - png_ptr->gamma_shift][blue>>8]; + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); - png_uint_16 gray16 = (png_uint_16)((rc * red_1 - + gc * green_1 + bc * blue_1)>>15); - - w = png_ptr->gamma_16_from_1[(gray16&0xff) >> - png_ptr->gamma_shift][gray16 >> 8]; - - rgb_error |= 1; - } - - *(dp++) = (png_byte)((w>>8) & 0xff); - *(dp++) = (png_byte)(w & 0xff); - *(dp++) = *(sp++); /* alpha */ + if (have_alpha != 0) + { + *(dp++) = *(sp++); *(dp++) = *(sp++); } } - else + } + else #endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) { - png_bytep sp = row; - png_bytep dp = row; - for (i = 0; i < row_width; i++) + png_uint_16 red, green, blue, gray16; + + red = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; + + if (red != green || red != blue) + rgb_error |= 1; + + /* From 1.5.5 in the 16 bit case do the accurate conversion even + * in the 'fast' case - this is because this is where the code + * ends up when handling linear 16 bit data. + */ + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> + 15); + *(dp++) = (png_byte)((gray16 >> 8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + + if (have_alpha != 0) { - png_uint_16 red, green, blue, gray16; - red = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; - - if (red != green || red != blue) - rgb_error |= 1; - - gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); - *(dp++) = (png_byte)((gray16>>8) & 0xff); - *(dp++) = (png_byte)(gray16 & 0xff); - *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); *(dp++) = *(sp++); } } } } - row_info->channels -= 2; + + row_info->channels = (png_byte)(row_info->channels - 2); row_info->color_type = (png_byte)(row_info->color_type & ~PNG_COLOR_MASK_COLOR); row_info->pixel_depth = (png_byte)(row_info->channels * @@ -3369,73 +3202,15 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) return rgb_error; } #endif -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth - * large of png_color. This lets grayscale images be treated as - * paletted. Most useful for gamma correction and simplification - * of code. This API is not used internally. - */ -void PNGAPI -png_build_grayscale_palette(int bit_depth, png_colorp palette) -{ - int num_palette; - int color_inc; - int i; - int v; - - png_debug(1, "in png_do_build_grayscale_palette"); - - if (palette == NULL) - return; - - switch (bit_depth) - { - case 1: - num_palette = 2; - color_inc = 0xff; - break; - - case 2: - num_palette = 4; - color_inc = 0x55; - break; - - case 4: - num_palette = 16; - color_inc = 0x11; - break; - - case 8: - num_palette = 256; - color_inc = 1; - break; - - default: - num_palette = 0; - color_inc = 0; - break; - } - - for (i = 0, v = 0; i < num_palette; i++, v += color_inc) - { - palette[i].red = (png_byte)v; - palette[i].green = (png_byte)v; - palette[i].blue = (png_byte)v; - } -} -#endif - - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -#ifdef PNG_READ_BACKGROUND_SUPPORTED +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) /* Replace any alpha or transparency with the supplied background color. * "background" is already in the screen gamma, while "background_1" is * at a gamma of 1.0. Paletted files have already been taken care of. */ -void /* PRIVATE */ -png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) +static void +png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { #ifdef PNG_READ_GAMMA_SUPPORTED png_const_bytep gamma_table = png_ptr->gamma_table; @@ -3445,12 +3220,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; int gamma_shift = png_ptr->gamma_shift; + int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; #endif png_bytep sp; png_uint_32 i; png_uint_32 row_width = row_info->width; - int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; int shift; png_debug(1, "in png_do_compose"); @@ -3471,11 +3246,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x01) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 7; sp++; @@ -3499,20 +3275,22 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x03) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } else { - png_byte p = (png_byte)((*sp >> shift) & 0x03); - png_byte g = (png_byte)((gamma_table [p | (p << 2) | - (p << 4) | (p << 6)] >> 6) & 0x03); - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(g << shift); + unsigned int p = (*sp >> shift) & 0x03; + unsigned int g = (gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03; + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= g << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 6; sp++; @@ -3533,11 +3311,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x03) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 6; sp++; @@ -3562,20 +3341,22 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x0f) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0xf0f >> (4 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } else { - png_byte p = (png_byte)((*sp >> shift) & 0x0f); - png_byte g = (png_byte)((gamma_table[p | - (p << 4)] >> 4) & 0x0f); - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(g << shift); + unsigned int p = (*sp >> shift) & 0x0f; + unsigned int g = (gamma_table[p | (p << 4)] >> 4) & + 0x0f; + unsigned int tmp = *sp & (0xf0f >> (4 - shift)); + tmp |= g << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 4; sp++; @@ -3596,11 +3377,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x0f) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0xf0f >> (4 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 4; sp++; @@ -3656,8 +3438,10 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if (v == png_ptr->trans_color.gray) { /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray + & 0xff); } else @@ -3680,8 +3464,10 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if (v == png_ptr->trans_color.gray) { - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray + & 0xff); } } } @@ -3761,9 +3547,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) /* Background is already in screen gamma */ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); } @@ -3804,9 +3593,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) { *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); } } @@ -3843,7 +3635,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) v = gamma_to_1[*sp]; png_composite(w, v, a, png_ptr->background_1.gray); - if (!optimize) + if (optimize == 0) w = gamma_from_1[w]; *sp = w; } @@ -3861,7 +3653,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) *sp = (png_byte)png_ptr->background.gray; else if (a < 0xff) - png_composite(*sp, *sp, a, png_ptr->background_1.gray); + png_composite(*sp, *sp, a, png_ptr->background.gray); } } } @@ -3889,7 +3681,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) else if (a == 0) { /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); } @@ -3899,7 +3692,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize) + if (optimize != 0) w = v; else w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; @@ -3919,7 +3712,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if (a == 0) { - *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); } @@ -3928,7 +3722,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) png_uint_16 g, v; g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_composite_16(v, g, a, png_ptr->background_1.gray); + png_composite_16(v, g, a, png_ptr->background.gray); *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); } @@ -3972,17 +3766,17 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) v = gamma_to_1[*sp]; png_composite(w, v, a, png_ptr->background_1.red); - if (!optimize) w = gamma_from_1[w]; + if (optimize == 0) w = gamma_from_1[w]; *sp = w; v = gamma_to_1[*(sp + 1)]; png_composite(w, v, a, png_ptr->background_1.green); - if (!optimize) w = gamma_from_1[w]; + if (optimize == 0) w = gamma_from_1[w]; *(sp + 1) = w; v = gamma_to_1[*(sp + 2)]; png_composite(w, v, a, png_ptr->background_1.blue); - if (!optimize) w = gamma_from_1[w]; + if (optimize == 0) w = gamma_from_1[w]; *(sp + 2) = w; } } @@ -4049,9 +3843,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) /* Background is already in screen gamma */ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); } @@ -4061,23 +3858,26 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(w, v, a, png_ptr->background_1.red); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + if (optimize == 0) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> + 8]; *sp = (png_byte)((w >> 8) & 0xff); *(sp + 1) = (png_byte)(w & 0xff); v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; png_composite_16(w, v, a, png_ptr->background_1.green); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + if (optimize == 0) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> + 8]; *(sp + 2) = (png_byte)((w >> 8) & 0xff); *(sp + 3) = (png_byte)(w & 0xff); v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; png_composite_16(w, v, a, png_ptr->background_1.blue); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; + if (optimize == 0) + w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> + 8]; *(sp + 4) = (png_byte)((w >> 8) & 0xff); *(sp + 5) = (png_byte)(w & 0xff); @@ -4098,9 +3898,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) { *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); } @@ -4137,7 +3940,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) } } } -#endif +#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ #ifdef PNG_READ_GAMMA_SUPPORTED /* Gamma correct the image, avoiding the alpha channel. Make sure @@ -4146,8 +3949,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) * is 16, use gamma_16_table and gamma_shift. Build these with * build_gamma_table(). */ -void /* PRIVATE */ -png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) +static void +png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { png_const_bytep gamma_table = png_ptr->gamma_table; png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; @@ -4347,14 +4150,14 @@ png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) * linear.) Called only with color types that have an alpha channel. Needs the * from_1 tables. */ -void /* PRIVATE */ -png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) +static void +png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { png_uint_32 row_width = row_info->width; png_debug(1, "in png_do_encode_alpha"); - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) { if (row_info->bit_depth == 8) { @@ -4413,7 +4216,7 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) /* Expands a palette row to an RGB or RGBA row depending * upon whether you supply trans and num_trans. */ -void /* PRIVATE */ +static void png_do_expand_palette(png_row_infop row_info, png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) { @@ -4566,7 +4369,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, /* If the bit depth < 8, it is expanded to 8. Also, if the already * expanded transparency value is supplied, an alpha channel is built. */ -void /* PRIVATE */ +static void png_do_expand(png_row_infop row_info, png_bytep row, png_const_color_16p trans_color) { @@ -4580,7 +4383,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { - png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0); + unsigned int gray = trans_color != NULL ? trans_color->gray : 0; if (row_info->bit_depth < 8) { @@ -4588,7 +4391,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { case 1: { - gray = (png_uint_16)((gray & 0x01) * 0xff); + gray = (gray & 0x01) * 0xff; sp = row + (png_size_t)((row_width - 1) >> 3); dp = row + (png_size_t)row_width - 1; shift = 7 - (int)((row_width + 7) & 0x07); @@ -4616,7 +4419,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, case 2: { - gray = (png_uint_16)((gray & 0x03) * 0x55); + gray = (gray & 0x03) * 0x55; sp = row + (png_size_t)((row_width - 1) >> 2); dp = row + (png_size_t)row_width - 1; shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); @@ -4641,7 +4444,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, case 4: { - gray = (png_uint_16)((gray & 0x0f) * 0x11); + gray = (gray & 0x0f) * 0x11; sp = row + (png_size_t)((row_width - 1) >> 1); dp = row + (png_size_t)row_width - 1; shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); @@ -4694,8 +4497,8 @@ png_do_expand(png_row_infop row_info, png_bytep row, else if (row_info->bit_depth == 16) { - png_byte gray_high = (png_byte)((gray >> 8) & 0xff); - png_byte gray_low = (png_byte)(gray & 0xff); + unsigned int gray_high = (gray >> 8) & 0xff; + unsigned int gray_low = gray & 0xff; sp = row + row_info->rowbytes - 1; dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) @@ -4724,7 +4527,8 @@ png_do_expand(png_row_infop row_info, png_bytep row, row_width); } } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && + trans_color != NULL) { if (row_info->bit_depth == 8) { @@ -4793,10 +4597,10 @@ png_do_expand(png_row_infop row_info, png_bytep row, #endif #ifdef PNG_READ_EXPAND_16_SUPPORTED -/* If the bit depth is 8 and the colour type is not a palette type expand the +/* If the bit depth is 8 and the color type is not a palette type expand the * whole row to 16 bits. Has no effect otherwise. */ -void /* PRIVATE */ +static void png_do_expand_16(png_row_infop row_info, png_bytep row) { if (row_info->bit_depth == 8 && @@ -4824,7 +4628,7 @@ png_do_expand_16(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED -void /* PRIVATE */ +static void png_do_quantize(png_row_infop row_info, png_bytep row, png_const_bytep palette_lookup, png_const_bytep quantize_lookup) { @@ -4915,70 +4719,304 @@ png_do_quantize(png_row_infop row_info, png_bytep row, } } } -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ +#endif /* READ_QUANTIZE */ -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing */ +/* Transform the row. The order of transformations is significant, + * and is very touchy. If you add a transformation, take care to + * decide how it fits in with the other transformations here. + */ void /* PRIVATE */ -png_do_read_intrapixel(png_row_infop row_info, png_bytep row) +png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) { - png_debug(1, "in png_do_read_intrapixel"); + png_debug(1, "in png_do_read_transformations"); - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + if (png_ptr->row_buf == NULL) { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; + /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this + * error is incredibly rare and incredibly easy to debug without this + * information. + */ + png_error(png_ptr, "NULL row buffer"); + } - if (row_info->bit_depth == 8) + /* The following is debugging; prior to 1.5.4 the code was never compiled in; + * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro + * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for + * all transformations, however in practice the ROW_INIT always gets done on + * demand, if necessary. + */ + if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && + (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + /* Application has failed to call either png_read_start_image() or + * png_read_update_info() after setting transforms that expand pixels. + * This check added to libpng-1.2.19 (but not enabled until 1.5.4). + */ + png_error(png_ptr, "Uninitialized row"); + } + +#ifdef PNG_READ_EXPAND_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); - *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); - } + png_do_expand_palette(row_info, png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); } - else if (row_info->bit_depth == 16) + + else { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; + if (png_ptr->num_trans != 0 && + (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) + png_do_expand(row_info, png_ptr->row_buf + 1, + &(png_ptr->trans_color)); else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); - png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } + png_do_expand(row_info, png_ptr->row_buf + 1, + NULL); } } +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) == 0 && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + { + int rgb_error = + png_do_rgb_to_gray(png_ptr, row_info, + png_ptr->row_buf + 1); + + if (rgb_error != 0) + { + png_ptr->rgb_to_gray_status=1; + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_WARN) + png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_ERR) + png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + } + } +#endif + +/* From Andreas Dilger e-mail to png-implement, 26 March 1998: + * + * In most cases, the "simple transparency" should be done prior to doing + * gray-to-RGB, or you will have to test 3x as many bytes to check if a + * pixel is transparent. You would also need to make sure that the + * transparency information is upgraded to RGB. + * + * To summarize, the current flow is: + * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + * with background "in place" if transparent, + * convert to RGB if necessary + * - Gray + alpha -> composite with gray background and remove alpha bytes, + * convert to RGB if necessary + * + * To support RGB backgrounds for gray images we need: + * - Gray + simple transparency -> convert to RGB + simple transparency, + * compare 3 or 6 bytes and composite with + * background "in place" if transparent + * (3x compare/pixel compared to doing + * composite with gray bkgrnd) + * - Gray + alpha -> convert to RGB + alpha, composite with background and + * remove alpha bytes (3x float + * operations/pixel compared with composite + * on gray background) + * + * Greg's change will do this. The reason it wasn't done before is for + * performance, as this increases the per-pixel operations. If we would check + * in advance if the background was gray or RGB, and position the gray-to-RGB + * transform appropriately, then it would save a lot of work/time. + */ + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* If gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons + */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + if ((png_ptr->transformations & PNG_GAMMA) != 0 && +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Because RGB_TO_GRAY does the gamma transform. */ + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* Because PNG_COMPOSE does the gamma transform if there is something to + * do (if there is an alpha channel or transparency.) + */ + !((png_ptr->transformations & PNG_COMPOSE) && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && +#endif + /* Because png_init_read_transformations transforms the palette, unless + * RGB_TO_GRAY will do the transform. + */ + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && + (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) + png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* There is no harm in doing both of these because only one has any effect, + * by putting the 'scale' option first if the app asks for scale (either by + * calling the API or in a TRANSFORM flag) this is what happens. + */ + if ((png_ptr->transformations & PNG_16_TO_8) != 0) + png_do_chop(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if ((png_ptr->transformations & PNG_QUANTIZE) != 0) + { + png_do_quantize(row_info, png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->quantize_index); + + if (row_info->rowbytes == 0) + png_error(png_ptr, "png_do_quantize returned rowbytes=0"); + } +#endif /* READ_QUANTIZE */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Do the expansion now, after all the arithmetic has been done. Notice + * that previous transformations can handle the PNG_EXPAND_16 flag if this + * is efficient (particularly true in the case of gamma correction, where + * better accuracy results faster!) + */ + if ((png_ptr->transformations & PNG_EXPAND_16) != 0) + png_do_expand_16(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* NOTE: moved here in 1.5.4 (from much later in this list.) */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_do_unshift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0) + png_do_unpack(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Added at libpng-1.5.10 */ + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, row_info); +#endif + +#ifdef PNG_READ_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_do_read_filler(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) + png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_16BIT_SUPPORTED +#ifdef PNG_READ_SWAP_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { + if (png_ptr->read_user_transform_fn != NULL) + (*(png_ptr->read_user_transform_fn)) /* User read transform function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + if (png_ptr->user_transform_depth != 0) + row_info->bit_depth = png_ptr->user_transform_depth; + + if (png_ptr->user_transform_channels != 0) + row_info->channels = png_ptr->user_transform_channels; +#endif + row_info->pixel_depth = (png_byte)(row_info->bit_depth * + row_info->channels); + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); + } +#endif } -#endif /* PNG_MNG_FEATURES_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED */ + +#endif /* READ_TRANSFORMS */ +#endif /* READ */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c index 4a023090f87..68e5caff89c 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -46,10 +46,8 @@ #ifdef PNG_READ_SUPPORTED -#define png_strtod(p,a,b) strtod(a,b) - png_uint_32 PNGAPI -png_get_uint_31(png_structp png_ptr, png_const_bytep buf) +png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) { png_uint_32 uval = png_get_uint_32(buf); @@ -68,7 +66,7 @@ png_get_uint_31(png_structp png_ptr, png_const_bytep buf) #define PNG_FIXED_ERROR (-1) static png_fixed_point /* PRIVATE */ -png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) +png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) { png_uint_32 uval = png_get_uint_32(buf); @@ -115,10 +113,10 @@ png_int_32 (PNGAPI png_get_int_32)(png_const_bytep buf) { png_uint_32 uval = png_get_uint_32(buf); - if ((uval & 0x80000000L) == 0) /* non-negative */ + if ((uval & 0x80000000) == 0) /* non-negative */ return uval; - uval = (uval ^ 0xffffffffL) + 1; /* 2's complement: -x = ~x+1 */ + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ return -(png_int_32)uval; } @@ -126,7 +124,7 @@ png_get_int_32)(png_const_bytep buf) png_uint_16 (PNGAPI png_get_uint_16)(png_const_bytep buf) { - /* ANSI-C requires an int value to accommodate at least 16 bits so this + /* ANSI-C requires an int value to accomodate at least 16 bits so this * works and allows the compiler not to worry about possible narrowing * on 32 bit systems. (Pre-ANSI systems did not make integers smaller * than 16 bits either.) @@ -138,11 +136,11 @@ png_get_uint_16)(png_const_bytep buf) return (png_uint_16)val; } -#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ +#endif /* READ_INT_FUNCTIONS */ /* Read and check the PNG file signature */ void /* PRIVATE */ -png_read_sig(png_structp png_ptr, png_infop info_ptr) +png_read_sig(png_structrp png_ptr, png_inforp info_ptr) { png_size_t num_checked, num_to_check; @@ -161,7 +159,7 @@ png_read_sig(png_structp png_ptr, png_infop info_ptr) png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); png_ptr->sig_bytes = 8; - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) { if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) @@ -177,7 +175,7 @@ png_read_sig(png_structp png_ptr, png_infop info_ptr) * Put the type name into png_ptr->chunk_name, and return the length. */ png_uint_32 /* PRIVATE */ -png_read_chunk_header(png_structp png_ptr) +png_read_chunk_header(png_structrp png_ptr) { png_byte buf[8]; png_uint_32 length; @@ -193,14 +191,14 @@ png_read_chunk_header(png_structp png_ptr) length = png_get_uint_31(png_ptr, buf); /* Put the chunk name into png_ptr->chunk_name. */ - png_memcpy(png_ptr->chunk_name, buf + 4, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - png_debug2(0, "Reading %s chunk, length = %u", - png_ptr->chunk_name, length); + png_debug2(0, "Reading %lx chunk, length = %lu", + (unsigned long)png_ptr->chunk_name, (unsigned long)length); /* Reset the crc and run it over the chunk name. */ png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); + png_calculate_crc(png_ptr, buf + 4, 4); /* Check to see if chunk name is valid. */ png_check_chunk_name(png_ptr, png_ptr->chunk_name); @@ -214,7 +212,7 @@ png_read_chunk_header(png_structp png_ptr) /* Read data, and (optionally) run it through the CRC. */ void /* PRIVATE */ -png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) +png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) { if (png_ptr == NULL) return; @@ -224,41 +222,40 @@ png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) } /* Optionally skip data and then check the CRC. Depending on whether we - * are reading a ancillary or critical chunk, and how the program has set + * are reading an ancillary or critical chunk, and how the program has set * things up, we may calculate the CRC on the data and print a message. * Returns '1' if there was a CRC error, '0' otherwise. */ int /* PRIVATE */ -png_crc_finish(png_structp png_ptr, png_uint_32 skip) +png_crc_finish(png_structrp png_ptr, png_uint_32 skip) { - png_size_t i; - png_size_t istop = png_ptr->zbuf_size; - - for (i = (png_size_t)skip; i > istop; i -= istop) + /* The size of the local buffer for inflate is a good guess as to a + * reasonable size to use for buffering reads from the application. + */ + while (skip > 0) { - png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); + png_uint_32 len; + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; + + len = (sizeof tmpbuf); + if (len > skip) + len = skip; + skip -= len; + + png_crc_read(png_ptr, tmpbuf, len); } - if (i) + if (png_crc_error(png_ptr) != 0) { - png_crc_read(png_ptr, png_ptr->zbuf, i); - } - - if (png_crc_error(png_ptr)) - { - if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ - !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || - (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ - (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) + if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? + (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) { png_chunk_warning(png_ptr, "CRC error"); } else - { - png_chunk_benign_error(png_ptr, "CRC error"); - return (0); - } + png_chunk_error(png_ptr, "CRC error"); return (1); } @@ -270,22 +267,22 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip) * the data it has read thus far. */ int /* PRIVATE */ -png_crc_error(png_structp png_ptr) +png_crc_error(png_structrp png_ptr) { png_byte crc_bytes[4]; png_uint_32 crc; int need_crc = 1; - if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) { if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) need_crc = 0; } - else /* critical */ + else /* critical */ { - if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) + if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) need_crc = 0; } @@ -296,7 +293,7 @@ png_crc_error(png_structp png_ptr) /* The chunk CRC must be serialized in a single I/O call. */ png_read_data(png_ptr, crc_bytes, 4); - if (need_crc) + if (need_crc != 0) { crc = png_get_uint_32(crc_bytes); return ((int)(crc != png_ptr->crc)); @@ -306,252 +303,522 @@ png_crc_error(png_structp png_ptr) return (0); } -#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED -static png_size_t -png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, - png_bytep output, png_size_t output_size) +#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ + defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ + defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ + defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) +/* Manage the read buffer; this simply reallocates the buffer if it is not small + * enough (or if it is not allocated). The routine returns a pointer to the + * buffer; if an error occurs and 'warn' is set the routine returns NULL, else + * it will call png_error (via png_malloc) on failure. (warn == 2 means + * 'silent'). + */ +static png_bytep +png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) { - png_size_t count = 0; + png_bytep buffer = png_ptr->read_buffer; - /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't - * even necessarily handle 65536 bytes) because the type uInt is "16 bits or - * more". Consequently it is necessary to chunk the input to zlib. This - * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value - * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a - * lower value in pngpriv.h and this may sometimes have a performance - * advantage, because it forces access of the input data to be separated from - * at least some of the use by some period of time. - */ - png_ptr->zstream.next_in = data; - /* avail_in is set below from 'size' */ - png_ptr->zstream.avail_in = 0; - - while (1) + if (buffer != NULL && new_size > png_ptr->read_buffer_size) { - int ret, avail; + png_ptr->read_buffer = NULL; + png_ptr->read_buffer = NULL; + png_ptr->read_buffer_size = 0; + png_free(png_ptr, buffer); + buffer = NULL; + } - /* The setting of 'avail_in' used to be outside the loop, by setting it - * inside it is possible to chunk the input to zlib and simply rely on - * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o - * data to be passed through zlib at the unavoidable cost of requiring a - * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX - * input bytes. - */ - if (png_ptr->zstream.avail_in == 0 && size > 0) + if (buffer == NULL) + { + buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); + + if (buffer != NULL) { - if (size <= ZLIB_IO_MAX) - { - /* The value is less than ZLIB_IO_MAX so the cast is safe: */ - png_ptr->zstream.avail_in = (uInt)size; - size = 0; - } - - else - { - png_ptr->zstream.avail_in = ZLIB_IO_MAX; - size -= ZLIB_IO_MAX; - } + png_ptr->read_buffer = buffer; + png_ptr->read_buffer_size = new_size; } - /* Reset the output buffer each time round - we empty it - * after every inflate call. - */ - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = png_ptr->zbuf_size; - - ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); - avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; - - /* First copy/count any new output - but only if we didn't - * get an error code. - */ - if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) + else if (warn < 2) /* else silent */ { - png_size_t space = avail; /* > 0, see above */ + if (warn != 0) + png_chunk_warning(png_ptr, "insufficient memory to read chunk"); - if (output != 0 && output_size > count) - { - png_size_t copy = output_size - count; + else + png_chunk_error(png_ptr, "insufficient memory to read chunk"); + } + } - if (space < copy) - copy = space; + return buffer; +} +#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ - png_memcpy(output + count, png_ptr->zbuf, copy); - } - count += space; +/* png_inflate_claim: claim the zstream for some nefarious purpose that involves + * decompression. Returns Z_OK on success, else a zlib error code. It checks + * the owner but, in final release builds, just issues a warning if some other + * chunk apparently owns the stream. Prior to release it does a png_error. + */ +static int +png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) +{ + if (png_ptr->zowner != 0) + { + char msg[64]; + + PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); + /* So the message that results is " using zstream"; this is an + * internal error, but is very useful for debugging. i18n requirements + * are minimal. + */ + (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); +#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_chunk_warning(png_ptr, msg); + png_ptr->zowner = 0; +#else + png_chunk_error(png_ptr, msg); +#endif + } + + /* Implementation note: unlike 'png_deflate_claim' this internal function + * does not take the size of the data as an argument. Some efficiency could + * be gained by using this when it is known *if* the zlib stream itself does + * not record the number; however, this is an illusion: the original writer + * of the PNG may have selected a lower window size, and we really must + * follow that because, for systems with with limited capabilities, we + * would otherwise reject the application's attempts to use a smaller window + * size (zlib doesn't have an interface to say "this or lower"!). + * + * inflateReset2 was added to zlib 1.2.4; before this the window could not be + * reset, therefore it is necessary to always allocate the maximum window + * size with earlier zlibs just in case later compressed chunks need it. + */ + { + int ret; /* zlib return code */ +#if PNG_ZLIB_VERNUM >= 0x1240 + +# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) + int window_bits; + + if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == + PNG_OPTION_ON) + window_bits = 15; + + else + window_bits = 0; +# else +# define window_bits 0 +# endif +#endif + + /* Set this for safety, just in case the previous owner left pointers to + * memory allocations. + */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->zstream.avail_out = 0; + + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) + { +#if PNG_ZLIB_VERNUM < 0x1240 + ret = inflateReset(&png_ptr->zstream); +#else + ret = inflateReset2(&png_ptr->zstream, window_bits); +#endif + } + + else + { +#if PNG_ZLIB_VERNUM < 0x1240 + ret = inflateInit(&png_ptr->zstream); +#else + ret = inflateInit2(&png_ptr->zstream, window_bits); +#endif + + if (ret == Z_OK) + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; } if (ret == Z_OK) - continue; + png_ptr->zowner = owner; - /* Termination conditions - always reset the zstream, it - * must be left in inflateInit state. + else + png_zstream_error(png_ptr, ret); + + return ret; + } + +#ifdef window_bits +# undef window_bits +#endif +} + +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to + * allow the caller to do multiple calls if required. If the 'finish' flag is + * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must + * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and + * Z_OK or Z_STREAM_END will be returned on success. + * + * The input and output sizes are updated to the actual amounts of data consumed + * or written, not the amount available (as in a z_stream). The data pointers + * are not changed, so the next input is (data+input_size) and the next + * available output is (output+output_size). + */ +static int +png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, + /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, + /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) +{ + if (png_ptr->zowner == owner) /* Else not claimed */ + { + int ret; + png_alloc_size_t avail_out = *output_size_ptr; + png_uint_32 avail_in = *input_size_ptr; + + /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it + * can't even necessarily handle 65536 bytes) because the type uInt is + * "16 bits or more". Consequently it is necessary to chunk the input to + * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the + * maximum value that can be stored in a uInt.) It is possible to set + * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have + * a performance advantage, because it reduces the amount of data accessed + * at each step and that may give the OS more time to page it in. */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); + /* avail_in and avail_out are set below from 'size' */ png_ptr->zstream.avail_in = 0; - inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_out = 0; - if (ret == Z_STREAM_END) - return count; /* NOTE: may be zero. */ - - /* Now handle the error codes - the API always returns 0 - * and the error message is dumped into the uncompressed - * buffer if available. + /* Read directly into the output if it is available (this is set to + * a local buffer below if output is NULL). */ -# ifdef PNG_WARNINGS_SUPPORTED + if (output != NULL) + png_ptr->zstream.next_out = output; + + do { - png_const_charp msg; + uInt avail; + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - if (png_ptr->zstream.msg != 0) - msg = png_ptr->zstream.msg; + /* zlib INPUT BUFFER */ + /* The setting of 'avail_in' used to be outside the loop; by setting it + * inside it is possible to chunk the input to zlib and simply rely on + * zlib to advance the 'next_in' pointer. This allows arbitrary + * amounts of data to be passed through zlib at the unavoidable cost of + * requiring a window save (memcpy of up to 32768 output bytes) + * every ZLIB_IO_MAX input bytes. + */ + avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ - else switch (ret) + avail = ZLIB_IO_MAX; + + if (avail_in < avail) + avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ + + avail_in -= avail; + png_ptr->zstream.avail_in = avail; + + /* zlib OUTPUT BUFFER */ + avail_out += png_ptr->zstream.avail_out; /* not written last time */ + + avail = ZLIB_IO_MAX; /* maximum zlib can process */ + + if (output == NULL) { - case Z_BUF_ERROR: - msg = "Buffer error in compressed datastream"; - break; - - case Z_DATA_ERROR: - msg = "Data error in compressed datastream"; - break; - - default: - msg = "Incomplete compressed datastream"; - break; + /* Reset the output buffer each time round if output is NULL and + * make available the full buffer, up to 'remaining_space' + */ + png_ptr->zstream.next_out = local_buffer; + if ((sizeof local_buffer) < avail) + avail = (sizeof local_buffer); } - png_chunk_warning(png_ptr, msg); - } -# endif + if (avail_out < avail) + avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ - /* 0 means an error - notice that this code simply ignores - * zero length compressed chunks as a result. + png_ptr->zstream.avail_out = avail; + avail_out -= avail; + + /* zlib inflate call */ + /* In fact 'avail_out' may be 0 at this point, that happens at the end + * of the read when the final LZ end code was not passed at the end of + * the previous chunk of input data. Tell zlib if we have reached the + * end of the output buffer. + */ + ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : + (finish ? Z_FINISH : Z_SYNC_FLUSH)); + } while (ret == Z_OK); + + /* For safety kill the local buffer pointer now */ + if (output == NULL) + png_ptr->zstream.next_out = NULL; + + /* Claw back the 'size' and 'remaining_space' byte counts. */ + avail_in += png_ptr->zstream.avail_in; + avail_out += png_ptr->zstream.avail_out; + + /* Update the input and output sizes; the updated values are the amount + * consumed or written, effectively the inverse of what zlib uses. */ - return 0; + if (avail_out > 0) + *output_size_ptr -= avail_out; + + if (avail_in > 0) + *input_size_ptr -= avail_in; + + /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ + png_zstream_error(png_ptr, ret); + return ret; + } + + else + { + /* This is a bad internal error. The recovery assigns to the zstream msg + * pointer, which is not owned by the caller, but this is safe; it's only + * used on errors! + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); + return Z_STREAM_ERROR; } } /* - * Decompress trailing data in a chunk. The assumption is that chunkdata + * Decompress trailing data in a chunk. The assumption is that read_buffer * points at an allocated area holding the contents of a chunk with a * trailing compressed part. What we get back is an allocated area * holding the original prefix part and an uncompressed version of the * trailing part (the malloc area passed in is freed). */ -void /* PRIVATE */ -png_decompress_chunk(png_structp png_ptr, int comp_type, - png_size_t chunklength, - png_size_t prefix_size, png_size_t *newlength) +static int +png_decompress_chunk(png_structrp png_ptr, + png_uint_32 chunklength, png_uint_32 prefix_size, + png_alloc_size_t *newlength /* must be initialized to the maximum! */, + int terminate /*add a '\0' to the end of the uncompressed data*/) { - /* The caller should guarantee this */ - if (prefix_size > chunklength) + /* TODO: implement different limits for different types of chunk. + * + * The caller supplies *newlength set to the maximum length of the + * uncompressed data, but this routine allocates space for the prefix and + * maybe a '\0' terminator too. We have to assume that 'prefix_size' is + * limited only by the maximum chunk size. + */ + png_alloc_size_t limit = PNG_SIZE_MAX; + +# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; +# endif + + if (limit >= prefix_size + (terminate != 0)) { - /* The recovery is to delete the chunk. */ - png_warning(png_ptr, "invalid chunklength"); - prefix_size = 0; /* To delete everything */ - } + int ret; - else if (comp_type == PNG_COMPRESSION_TYPE_BASE) - { - png_size_t expanded_size = png_inflate(png_ptr, - (png_bytep)(png_ptr->chunkdata + prefix_size), - chunklength - prefix_size, - 0, /* output */ - 0); /* output size */ + limit -= prefix_size + (terminate != 0); - /* Now check the limits on this chunk - if the limit fails the - * compressed data will be removed, the prefix will remain. - */ -#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED - if (png_ptr->user_chunk_malloc_max && - (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) -#else -# ifdef PNG_USER_CHUNK_MALLOC_MAX - if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && - prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) -# endif -#endif - png_warning(png_ptr, "Exceeded size limit while expanding chunk"); + if (limit < *newlength) + *newlength = limit; - /* If the size is zero either there was an error and a message - * has already been output (warning) or the size really is zero - * and we have nothing to do - the code will exit through the - * error case below. - */ -#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ - defined(PNG_USER_CHUNK_MALLOC_MAX) - else if (expanded_size > 0) -#else - if (expanded_size > 0) -#endif + /* Now try to claim the stream. */ + ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); + + if (ret == Z_OK) { - /* Success (maybe) - really uncompress the chunk. */ - png_size_t new_size = 0; - png_charp text = png_malloc_warn(png_ptr, - prefix_size + expanded_size + 1); + png_uint_32 lzsize = chunklength - prefix_size; - if (text != NULL) + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, + /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, + /* output: */ NULL, newlength); + + if (ret == Z_STREAM_END) { - png_memcpy(text, png_ptr->chunkdata, prefix_size); - new_size = png_inflate(png_ptr, - (png_bytep)(png_ptr->chunkdata + prefix_size), - chunklength - prefix_size, - (png_bytep)(text + prefix_size), expanded_size); - text[prefix_size + expanded_size] = 0; /* just in case */ - - if (new_size == expanded_size) + /* Use 'inflateReset' here, not 'inflateReset2' because this + * preserves the previously decided window size (otherwise it would + * be necessary to store the previous window size.) In practice + * this doesn't matter anyway, because png_inflate will call inflate + * with Z_FINISH in almost all cases, so the window will not be + * maintained. + */ + if (inflateReset(&png_ptr->zstream) == Z_OK) { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = text; - *newlength = prefix_size + expanded_size; - return; /* The success return! */ + /* Because of the limit checks above we know that the new, + * expanded, size will fit in a size_t (let alone an + * png_alloc_size_t). Use png_malloc_base here to avoid an + * extra OOM message. + */ + png_alloc_size_t new_size = *newlength; + png_alloc_size_t buffer_size = prefix_size + new_size + + (terminate != 0); + png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, + buffer_size)); + + if (text != NULL) + { + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, + png_ptr->read_buffer + prefix_size, &lzsize, + text + prefix_size, newlength); + + if (ret == Z_STREAM_END) + { + if (new_size == *newlength) + { + if (terminate != 0) + text[prefix_size + *newlength] = 0; + + if (prefix_size > 0) + memcpy(text, png_ptr->read_buffer, prefix_size); + + { + png_bytep old_ptr = png_ptr->read_buffer; + + png_ptr->read_buffer = text; + png_ptr->read_buffer_size = buffer_size; + text = old_ptr; /* freed below */ + } + } + + else + { + /* The size changed on the second read, there can be no + * guarantee that anything is correct at this point. + * The 'msg' pointer has been set to "unexpected end of + * LZ stream", which is fine, but return an error code + * that the caller won't accept. + */ + ret = PNG_UNEXPECTED_ZLIB_RETURN; + } + } + + else if (ret == Z_OK) + ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ + + /* Free the text pointer (this is the old read_buffer on + * success) + */ + png_free(png_ptr, text); + text = NULL; + + /* This really is very benign, but it's still an error because + * the extra space may otherwise be used as a Trojan Horse. + */ + if (ret == Z_STREAM_END && + chunklength - prefix_size != lzsize) + png_chunk_benign_error(png_ptr, "extra compressed data"); + } + + else + { + /* Out of memory allocating the buffer */ + ret = Z_MEM_ERROR; + png_zstream_error(png_ptr, Z_MEM_ERROR); + } } - png_warning(png_ptr, "png_inflate logic error"); - png_free(png_ptr, text); + else + { + /* inflateReset failed, store the error message */ + png_zstream_error(png_ptr, ret); + + if (ret == Z_STREAM_END) + ret = PNG_UNEXPECTED_ZLIB_RETURN; + } } - else - png_warning(png_ptr, "Not enough memory to decompress chunk"); + else if (ret == Z_OK) + ret = PNG_UNEXPECTED_ZLIB_RETURN; + + /* Release the claimed stream */ + png_ptr->zowner = 0; } + + else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ + ret = PNG_UNEXPECTED_ZLIB_RETURN; + + return ret; } - else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ + else { - PNG_WARNING_PARAMETERS(p) - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); - png_formatted_warning(png_ptr, p, "Unknown zTXt compression type @1"); - - /* The recovery is to simply drop the data. */ + /* Application/configuration limits exceeded */ + png_zstream_error(png_ptr, Z_MEM_ERROR); + return Z_MEM_ERROR; } - - /* Generic error return - leave the prefix, delete the compressed - * data, reallocate the chunkdata to remove the potentially large - * amount of compressed data. - */ - { - png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); - - if (text != NULL) - { - if (prefix_size > 0) - png_memcpy(text, png_ptr->chunkdata, prefix_size); - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = text; - - /* This is an extra zero in the 'uncompressed' part. */ - *(png_ptr->chunkdata + prefix_size) = 0x00; - } - /* Ignore a malloc error here - it is safe. */ - } - - *newlength = prefix_size; } -#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ +#endif /* READ_COMPRESSED_TEXT */ + +#ifdef PNG_READ_iCCP_SUPPORTED +/* Perform a partial read and decompress, producing 'avail_out' bytes and + * reading from the current chunk as required. + */ +static int +png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, + png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, + int finish) +{ + if (png_ptr->zowner == png_ptr->chunk_name) + { + int ret; + + /* next_in and avail_in must have been initialized by the caller. */ + png_ptr->zstream.next_out = next_out; + png_ptr->zstream.avail_out = 0; /* set in the loop */ + + do + { + if (png_ptr->zstream.avail_in == 0) + { + if (read_size > *chunk_bytes) + read_size = (uInt)*chunk_bytes; + *chunk_bytes -= read_size; + + if (read_size > 0) + png_crc_read(png_ptr, read_buffer, read_size); + + png_ptr->zstream.next_in = read_buffer; + png_ptr->zstream.avail_in = read_size; + } + + if (png_ptr->zstream.avail_out == 0) + { + uInt avail = ZLIB_IO_MAX; + if (avail > *out_size) + avail = (uInt)*out_size; + *out_size -= avail; + + png_ptr->zstream.avail_out = avail; + } + + /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all + * the available output is produced; this allows reading of truncated + * streams. + */ + ret = inflate(&png_ptr->zstream, + *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); + } + while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); + + *out_size += png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ + + /* Ensure the error message pointer is always set: */ + png_zstream_error(png_ptr, ret); + return ret; + } + + else + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); + return Z_STREAM_ERROR; + } +} +#endif /* Read and check the IDHR chunk */ + void /* PRIVATE */ -png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[13]; png_uint_32 width, height; @@ -560,12 +827,12 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_IHDR"); - if (png_ptr->mode & PNG_HAVE_IHDR) - png_error(png_ptr, "Out of place IHDR"); + if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) + png_chunk_error(png_ptr, "out of place"); /* Check the length */ if (length != 13) - png_error(png_ptr, "Invalid IHDR chunk"); + png_chunk_error(png_ptr, "invalid"); png_ptr->mode |= PNG_HAVE_IHDR; @@ -614,8 +881,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } /* Set up other useful info */ - png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * - png_ptr->channels); + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); png_debug1(3, "channels = %d", png_ptr->channels); @@ -626,7 +892,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Read and check the palette */ void /* PRIVATE */ -png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_color palette[PNG_MAX_PALETTE_LENGTH]; int num, i; @@ -636,26 +902,33 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_PLTE"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before PLTE"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + /* Moved to before the 'after IDAT' check below because otherwise duplicate + * PLTE chunks are potentially ignored (the spec says there shall not be more + * than one PLTE, the error is not treated as benign, so this check trumps + * the requirement that PLTE appears before IDAT.) + */ + else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) + png_chunk_error(png_ptr, "duplicate"); + + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid PLTE after IDAT"); + /* This is benign because the non-benign error happened before, when an + * IDAT was encountered in a color-mapped image with no PLTE. + */ png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (png_ptr->mode & PNG_HAVE_PLTE) - png_error(png_ptr, "Duplicate PLTE chunk"); - png_ptr->mode |= PNG_HAVE_PLTE; - if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) { - png_warning(png_ptr, - "Ignoring PLTE chunk in grayscale PNG"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); return; } @@ -669,19 +942,18 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) { + png_crc_finish(png_ptr, length); + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - png_warning(png_ptr, "Invalid palette chunk"); - png_crc_finish(png_ptr, length); - return; - } + png_chunk_benign_error(png_ptr, "invalid"); else - { - png_error(png_ptr, "Invalid palette chunk"); - } + png_chunk_error(png_ptr, "invalid"); + + return; } + /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ num = (int)length / 3; #ifdef PNG_POINTER_INDEXING_SUPPORTED @@ -720,214 +992,196 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #ifndef PNG_READ_OPT_PLTE_SUPPORTED - else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ + else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ { /* If we don't want to use the data from an ancillary chunk, * we have two options: an error abort, or a warning and we * ignore the data in this chunk (which should be OK, since * it's considered ancillary for a RGB or RGBA image). + * + * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the + * chunk type to determine whether to check the ancillary or the critical + * flags. */ - if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) { - if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) - { - png_chunk_benign_error(png_ptr, "CRC error"); - } + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) + return; else - { - png_chunk_warning(png_ptr, "CRC error"); - return; - } + png_chunk_error(png_ptr, "CRC error"); } /* Otherwise, we (optionally) emit a warning and use the chunk. */ - else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) - { + else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) png_chunk_warning(png_ptr, "CRC error"); - } } #endif + /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its + * own copy of the palette. This has the side effect that when png_start_row + * is called (this happens after any call to png_read_update_info) the + * info_ptr palette gets changed. This is extremely unexpected and + * confusing. + * + * Fix this by not sharing the palette in this way. + */ png_set_PLTE(png_ptr, info_ptr, palette, num); + /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before + * IDAT. Prior to 1.6.0 this was not checked; instead the code merely + * checked the apparent validity of a tRNS chunk inserted before PLTE on a + * palette PNG. 1.6.0 attempts to rigorously follow the standard and + * therefore does a benign error if the erroneous condition is detected *and* + * cancels the tRNS if the benign error returns. The alternative is to + * amend the standard since it would be rather hypocritical of the standards + * maintainers to ignore it. + */ #ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + if (png_ptr->num_trans > 0 || + (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) { - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) - { - if (png_ptr->num_trans > (png_uint_16)num) - { - png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); - png_ptr->num_trans = (png_uint_16)num; - } + /* Cancel this because otherwise it would be used if the transforms + * require it. Don't cancel the 'valid' flag because this would prevent + * detection of duplicate chunks. + */ + png_ptr->num_trans = 0; - if (info_ptr->num_trans > (png_uint_16)num) - { - png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); - info_ptr->num_trans = (png_uint_16)num; - } - } + if (info_ptr != NULL) + info_ptr->num_trans = 0; + + png_chunk_benign_error(png_ptr, "tRNS must be after"); } #endif +#ifdef PNG_READ_hIST_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) + png_chunk_benign_error(png_ptr, "hIST must be after"); +#endif + +#ifdef PNG_READ_bKGD_SUPPORTED + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) + png_chunk_benign_error(png_ptr, "bKGD must be after"); +#endif } void /* PRIVATE */ -png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_debug(1, "in png_handle_IEND"); - if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) - { - png_error(png_ptr, "No image in file"); - } + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || + (png_ptr->mode & PNG_HAVE_IDAT) == 0) + png_chunk_error(png_ptr, "out of place"); png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); - if (length != 0) - { - png_warning(png_ptr, "Incorrect IEND chunk length"); - } - png_crc_finish(png_ptr, length); - PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ + if (length != 0) + png_chunk_benign_error(png_ptr, "invalid"); + + PNG_UNUSED(info_ptr) } #ifdef PNG_READ_gAMA_SUPPORTED void /* PRIVATE */ -png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_fixed_point igamma; png_byte buf[4]; png_debug(1, "in png_handle_gAMA"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before gAMA"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) { - png_warning(png_ptr, "Invalid gAMA after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place gAMA chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) -#ifdef PNG_READ_sRGB_SUPPORTED - && !(info_ptr->valid & PNG_INFO_sRGB) -#endif - ) - { - png_warning(png_ptr, "Duplicate gAMA chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } if (length != 4) { - png_warning(png_ptr, "Incorrect gAMA chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_crc_read(png_ptr, buf, 4); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; igamma = png_get_fixed_point(NULL, buf); - /* Check for zero gamma or an error. */ - if (igamma <= 0) - { - png_warning(png_ptr, - "Ignoring gAMA chunk with out of range gamma"); - - return; - } - -# ifdef PNG_READ_sRGB_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) - { - if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) - { - PNG_WARNING_PARAMETERS(p) - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); - png_formatted_warning(png_ptr, p, - "Ignoring incorrect gAMA value @1 when sRGB is also present"); - return; - } - } -# endif /* PNG_READ_sRGB_SUPPORTED */ - -# ifdef PNG_READ_GAMMA_SUPPORTED - /* Gamma correction on read is supported. */ - png_ptr->gamma = igamma; -# endif - /* And set the 'info' structure members. */ - png_set_gAMA_fixed(png_ptr, info_ptr, igamma); + png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); + png_colorspace_sync(png_ptr, info_ptr); } #endif #ifdef PNG_READ_sBIT_SUPPORTED void /* PRIVATE */ -png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_size_t truelen; + unsigned int truelen, i; + png_byte sample_depth; png_byte buf[4]; png_debug(1, "in png_handle_sBIT"); - buf[0] = buf[1] = buf[2] = buf[3] = 0; + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sBIT"); - - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) { - png_warning(png_ptr, "Invalid sBIT after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (png_ptr->mode & PNG_HAVE_PLTE) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) { - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place sBIT chunk"); - } - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) - { - png_warning(png_ptr, "Duplicate sBIT chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { truelen = 3; + sample_depth = 8; + } else - truelen = (png_size_t)png_ptr->channels; + { + truelen = png_ptr->channels; + sample_depth = png_ptr->bit_depth; + } if (length != truelen || length > 4) { - png_warning(png_ptr, "Incorrect sBIT chunk length"); + png_chunk_benign_error(png_ptr, "invalid"); png_crc_finish(png_ptr, length); return; } + buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; png_crc_read(png_ptr, buf, truelen); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; - if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + for (i=0; i sample_depth) + { + png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) { png_ptr->sig_bit.red = buf[0]; png_ptr->sig_bit.green = buf[1]; @@ -950,377 +1204,416 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_cHRM_SUPPORTED void /* PRIVATE */ -png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[32]; - png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, - y_blue; + png_xy xy; png_debug(1, "in png_handle_cHRM"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before cHRM"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) { - png_warning(png_ptr, "Invalid cHRM after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Missing PLTE before cHRM"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) -# ifdef PNG_READ_sRGB_SUPPORTED - && !(info_ptr->valid & PNG_INFO_sRGB) -# endif - ) - { - png_warning(png_ptr, "Duplicate cHRM chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } if (length != 32) { - png_warning(png_ptr, "Incorrect cHRM chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_crc_read(png_ptr, buf, 32); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; - x_white = png_get_fixed_point(NULL, buf); - y_white = png_get_fixed_point(NULL, buf + 4); - x_red = png_get_fixed_point(NULL, buf + 8); - y_red = png_get_fixed_point(NULL, buf + 12); - x_green = png_get_fixed_point(NULL, buf + 16); - y_green = png_get_fixed_point(NULL, buf + 20); - x_blue = png_get_fixed_point(NULL, buf + 24); - y_blue = png_get_fixed_point(NULL, buf + 28); + xy.whitex = png_get_fixed_point(NULL, buf); + xy.whitey = png_get_fixed_point(NULL, buf + 4); + xy.redx = png_get_fixed_point(NULL, buf + 8); + xy.redy = png_get_fixed_point(NULL, buf + 12); + xy.greenx = png_get_fixed_point(NULL, buf + 16); + xy.greeny = png_get_fixed_point(NULL, buf + 20); + xy.bluex = png_get_fixed_point(NULL, buf + 24); + xy.bluey = png_get_fixed_point(NULL, buf + 28); - if (x_white == PNG_FIXED_ERROR || - y_white == PNG_FIXED_ERROR || - x_red == PNG_FIXED_ERROR || - y_red == PNG_FIXED_ERROR || - x_green == PNG_FIXED_ERROR || - y_green == PNG_FIXED_ERROR || - x_blue == PNG_FIXED_ERROR || - y_blue == PNG_FIXED_ERROR) + if (xy.whitex == PNG_FIXED_ERROR || + xy.whitey == PNG_FIXED_ERROR || + xy.redx == PNG_FIXED_ERROR || + xy.redy == PNG_FIXED_ERROR || + xy.greenx == PNG_FIXED_ERROR || + xy.greeny == PNG_FIXED_ERROR || + xy.bluex == PNG_FIXED_ERROR || + xy.bluey == PNG_FIXED_ERROR) { - png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); + png_chunk_benign_error(png_ptr, "invalid values"); return; } -#ifdef PNG_READ_sRGB_SUPPORTED - if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) + /* If a colorspace error has already been output skip this chunk */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) + return; + + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) { - if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(x_red, 64000L, 1000) || - PNG_OUT_OF_RANGE(y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(y_green, 60000L, 1000) || - PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); - png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); - png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); - png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); - png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); - png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); - png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); - png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); - - png_formatted_warning(png_ptr, p, - "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " - "when sRGB is also present"); - } + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; + png_colorspace_sync(png_ptr, info_ptr); + png_chunk_benign_error(png_ptr, "duplicate"); return; } -#endif /* PNG_READ_sRGB_SUPPORTED */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Store the _white values as default coefficients for the rgb to gray - * operation if it is supported. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) - { - /* png_set_background has not been called, the coefficients must be in - * range for the following to work without overflow. - */ - if (y_red <= (1<<17) && y_green <= (1<<17) && y_blue <= (1<<17)) - { - /* The y values are chromaticities: Y/X+Y+Z, the weights for the gray - * transformation are simply the normalized Y values for red, green and - * blue scaled by 32768. - */ - png_uint_32 w = y_red + y_green + y_blue; - - png_ptr->rgb_to_gray_red_coeff = (png_uint_16)(((png_uint_32)y_red * - 32768)/w); - png_ptr->rgb_to_gray_green_coeff = (png_uint_16)(((png_uint_32)y_green - * 32768)/w); - png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(((png_uint_32)y_blue * - 32768)/w); - } - } -#endif - - png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, - x_green, y_green, x_blue, y_blue); + png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, + 1/*prefer cHRM values*/); + png_colorspace_sync(png_ptr, info_ptr); } #endif #ifdef PNG_READ_sRGB_SUPPORTED void /* PRIVATE */ -png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - int intent; - png_byte buf[1]; + png_byte intent; png_debug(1, "in png_handle_sRGB"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sRGB"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) { - png_warning(png_ptr, "Invalid sRGB after IDAT"); - png_crc_finish(png_ptr, length); - return; - } - - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place sRGB chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) - { - png_warning(png_ptr, "Duplicate sRGB chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } if (length != 1) { - png_warning(png_ptr, "Incorrect sRGB chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } - png_crc_read(png_ptr, buf, 1); + png_crc_read(png_ptr, &intent, 1); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; - intent = buf[0]; + /* If a colorspace error has already been output skip this chunk */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) + return; - /* Check for bad intent */ - if (intent >= PNG_sRGB_INTENT_LAST) + /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect + * this. + */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) { - png_warning(png_ptr, "Unknown sRGB intent"); + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; + png_colorspace_sync(png_ptr, info_ptr); + png_chunk_benign_error(png_ptr, "too many profiles"); return; } -#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) - { - if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, - info_ptr->gamma); - - png_formatted_warning(png_ptr, p, - "Ignoring incorrect gAMA value @1 when sRGB is also present"); - } - } -#endif /* PNG_READ_gAMA_SUPPORTED */ - -#ifdef PNG_READ_cHRM_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(info_ptr->x_red, 64000L, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) || - PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) - { - png_warning(png_ptr, - "Ignoring incorrect cHRM value when sRGB is also present"); - } -#endif /* PNG_READ_cHRM_SUPPORTED */ - - png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); + (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); + png_colorspace_sync(png_ptr, info_ptr); } -#endif /* PNG_READ_sRGB_SUPPORTED */ +#endif /* READ_sRGB */ #ifdef PNG_READ_iCCP_SUPPORTED void /* PRIVATE */ -png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -/* Note: this does not properly handle chunks that are > 64K under DOS */ +png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +/* Note: this does not properly handle profiles that are > 64K under DOS */ { - png_byte compression_type; - png_bytep pC; - png_charp profile; - png_uint_32 skip = 0; - png_uint_32 profile_size; - png_alloc_size_t profile_length; - png_size_t slength, prefix_length, data_length; + png_const_charp errmsg = NULL; /* error message output, or no error */ + int finished = 0; /* crc checked */ png_debug(1, "in png_handle_iCCP"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before iCCP"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + /* Consistent with all the above colorspace handling an obviously *invalid* + * chunk is just ignored, so does not invalidate the color space. An + * alternative is to set the 'invalid' flags at the start of this routine + * and only clear them in they were not set before and all the tests pass. + * The minimum 'deflate' stream is assumed to be just the 2 byte header and + * 4 byte checksum. The keyword must be at least one character and there is + * a terminator (0) byte and the compression method. + */ + if (length < 9) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too short"); + return; + } + + /* If a colorspace error has already been output skip this chunk */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) { - png_warning(png_ptr, "Invalid iCCP after IDAT"); png_crc_finish(png_ptr, length); return; } - else if (png_ptr->mode & PNG_HAVE_PLTE) - /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place iCCP chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) + /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect + * this. + */ + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) { - png_warning(png_ptr, "Duplicate iCCP chunk"); + uInt read_length, keyword_length; + char keyword[81]; + + /* Find the keyword; the keyword plus separator and compression method + * bytes can be at most 81 characters long. + */ + read_length = 81; /* maximum */ + if (read_length > length) + read_length = (uInt)length; + + png_crc_read(png_ptr, (png_bytep)keyword, read_length); + length -= read_length; + + keyword_length = 0; + while (keyword_length < 80 && keyword_length < read_length && + keyword[keyword_length] != 0) + ++keyword_length; + + /* TODO: make the keyword checking common */ + if (keyword_length >= 1 && keyword_length <= 79) + { + /* We only understand '0' compression - deflate - so if we get a + * different value we can't safely decode the chunk. + */ + if (keyword_length+1 < read_length && + keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) + { + read_length -= keyword_length+2; + + if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) + { + Byte profile_header[132]; + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; + png_alloc_size_t size = (sizeof profile_header); + + png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); + png_ptr->zstream.avail_in = read_length; + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, profile_header, &size, + 0/*finish: don't, because the output is too small*/); + + if (size == 0) + { + /* We have the ICC profile header; do the basic header checks. + */ + const png_uint_32 profile_length = + png_get_uint_32(profile_header); + + if (png_icc_check_length(png_ptr, &png_ptr->colorspace, + keyword, profile_length) != 0) + { + /* The length is apparently ok, so we can check the 132 + * byte header. + */ + if (png_icc_check_header(png_ptr, &png_ptr->colorspace, + keyword, profile_length, profile_header, + png_ptr->color_type) != 0) + { + /* Now read the tag table; a variable size buffer is + * needed at this point, allocate one for the whole + * profile. The header check has already validated + * that none of these stuff will overflow. + */ + const png_uint_32 tag_count = png_get_uint_32( + profile_header+128); + png_bytep profile = png_read_buffer(png_ptr, + profile_length, 2/*silent*/); + + if (profile != NULL) + { + memcpy(profile, profile_header, + (sizeof profile_header)); + + size = 12 * tag_count; + + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, + profile + (sizeof profile_header), &size, 0); + + /* Still expect a buffer error because we expect + * there to be some tag data! + */ + if (size == 0) + { + if (png_icc_check_tag_table(png_ptr, + &png_ptr->colorspace, keyword, profile_length, + profile) != 0) + { + /* The profile has been validated for basic + * security issues, so read the whole thing in. + */ + size = profile_length - (sizeof profile_header) + - 12 * tag_count; + + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, + profile + (sizeof profile_header) + + 12 * tag_count, &size, 1/*finish*/); + + if (length > 0 && !(png_ptr->flags & + PNG_FLAG_BENIGN_ERRORS_WARN)) + errmsg = "extra compressed data"; + + /* But otherwise allow extra data: */ + else if (size == 0) + { + if (length > 0) + { + /* This can be handled completely, so + * keep going. + */ + png_chunk_warning(png_ptr, + "extra compressed data"); + } + + png_crc_finish(png_ptr, length); + finished = 1; + +# ifdef PNG_sRGB_SUPPORTED + /* Check for a match against sRGB */ + png_icc_set_sRGB(png_ptr, + &png_ptr->colorspace, profile, + png_ptr->zstream.adler); +# endif + + /* Steal the profile for info_ptr. */ + if (info_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, + PNG_FREE_ICCP, 0); + + info_ptr->iccp_name = png_voidcast(char*, + png_malloc_base(png_ptr, + keyword_length+1)); + if (info_ptr->iccp_name != NULL) + { + memcpy(info_ptr->iccp_name, keyword, + keyword_length+1); + info_ptr->iccp_proflen = + profile_length; + info_ptr->iccp_profile = profile; + png_ptr->read_buffer = NULL; /*steal*/ + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; + } + + else + { + png_ptr->colorspace.flags |= + PNG_COLORSPACE_INVALID; + errmsg = "out of memory"; + } + } + + /* else the profile remains in the read + * buffer which gets reused for subsequent + * chunks. + */ + + if (info_ptr != NULL) + png_colorspace_sync(png_ptr, info_ptr); + + if (errmsg == NULL) + { + png_ptr->zowner = 0; + return; + } + } + + else if (size > 0) + errmsg = "truncated"; + + else + errmsg = png_ptr->zstream.msg; + } + + /* else png_icc_check_tag_table output an error */ + } + + else /* profile truncated */ + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "out of memory"; + } + + /* else png_icc_check_header output an error */ + } + + /* else png_icc_check_length output an error */ + } + + else /* profile truncated */ + errmsg = png_ptr->zstream.msg; + + /* Release the stream */ + png_ptr->zowner = 0; + } + + else /* png_inflate_claim failed */ + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "bad compression method"; /* or missing */ + } + + else + errmsg = "bad keyword"; + } + + else + errmsg = "too many profiles"; + + /* Failure: the reason is in 'errmsg' */ + if (finished == 0) png_crc_finish(png_ptr, length); - return; - } -#ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "iCCP chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - - if (png_crc_finish(png_ptr, skip)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - png_ptr->chunkdata[slength] = 0x00; - - for (profile = png_ptr->chunkdata; *profile; profile++) - /* Empty loop to find end of name */ ; - - ++profile; - - /* There should be at least one zero (the compression type byte) - * following the separator, and we should be on it - */ - if (profile >= png_ptr->chunkdata + slength - 1) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "Malformed iCCP chunk"); - return; - } - - /* Compression_type should always be zero */ - compression_type = *profile++; - - if (compression_type) - { - png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); - compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 - wrote nonzero) */ - } - - prefix_length = profile - png_ptr->chunkdata; - png_decompress_chunk(png_ptr, compression_type, - slength, prefix_length, &data_length); - - profile_length = data_length - prefix_length; - - if (prefix_length > data_length || profile_length < 4) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "Profile size field missing from iCCP chunk"); - return; - } - - /* Check the profile_size recorded in the first 32 bits of the ICC profile */ - pC = (png_bytep)(png_ptr->chunkdata + prefix_length); - profile_size = ((*(pC )) << 24) | - ((*(pC + 1)) << 16) | - ((*(pC + 2)) << 8) | - ((*(pC + 3)) ); - - /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, - * because profile_size is a 32 bit value. - */ - if (profile_size < profile_length) - profile_length = profile_size; - - /* And the following guarantees that profile_size == profile_length. */ - if (profile_size > profile_length) - { - PNG_WARNING_PARAMETERS(p) - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - - png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); - png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); - png_formatted_warning(png_ptr, p, - "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); - return; - } - - png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, - compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, - profile_size); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; + png_colorspace_sync(png_ptr, info_ptr); + if (errmsg != NULL) /* else already output */ + png_chunk_benign_error(png_ptr, errmsg); } -#endif /* PNG_READ_iCCP_SUPPORTED */ +#endif /* READ_iCCP */ #ifdef PNG_READ_sPLT_SUPPORTED void /* PRIVATE */ -png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { - png_bytep entry_start; + png_bytep entry_start, buffer; png_sPLT_t new_palette; png_sPLT_entryp pp; png_uint_32 data_length; int entry_size, i; png_uint_32 skip = 0; - png_size_t slength; png_uint_32 dl; png_size_t max_dl; png_debug(1, "in png_handle_sPLT"); #ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) { if (png_ptr->user_chunk_cache_max == 1) @@ -1338,55 +1631,53 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sPLT"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid sPLT after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } #ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) + if (length > 65535U) { - png_warning(png_ptr, "sPLT chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too large to fit in memory"); + return; } #endif - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + /* WARNING: this may break if size_t is less than 32 bits; it is assumed * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a * potential breakage point if the types in pngconf.h aren't exactly right. */ - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_crc_read(png_ptr, buffer, length); - if (png_crc_finish(png_ptr, skip)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + if (png_crc_finish(png_ptr, skip) != 0) return; - } - png_ptr->chunkdata[slength] = 0x00; + buffer[length] = 0; - for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; - entry_start++) + for (entry_start = buffer; *entry_start; entry_start++) /* Empty loop to find end of name */ ; ++entry_start; /* A sample depth should follow the separator, and we should be on it */ - if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) + if (entry_start > buffer + length - 2) { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; png_warning(png_ptr, "malformed sPLT chunk"); return; } @@ -1394,23 +1685,19 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) new_palette.depth = *entry_start++; entry_size = (new_palette.depth == 8 ? 6 : 10); /* This must fit in a png_uint_32 because it is derived from the original - * chunk data length (and use 'length', not 'slength' here for clarity - - * they are guaranteed to be the same, see the tests above.) + * chunk data length. */ - data_length = length - (png_uint_32)(entry_start - - (png_bytep)png_ptr->chunkdata); + data_length = length - (png_uint_32)(entry_start - buffer); /* Integrity-check the data length */ - if (data_length % entry_size) + if ((data_length % entry_size) != 0) { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; png_warning(png_ptr, "sPLT chunk has bad length"); return; } dl = (png_int_32)(data_length / entry_size); - max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); + max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); if (dl > max_dl) { @@ -1421,7 +1708,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) new_palette.nentries = (png_int_32)(data_length / entry_size); new_palette.entries = (png_sPLT_entryp)png_malloc_warn( - png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); + png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry))); if (new_palette.entries == NULL) { @@ -1479,38 +1766,36 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif /* Discard all chunk data except the name and stash that */ - new_palette.name = png_ptr->chunkdata; + new_palette.name = (png_charp)buffer; png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; png_free(png_ptr, new_palette.entries); } -#endif /* PNG_READ_sPLT_SUPPORTED */ +#endif /* READ_sPLT */ #ifdef PNG_READ_tRNS_SUPPORTED void /* PRIVATE */ -png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_tRNS"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before tRNS"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid tRNS after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) { - png_warning(png_ptr, "Duplicate tRNS chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } @@ -1520,8 +1805,8 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (length != 2) { - png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } @@ -1536,12 +1821,12 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (length != 6) { - png_warning(png_ptr, "Incorrect tRNS chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } - png_crc_read(png_ptr, buf, (png_size_t)length); + png_crc_read(png_ptr, buf, length); png_ptr->num_trans = 1; png_ptr->trans_color.red = png_get_uint_16(buf); png_ptr->trans_color.green = png_get_uint_16(buf + 2); @@ -1550,44 +1835,43 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - if (!(png_ptr->mode & PNG_HAVE_PLTE)) + if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) { - /* Should be an error, but we can cope with it. */ - png_warning(png_ptr, "Missing PLTE before tRNS"); - } - - if (length > (png_uint_32)png_ptr->num_palette || - length > PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, "Incorrect tRNS chunk length"); + /* TODO: is this actually an error in the ISO spec? */ png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - if (length == 0) + if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH || + length == 0) { - png_warning(png_ptr, "Zero length tRNS chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } - png_crc_read(png_ptr, readbuf, (png_size_t)length); + png_crc_read(png_ptr, readbuf, length); png_ptr->num_trans = (png_uint_16)length; } else { - png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid with alpha channel"); return; } - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) { png_ptr->num_trans = 0; return; } + /* TODO: this is a horrible side effect in the palette case because the + * png_struct ends up with a pointer to the tRNS buffer owned by the + * png_info. Fix this. + */ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, &(png_ptr->trans_color)); } @@ -1595,43 +1879,37 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_bKGD_SUPPORTED void /* PRIVATE */ -png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_size_t truelen; + unsigned int truelen; png_byte buf[6]; png_color_16 background; png_debug(1, "in png_handle_bKGD"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before bKGD"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + (png_ptr->mode & PNG_HAVE_PLTE) == 0)) { - png_warning(png_ptr, "Invalid bKGD after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) { - png_warning(png_ptr, "Missing PLTE before bKGD"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) - { - png_warning(png_ptr, "Duplicate bKGD chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 1; - else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) truelen = 6; else @@ -1639,14 +1917,14 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (length != truelen) { - png_warning(png_ptr, "Incorrect bKGD chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_crc_read(png_ptr, buf, truelen); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; /* We convert the index value into RGB components so that we can allow @@ -1658,11 +1936,11 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { background.index = buf[0]; - if (info_ptr && info_ptr->num_palette) + if (info_ptr != NULL && info_ptr->num_palette != 0) { if (buf[0] >= info_ptr->num_palette) { - png_warning(png_ptr, "Incorrect bKGD chunk index value"); + png_chunk_benign_error(png_ptr, "invalid index"); return; } @@ -1677,7 +1955,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) background.gray = 0; } - else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ + else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ { background.index = 0; background.red = @@ -1701,44 +1979,37 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_hIST_SUPPORTED void /* PRIVATE */ -png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { unsigned int num, i; png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_hIST"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before hIST"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || + (png_ptr->mode & PNG_HAVE_PLTE) == 0) { - png_warning(png_ptr, "Invalid hIST after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (!(png_ptr->mode & PNG_HAVE_PLTE)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) { - png_warning(png_ptr, "Missing PLTE before hIST"); - png_crc_finish(png_ptr, length); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) - { - png_warning(png_ptr, "Duplicate hIST chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } num = length / 2 ; - if (num != (unsigned int)png_ptr->num_palette || num > - (unsigned int)PNG_MAX_PALETTE_LENGTH) + if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH) { - png_warning(png_ptr, "Incorrect hIST chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } @@ -1750,7 +2021,7 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) readbuf[i] = png_get_uint_16(buf); } - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; png_set_hIST(png_ptr, info_ptr, readbuf); @@ -1759,7 +2030,7 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_pHYs_SUPPORTED void /* PRIVATE */ -png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[9]; png_uint_32 res_x, res_y; @@ -1767,33 +2038,33 @@ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_pHYs"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before pHYs"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid pHYs after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_warning(png_ptr, "Duplicate pHYs chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } if (length != 9) { - png_warning(png_ptr, "Incorrect pHYs chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_crc_read(png_ptr, buf, 9); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; res_x = png_get_uint_32(buf); @@ -1805,7 +2076,7 @@ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_oFFs_SUPPORTED void /* PRIVATE */ -png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[9]; png_int_32 offset_x, offset_y; @@ -1813,33 +2084,33 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_oFFs"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before oFFs"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid oFFs after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_warning(png_ptr, "Duplicate oFFs chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } if (length != 9) { - png_warning(png_ptr, "Incorrect oFFs chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_crc_read(png_ptr, buf, 9); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; offset_x = png_get_int_32(buf); @@ -1852,71 +2123,64 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_pCAL_SUPPORTED /* Read the pCAL chunk (described in the PNG Extensions document) */ void /* PRIVATE */ -png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_int_32 X0, X1; png_byte type, nparams; - png_charp buf, units, endptr; + png_bytep buffer, buf, units, endptr; png_charpp params; - png_size_t slength; int i; png_debug(1, "in png_handle_pCAL"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before pCAL"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid pCAL after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) { - png_warning(png_ptr, "Duplicate pCAL chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", length + 1); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - if (png_ptr->chunkdata == NULL) + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); + + if (buffer == NULL) { - png_warning(png_ptr, "No memory for pCAL purpose"); + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); return; } - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_crc_read(png_ptr, buffer, length); - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + if (png_crc_finish(png_ptr, 0) != 0) return; - } - png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ + buffer[length] = 0; /* Null terminate the last string */ png_debug(3, "Finding end of pCAL purpose string"); - for (buf = png_ptr->chunkdata; *buf; buf++) + for (buf = buffer; *buf; buf++) /* Empty loop */ ; - endptr = png_ptr->chunkdata + slength; + endptr = buffer + length; /* We need to have at least 12 bytes after the purpose string * in order to get the parameter information. */ if (endptr <= buf + 12) { - png_warning(png_ptr, "Invalid pCAL data"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + png_chunk_benign_error(png_ptr, "invalid"); return; } @@ -1936,15 +2200,13 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) (type == PNG_EQUATION_ARBITRARY && nparams != 3) || (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) { - png_warning(png_ptr, "Invalid pCAL parameters for equation type"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + png_chunk_benign_error(png_ptr, "invalid parameter count"); return; } else if (type >= PNG_EQUATION_LAST) { - png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + png_chunk_benign_error(png_ptr, "unrecognized equation type"); } for (buf = units; *buf; buf++) @@ -1952,43 +2214,37 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(3, "Allocating pCAL parameters array"); - params = (png_charpp)png_malloc_warn(png_ptr, - (png_size_t)(nparams * png_sizeof(png_charp))); + params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, + nparams * (sizeof (png_charp)))); if (params == NULL) { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "No memory for pCAL params"); + png_chunk_benign_error(png_ptr, "out of memory"); return; } /* Get pointers to the start of each parameter string. */ - for (i = 0; i < (int)nparams; i++) + for (i = 0; i < nparams; i++) { buf++; /* Skip the null string terminator from previous parameter. */ png_debug1(3, "Reading pCAL parameter %d", i); - for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) + for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) /* Empty loop to move past each parameter string */ ; /* Make sure we haven't run out of data yet */ if (buf > endptr) { - png_warning(png_ptr, "Invalid pCAL data"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; png_free(png_ptr, params); + png_chunk_benign_error(png_ptr, "invalid data"); return; } } - png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, - units, params); + png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, + (png_charp)units, params); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; png_free(png_ptr, params); } #endif @@ -1996,67 +2252,61 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_sCAL_SUPPORTED /* Read the sCAL chunk */ void /* PRIVATE */ -png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_size_t slength, i; + png_bytep buffer; + png_size_t i; int state; png_debug(1, "in png_handle_sCAL"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sCAL"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (png_ptr->mode & PNG_HAVE_IDAT) + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) { - png_warning(png_ptr, "Invalid sCAL after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); return; } - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { - png_warning(png_ptr, "Duplicate sCAL chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } /* Need unit type, width, \0, height: minimum 4 bytes */ else if (length < 4) { - png_warning(png_ptr, "sCAL chunk too short"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", length + 1); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - if (png_ptr->chunkdata == NULL) + if (buffer == NULL) { - png_warning(png_ptr, "Out of memory while processing sCAL chunk"); + png_chunk_benign_error(png_ptr, "out of memory"); png_crc_finish(png_ptr, length); return; } - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ + png_crc_read(png_ptr, buffer, length); + buffer[length] = 0; /* Null terminate the last string */ - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + if (png_crc_finish(png_ptr, 0) != 0) return; - } /* Validate the unit. */ - if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) + if (buffer[0] != 1 && buffer[0] != 2) { - png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + png_chunk_benign_error(png_ptr, "invalid unit"); return; } @@ -2066,70 +2316,65 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) i = 1; state = 0; - if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || - i >= slength || png_ptr->chunkdata[i++] != 0) - png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); + if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || + i >= length || buffer[i++] != 0) + png_chunk_benign_error(png_ptr, "bad width format"); - else if (!PNG_FP_IS_POSITIVE(state)) - png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); + else if (PNG_FP_IS_POSITIVE(state) == 0) + png_chunk_benign_error(png_ptr, "non-positive width"); else { png_size_t heighti = i; state = 0; - if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || - i != slength) - png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); + if (png_check_fp_number((png_const_charp)buffer, length, + &state, &i) == 0 || i != length) + png_chunk_benign_error(png_ptr, "bad height format"); - else if (!PNG_FP_IS_POSITIVE(state)) - png_warning(png_ptr, - "Invalid sCAL chunk ignored: non-positive height"); + else if (PNG_FP_IS_POSITIVE(state) == 0) + png_chunk_benign_error(png_ptr, "non-positive height"); else /* This is the (only) success case. */ - png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], - png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); + png_set_sCAL_s(png_ptr, info_ptr, buffer[0], + (png_charp)buffer+1, (png_charp)buffer+heighti); } - - /* Clean up - just free the temporarily allocated buffer. */ - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; } #endif #ifdef PNG_READ_tIME_SUPPORTED void /* PRIVATE */ -png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_byte buf[7]; png_time mod_time; png_debug(1, "in png_handle_tIME"); - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Out of place tIME chunk"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) { - png_warning(png_ptr, "Duplicate tIME chunk"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); return; } - if (png_ptr->mode & PNG_HAVE_IDAT) + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; if (length != 7) { - png_warning(png_ptr, "Incorrect tIME chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); return; } png_crc_read(png_ptr, buf, 7); - if (png_crc_finish(png_ptr, 0)) + if (png_crc_finish(png_ptr, 0) != 0) return; mod_time.second = buf[6]; @@ -2146,14 +2391,13 @@ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_tEXt_SUPPORTED /* Note: this does not properly handle chunks that are > 64K under DOS */ void /* PRIVATE */ -png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_textp text_ptr; + png_text text_info; + png_bytep buffer; png_charp key; png_charp text; png_uint_32 skip = 0; - png_size_t slength; - int ret; png_debug(1, "in png_handle_tEXt"); @@ -2168,84 +2412,59 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (--png_ptr->user_chunk_cache_max == 1) { - png_warning(png_ptr, "No space in chunk cache for tEXt"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "no space in chunk cache"); return; } } #endif - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before tEXt"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - if (png_ptr->mode & PNG_HAVE_IDAT) + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; #ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) + if (length > 65535U) { - png_warning(png_ptr, "tEXt chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too large to fit in memory"); + return; } #endif - png_free(png_ptr, png_ptr->chunkdata); + buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) + if (buffer == NULL) { - png_warning(png_ptr, "No memory to process text chunk"); + png_chunk_benign_error(png_ptr, "out of memory"); return; } - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_crc_read(png_ptr, buffer, length); - if (png_crc_finish(png_ptr, skip)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + if (png_crc_finish(png_ptr, skip) != 0) return; - } - key = png_ptr->chunkdata; - - key[slength] = 0x00; + key = (png_charp)buffer; + key[length] = 0; for (text = key; *text; text++) /* Empty loop to find end of key */ ; - if (text != key + slength) + if (text != key + length) text++; - text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); + text_info.compression = PNG_TEXT_COMPRESSION_NONE; + text_info.key = key; + text_info.lang = NULL; + text_info.lang_key = NULL; + text_info.itxt_length = 0; + text_info.text = text; + text_info.text_length = strlen(text); - if (text_ptr == NULL) - { - png_warning(png_ptr, "Not enough memory to process text chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; - text_ptr->key = key; - text_ptr->lang = NULL; - text_ptr->lang_key = NULL; - text_ptr->itxt_length = 0; - text_ptr->text = text; - text_ptr->text_length = png_strlen(text); - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_free(png_ptr, text_ptr); - - if (ret) + if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) png_warning(png_ptr, "Insufficient memory to process text chunk"); } #endif @@ -2253,13 +2472,11 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_zTXt_SUPPORTED /* Note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ -png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_textp text_ptr; - png_charp text; - int comp_type; - int ret; - png_size_t slength, prefix_len, data_len; + png_const_charp errmsg = NULL; + png_bytep buffer; + png_uint_32 keyword_length; png_debug(1, "in png_handle_zTXt"); @@ -2274,123 +2491,101 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (--png_ptr->user_chunk_cache_max == 1) { - png_warning(png_ptr, "No space in chunk cache for zTXt"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "no space in chunk cache"); return; } } #endif - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before zTXt"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - if (png_ptr->mode & PNG_HAVE_IDAT) + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; -#ifdef PNG_MAX_MALLOC_64K - /* We will no doubt have problems with chunks even half this size, but - * there is no hard and fast rule to tell us where to stop. - */ - if (length > (png_uint_32)65535L) + buffer = png_read_buffer(png_ptr, length, 2/*silent*/); + + if (buffer == NULL) { - png_warning(png_ptr, "zTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); - return; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "Out of memory processing zTXt chunk"); + png_chunk_benign_error(png_ptr, "out of memory"); return; } - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_crc_read(png_ptr, buffer, length); - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + if (png_crc_finish(png_ptr, 0) != 0) return; - } - png_ptr->chunkdata[slength] = 0x00; + /* TODO: also check that the keyword contents match the spec! */ + for (keyword_length = 0; + keyword_length < length && buffer[keyword_length] != 0; + ++keyword_length) + /* Empty loop to find end of name */ ; - for (text = png_ptr->chunkdata; *text; text++) - /* Empty loop */ ; + if (keyword_length > 79 || keyword_length < 1) + errmsg = "bad keyword"; - /* zTXt must have some text after the chunkdataword */ - if (text >= png_ptr->chunkdata + slength - 2) - { - png_warning(png_ptr, "Truncated zTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } + /* zTXt must have some LZ data after the keyword, although it may expand to + * zero bytes; we need a '\0' at the end of the keyword, the compression type + * then the LZ data: + */ + else if (keyword_length + 3 > length) + errmsg = "truncated"; + + else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) + errmsg = "unknown compression type"; else { - comp_type = *(++text); + png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; - if (comp_type != PNG_TEXT_COMPRESSION_zTXt) - { - png_warning(png_ptr, "Unknown compression type in zTXt chunk"); - comp_type = PNG_TEXT_COMPRESSION_zTXt; - } + /* TODO: at present png_decompress_chunk imposes a single application + * level memory limit, this should be split to different values for iCCP + * and text chunks. + */ + if (png_decompress_chunk(png_ptr, length, keyword_length+2, + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + { + png_text text; - text++; /* Skip the compression_method byte */ + /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except + * for the extra compression type byte and the fact that it isn't + * necessarily '\0' terminated. + */ + buffer = png_ptr->read_buffer; + buffer[uncompressed_length+(keyword_length+2)] = 0; + + text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.key = (png_charp)buffer; + text.text = (png_charp)(buffer + keyword_length+2); + text.text_length = uncompressed_length; + text.itxt_length = 0; + text.lang = NULL; + text.lang_key = NULL; + + if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) + errmsg = "insufficient memory"; + } + + else + errmsg = png_ptr->zstream.msg; } - prefix_len = text - png_ptr->chunkdata; - - png_decompress_chunk(png_ptr, comp_type, - (png_size_t)length, prefix_len, &data_len); - - text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); - - if (text_ptr == NULL) - { - png_warning(png_ptr, "Not enough memory to process zTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - text_ptr->compression = comp_type; - text_ptr->key = png_ptr->chunkdata; - text_ptr->lang = NULL; - text_ptr->lang_key = NULL; - text_ptr->itxt_length = 0; - text_ptr->text = png_ptr->chunkdata + prefix_len; - text_ptr->text_length = data_len; - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, text_ptr); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - - if (ret) - png_error(png_ptr, "Insufficient memory to store zTXt chunk"); + if (errmsg != NULL) + png_chunk_benign_error(png_ptr, errmsg); } #endif #ifdef PNG_READ_iTXt_SUPPORTED /* Note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ -png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { - png_textp text_ptr; - png_charp key, lang, text, lang_key; - int comp_flag; - int comp_type = 0; - int ret; - png_size_t slength, prefix_len, data_len; + png_const_charp errmsg = NULL; + png_bytep buffer; + png_uint_32 prefix_length; png_debug(1, "in png_handle_iTXt"); @@ -2405,274 +2600,393 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (--png_ptr->user_chunk_cache_max == 1) { - png_warning(png_ptr, "No space in chunk cache for iTXt"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "no space in chunk cache"); return; } } #endif - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before iTXt"); + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); - if (png_ptr->mode & PNG_HAVE_IDAT) + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; -#ifdef PNG_MAX_MALLOC_64K - /* We will no doubt have problems with chunks even half this size, but - * there is no hard and fast rule to tell us where to stop. - */ - if (length > (png_uint_32)65535L) + buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); + + if (buffer == NULL) { - png_warning(png_ptr, "iTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); - return; - } -#endif - - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - - if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "No memory to process iTXt chunk"); + png_chunk_benign_error(png_ptr, "out of memory"); return; } - slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_crc_read(png_ptr, buffer, length); - if (png_crc_finish(png_ptr, 0)) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; + if (png_crc_finish(png_ptr, 0) != 0) return; - } - png_ptr->chunkdata[slength] = 0x00; - - for (lang = png_ptr->chunkdata; *lang; lang++) + /* First the keyword. */ + for (prefix_length=0; + prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) /* Empty loop */ ; - lang++; /* Skip NUL separator */ + /* Perform a basic check on the keyword length here. */ + if (prefix_length > 79 || prefix_length < 1) + errmsg = "bad keyword"; - /* iTXt must have a language tag (possibly empty), two compression bytes, - * translated keyword (possibly empty), and possibly some text after the - * keyword + /* Expect keyword, compression flag, compression type, language, translated + * keyword (both may be empty but are 0 terminated) then the text, which may + * be empty. */ + else if (prefix_length + 5 > length) + errmsg = "truncated"; - if (lang >= png_ptr->chunkdata + slength - 3) + else if (buffer[prefix_length+1] == 0 || + (buffer[prefix_length+1] == 1 && + buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) { - png_warning(png_ptr, "Truncated iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; + int compressed = buffer[prefix_length+1] != 0; + png_uint_32 language_offset, translated_keyword_offset; + png_alloc_size_t uncompressed_length = 0; + + /* Now the language tag */ + prefix_length += 3; + language_offset = prefix_length; + + for (; prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* WARNING: the length may be invalid here, this is checked below. */ + translated_keyword_offset = ++prefix_length; + + for (; prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* prefix_length should now be at the trailing '\0' of the translated + * keyword, but it may already be over the end. None of this arithmetic + * can overflow because chunks are at most 2^31 bytes long, but on 16-bit + * systems the available allocation may overflow. + */ + ++prefix_length; + + if (compressed == 0 && prefix_length <= length) + uncompressed_length = length - prefix_length; + + else if (compressed != 0 && prefix_length < length) + { + uncompressed_length = PNG_SIZE_MAX; + + /* TODO: at present png_decompress_chunk imposes a single application + * level memory limit, this should be split to different values for + * iCCP and text chunks. + */ + if (png_decompress_chunk(png_ptr, length, prefix_length, + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + buffer = png_ptr->read_buffer; + + else + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "truncated"; + + if (errmsg == NULL) + { + png_text text; + + buffer[uncompressed_length+prefix_length] = 0; + + if (compressed == 0) + text.compression = PNG_ITXT_COMPRESSION_NONE; + + else + text.compression = PNG_ITXT_COMPRESSION_zTXt; + + text.key = (png_charp)buffer; + text.lang = (png_charp)buffer + language_offset; + text.lang_key = (png_charp)buffer + translated_keyword_offset; + text.text = (png_charp)buffer + prefix_length; + text.text_length = 0; + text.itxt_length = uncompressed_length; + + if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) + errmsg = "insufficient memory"; + } } else - { - comp_flag = *lang++; - comp_type = *lang++; - } + errmsg = "bad compression info"; - for (lang_key = lang; *lang_key; lang_key++) - /* Empty loop */ ; - - lang_key++; /* Skip NUL separator */ - - if (lang_key >= png_ptr->chunkdata + slength) - { - png_warning(png_ptr, "Truncated iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - for (text = lang_key; *text; text++) - /* Empty loop */ ; - - text++; /* Skip NUL separator */ - - if (text >= png_ptr->chunkdata + slength) - { - png_warning(png_ptr, "Malformed iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - prefix_len = text - png_ptr->chunkdata; - - key=png_ptr->chunkdata; - - if (comp_flag) - png_decompress_chunk(png_ptr, comp_type, - (size_t)length, prefix_len, &data_len); - - else - data_len = png_strlen(png_ptr->chunkdata + prefix_len); - - text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); - - if (text_ptr == NULL) - { - png_warning(png_ptr, "Not enough memory to process iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - - text_ptr->compression = (int)comp_flag + 1; - text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); - text_ptr->lang = png_ptr->chunkdata + (lang - key); - text_ptr->itxt_length = data_len; - text_ptr->text_length = 0; - text_ptr->key = png_ptr->chunkdata; - text_ptr->text = png_ptr->chunkdata + prefix_len; - - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - - png_free(png_ptr, text_ptr); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - - if (ret) - png_error(png_ptr, "Insufficient memory to store iTXt chunk"); + if (errmsg != NULL) + png_chunk_benign_error(png_ptr, errmsg); } #endif -/* This function is called when we haven't found a handler for a - * chunk. If there isn't a problem with the chunk itself (ie bad - * chunk name, CRC, or a critical chunk), the chunk is silently ignored - * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which - * case it will be saved away to be written out later. - */ -void /* PRIVATE */ -png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_uint_32 skip = 0; - - png_debug(1, "in png_handle_unknown"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for unknown chunk"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if (png_ptr->mode & PNG_HAVE_IDAT) - { - PNG_IDAT; - - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ - png_ptr->mode |= PNG_AFTER_IDAT; - } - - if (!(png_ptr->chunk_name[0] & 0x20)) - { -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - && png_ptr->read_user_chunk_fn == NULL -#endif - ) -#endif - png_chunk_error(png_ptr, "unknown critical chunk"); - } - #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - || (png_ptr->read_user_chunk_fn != NULL) -#endif - ) +/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ +static int +png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) +{ + png_alloc_size_t limit = PNG_SIZE_MAX; + + if (png_ptr->unknown_chunk.data != NULL) { -#ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } -#endif + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } - png_memcpy((png_charp)png_ptr->unknown_chunk.name, - (png_charp)png_ptr->chunk_name, - png_sizeof(png_ptr->unknown_chunk.name)); +# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; - png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] - = '\0'; +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; +# endif - png_ptr->unknown_chunk.size = (png_size_t)length; + if (length <= limit) + { + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + /* The following is safe because of the PNG_SIZE_MAX init above */ + png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/; + /* 'mode' is a flag array, only the bottom four bits matter here */ + png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; if (length == 0) png_ptr->unknown_chunk.data = NULL; else { - png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); - png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); + /* Do a 'warn' here - it is handled below. */ + png_ptr->unknown_chunk.data = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, length)); } + } -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - { - /* Callback to user unknown chunk handler */ - int ret; - - ret = (*(png_ptr->read_user_chunk_fn)) - (png_ptr, &png_ptr->unknown_chunk); - - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - - if (ret == 0) - { - if (!(png_ptr->chunk_name[0] & 0x20)) - { -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) -#endif - png_chunk_error(png_ptr, "unknown critical chunk"); - } - - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - } - } - - else -#endif - png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); - - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; + if (png_ptr->unknown_chunk.data == NULL && length > 0) + { + /* This is benign because we clean up correctly */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); + return 0; } else -#endif - skip = length; + { + if (length > 0) + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); + png_crc_finish(png_ptr, 0); + return 1; + } +} +#endif /* READ_UNKNOWN_CHUNKS */ - png_crc_finish(png_ptr, skip); +/* Handle an unknown, or known but disabled, chunk */ +void /* PRIVATE */ +png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, + png_uint_32 length, int keep) +{ + int handled = 0; /* the chunk was handled */ -#ifndef PNG_READ_USER_CHUNKS_SUPPORTED - PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ -#endif + png_debug(1, "in png_handle_unknown"); + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing + * the bug which meant that setting a non-default behavior for a specific + * chunk would be ignored (the default was always used unless a user + * callback was installed). + * + * 'keep' is the value from the png_chunk_unknown_handling, the setting for + * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it + * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. + * This is just an optimization to avoid multiple calls to the lookup + * function. + */ +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); +# endif +# endif + + /* One of the following methods will read the chunk or skip it (at least one + * of these is always defined because this is the only way to switch on + * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + */ +# ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* The user callback takes precedence over the chunk keep value, but the + * keep value is still required to validate a save of a critical chunk. + */ + if (png_ptr->read_user_chunk_fn != NULL) + { + if (png_cache_unknown_chunk(png_ptr, length) != 0) + { + /* Callback to user unknown chunk handler */ + int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, + &png_ptr->unknown_chunk); + + /* ret is: + * negative: An error occured, png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be discarded + * unless png_set_keep_unknown_chunks has been used to set + * a 'keep' behavior for this particular chunk, in which + * case that will be used. A critical chunk will cause an + * error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + */ + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + + else if (ret == 0) + { + /* If the keep value is 'default' or 'never' override it, but + * still error out on critical chunks unless the keep value is + * 'always' While this is weird it is the behavior in 1.4.12. + * A possible improvement would be to obey the value set for the + * chunk, but this would be an API change that would probably + * damage some applications. + * + * The png_app_warning below catches the case that matters, where + * the application has not set specific save or ignore for this + * chunk or global save or ignore. + */ + if (keep < PNG_HANDLE_CHUNK_IF_SAFE) + { +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) + { + png_chunk_warning(png_ptr, "Saving unknown chunk:"); + png_app_warning(png_ptr, + "forcing save of an unhandled chunk;" + " please call png_set_keep_unknown_chunks"); + /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ + } +# endif + keep = PNG_HANDLE_CHUNK_IF_SAFE; + } + } + + else /* chunk was handled */ + { + handled = 1; + /* Critical chunks can be safely discarded at this point. */ + keep = PNG_HANDLE_CHUNK_NEVER; + } + } + + else + keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ + } + + else + /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ +# endif /* READ_USER_CHUNKS */ + +# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + { + /* keep is currently just the per-chunk setting, if there was no + * setting change it to the global default now (not that this may + * still be AS_DEFAULT) then obtain the cache of the chunk if required, + * if not simply skip the chunk. + */ + if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) + keep = png_ptr->unknown_default; + + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { + if (png_cache_unknown_chunk(png_ptr, length) == 0) + keep = PNG_HANDLE_CHUNK_NEVER; + } + + else + png_crc_finish(png_ptr, length); + } +# else +# ifndef PNG_READ_USER_CHUNKS_SUPPORTED +# error no method to support READ_UNKNOWN_CHUNKS +# endif + + { + /* If here there is no read callback pointer set and no support is + * compiled in to just save the unknown chunks, so simply skip this + * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then + * the app has erroneously asked for unknown chunk saving when there + * is no support. + */ + if (keep > PNG_HANDLE_CHUNK_NEVER) + png_app_error(png_ptr, "no unknown chunk support available"); + + png_crc_finish(png_ptr, length); + } +# endif + +# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + /* Now store the chunk in the chunk list if appropriate, and if the limits + * permit it. + */ + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { +# ifdef PNG_USER_LIMITS_SUPPORTED + switch (png_ptr->user_chunk_cache_max) + { + case 2: + png_ptr->user_chunk_cache_max = 1; + png_chunk_benign_error(png_ptr, "no space in chunk cache"); + /* FALL THROUGH */ + case 1: + /* NOTE: prior to 1.6.0 this case resulted in an unknown critical + * chunk being skipped, now there will be a hard error below. + */ + break; + + default: /* not at limit */ + --(png_ptr->user_chunk_cache_max); + /* FALL THROUGH */ + case 0: /* no limit */ +# endif /* USER_LIMITS */ + /* Here when the limit isn't reached or when limits are compiled + * out; store the chunk. + */ + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + handled = 1; +# ifdef PNG_USER_LIMITS_SUPPORTED + break; + } +# endif + } +# else /* no store support: the chunk must be handled by the user callback */ + PNG_UNUSED(info_ptr) +# endif + + /* Regardless of the error handling below the cached data (if any) can be + * freed now. Notice that the data is not freed if there is a png_error, but + * it will be freed by destroy_read_struct. + */ + if (png_ptr->unknown_chunk.data != NULL) + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + +#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ + /* There is no support to read an unknown chunk, so just skip it. */ + png_crc_finish(png_ptr, length); + PNG_UNUSED(info_ptr) + PNG_UNUSED(keep) +#endif /* !READ_UNKNOWN_CHUNKS */ + + /* Check for unhandled critical chunks */ + if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + png_chunk_error(png_ptr, "unhandled critical chunk"); } /* This function is called to verify that a chunk name is valid. @@ -2682,267 +2996,527 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) * the chunk name itself is valid. */ -#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) - -void /* PRIVATE */ -png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name) -{ - png_debug(1, "in png_check_chunk_name"); - if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || - isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) - { - png_chunk_error(png_ptr, "invalid chunk type"); - } -} - -/* Combines the row recently read in with the existing pixels in the - * row. This routine takes care of alpha and transparency if requested. - * This routine also handles the two methods of progressive display - * of interlaced images, depending on the mask value. - * The mask value describes which pixels are to be combined with - * the row. The pattern always repeats every 8 pixels, so just 8 - * bits are needed. A one indicates the pixel is to be combined, - * a zero indicates the pixel is to be skipped. This is in addition - * to any alpha or transparency value associated with the pixel. If - * you want all pixels to be combined, pass 0xff (255) in mask. +/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: + * + * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) */ void /* PRIVATE */ -png_combine_row(png_structp png_ptr, png_bytep row, int mask) +png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name) { + int i; + + png_debug(1, "in png_check_chunk_name"); + + for (i=1; i<=4; ++i) + { + int c = chunk_name & 0xff; + + if (c < 65 || c > 122 || (c > 90 && c < 97)) + png_chunk_error(png_ptr, "invalid chunk type"); + + chunk_name >>= 8; + } +} + +/* Combines the row recently read in with the existing pixels in the row. This + * routine takes care of alpha and transparency if requested. This routine also + * handles the two methods of progressive display of interlaced images, + * depending on the 'display' value; if 'display' is true then the whole row + * (dp) is filled from the start by replicating the available pixels. If + * 'display' is false only those pixels present in the pass are filled in. + */ +void /* PRIVATE */ +png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) +{ + unsigned int pixel_depth = png_ptr->transformed_pixel_depth; + png_const_bytep sp = png_ptr->row_buf + 1; + png_alloc_size_t row_width = png_ptr->width; + unsigned int pass = png_ptr->pass; + png_bytep end_ptr = 0; + png_byte end_byte = 0; + unsigned int end_mask; + png_debug(1, "in png_combine_row"); - /* Added in 1.5.4: the row_info should match the information returned by any - * call to png_read_update_info at this point. Do not continue if we got + /* Added in 1.5.6: it should not be possible to enter this routine until at + * least one row has been read from the PNG data and transformed. + */ + if (pixel_depth == 0) + png_error(png_ptr, "internal row logic error"); + + /* Added in 1.5.4: the pixel depth should match the information returned by + * any call to png_read_update_info at this point. Do not continue if we got * this wrong. */ if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != - PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)) + PNG_ROWBYTES(pixel_depth, row_width)) png_error(png_ptr, "internal row size calculation error"); - if (mask == 0xff) + /* Don't expect this to ever happen: */ + if (row_width == 0) + png_error(png_ptr, "internal row width error"); + + /* Preserve the last byte in cases where only part of it will be overwritten, + * the multiply below may overflow, we don't care because ANSI-C guarantees + * we get the low bits. + */ + end_mask = (pixel_depth * row_width) & 7; + if (end_mask != 0) { - png_memcpy(row, png_ptr->row_buf + 1, - PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); + /* end_ptr == NULL is a flag to say do nothing */ + end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; + end_byte = *end_ptr; +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + /* little-endian byte */ + end_mask = 0xff << end_mask; + + else /* big-endian byte */ +# endif + end_mask = 0xff >> end_mask; + /* end_mask is now the bits to *keep* from the destination row */ } - else + /* For non-interlaced images this reduces to a memcpy(). A memcpy() + * will also happen if interlacing isn't supported or if the application + * does not call png_set_interlace_handling(). In the latter cases the + * caller just gets a sequence of the unexpanded rows from each interlace + * pass. + */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0 && + pass < 6 && (display == 0 || + /* The following copies everything for 'display' on passes 0, 2 and 4. */ + (display == 1 && (pass & 1) != 0))) { - switch (png_ptr->row_info.pixel_depth) + /* Narrow images may have no bits in a pass; the caller should handle + * this, but this test is cheap: + */ + if (row_width <= PNG_PASS_START_COL(pass)) + return; + + if (pixel_depth < 8) { - case 1: - { - png_bytep sp = png_ptr->row_buf + 1; - png_bytep dp = row; - int s_inc, s_start, s_end; - int m = 0x80; - int shift; - png_uint_32 i; - png_uint_32 row_width = png_ptr->width; + /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit + * into 32 bits, then a single loop over the bytes using the four byte + * values in the 32-bit mask can be used. For the 'display' option the + * expanded mask may also not require any masking within a byte. To + * make this work the PACKSWAP option must be taken into account - it + * simply requires the pixels to be reversed in each byte. + * + * The 'regular' case requires a mask for each of the first 6 passes, + * the 'display' case does a copy for the even passes in the range + * 0..6. This has already been handled in the test above. + * + * The masks are arranged as four bytes with the first byte to use in + * the lowest bits (little-endian) regardless of the order (PACKSWAP or + * not) of the pixels in each byte. + * + * NOTE: the whole of this logic depends on the caller of this function + * only calling it on rows appropriate to the pass. This function only + * understands the 'x' logic; the 'y' logic is handled by the caller. + * + * The following defines allow generation of compile time constant bit + * masks for each pixel depth and each possibility of swapped or not + * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, + * is in the range 0..7; and the result is 1 if the pixel is to be + * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' + * for the block method. + * + * With some compilers a compile time expression of the general form: + * + * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) + * + * Produces warnings with values of 'shift' in the range 33 to 63 + * because the right hand side of the ?: expression is evaluated by + * the compiler even though it isn't used. Microsoft Visual C (various + * versions) and the Intel C compiler are known to do this. To avoid + * this the following macros are used in 1.5.6. This is a temporary + * solution to avoid destabilizing the code during the release process. + */ +# if PNG_USE_COMPILE_TIME_MASKS +# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) +# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) +# else +# define PNG_LSR(x,s) ((x)>>(s)) +# define PNG_LSL(x,s) ((x)<<(s)) +# endif +# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) +# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 7; - s_inc = 1; - } + /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is + * little endian - the first pixel is at bit 0 - however the extra + * parameter 's' can be set to cause the mask position to be swapped + * within each byte, to match the PNG format. This is done by XOR of + * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. + */ +# define PIXEL_MASK(p,x,d,s) \ + (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) + + /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. + */ +# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) +# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) + + /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp + * cases the result needs replicating, for the 4-bpp case the above + * generates a full 32 bits. + */ +# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) + +# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ + S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ + S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) + +# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ + B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ + B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) + +#if PNG_USE_COMPILE_TIME_MASKS + /* Utility macros to construct all the masks for a depth/swap + * combination. The 's' parameter says whether the format is PNG + * (big endian bytes) or not. Only the three odd-numbered passes are + * required for the display/block algorithm. + */ +# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ + S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } + +# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) } + +# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) + + /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and + * then pass: + */ + static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + { + /* Little-endian byte masks for PACKSWAP */ + { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } + }; + + /* display_mask has only three entries for the odd passes, so index by + * pass>>1. + */ + static PNG_CONST png_uint_32 display_mask[2][3][3] = + { + /* Little-endian byte masks for PACKSWAP */ + { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } + }; + +# define MASK(pass,depth,display,png)\ + ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ + row_mask[png][DEPTH_INDEX(depth)][pass]) + +#else /* !PNG_USE_COMPILE_TIME_MASKS */ + /* This is the runtime alternative: it seems unlikely that this will + * ever be either smaller or faster than the compile time approach. + */ +# define MASK(pass,depth,display,png)\ + ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) +#endif /* !USE_COMPILE_TIME_MASKS */ + + /* Use the appropriate mask to copy the required bits. In some cases + * the byte mask will be 0 or 0xff; optimize these cases. row_width is + * the number of pixels, but the code copies bytes, so it is necessary + * to special case the end. + */ + png_uint_32 pixels_per_byte = 8 / pixel_depth; + png_uint_32 mask; + +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + mask = MASK(pass, pixel_depth, display, 0); else -#endif - { - s_start = 7; - s_end = 0; - s_inc = -1; - } +# endif + mask = MASK(pass, pixel_depth, display, 1); - shift = s_start; - - for (i = 0; i < row_width; i++) - { - if (m & mask) - { - int value; - - value = (*sp >> shift) & 0x01; - *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - - else - shift += s_inc; - - if (m == 1) - m = 0x80; - - else - m >>= 1; - } - break; - } - - case 2: + for (;;) { - png_bytep sp = png_ptr->row_buf + 1; - png_bytep dp = row; - int s_start, s_end, s_inc; - int m = 0x80; - int shift; - png_uint_32 i; - png_uint_32 row_width = png_ptr->width; - int value; + png_uint_32 m; -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) + /* It doesn't matter in the following if png_uint_32 has more than + * 32 bits because the high bits always match those in m<<24; it is, + * however, essential to use OR here, not +, because of this. + */ + m = mask; + mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ + m &= 0xff; + + if (m != 0) /* something to copy */ { - s_start = 0; - s_end = 6; - s_inc = 2; - } - - else -#endif - { - s_start = 6; - s_end = 0; - s_inc = -2; - } - - shift = s_start; - - for (i = 0; i < row_width; i++) - { - if (m & mask) - { - value = (*sp >> shift) & 0x03; - *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - + if (m != 0xff) + *dp = (png_byte)((*dp & ~m) | (*sp & m)); else - shift += s_inc; - - if (m == 1) - m = 0x80; - - else - m >>= 1; - } - break; - } - - case 4: - { - png_bytep sp = png_ptr->row_buf + 1; - png_bytep dp = row; - int s_start, s_end, s_inc; - int m = 0x80; - int shift; - png_uint_32 i; - png_uint_32 row_width = png_ptr->width; - int value; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 4; - s_inc = 4; + *dp = *sp; } - else -#endif - { - s_start = 4; - s_end = 0; - s_inc = -4; - } - shift = s_start; + /* NOTE: this may overwrite the last byte with garbage if the image + * is not an exact number of bytes wide; libpng has always done + * this. + */ + if (row_width <= pixels_per_byte) + break; /* May need to restore part of the last byte */ - for (i = 0; i < row_width; i++) - { - if (m & mask) - { - value = (*sp >> shift) & 0xf; - *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - - else - shift += s_inc; - - if (m == 1) - m = 0x80; - - else - m >>= 1; - } - break; - } - - default: - { - png_bytep sp = png_ptr->row_buf + 1; - png_bytep dp = row; - png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - png_uint_32 i; - png_uint_32 row_width = png_ptr->width; - png_byte m = 0x80; - - for (i = 0; i < row_width; i++) - { - if (m & mask) - { - png_memcpy(dp, sp, pixel_bytes); - } - - sp += pixel_bytes; - dp += pixel_bytes; - - if (m == 1) - m = 0x80; - - else - m >>= 1; - } - break; + row_width -= pixels_per_byte; + ++dp; + ++sp; } } + + else /* pixel_depth >= 8 */ + { + unsigned int bytes_to_copy, bytes_to_jump; + + /* Validate the depth - it must be a multiple of 8 */ + if (pixel_depth & 7) + png_error(png_ptr, "invalid user transform pixel depth"); + + pixel_depth >>= 3; /* now in bytes */ + row_width *= pixel_depth; + + /* Regardless of pass number the Adam 7 interlace always results in a + * fixed number of pixels to copy then to skip. There may be a + * different number of pixels to skip at the start though. + */ + { + unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; + + row_width -= offset; + dp += offset; + sp += offset; + } + + /* Work out the bytes to copy. */ + if (display != 0) + { + /* When doing the 'block' algorithm the pixel in the pass gets + * replicated to adjacent pixels. This is why the even (0,2,4,6) + * passes are skipped above - the entire expanded row is copied. + */ + bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; + + /* But don't allow this number to exceed the actual row width. */ + if (bytes_to_copy > row_width) + bytes_to_copy = (unsigned int)/*SAFE*/row_width; + } + + else /* normal row; Adam7 only ever gives us one pixel to copy. */ + bytes_to_copy = pixel_depth; + + /* In Adam7 there is a constant offset between where the pixels go. */ + bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; + + /* And simply copy these bytes. Some optimization is possible here, + * depending on the value of 'bytes_to_copy'. Special case the low + * byte counts, which we know to be frequent. + * + * Notice that these cases all 'return' rather than 'break' - this + * avoids an unnecessary test on whether to restore the last byte + * below. + */ + switch (bytes_to_copy) + { + case 1: + for (;;) + { + *dp = *sp; + + if (row_width <= bytes_to_jump) + return; + + dp += bytes_to_jump; + sp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + case 2: + /* There is a possibility of a partial copy at the end here; this + * slows the code down somewhat. + */ + do + { + dp[0] = sp[0], dp[1] = sp[1]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + while (row_width > 1); + + /* And there can only be one byte left at this point: */ + *dp = *sp; + return; + + case 3: + /* This can only be the RGB case, so each copy is exactly one + * pixel and it is not necessary to check for a partial copy. + */ + for (;;) + { + dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + default: +#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE + /* Check for double byte alignment and, if possible, use a + * 16-bit copy. Don't attempt this for narrow images - ones that + * are less than an interlace panel wide. Don't attempt it for + * wide bytes_to_copy either - use the memcpy there. + */ + if (bytes_to_copy < 16 /*else use memcpy*/ && + png_isaligned(dp, png_uint_16) && + png_isaligned(sp, png_uint_16) && + bytes_to_copy % (sizeof (png_uint_16)) == 0 && + bytes_to_jump % (sizeof (png_uint_16)) == 0) + { + /* Everything is aligned for png_uint_16 copies, but try for + * png_uint_32 first. + */ + if (png_isaligned(dp, png_uint_32) != 0 && + png_isaligned(sp, png_uint_32) != 0 && + bytes_to_copy % (sizeof (png_uint_32)) == 0 && + bytes_to_jump % (sizeof (png_uint_32)) == 0) + { + png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); + png_const_uint_32p sp32 = png_aligncastconst( + png_const_uint_32p, sp); + size_t skip = (bytes_to_jump-bytes_to_copy) / + (sizeof (png_uint_32)); + + do + { + size_t c = bytes_to_copy; + do + { + *dp32++ = *sp32++; + c -= (sizeof (png_uint_32)); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp32 += skip; + sp32 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* Get to here when the row_width truncates the final copy. + * There will be 1-3 bytes left to copy, so don't try the + * 16-bit loop below. + */ + dp = (png_bytep)dp32; + sp = (png_const_bytep)sp32; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + + /* Else do it in 16-bit quantities, but only if the size is + * not too large. + */ + else + { + png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); + png_const_uint_16p sp16 = png_aligncastconst( + png_const_uint_16p, sp); + size_t skip = (bytes_to_jump-bytes_to_copy) / + (sizeof (png_uint_16)); + + do + { + size_t c = bytes_to_copy; + do + { + *dp16++ = *sp16++; + c -= (sizeof (png_uint_16)); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp16 += skip; + sp16 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* End of row - 1 byte left, bytes_to_copy > row_width: */ + dp = (png_bytep)dp16; + sp = (png_const_bytep)sp16; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + } +#endif /* ALIGN_TYPE code */ + + /* The true default - use a memcpy: */ + for (;;) + { + memcpy(dp, sp, bytes_to_copy); + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + if (bytes_to_copy > row_width) + bytes_to_copy = (unsigned int)/*SAFE*/row_width; + } + } + + /* NOT REACHED*/ + } /* pixel_depth >= 8 */ + + /* Here if pixel_depth < 8 to check 'end_ptr' below. */ } + else +#endif /* READ_INTERLACING */ + + /* If here then the switch above wasn't used so just memcpy the whole row + * from the temporary row buffer (notice that this overwrites the end of the + * destination row if it is a partial byte.) + */ + memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); + + /* Restore the overwritten bits from the last byte if necessary. */ + if (end_ptr != NULL) + *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); } #ifdef PNG_READ_INTERLACING_SUPPORTED void /* PRIVATE */ -png_do_read_interlace(png_structp png_ptr) +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations /* Because these may affect the byte layout */) { - png_row_infop row_info = &(png_ptr->row_info); - png_bytep row = png_ptr->row_buf + 1; - int pass = png_ptr->pass; - png_uint_32 transformations = png_ptr->transformations; /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Offset to next interlace block */ - PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) @@ -2965,7 +3539,7 @@ png_do_read_interlace(png_structp png_ptr) int j; #ifdef PNG_READ_PACKSWAP_SUPPORTED - if (transformations & PNG_PACKSWAP) + if ((transformations & PNG_PACKSWAP) != 0) { sshift = (int)((row_info->width + 7) & 0x07); dshift = (int)((final_width + 7) & 0x07); @@ -2989,8 +3563,9 @@ png_do_read_interlace(png_structp png_ptr) v = (png_byte)((*sp >> sshift) & 0x01); for (j = 0; j < jstop; j++) { - *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); - *dp |= (png_byte)(v << dshift); + unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); + tmp |= v << dshift; + *dp = (png_byte)(tmp & 0xff); if (dshift == s_end) { @@ -3024,7 +3599,7 @@ png_do_read_interlace(png_structp png_ptr) png_uint_32 i; #ifdef PNG_READ_PACKSWAP_SUPPORTED - if (transformations & PNG_PACKSWAP) + if ((transformations & PNG_PACKSWAP) != 0) { sshift = (int)(((row_info->width + 3) & 0x03) << 1); dshift = (int)(((final_width + 3) & 0x03) << 1); @@ -3051,8 +3626,9 @@ png_do_read_interlace(png_structp png_ptr) v = (png_byte)((*sp >> sshift) & 0x03); for (j = 0; j < jstop; j++) { - *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); - *dp |= (png_byte)(v << dshift); + unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); + tmp |= v << dshift; + *dp = (png_byte)(tmp & 0xff); if (dshift == s_end) { @@ -3086,7 +3662,7 @@ png_do_read_interlace(png_structp png_ptr) int jstop = png_pass_inc[pass]; #ifdef PNG_READ_PACKSWAP_SUPPORTED - if (transformations & PNG_PACKSWAP) + if ((transformations & PNG_PACKSWAP) != 0) { sshift = (int)(((row_info->width + 1) & 0x01) << 2); dshift = (int)(((final_width + 1) & 0x01) << 2); @@ -3107,13 +3683,14 @@ png_do_read_interlace(png_structp png_ptr) for (i = 0; i < row_info->width; i++) { - png_byte v = (png_byte)((*sp >> sshift) & 0xf); + png_byte v = (png_byte)((*sp >> sshift) & 0x0f); int j; for (j = 0; j < jstop; j++) { - *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); - *dp |= (png_byte)(v << dshift); + unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); + tmp |= v << dshift; + *dp = (png_byte)(tmp & 0xff); if (dshift == s_end) { @@ -3136,6 +3713,7 @@ png_do_read_interlace(png_structp png_ptr) } break; } + default: { png_size_t pixel_bytes = (row_info->pixel_depth >> 3); @@ -3150,14 +3728,14 @@ png_do_read_interlace(png_structp png_ptr) for (i = 0; i < row_info->width; i++) { - png_byte v[8]; + png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ int j; - png_memcpy(v, sp, pixel_bytes); + memcpy(v, sp, pixel_bytes); for (j = 0; j < jstop; j++) { - png_memcpy(dp, v, pixel_bytes); + memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } @@ -3166,6 +3744,7 @@ png_do_read_interlace(png_structp png_ptr) break; } } + row_info->width = final_width; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); } @@ -3173,167 +3752,427 @@ png_do_read_interlace(png_structp png_ptr) PNG_UNUSED(transformations) /* Silence compiler warning */ #endif } -#endif /* PNG_READ_INTERLACING_SUPPORTED */ +#endif /* READ_INTERLACING */ + +static void +png_read_filter_row_sub(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_size_t istop = row_info->rowbytes; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + + PNG_UNUSED(prev_row) + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_up(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_size_t istop = row_info->rowbytes; + png_bytep rp = row; + png_const_bytep pp = prev_row; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_avg(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_bytep rp = row; + png_const_bytep pp = prev_row; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_size_t istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } +} + +static void +png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp_end = row + row_info->rowbytes; + int a, c; + + /* First pixel/byte */ + c = *prev_row++; + a = *row + c; + *row++ = (png_byte)a; + + /* Remainder */ + while (row < rp_end) + { + int b, pa, pb, pc, p; + + a &= 0xff; /* From previous iteration or start */ + b = *prev_row++; + + p = b - c; + pc = a - c; + +# ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +# else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +# endif + + /* Find the best predictor, the least of pa, pb, pc favoring the earlier + * ones in the case of a tie. + */ + if (pb < pa) pa = pb, a = b; + if (pc < pa) a = c; + + /* Calculate the current pixel in a, and move the previous row pixel to c + * for the next time round the loop + */ + c = b; + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp_end = row + bpp; + + /* Process the first pixel in the row completely (this is the same as 'up' + * because there is only one candidate predictor for the first row). + */ + while (row < rp_end) + { + int a = *row + *prev_row++; + *row++ = (png_byte)a; + } + + /* Remainder */ + rp_end += row_info->rowbytes - bpp; + + while (row < rp_end) + { + int a, b, c, pa, pb, pc, p; + + c = *(prev_row - bpp); + a = *(row - bpp); + b = *prev_row++; + + p = b - c; + pc = a - c; + +# ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +# else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +# endif + + if (pb < pa) pa = pb, a = b; + if (pc < pa) a = c; + + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_init_filter_functions(png_structrp pp) + /* This function is called once for every PNG image (except for PNG images + * that only use PNG_FILTER_VALUE_NONE for all rows) to set the + * implementations required to reverse the filtering of PNG rows. Reversing + * the filter is the first transformation performed on the row data. It is + * performed in place, therefore an implementation can be selected based on + * the image pixel format. If the implementation depends on image width then + * take care to ensure that it works correctly if the image is interlaced - + * interlacing causes the actual row width to vary. + */ +{ + unsigned int bpp = (pp->pixel_depth + 7) >> 3; + + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; + if (bpp == 1) + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_1byte_pixel; + else + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_multibyte_pixel; + +#ifdef PNG_FILTER_OPTIMIZATIONS + /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to + * call to install hardware optimizations for the above functions; simply + * replace whatever elements of the pp->read_filter[] array with a hardware + * specific (or, for that matter, generic) optimization. + * + * To see an example of this examine what configure.ac does when + * --enable-arm-neon is specified on the command line. + */ + PNG_FILTER_OPTIMIZATIONS(pp, bpp); +#endif +} void /* PRIVATE */ -png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, - png_const_bytep prev_row, int filter) +png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, + png_const_bytep prev_row, int filter) { - png_debug(1, "in png_read_filter_row"); - png_debug2(2, "row = %u, filter = %d", png_ptr->row_number, filter); - switch (filter) + /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define + * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic + * implementations. See png_init_filter_functions above. + */ + if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) { - case PNG_FILTER_VALUE_NONE: - break; + if (pp->read_filter[0] == NULL) + png_init_filter_functions(pp); - case PNG_FILTER_VALUE_SUB: - { - png_size_t i; - png_size_t istop = row_info->rowbytes; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp = row + bpp; - png_bytep lp = row; - - for (i = bpp; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); - rp++; - } - break; - } - case PNG_FILTER_VALUE_UP: - { - png_size_t i; - png_size_t istop = row_info->rowbytes; - png_bytep rp = row; - png_const_bytep pp = prev_row; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } - break; - } - case PNG_FILTER_VALUE_AVG: - { - png_size_t i; - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep lp = row; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_size_t istop = row_info->rowbytes - bpp; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) / 2 )) & 0xff); - - rp++; - } - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + - (int)(*pp++ + *lp++) / 2 ) & 0xff); - - rp++; - } - break; - } - case PNG_FILTER_VALUE_PAETH: - { - png_size_t i; - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep lp = row; - png_const_bytep cp = prev_row; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_size_t istop=row_info->rowbytes - bpp; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } - - for (i = 0; i < istop; i++) /* Use leftover rp,pp */ - { - int a, b, c, pa, pb, pc, p; - - a = *lp++; - b = *pp++; - c = *cp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - /* - if (pa <= pb && pa <= pc) - p = a; - - else if (pb <= pc) - p = b; - - else - p = c; - */ - - p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; - - *rp = (png_byte)(((int)(*rp) + p) & 0xff); - rp++; - } - break; - } - default: - png_error(png_ptr, "Ignoring bad adaptive filter type"); - /*NOT REACHED */ - break; + pp->read_filter[filter-1](row_info, row, prev_row); } } #ifdef PNG_SEQUENTIAL_READ_SUPPORTED void /* PRIVATE */ -png_read_finish_row(png_structp png_ptr) +png_read_IDAT_data(png_structrp png_ptr, png_bytep output, + png_alloc_size_t avail_out) +{ + /* Loop reading IDATs and decompressing the result into output[avail_out] */ + png_ptr->zstream.next_out = output; + png_ptr->zstream.avail_out = 0; /* safety: set below */ + + if (output == NULL) + avail_out = 0; + + do + { + int ret; + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; + + if (png_ptr->zstream.avail_in == 0) + { + uInt avail_in; + png_bytep buffer; + + while (png_ptr->idat_size == 0) + { + png_crc_finish(png_ptr, 0); + + png_ptr->idat_size = png_read_chunk_header(png_ptr); + /* This is an error even in the 'check' case because the code just + * consumed a non-IDAT header. + */ + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); + } + + avail_in = png_ptr->IDAT_read_size; + + if (avail_in > png_ptr->idat_size) + avail_in = (uInt)png_ptr->idat_size; + + /* A PNG with a gradually increasing IDAT size will defeat this attempt + * to minimize memory usage by causing lots of re-allocs, but + * realistically doing IDAT_read_size re-allocs is not likely to be a + * big problem. + */ + buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); + + png_crc_read(png_ptr, buffer, avail_in); + png_ptr->idat_size -= avail_in; + + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = avail_in; + } + + /* And set up the output side. */ + if (output != NULL) /* standard read */ + { + uInt out = ZLIB_IO_MAX; + + if (out > avail_out) + out = (uInt)avail_out; + + avail_out -= out; + png_ptr->zstream.avail_out = out; + } + + else /* after last row, checking for end */ + { + png_ptr->zstream.next_out = tmpbuf; + png_ptr->zstream.avail_out = (sizeof tmpbuf); + } + + /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the + * process. If the LZ stream is truncated the sequential reader will + * terminally damage the stream, above, by reading the chunk header of the + * following chunk (it then exits with png_error). + * + * TODO: deal more elegantly with truncated IDAT lists. + */ + ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); + + /* Take the unconsumed output back. */ + if (output != NULL) + avail_out += png_ptr->zstream.avail_out; + + else /* avail_out counts the extra bytes */ + avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; + + png_ptr->zstream.avail_out = 0; + + if (ret == Z_STREAM_END) + { + /* Do this for safety; we won't read any more into this row. */ + png_ptr->zstream.next_out = NULL; + + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + + if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) + png_chunk_benign_error(png_ptr, "Extra compressed data"); + break; + } + + if (ret != Z_OK) + { + png_zstream_error(png_ptr, ret); + + if (output != NULL) + png_chunk_error(png_ptr, png_ptr->zstream.msg); + + else /* checking */ + { + png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); + return; + } + } + } while (avail_out > 0); + + if (avail_out > 0) + { + /* The stream ended before the image; this is the same as too few IDATs so + * should be handled the same way. + */ + if (output != NULL) + png_error(png_ptr, "Not enough image data"); + + else /* the deflate stream contained extra data */ + png_chunk_benign_error(png_ptr, "Too much image data"); + } +} + +void /* PRIVATE */ +png_read_finish_IDAT(png_structrp png_ptr) +{ + /* We don't need any more data and the stream should have ended, however the + * LZ end code may actually not have been processed. In this case we must + * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk + * may still remain to be consumed. + */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + { + /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in + * the compressed stream, but the stream may be damaged too, so even after + * this call we may need to terminate the zstream ownership. + */ + png_read_IDAT_data(png_ptr, NULL, 0); + png_ptr->zstream.next_out = NULL; /* safety */ + + /* Now clear everything out for safety; the following may not have been + * done. + */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + { + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + } + } + + /* If the zstream has not been released do it now *and* terminate the reading + * of the final IDAT chunk. + */ + if (png_ptr->zowner == png_IDAT) + { + /* Always do this; the pointers otherwise point into the read buffer. */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + + /* Now we no longer own the zstream. */ + png_ptr->zowner = 0; + + /* The slightly weird semantics of the sequential IDAT reading is that we + * are always in or at the end of an IDAT chunk, so we always need to do a + * crc_finish here. If idat_size is non-zero we also need to read the + * spurious bytes at the end of the chunk now. + */ + (void)png_crc_finish(png_ptr, png_ptr->idat_size); + } +} + +void /* PRIVATE */ +png_read_finish_row(png_structrp png_ptr) { -#ifdef PNG_READ_INTERLACING_SUPPORTED /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif /* PNG_READ_INTERLACING_SUPPORTED */ + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; png_debug(1, "in png_read_finish_row"); png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) return; -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced) + if (png_ptr->interlaced != 0) { png_ptr->row_number = 0; - png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + /* TO DO: don't do this if prev_row isn't needed (requires + * read-ahead of the next row's filter byte. + */ + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); do { @@ -3347,7 +4186,7 @@ png_read_finish_row(png_structp png_ptr) png_pass_start[png_ptr->pass]) / png_pass_inc[png_ptr->pass]; - if (!(png_ptr->transformations & PNG_INTERLACE)) + if ((png_ptr->transformations & PNG_INTERLACE) == 0) { png_ptr->num_rows = (png_ptr->height + png_pass_yinc[png_ptr->pass] - 1 - @@ -3363,108 +4202,40 @@ png_read_finish_row(png_structp png_ptr) if (png_ptr->pass < 7) return; } -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - { - PNG_IDAT; - char extra; - int ret; - - png_ptr->zstream.next_out = (Byte *)&extra; - png_ptr->zstream.avail_out = (uInt)1; - - for (;;) - { - if (!(png_ptr->zstream.avail_in)) - { - while (!png_ptr->idat_size) - { - png_crc_finish(png_ptr, 0); - png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) - png_error(png_ptr, "Not enough image data"); - } - - png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_in = png_ptr->zbuf; - - if (png_ptr->zbuf_size > png_ptr->idat_size) - png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; - - png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); - png_ptr->idat_size -= png_ptr->zstream.avail_in; - } - - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); - - if (ret == Z_STREAM_END) - { - if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || - png_ptr->idat_size) - png_warning(png_ptr, "Extra compressed data"); - - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; - } - - if (ret != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : - "Decompression Error"); - - if (!(png_ptr->zstream.avail_out)) - { - png_warning(png_ptr, "Extra compressed data"); - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; - } - - } - png_ptr->zstream.avail_out = 0; - } - - if (png_ptr->idat_size || png_ptr->zstream.avail_in) - png_warning(png_ptr, "Extra compression data"); - - inflateReset(&png_ptr->zstream); - - png_ptr->mode |= PNG_AFTER_IDAT; + /* Here after at the end of the last row of the last pass. */ + png_read_finish_IDAT(png_ptr); } -#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ +#endif /* SEQUENTIAL_READ */ void /* PRIVATE */ -png_read_start_row(png_structp png_ptr) +png_read_start_row(png_structrp png_ptr) { -#ifdef PNG_READ_INTERLACING_SUPPORTED /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; int max_pixel_depth; png_size_t row_bytes; png_debug(1, "in png_read_start_row"); - png_ptr->zstream.avail_in = 0; + #ifdef PNG_READ_TRANSFORMS_SUPPORTED png_init_read_transformations(png_ptr); #endif -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced) + if (png_ptr->interlaced != 0) { - if (!(png_ptr->transformations & PNG_INTERLACE)) + if ((png_ptr->transformations & PNG_INTERLACE) == 0) png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - png_pass_ystart[0]) / png_pass_yinc[0]; @@ -3478,7 +4249,6 @@ png_read_start_row(png_structp png_ptr) } else -#endif /* PNG_READ_INTERLACING_SUPPORTED */ { png_ptr->num_rows = png_ptr->height; png_ptr->iwidth = png_ptr->width; @@ -3486,17 +4256,27 @@ png_read_start_row(png_structp png_ptr) max_pixel_depth = png_ptr->pixel_depth; + /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of + * calculations to calculate the final pixel depth, then + * png_do_read_transforms actually does the transforms. This means that the + * code which effectively calculates this value is actually repeated in three + * separate places. They must all match. Innocent changes to the order of + * transformations can and will break libpng in a way that causes memory + * overwrites. + * + * TODO: fix this. + */ #ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) + if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8) max_pixel_depth = 8; #endif #ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) + if ((png_ptr->transformations & PNG_EXPAND) != 0) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - if (png_ptr->num_trans) + if (png_ptr->num_trans != 0) max_pixel_depth = 32; else @@ -3508,13 +4288,13 @@ png_read_start_row(png_structp png_ptr) if (max_pixel_depth < 8) max_pixel_depth = 8; - if (png_ptr->num_trans) + if (png_ptr->num_trans != 0) max_pixel_depth *= 2; } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { - if (png_ptr->num_trans) + if (png_ptr->num_trans != 0) { max_pixel_depth *= 4; max_pixel_depth /= 3; @@ -3524,13 +4304,13 @@ png_read_start_row(png_structp png_ptr) #endif #ifdef PNG_READ_EXPAND_16_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND_16) + if ((png_ptr->transformations & PNG_EXPAND_16) != 0) { # ifdef PNG_READ_EXPAND_SUPPORTED /* In fact it is an error if it isn't supported, but checking is * the safe way. */ - if (png_ptr->transformations & PNG_EXPAND) + if ((png_ptr->transformations & PNG_EXPAND) != 0) { if (png_ptr->bit_depth < 16) max_pixel_depth *= 2; @@ -3542,12 +4322,9 @@ png_read_start_row(png_structp png_ptr) #endif #ifdef PNG_READ_FILLER_SUPPORTED - if (png_ptr->transformations & (PNG_FILLER)) + if ((png_ptr->transformations & (PNG_FILLER)) != 0) { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - max_pixel_depth = 32; - - else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { if (max_pixel_depth <= 8) max_pixel_depth = 16; @@ -3556,7 +4333,8 @@ png_read_start_row(png_structp png_ptr) max_pixel_depth = 32; } - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || + png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (max_pixel_depth <= 32) max_pixel_depth = 32; @@ -3568,14 +4346,15 @@ png_read_start_row(png_structp png_ptr) #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if (png_ptr->transformations & PNG_GRAY_TO_RGB) + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) { if ( #ifdef PNG_READ_EXPAND_SUPPORTED - (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || + (png_ptr->num_trans != 0 && + (png_ptr->transformations & PNG_EXPAND) != 0) || #endif #ifdef PNG_READ_FILLER_SUPPORTED - (png_ptr->transformations & (PNG_FILLER)) || + (png_ptr->transformations & (PNG_FILLER)) != 0 || #endif png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { @@ -3608,16 +4387,22 @@ png_read_start_row(png_structp png_ptr) #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - if (png_ptr->transformations & PNG_USER_TRANSFORM) + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) { - int user_pixel_depth = png_ptr->user_transform_depth* + int user_pixel_depth = png_ptr->user_transform_depth * png_ptr->user_transform_channels; if (user_pixel_depth > max_pixel_depth) - max_pixel_depth=user_pixel_depth; + max_pixel_depth = user_pixel_depth; } #endif + /* This value is stored in png_struct and double checked in the row read + * code. + */ + png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; + png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ + /* Align the width on the next larger 8 pixels. Mainly used * for interlacing */ @@ -3636,28 +4421,39 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (row_bytes + 48 > png_ptr->old_big_row_buf_size) { png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); - if (png_ptr->interlaced) + if (png_ptr->interlaced != 0) png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, row_bytes + 48); else - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, - row_bytes + 48); + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - png_ptr->old_big_row_buf_size = row_bytes + 48; + png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); #ifdef PNG_ALIGNED_MEMORY_SUPPORTED /* Use 16-byte aligned memory for row_buf with at least 16 bytes - * of padding before and after row_buf. + * of padding before and after row_buf; treat prev_row similarly. + * NOTE: the alignment is to the start of the pixels, one beyond the start + * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this + * was incorrect; the filter byte was aligned, which had the exact + * opposite effect of that intended. */ - png_ptr->row_buf = png_ptr->big_row_buf + 32 - - (((png_alloc_size_t)png_ptr->big_row_buf + 15) & 0x0F); + { + png_bytep temp = png_ptr->big_row_buf + 32; + int extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->row_buf = temp - extra - 1/*filter byte*/; + + temp = png_ptr->big_prev_row + 32; + extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->prev_row = temp - extra - 1/*filter byte*/; + } - png_ptr->old_big_row_buf_size = row_bytes + 48; #else - /* Use 32 bytes of padding before and 16 bytes after row_buf. */ - png_ptr->row_buf = png_ptr->big_row_buf + 32; + /* Use 31 bytes of padding before and 17 bytes after row_buf. */ + png_ptr->row_buf = png_ptr->big_row_buf + 31; + png_ptr->prev_row = png_ptr->big_prev_row + 31; #endif png_ptr->old_big_row_buf_size = row_bytes + 48; } @@ -3670,16 +4466,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) png_error(png_ptr, "Row has too many bytes to allocate in memory"); - if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size) - { - png_free(png_ptr, png_ptr->prev_row); - - png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); - - png_ptr->old_prev_row_size = png_ptr->rowbytes + 1; - } - - png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); png_debug1(3, "width = %u,", png_ptr->width); png_debug1(3, "height = %u,", png_ptr->height); @@ -3689,6 +4476,27 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) png_debug1(3, "irowbytes = %lu", (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); + /* The sequential reader needs a buffer for IDAT, but the progressive reader + * does not, so free the read buffer now regardless; the sequential reader + * reallocates it on demand. + */ + if (png_ptr->read_buffer != 0) + { + png_bytep buffer = png_ptr->read_buffer; + + png_ptr->read_buffer_size = 0; + png_ptr->read_buffer = NULL; + png_free(png_ptr, buffer); + } + + /* Finally claim the zstream for the inflate of the IDAT data, use the bits + * value from the stream (note that this will result in a fatal error if the + * IDAT stream has a bogus deflate header window_bits value, but this should + * not be happening any longer!) + */ + if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + png_ptr->flags |= PNG_FLAG_ROW_INIT; } -#endif /* PNG_READ_SUPPORTED */ +#endif /* READ */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c index 819605f5025..d2c89b2a55f 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -50,51 +50,84 @@ #ifdef PNG_bKGD_SUPPORTED void PNGAPI -png_set_bKGD(png_structp png_ptr, png_infop info_ptr, +png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, png_const_color_16p background) { png_debug1(1, "in %s storage function", "bKGD"); - if (png_ptr == NULL || info_ptr == NULL) + if (png_ptr == NULL || info_ptr == NULL || background == NULL) return; - png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); + info_ptr->background = *background; info_ptr->valid |= PNG_INFO_bKGD; } #endif #ifdef PNG_cHRM_SUPPORTED void PNGFAPI -png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, +png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point blue_y) { + png_xy xy; + png_debug1(1, "in %s storage function", "cHRM fixed"); if (png_ptr == NULL || info_ptr == NULL) return; -# ifdef PNG_CHECK_cHRM_SUPPORTED - if (png_check_cHRM_fixed(png_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) -# endif - { - info_ptr->x_white = white_x; - info_ptr->y_white = white_y; - info_ptr->x_red = red_x; - info_ptr->y_red = red_y; - info_ptr->x_green = green_x; - info_ptr->y_green = green_y; - info_ptr->x_blue = blue_x; - info_ptr->y_blue = blue_y; - info_ptr->valid |= PNG_INFO_cHRM; - } + xy.redx = red_x; + xy.redy = red_y; + xy.greenx = green_x; + xy.greeny = green_y; + xy.bluex = blue_x; + xy.bluey = blue_y; + xy.whitex = white_x; + xy.whitey = white_y; + + if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, + 2/* override with app values*/) != 0) + info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + + png_colorspace_sync_info(png_ptr, info_ptr); +} + +void PNGFAPI +png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z) +{ + png_XYZ XYZ; + + png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + XYZ.red_X = int_red_X; + XYZ.red_Y = int_red_Y; + XYZ.red_Z = int_red_Z; + XYZ.green_X = int_green_X; + XYZ.green_Y = int_green_Y; + XYZ.green_Z = int_green_Z; + XYZ.blue_X = int_blue_X; + XYZ.blue_Y = int_blue_Y; + XYZ.blue_Z = int_blue_Z; + + if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, + &XYZ, 2) != 0) + info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; + + png_colorspace_sync_info(png_ptr, info_ptr); } # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_cHRM(png_structp png_ptr, png_infop info_ptr, +png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y) { @@ -108,41 +141,44 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr, png_fixed(png_ptr, blue_x, "cHRM Blue X"), png_fixed(png_ptr, blue_y, "cHRM Blue Y")); } -# endif /* PNG_FLOATING_POINT_SUPPORTED */ -#endif /* PNG_cHRM_SUPPORTED */ +void PNGAPI +png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, + double red_Y, double red_Z, double green_X, double green_Y, double green_Z, + double blue_X, double blue_Y, double blue_Z) +{ + png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, red_X, "cHRM Red X"), + png_fixed(png_ptr, red_Y, "cHRM Red Y"), + png_fixed(png_ptr, red_Z, "cHRM Red Z"), + png_fixed(png_ptr, green_X, "cHRM Red X"), + png_fixed(png_ptr, green_Y, "cHRM Red Y"), + png_fixed(png_ptr, green_Z, "cHRM Red Z"), + png_fixed(png_ptr, blue_X, "cHRM Red X"), + png_fixed(png_ptr, blue_Y, "cHRM Red Y"), + png_fixed(png_ptr, blue_Z, "cHRM Red Z")); +} +# endif /* FLOATING_POINT */ + +#endif /* cHRM */ #ifdef PNG_gAMA_SUPPORTED void PNGFAPI -png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point - file_gamma) +png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point file_gamma) { png_debug1(1, "in %s storage function", "gAMA"); if (png_ptr == NULL || info_ptr == NULL) return; - /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is assymetrical it is - * possible for 1/gamma to overflow the limit of 21474 and this means the - * gamma value must be at least 5/100000 and hence at most 20000.0. For - * safety the limits here are a little narrower. The values are 0.00016 to - * 6250.0, which are truely ridiculous gammma values (and will produce - * displays that are all black or all white.) - */ - if (file_gamma < 16 || file_gamma > 625000000) - png_warning(png_ptr, "Out of range gamma value ignored"); - - else - { - info_ptr->gamma = file_gamma; - info_ptr->valid |= PNG_INFO_gAMA; - } + png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); + png_colorspace_sync_info(png_ptr, info_ptr); } # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) +png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) { png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, "png_set_gAMA")); @@ -152,7 +188,8 @@ png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) #ifdef PNG_hIST_SUPPORTED void PNGAPI -png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) +png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_uint_16p hist) { int i; @@ -175,26 +212,26 @@ png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in * version 1.2.1 */ - png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, - PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); + info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); - if (png_ptr->hist == NULL) + if (info_ptr->hist == NULL) { png_warning(png_ptr, "Insufficient memory for hIST chunk data"); return; } - for (i = 0; i < info_ptr->num_palette; i++) - png_ptr->hist[i] = hist[i]; - - info_ptr->hist = png_ptr->hist; - info_ptr->valid |= PNG_INFO_hIST; info_ptr->free_me |= PNG_FREE_HIST; + + for (i = 0; i < info_ptr->num_palette; i++) + info_ptr->hist[i] = hist[i]; + + info_ptr->valid |= PNG_INFO_hIST; } #endif void PNGAPI -png_set_IHDR(png_structp png_ptr, png_infop info_ptr, +png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int interlace_type, int compression_type, int filter_type) @@ -219,32 +256,23 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; - else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) info_ptr->channels = 3; else info_ptr->channels = 1; - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) info_ptr->channels++; info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); - /* Check for potential overflow */ - if (width > - (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ - - 48 /* bigrowbuf hack */ - - 1 /* filter byte */ - - 7*8 /* rounding of width to multiple of 8 pixels */ - - 8) /* extra max_pixel_depth pad */ - info_ptr->rowbytes = 0; - else - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); } #ifdef PNG_oFFs_SUPPORTED void PNGAPI -png_set_oFFs(png_structp png_ptr, png_infop info_ptr, +png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, int unit_type) { png_debug1(1, "in %s storage function", "oFFs"); @@ -261,7 +289,7 @@ png_set_oFFs(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_pCAL_SUPPORTED void PNGAPI -png_set_pCAL(png_structp png_ptr, png_infop info_ptr, +png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_const_charp units, png_charpp params) { @@ -270,10 +298,11 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, png_debug1(1, "in %s storage function", "pCAL"); - if (png_ptr == NULL || info_ptr == NULL) + if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL + || (nparams > 0 && params == NULL)) return; - length = png_strlen(purpose) + 1; + length = strlen(purpose) + 1; png_debug1(3, "allocating purpose for info (%lu bytes)", (unsigned long)length); @@ -283,12 +312,19 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, if (type < 0 || type > 3) png_error(png_ptr, "Invalid pCAL equation type"); + if (nparams < 0 || nparams > 255) + png_error(png_ptr, "Invalid pCAL parameter count"); + /* Validate params[nparams] */ for (i=0; ipcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); + info_ptr->pcal_purpose = png_voidcast(png_charp, + png_malloc_warn(png_ptr, length)); if (info_ptr->pcal_purpose == NULL) { @@ -296,7 +332,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, return; } - png_memcpy(info_ptr->pcal_purpose, purpose, length); + memcpy(info_ptr->pcal_purpose, purpose, length); png_debug(3, "storing X0, X1, type, and nparams in info"); info_ptr->pcal_X0 = X0; @@ -304,11 +340,12 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, info_ptr->pcal_type = (png_byte)type; info_ptr->pcal_nparams = (png_byte)nparams; - length = png_strlen(units) + 1; + length = strlen(units) + 1; png_debug1(3, "allocating units for info (%lu bytes)", (unsigned long)length); - info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); + info_ptr->pcal_units = png_voidcast(png_charp, + png_malloc_warn(png_ptr, length)); if (info_ptr->pcal_units == NULL) { @@ -316,10 +353,10 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, return; } - png_memcpy(info_ptr->pcal_units, units, length); + memcpy(info_ptr->pcal_units, units, length); - info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, - (png_size_t)((nparams + 1) * png_sizeof(png_charp))); + info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, + (png_size_t)((nparams + 1) * (sizeof (png_charp))))); if (info_ptr->pcal_params == NULL) { @@ -327,11 +364,11 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, return; } - png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); + memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); for (i = 0; i < nparams; i++) { - length = png_strlen(params[i]) + 1; + length = strlen(params[i]) + 1; png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, (unsigned long)length); @@ -343,7 +380,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, return; } - png_memcpy(info_ptr->pcal_params[i], params[i], length); + memcpy(info_ptr->pcal_params[i], params[i], length); } info_ptr->valid |= PNG_INFO_pCAL; @@ -353,7 +390,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sCAL_SUPPORTED void PNGAPI -png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, +png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, int unit, png_const_charp swidth, png_const_charp sheight) { png_size_t lengthw = 0, lengthh = 0; @@ -369,11 +406,11 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, if (unit != 1 && unit != 2) png_error(png_ptr, "Invalid sCAL unit"); - if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 || + if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) png_error(png_ptr, "Invalid sCAL width"); - if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 || + if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) png_error(png_ptr, "Invalid sCAL height"); @@ -383,7 +420,8 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); - info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); + info_ptr->scal_s_width = png_voidcast(png_charp, + png_malloc_warn(png_ptr, lengthw)); if (info_ptr->scal_s_width == NULL) { @@ -391,13 +429,14 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, return; } - png_memcpy(info_ptr->scal_s_width, swidth, lengthw); + memcpy(info_ptr->scal_s_width, swidth, lengthw); ++lengthh; png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); - info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); + info_ptr->scal_s_height = png_voidcast(png_charp, + png_malloc_warn(png_ptr, lengthh)); if (info_ptr->scal_s_height == NULL) { @@ -408,7 +447,7 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, return; } - png_memcpy(info_ptr->scal_s_height, sheight, lengthh); + memcpy(info_ptr->scal_s_height, sheight, lengthh); info_ptr->valid |= PNG_INFO_sCAL; info_ptr->free_me |= PNG_FREE_SCAL; @@ -416,8 +455,8 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, - double height) +png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, + double width, double height) { png_debug1(1, "in %s storage function", "sCAL"); @@ -434,9 +473,9 @@ png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, char swidth[PNG_sCAL_MAX_DIGITS+1]; char sheight[PNG_sCAL_MAX_DIGITS+1]; - png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, + png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, PNG_sCAL_PRECISION); - png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, + png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, PNG_sCAL_PRECISION); png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); @@ -446,7 +485,7 @@ png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, # ifdef PNG_FIXED_POINT_SUPPORTED void PNGAPI -png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, +png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, png_fixed_point width, png_fixed_point height) { png_debug1(1, "in %s storage function", "sCAL"); @@ -464,8 +503,8 @@ png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, char swidth[PNG_sCAL_MAX_DIGITS+1]; char sheight[PNG_sCAL_MAX_DIGITS+1]; - png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); - png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); + png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); + png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); } @@ -475,7 +514,7 @@ png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, #ifdef PNG_pHYs_SUPPORTED void PNGAPI -png_set_pHYs(png_structp png_ptr, png_infop info_ptr, +png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type) { png_debug1(1, "in %s storage function", "pHYs"); @@ -491,7 +530,7 @@ png_set_pHYs(png_structp png_ptr, png_infop info_ptr, #endif void PNGAPI -png_set_PLTE(png_structp png_ptr, png_infop info_ptr, +png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_const_colorp palette, int num_palette) { @@ -526,6 +565,9 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, /* It may not actually be necessary to set png_ptr->palette here; * we do it for backward compatibility with the way the png_handle_tRNS * function used to do the allocation. + * + * 1.6.0: the above statement appears to be incorrect; something has to set + * the palette inside png_struct on read. */ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); @@ -533,10 +575,11 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, * of num_palette entries, in case of an invalid PNG file that has * too-large sample values. */ - png_ptr->palette = (png_colorp)png_calloc(png_ptr, - PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); - png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); + if (num_palette > 0) + memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; @@ -547,34 +590,34 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sBIT_SUPPORTED void PNGAPI -png_set_sBIT(png_structp png_ptr, png_infop info_ptr, +png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, png_const_color_8p sig_bit) { png_debug1(1, "in %s storage function", "sBIT"); - if (png_ptr == NULL || info_ptr == NULL) + if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) return; - png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); + info_ptr->sig_bit = *sig_bit; info_ptr->valid |= PNG_INFO_sBIT; } #endif #ifdef PNG_sRGB_SUPPORTED void PNGAPI -png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) +png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) { png_debug1(1, "in %s storage function", "sRGB"); if (png_ptr == NULL || info_ptr == NULL) return; - info_ptr->srgb_intent = (png_byte)srgb_intent; - info_ptr->valid |= PNG_INFO_sRGB; + (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); + png_colorspace_sync_info(png_ptr, info_ptr); } void PNGAPI -png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, +png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) { png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); @@ -582,71 +625,87 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; - png_set_sRGB(png_ptr, info_ptr, srgb_intent); + if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, + srgb_intent) != 0) + { + /* This causes the gAMA and cHRM to be written too */ + info_ptr->colorspace.flags |= + PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; + } -# ifdef PNG_gAMA_SUPPORTED - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); -# endif - -# ifdef PNG_cHRM_SUPPORTED - png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270L, 32900L, - /* red */ 64000L, 33000L, - /* green */ 30000L, 60000L, - /* blue */ 15000L, 6000L - ); -# endif /* cHRM */ + png_colorspace_sync_info(png_ptr, info_ptr); } #endif /* sRGB */ #ifdef PNG_iCCP_SUPPORTED void PNGAPI -png_set_iCCP(png_structp png_ptr, png_infop info_ptr, +png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, png_const_charp name, int compression_type, png_const_bytep profile, png_uint_32 proflen) { png_charp new_iccp_name; png_bytep new_iccp_profile; - png_uint_32 length; + png_size_t length; png_debug1(1, "in %s storage function", "iCCP"); if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) return; - length = png_strlen(name)+1; - new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_app_error(png_ptr, "Invalid iCCP compression method"); + + /* Set the colorspace first because this validates the profile; do not + * override previously set app cHRM or gAMA here (because likely as not the + * application knows better than libpng what the correct values are.) Pass + * the info_ptr color_type field to png_colorspace_set_ICC because in the + * write case it has not yet been stored in png_ptr. + */ + { + int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, + proflen, profile, info_ptr->color_type); + + png_colorspace_sync_info(png_ptr, info_ptr); + + /* Don't do any of the copying if the profile was bad, or inconsistent. */ + if (result == 0) + return; + + /* But do write the gAMA and cHRM chunks from the profile. */ + info_ptr->colorspace.flags |= + PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; + } + + length = strlen(name)+1; + new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); if (new_iccp_name == NULL) { - png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); + png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); return; } - png_memcpy(new_iccp_name, name, length); - new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); + memcpy(new_iccp_name, name, length); + new_iccp_profile = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, proflen)); if (new_iccp_profile == NULL) { - png_free (png_ptr, new_iccp_name); - png_warning(png_ptr, + png_free(png_ptr, new_iccp_name); + new_iccp_name = NULL; + png_benign_error(png_ptr, "Insufficient memory to process iCCP profile"); return; } - png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); + memcpy(new_iccp_profile, profile, proflen); png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); info_ptr->iccp_proflen = proflen; info_ptr->iccp_name = new_iccp_name; info_ptr->iccp_profile = new_iccp_profile; - /* Compression is always zero but is here so the API and info structure - * does not have to change if we introduce multiple compression types - */ - info_ptr->iccp_compression = (png_byte)compression_type; info_ptr->free_me |= PNG_FREE_ICCP; info_ptr->valid |= PNG_INFO_iCCP; } @@ -654,74 +713,81 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_TEXT_SUPPORTED void PNGAPI -png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, - int num_text) +png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_textp text_ptr, int num_text) { int ret; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); - if (ret) + if (ret != 0) png_error(png_ptr, "Insufficient memory to store text"); } int /* PRIVATE */ -png_set_text_2(png_structp png_ptr, png_infop info_ptr, +png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, png_const_textp text_ptr, int num_text) { int i; - png_debug1(1, "in %s storage function", ((png_ptr == NULL || - png_ptr->chunk_name[0] == '\0') ? - "text" : (png_const_charp)png_ptr->chunk_name)); + png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : + (unsigned long)png_ptr->chunk_name); - if (png_ptr == NULL || info_ptr == NULL || num_text == 0) + if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) return(0); /* Make sure we have enough space in the "text" array in info_struct - * to hold all of the incoming text_ptr objects. + * to hold all of the incoming text_ptr objects. This compare can't overflow + * because max_text >= num_text (anyway, subtract of two positive integers + * can't overflow in any case.) */ - if (info_ptr->num_text + num_text > info_ptr->max_text) + if (num_text > info_ptr->max_text - info_ptr->num_text) { - if (info_ptr->text != NULL) + int old_num_text = info_ptr->num_text; + int max_text; + png_textp new_text = NULL; + + /* Calculate an appropriate max_text, checking for overflow. */ + max_text = old_num_text; + if (num_text <= INT_MAX - max_text) { - png_textp old_text; - int old_max; + max_text += num_text; - old_max = info_ptr->max_text; - info_ptr->max_text = info_ptr->num_text + num_text + 8; - old_text = info_ptr->text; - info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); + /* Round up to a multiple of 8 */ + if (max_text < INT_MAX-8) + max_text = (max_text + 8) & ~0x7; - if (info_ptr->text == NULL) - { - png_free(png_ptr, old_text); - return(1); - } + else + max_text = INT_MAX; - png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * - png_sizeof(png_text))); - png_free(png_ptr, old_text); + /* Now allocate a new array and copy the old members in; this does all + * the overflow checks. + */ + new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, + info_ptr->text, old_num_text, max_text-old_num_text, + sizeof *new_text)); } - else + if (new_text == NULL) { - info_ptr->max_text = num_text + 8; - info_ptr->num_text = 0; - info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); - if (info_ptr->text == NULL) - return(1); - info_ptr->free_me |= PNG_FREE_TEXT; + png_chunk_report(png_ptr, "too many text chunks", + PNG_CHUNK_WRITE_ERROR); + return 1; } - png_debug1(3, "allocated %d entries for info_ptr->text", - info_ptr->max_text); + png_free(png_ptr, info_ptr->text); + + info_ptr->text = new_text; + info_ptr->free_me |= PNG_FREE_TEXT; + info_ptr->max_text = max_text; + /* num_text is adjusted below as the entries are copied in */ + + png_debug1(3, "allocated %d entries for info_ptr->text", max_text); } + for (i = 0; i < num_text; i++) { - png_size_t text_length, key_len; - png_size_t lang_len, lang_key_len; + size_t text_length, key_len; + size_t lang_len, lang_key_len; png_textp textp = &(info_ptr->text[info_ptr->num_text]); if (text_ptr[i].key == NULL) @@ -730,11 +796,12 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) { - png_warning(png_ptr, "text compression mode is out of range"); + png_chunk_report(png_ptr, "text compression mode is out of range", + PNG_CHUNK_WRITE_ERROR); continue; } - key_len = png_strlen(text_ptr[i].key); + key_len = strlen(text_ptr[i].key); if (text_ptr[i].compression <= 0) { @@ -748,20 +815,21 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, /* Set iTXt data */ if (text_ptr[i].lang != NULL) - lang_len = png_strlen(text_ptr[i].lang); + lang_len = strlen(text_ptr[i].lang); else lang_len = 0; if (text_ptr[i].lang_key != NULL) - lang_key_len = png_strlen(text_ptr[i].lang_key); + lang_key_len = strlen(text_ptr[i].lang_key); else lang_key_len = 0; } # else /* PNG_iTXt_SUPPORTED */ { - png_warning(png_ptr, "iTXt chunk not supported"); + png_chunk_report(png_ptr, "iTXt chunk not supported", + PNG_CHUNK_WRITE_ERROR); continue; } # endif @@ -780,32 +848,35 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, else { - text_length = png_strlen(text_ptr[i].text); + text_length = strlen(text_ptr[i].text); textp->compression = text_ptr[i].compression; } - textp->key = (png_charp)png_malloc_warn(png_ptr, - (png_size_t) - (key_len + text_length + lang_len + lang_key_len + 4)); + textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, + key_len + text_length + lang_len + lang_key_len + 4)); if (textp->key == NULL) - return(1); + { + png_chunk_report(png_ptr, "text chunk: out of memory", + PNG_CHUNK_WRITE_ERROR); + return 1; + } png_debug2(2, "Allocated %lu bytes at %p in png_set_text", (unsigned long)(png_uint_32) (key_len + lang_len + lang_key_len + text_length + 4), textp->key); - png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); + memcpy(textp->key, text_ptr[i].key, key_len); *(textp->key + key_len) = '\0'; if (text_ptr[i].compression > 0) { textp->lang = textp->key + key_len + 1; - png_memcpy(textp->lang, text_ptr[i].lang, lang_len); + memcpy(textp->lang, text_ptr[i].lang, lang_len); *(textp->lang + lang_len) = '\0'; textp->lang_key = textp->lang + lang_len + 1; - png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); + memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); *(textp->lang_key + lang_key_len) = '\0'; textp->text = textp->lang_key + lang_key_len + 1; } @@ -817,9 +888,8 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, textp->text = textp->key + key_len + 1; } - if (text_length) - png_memcpy(textp->text, text_ptr[i].text, - (png_size_t)(text_length)); + if (text_length != 0) + memcpy(textp->text, text_ptr[i].text, text_length); *(textp->text + text_length) = '\0'; @@ -840,28 +910,39 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, info_ptr->num_text++; png_debug1(3, "transferred text chunk %d", info_ptr->num_text); } + return(0); } #endif #ifdef PNG_tIME_SUPPORTED void PNGAPI -png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) +png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_timep mod_time) { png_debug1(1, "in %s storage function", "tIME"); - if (png_ptr == NULL || info_ptr == NULL || - (png_ptr->mode & PNG_WROTE_tIME)) + if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || + (png_ptr->mode & PNG_WROTE_tIME) != 0) return; - png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); + if (mod_time->month == 0 || mod_time->month > 12 || + mod_time->day == 0 || mod_time->day > 31 || + mod_time->hour > 23 || mod_time->minute > 59 || + mod_time->second > 60) + { + png_warning(png_ptr, "Ignoring invalid time value"); + return; + } + + info_ptr->mod_time = *mod_time; info_ptr->valid |= PNG_INFO_tIME; } #endif #ifdef PNG_tRNS_SUPPORTED void PNGAPI -png_set_tRNS(png_structp png_ptr, png_infop info_ptr, +png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) { png_debug1(1, "in %s storage function", "tRNS"); @@ -874,16 +955,20 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, /* It may not actually be necessary to set png_ptr->trans_alpha here; * we do it for backward compatibility with the way the png_handle_tRNS * function used to do the allocation. + * + * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively + * relies on png_set_tRNS storing the information in png_struct + * (otherwise it won't be there for the code in pngrtran.c). */ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - png_ptr->trans_alpha = info_ptr->trans_alpha = - (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); + png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, + png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) - png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); } if (trans_color != NULL) @@ -891,16 +976,15 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, int sample_max = (1 << info_ptr->bit_depth); if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && - (int)trans_color->gray > sample_max) || + trans_color->gray > sample_max) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - ((int)trans_color->red > sample_max || - (int)trans_color->green > sample_max || - (int)trans_color->blue > sample_max))) + (trans_color->red > sample_max || + trans_color->green > sample_max || + trans_color->blue > sample_max))) png_warning(png_ptr, "tRNS chunk has out-of-range samples for bit_depth"); - png_memcpy(&(info_ptr->trans_color), trans_color, - png_sizeof(png_color_16)); + info_ptr->trans_color = *trans_color; if (num_trans == 0) num_trans = 1; @@ -918,8 +1002,8 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sPLT_SUPPORTED void PNGAPI -png_set_sPLT(png_structp png_ptr, - png_infop info_ptr, png_const_sPLT_tp entries, int nentries) +png_set_sPLT(png_const_structrp png_ptr, + png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) /* * entries - array of png_sPLT_t structures * to be added to the list of palettes @@ -930,220 +1014,455 @@ png_set_sPLT(png_structp png_ptr, */ { png_sPLT_tp np; - int i; - if (png_ptr == NULL || info_ptr == NULL) + if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) return; - np = (png_sPLT_tp)png_malloc_warn(png_ptr, - (info_ptr->splt_palettes_num + nentries) * - (png_size_t)png_sizeof(png_sPLT_t)); + /* Use the internal realloc function, which checks for all the possible + * overflows. Notice that the parameters are (int) and (size_t) + */ + np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, + info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, + sizeof *np)); if (np == NULL) { - png_warning(png_ptr, "No memory for sPLT palettes"); + /* Out of memory or too many chunks */ + png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); return; } - png_memcpy(np, info_ptr->splt_palettes, - info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes=NULL; + info_ptr->splt_palettes = np; + info_ptr->free_me |= PNG_FREE_SPLT; - for (i = 0; i < nentries; i++) + np += info_ptr->splt_palettes_num; + + do { - png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; - png_const_sPLT_tp from = entries + i; - png_uint_32 length; + png_size_t length; - length = png_strlen(from->name) + 1; - to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length); - - if (to->name == NULL) + /* Skip invalid input entries */ + if (entries->name == NULL || entries->entries == NULL) { - png_warning(png_ptr, - "Out of memory while processing sPLT chunk"); + /* png_handle_sPLT doesn't do this, so this is an app error */ + png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); + /* Just skip the invalid entry */ continue; } - png_memcpy(to->name, from->name, length); - to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, - (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry))); + np->depth = entries->depth; - if (to->entries == NULL) + /* In the event of out-of-memory just return - there's no point keeping + * on trying to add sPLT chunks. + */ + length = strlen(entries->name) + 1; + np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); + + if (np->name == NULL) + break; + + memcpy(np->name, entries->name, length); + + /* IMPORTANT: we have memory now that won't get freed if something else + * goes wrong; this code must free it. png_malloc_array produces no + * warnings; use a png_chunk_report (below) if there is an error. + */ + np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, + entries->nentries, sizeof (png_sPLT_entry))); + + if (np->entries == NULL) { - png_warning(png_ptr, - "Out of memory while processing sPLT chunk"); - png_free(png_ptr, to->name); - to->name = NULL; - continue; + png_free(png_ptr, np->name); + np->name = NULL; + break; } - png_memcpy(to->entries, from->entries, - from->nentries * png_sizeof(png_sPLT_entry)); + np->nentries = entries->nentries; + /* This multiply can't overflow because png_malloc_array has already + * checked it when doing the allocation. + */ + memcpy(np->entries, entries->entries, + entries->nentries * sizeof (png_sPLT_entry)); - to->nentries = from->nentries; - to->depth = from->depth; + /* Note that 'continue' skips the advance of the out pointer and out + * count, so an invalid entry is not added. + */ + info_ptr->valid |= PNG_INFO_sPLT; + ++(info_ptr->splt_palettes_num); + ++np; + } + while (++entries, --nentries); + + if (nentries > 0) + png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); +} +#endif /* sPLT */ + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +static png_byte +check_location(png_const_structrp png_ptr, int location) +{ + location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); + + /* New in 1.6.0; copy the location and check it. This is an API + * change; previously the app had to use the + * png_set_unknown_chunk_location API below for each chunk. + */ + if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + /* Write struct, so unknown chunks come from the app */ + png_app_warning(png_ptr, + "png_set_unknown_chunks now expects a valid location"); + /* Use the old behavior */ + location = (png_byte)(png_ptr->mode & + (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); } - info_ptr->splt_palettes = np; - info_ptr->splt_palettes_num += nentries; - info_ptr->valid |= PNG_INFO_sPLT; - info_ptr->free_me |= PNG_FREE_SPLT; -} -#endif /* PNG_sPLT_SUPPORTED */ + /* This need not be an internal error - if the app calls + * png_set_unknown_chunks on a read pointer it must get the location right. + */ + if (location == 0) + png_error(png_ptr, "invalid location in png_set_unknown_chunks"); + + /* Now reduce the location to the top-most set bit by removing each least + * significant bit in turn. + */ + while (location != (location & -location)) + location &= ~(location & -location); + + /* The cast is safe because 'location' is a bit mask and only the low four + * bits are significant. + */ + return (png_byte)location; +} -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED void PNGAPI -png_set_unknown_chunks(png_structp png_ptr, - png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) +png_set_unknown_chunks(png_const_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) { png_unknown_chunkp np; - int i; - if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) + if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || + unknowns == NULL) return; - np = (png_unknown_chunkp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * - png_sizeof(png_unknown_chunk)); + /* Check for the failure cases where support has been disabled at compile + * time. This code is hardly ever compiled - it's here because + * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this + * code) but may be meaningless if the read or write handling of unknown + * chunks is not compiled in. + */ +# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_READ_SUPPORTED) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { + png_app_error(png_ptr, "no unknown chunk support on read"); + return; + } +# endif +# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_WRITE_SUPPORTED) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + png_app_error(png_ptr, "no unknown chunk support on write"); + return; + } +# endif + + /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that + * unknown critical chunks could be lost with just a warning resulting in + * undefined behavior. Now png_chunk_report is used to provide behavior + * appropriate to read or write. + */ + np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, + info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, + sizeof *np)); if (np == NULL) { - png_warning(png_ptr, - "Out of memory while processing unknown chunk"); + png_chunk_report(png_ptr, "too many unknown chunks", + PNG_CHUNK_WRITE_ERROR); return; } - png_memcpy(np, info_ptr->unknown_chunks, - (png_size_t)info_ptr->unknown_chunks_num * - png_sizeof(png_unknown_chunk)); - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; + info_ptr->unknown_chunks = np; /* safe because it is initialized */ + info_ptr->free_me |= PNG_FREE_UNKN; - for (i = 0; i < num_unknowns; i++) + np += info_ptr->unknown_chunks_num; + + /* Increment unknown_chunks_num each time round the loop to protect the + * just-allocated chunk data. + */ + for (; num_unknowns > 0; --num_unknowns, ++unknowns) { - png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; - png_const_unknown_chunkp from = unknowns + i; + memcpy(np->name, unknowns->name, (sizeof np->name)); + np->name[(sizeof np->name)-1] = '\0'; + np->location = check_location(png_ptr, unknowns->location); - png_memcpy(to->name, from->name, png_sizeof(from->name)); - to->name[png_sizeof(to->name)-1] = '\0'; - to->size = from->size; - - /* Note our location in the read or write sequence */ - to->location = (png_byte)(png_ptr->mode & 0xff); - - if (from->size == 0) - to->data=NULL; + if (unknowns->size == 0) + { + np->data = NULL; + np->size = 0; + } else { - to->data = (png_bytep)png_malloc_warn(png_ptr, - (png_size_t)from->size); + np->data = png_voidcast(png_bytep, + png_malloc_base(png_ptr, unknowns->size)); - if (to->data == NULL) + if (np->data == NULL) { - png_warning(png_ptr, - "Out of memory while processing unknown chunk"); - to->size = 0; + png_chunk_report(png_ptr, "unknown chunk: out of memory", + PNG_CHUNK_WRITE_ERROR); + /* But just skip storing the unknown chunk */ + continue; } - else - png_memcpy(to->data, from->data, from->size); + memcpy(np->data, unknowns->data, unknowns->size); + np->size = unknowns->size; } - } - info_ptr->unknown_chunks = np; - info_ptr->unknown_chunks_num += num_unknowns; - info_ptr->free_me |= PNG_FREE_UNKN; + /* These increments are skipped on out-of-memory for the data - the + * unknown chunk entry gets overwritten if the png_chunk_report returns. + * This is correct in the read case (the chunk is just dropped.) + */ + ++np; + ++(info_ptr->unknown_chunks_num); + } } void PNGAPI -png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, +png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location) { - if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < - info_ptr->unknown_chunks_num) - info_ptr->unknown_chunks[chunk].location = (png_byte)location; + /* This API is pretty pointless in 1.6.0 because the location can be set + * before the call to png_set_unknown_chunks. + * + * TODO: add a png_app_warning in 1.7 + */ + if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && + chunk < info_ptr->unknown_chunks_num) + { + if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) + { + png_app_error(png_ptr, "invalid unknown chunk location"); + /* Fake out the pre 1.6.0 behavior: */ + if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ + location = PNG_AFTER_IDAT; + + else + location = PNG_HAVE_IHDR; /* also undocumented */ + } + + info_ptr->unknown_chunks[chunk].location = + check_location(png_ptr, location); + } } #endif #ifdef PNG_MNG_FEATURES_SUPPORTED png_uint_32 PNGAPI -png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) +png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) { png_debug(1, "in png_permit_mng_features"); if (png_ptr == NULL) - return (png_uint_32)0; + return 0; - png_ptr->mng_features_permitted = - (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); + png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; - return (png_uint_32)png_ptr->mng_features_permitted; + return png_ptr->mng_features_permitted; } #endif #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -void PNGAPI -png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep - chunk_list, int num_chunks) +static unsigned int +add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) { - png_bytep new_list, p; - int i, old_num_chunks; + unsigned int i; + + /* Utility function: update the 'keep' state of a chunk if it is already in + * the list, otherwise add it to the list. + */ + for (i=0; i= PNG_HANDLE_CHUNK_LAST) { - if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) - png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; - - else - png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS) - png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; - - else - png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; - + png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); return; } - if (chunk_list == NULL) - return; + if (num_chunks_in <= 0) + { + png_ptr->unknown_default = keep; + + /* '0' means just set the flags, so stop here */ + if (num_chunks_in == 0) + return; + } + + if (num_chunks_in < 0) + { + /* Ignore all unknown chunks and all chunks recognized by + * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND + */ + static PNG_CONST png_byte chunks_to_ignore[] = { + 98, 75, 71, 68, '\0', /* bKGD */ + 99, 72, 82, 77, '\0', /* cHRM */ + 103, 65, 77, 65, '\0', /* gAMA */ + 104, 73, 83, 84, '\0', /* hIST */ + 105, 67, 67, 80, '\0', /* iCCP */ + 105, 84, 88, 116, '\0', /* iTXt */ + 111, 70, 70, 115, '\0', /* oFFs */ + 112, 67, 65, 76, '\0', /* pCAL */ + 112, 72, 89, 115, '\0', /* pHYs */ + 115, 66, 73, 84, '\0', /* sBIT */ + 115, 67, 65, 76, '\0', /* sCAL */ + 115, 80, 76, 84, '\0', /* sPLT */ + 115, 84, 69, 82, '\0', /* sTER */ + 115, 82, 71, 66, '\0', /* sRGB */ + 116, 69, 88, 116, '\0', /* tEXt */ + 116, 73, 77, 69, '\0', /* tIME */ + 122, 84, 88, 116, '\0' /* zTXt */ + }; + + chunk_list = chunks_to_ignore; + num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; + } + + else /* num_chunks_in > 0 */ + { + if (chunk_list == NULL) + { + /* Prior to 1.6.0 this was silently ignored, now it is an app_error + * which can be switched off. + */ + png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); + return; + } + + num_chunks = num_chunks_in; + } old_num_chunks = png_ptr->num_chunk_list; - new_list=(png_bytep)png_malloc(png_ptr, - (png_size_t)(5*(num_chunks + old_num_chunks))); + if (png_ptr->chunk_list == NULL) + old_num_chunks = 0; - if (png_ptr->chunk_list != NULL) + /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. + */ + if (num_chunks + old_num_chunks > UINT_MAX/5) { - png_memcpy(new_list, png_ptr->chunk_list, - (png_size_t)(5*old_num_chunks)); - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list=NULL; + png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); + return; } - png_memcpy(new_list + 5*old_num_chunks, chunk_list, - (png_size_t)(5*num_chunks)); + /* If these chunks are being reset to the default then no more memory is + * required because add_one_chunk above doesn't extend the list if the 'keep' + * parameter is the default. + */ + if (keep != 0) + { + new_list = png_voidcast(png_bytep, png_malloc(png_ptr, + 5 * (num_chunks + old_num_chunks))); - for (p = new_list + 5*old_num_chunks + 4, i = 0; i 0) + memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); + } - png_ptr->num_chunk_list = old_num_chunks + num_chunks; - png_ptr->chunk_list = new_list; - png_ptr->free_me |= PNG_FREE_LIST; + else if (old_num_chunks > 0) + new_list = png_ptr->chunk_list; + + else + new_list = NULL; + + /* Add the new chunks together with each one's handling code. If the chunk + * already exists the code is updated, otherwise the chunk is added to the + * end. (In libpng 1.6.0 order no longer matters because this code enforces + * the earlier convention that the last setting is the one that is used.) + */ + if (new_list != NULL) + { + png_const_bytep inlist; + png_bytep outlist; + unsigned int i; + + for (i=0; ichunk_list != new_list) + png_free(png_ptr, new_list); + + new_list = NULL; + } + } + + else + num_chunks = 0; + + png_ptr->num_chunk_list = num_chunks; + + if (png_ptr->chunk_list != new_list) + { + if (png_ptr->chunk_list != NULL) + png_free(png_ptr, png_ptr->chunk_list); + + png_ptr->chunk_list = new_list; + } } #endif #ifdef PNG_READ_USER_CHUNKS_SUPPORTED void PNGAPI -png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, +png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn) { png_debug(1, "in png_set_read_user_chunk_fn"); @@ -1158,64 +1477,90 @@ png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, #ifdef PNG_INFO_IMAGE_SUPPORTED void PNGAPI -png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) +png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytepp row_pointers) { png_debug1(1, "in %s storage function", "rows"); if (png_ptr == NULL || info_ptr == NULL) return; - if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) + if (info_ptr->row_pointers != NULL && + (info_ptr->row_pointers != row_pointers)) png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); info_ptr->row_pointers = row_pointers; - if (row_pointers) + if (row_pointers != NULL) info_ptr->valid |= PNG_INFO_IDAT; } #endif void PNGAPI -png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) +png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) { if (png_ptr == NULL) return; - png_free(png_ptr, png_ptr->zbuf); + if (size == 0 || size > PNG_UINT_31_MAX) + png_error(png_ptr, "invalid compression buffer size"); - if (size > ZLIB_IO_MAX) - { - png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); - png_ptr->zbuf_size = ZLIB_IO_MAX; - size = ZLIB_IO_MAX; /* must fit */ - } +# ifdef PNG_SEQUENTIAL_READ_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { + png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ + return; + } +# endif - else - png_ptr->zbuf_size = (uInt)size; +# ifdef PNG_WRITE_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + if (png_ptr->zowner != 0) + { + png_warning(png_ptr, + "Compression buffer size cannot be changed because it is in use"); + return; + } - png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, + "Compression buffer size limited to system maximum"); + size = ZLIB_IO_MAX; /* must fit */ + } - /* The following ensures a relatively safe failure if this gets called while - * the buffer is actually in use. - */ - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = 0; - png_ptr->zstream.avail_in = 0; + else if (size < 6) + { + /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH + * if this is permitted. + */ + png_warning(png_ptr, + "Compression buffer size cannot be reduced below 6"); + return; + } + + if (png_ptr->zbuffer_size != size) + { + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_ptr->zbuffer_size = (uInt)size; + } + } +# endif } void PNGAPI -png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) +png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) { - if (png_ptr && info_ptr) + if (png_ptr != NULL && info_ptr != NULL) info_ptr->valid &= ~mask; } - #ifdef PNG_SET_USER_LIMITS_SUPPORTED /* This function was added to libpng 1.2.6 */ void PNGAPI -png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, +png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max) { /* Images with dimensions larger than these limits will be @@ -1231,35 +1576,64 @@ png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, /* This function was added to libpng 1.4.0 */ void PNGAPI -png_set_chunk_cache_max (png_structp png_ptr, - png_uint_32 user_chunk_cache_max) +png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) { - if (png_ptr) + if (png_ptr != NULL) png_ptr->user_chunk_cache_max = user_chunk_cache_max; } /* This function was added to libpng 1.4.1 */ void PNGAPI -png_set_chunk_malloc_max (png_structp png_ptr, +png_set_chunk_malloc_max (png_structrp png_ptr, png_alloc_size_t user_chunk_malloc_max) { - if (png_ptr) + if (png_ptr != NULL) png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; } -#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ +#endif /* ?SET_USER_LIMITS */ #ifdef PNG_BENIGN_ERRORS_SUPPORTED void PNGAPI -png_set_benign_errors(png_structp png_ptr, int allowed) +png_set_benign_errors(png_structrp png_ptr, int allowed) { png_debug(1, "in png_set_benign_errors"); - if (allowed) - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + /* If allowed is 1, png_benign_error() is treated as a warning. + * + * If allowed is 0, png_benign_error() is treated as an error (which + * is the default behavior if png_set_benign_errors() is not called). + */ + + if (allowed != 0) + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | + PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; else - png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; + png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | + PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); } -#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ +#endif /* BENIGN_ERRORS */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Whether to report invalid palette index; added at libng-1.5.10. + * It is possible for an indexed (color-type==3) PNG file to contain + * pixels with invalid (out-of-range) indexes if the PLTE chunk has + * fewer entries than the image's bit-depth would allow. We recover + * from this gracefully by filling any incomplete palette with zeros + * (opaque black). By default, when this occurs libpng will issue + * a benign error. This API can be used to override that behavior. + */ +void PNGAPI +png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) +{ + png_debug(1, "in png_set_check_for_invalid_index"); + + if (allowed > 0) + png_ptr->num_palette_max = 0; + + else + png_ptr->num_palette_max = -1; +} +#endif +#endif /* READ || WRITE */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h index 6a587e34b58..8670a5a4e8d 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h @@ -29,11 +29,11 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Copyright (c) 1998-2013 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * - * Last changed in libpng 1.5.4 [July 7, 2011] + * Last changed in libpng 1.6.1 [March 28, 2013] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -52,13 +52,130 @@ * in this structure and is required for decompressing the LZ compressed * data in PNG files. */ +#ifndef ZLIB_CONST + /* We must ensure that zlib uses 'const' in declarations. */ +# define ZLIB_CONST +#endif #include "zlib.h" +#ifdef const + /* zlib.h sometimes #defines const to nothing, undo this. */ +# undef const +#endif + +/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility + * with older builds. + */ +#if ZLIB_VERNUM < 0x1260 +# define PNGZ_MSG_CAST(s) png_constcast(char*,s) +# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) +#else +# define PNGZ_MSG_CAST(s) (s) +# define PNGZ_INPUT_CAST(b) (b) +#endif + +/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib + * can handle at once. This type need be no larger than 16 bits (so maximum of + * 65535), this define allows us to discover how big it is, but limited by the + * maximuum for png_size_t. The value can be overriden in a library build + * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably + * lower value (e.g. 255 works). A lower value may help memory usage (slightly) + * and may even improve performance on some systems (and degrade it on others.) + */ +#ifndef ZLIB_IO_MAX +# define ZLIB_IO_MAX ((uInt)-1) +#endif + +#ifdef PNG_WRITE_SUPPORTED +/* The type of a compression buffer list used by the write code. */ +typedef struct png_compression_buffer +{ + struct png_compression_buffer *next; + png_byte output[1]; /* actually zbuf_size */ +} png_compression_buffer, *png_compression_bufferp; + +#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ + (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) +#endif + +/* Colorspace support; structures used in png_struct, png_info and in internal + * functions to hold and communicate information about the color space. + * + * PNG_COLORSPACE_SUPPORTED is only required if the application will perform + * colorspace corrections, otherwise all the colorspace information can be + * skipped and the size of libpng can be reduced (significantly) by compiling + * out the colorspace support. + */ +#ifdef PNG_COLORSPACE_SUPPORTED +/* The chromaticities of the red, green and blue colorants and the chromaticity + * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). + */ +typedef struct png_xy +{ + png_fixed_point redx, redy; + png_fixed_point greenx, greeny; + png_fixed_point bluex, bluey; + png_fixed_point whitex, whitey; +} png_xy; + +/* The same data as above but encoded as CIE XYZ values. When this data comes + * from chromaticities the sum of the Y values is assumed to be 1.0 + */ +typedef struct png_XYZ +{ + png_fixed_point red_X, red_Y, red_Z; + png_fixed_point green_X, green_Y, green_Z; + png_fixed_point blue_X, blue_Y, blue_Z; +} png_XYZ; +#endif /* COLORSPACE */ + +#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) +/* A colorspace is all the above plus, potentially, profile information, + * however at present libpng does not use the profile internally so it is only + * stored in the png_info struct (if iCCP is supported.) The rendering intent + * is retained here and is checked. + * + * The file gamma encoding information is also stored here and gamma correction + * is done by libpng, whereas color correction must currently be done by the + * application. + */ +typedef struct png_colorspace +{ +#ifdef PNG_GAMMA_SUPPORTED + png_fixed_point gamma; /* File gamma */ +#endif + +#ifdef PNG_COLORSPACE_SUPPORTED + png_xy end_points_xy; /* End points as chromaticities */ + png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ + png_uint_16 rendering_intent; /* Rendering intent of a profile */ +#endif + + /* Flags are always defined to simplify the code. */ + png_uint_16 flags; /* As defined below */ +} png_colorspace, * PNG_RESTRICT png_colorspacerp; + +typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; + +/* General flags for the 'flags' field */ +#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 +#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 +#define PNG_COLORSPACE_HAVE_INTENT 0x0004 +#define PNG_COLORSPACE_FROM_gAMA 0x0008 +#define PNG_COLORSPACE_FROM_cHRM 0x0010 +#define PNG_COLORSPACE_FROM_sRGB 0x0020 +#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 +#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ +#define PNG_COLORSPACE_INVALID 0x8000 +#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) +#endif /* COLORSPACE || GAMMA */ struct png_struct_def { #ifdef PNG_SETJMP_SUPPORTED - jmp_buf longjmp_buffer; /* used in png_error */ + jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ + jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ + size_t jmp_buf_size; /* size of the above, if allocated */ #endif png_error_ptr error_fn; /* function for printing errors and aborting */ #ifdef PNG_WARNINGS_SUPPORTED @@ -91,22 +208,12 @@ struct png_struct_def png_uint_32 flags; /* flags indicating various things to libpng */ png_uint_32 transformations; /* which transformations to perform */ - z_stream zstream; /* pointer to decompression structure (below) */ - png_bytep zbuf; /* buffer for zlib */ - uInt zbuf_size; /* size of zbuf (typically 65536) */ + png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ + z_stream zstream; /* decompression structure */ + #ifdef PNG_WRITE_SUPPORTED - -/* Added in 1.5.4: state to keep track of whether the zstream has been - * initialized and if so whether it is for IDAT or some other chunk. - */ -#define PNG_ZLIB_UNINITIALIZED 0 -#define PNG_ZLIB_FOR_IDAT 1 -#define PNG_ZLIB_FOR_TEXT 2 /* anything other than IDAT */ -#define PNG_ZLIB_USE_MASK 3 /* bottom two bits */ -#define PNG_ZLIB_IN_USE 4 /* a flag value */ - - png_uint_32 zlib_state; /* State of zlib initialization */ -/* End of material added at libpng 1.5.4 */ + png_compression_bufferp zbuffer_list; /* Created on demand during write */ + uInt zbuffer_size; /* size of the actual buffer */ int zlib_level; /* holds zlib compression level */ int zlib_method; /* holds zlib compression method */ @@ -115,8 +222,7 @@ struct png_struct_def int zlib_strategy; /* holds zlib compression strategy */ #endif /* Added at libpng 1.5.4 */ -#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \ - defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED) +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED int zlib_text_level; /* holds zlib compression level */ int zlib_text_method; /* holds zlib compression method */ int zlib_text_window_bits; /* holds zlib compression window bits */ @@ -124,6 +230,14 @@ struct png_struct_def int zlib_text_strategy; /* holds zlib compression strategy */ #endif /* End of material added at libpng 1.5.4 */ +/* Added at libpng 1.6.0 */ +#ifdef PNG_WRITE_SUPPORTED + int zlib_set_level; /* Actual values set into the zstream on write */ + int zlib_set_method; + int zlib_set_window_bits; + int zlib_set_mem_level; + int zlib_set_strategy; +#endif png_uint_32 width; /* width of image in pixels */ png_uint_32 height; /* height of image in pixels */ @@ -132,21 +246,32 @@ struct png_struct_def png_size_t rowbytes; /* size of row in bytes */ png_uint_32 iwidth; /* width of current interlaced row in pixels */ png_uint_32 row_number; /* current row in interlace pass */ - png_bytep prev_row; /* buffer to save previous (unfiltered) row */ - png_bytep row_buf; /* buffer to save current (unfiltered) row */ + png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row. + * This is a pointer into big_prev_row + */ + png_bytep row_buf; /* buffer to save current (unfiltered) row. + * This is a pointer into big_row_buf + */ +#ifdef PNG_WRITE_SUPPORTED png_bytep sub_row; /* buffer to save "sub" row when filtering */ png_bytep up_row; /* buffer to save "up" row when filtering */ png_bytep avg_row; /* buffer to save "avg" row when filtering */ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ - png_row_info row_info; /* used for transformation routines */ +#endif png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ png_uint_32 idat_size; /* current IDAT size for read */ png_uint_32 crc; /* current chunk CRC value */ png_colorp palette; /* palette from the input file */ png_uint_16 num_palette; /* number of color entries in palette */ + +/* Added at libpng-1.5.10 */ +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + int num_palette_max; /* maximum palette index found in IDAT */ +#endif + png_uint_16 num_trans; /* number of transparency values */ - png_byte chunk_name[5]; /* null-terminated name of current chunk */ png_byte compression; /* file compression type (always 0) */ png_byte filter; /* file filter type (always 0) */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ @@ -154,12 +279,17 @@ struct png_struct_def png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ png_byte color_type; /* color type of file */ png_byte bit_depth; /* bit depth of file */ - png_byte usr_bit_depth; /* bit depth of users row */ + png_byte usr_bit_depth; /* bit depth of users row: write only */ png_byte pixel_depth; /* number of bits per pixel */ png_byte channels; /* number of channels in file */ - png_byte usr_channels; /* channels at start of write */ +#ifdef PNG_WRITE_SUPPORTED + png_byte usr_channels; /* channels at start of write: write only */ +#endif png_byte sig_bytes; /* magic bytes read/written from start of file */ - + png_byte maximum_pixel_depth; + /* pixel depth used for the row buffers */ + png_byte transformed_pixel_depth; + /* pixel depth after read/write transforms */ #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) png_uint_16 filler; /* filler bytes for pixel expansion */ #endif @@ -172,7 +302,7 @@ struct png_struct_def #ifdef PNG_READ_GAMMA_SUPPORTED png_color_16 background_1; /* background normalized to gamma 1.0 */ #endif -#endif /* PNG_bKGD_SUPPORTED */ +#endif /* bKGD */ #ifdef PNG_WRITE_FLUSH_SUPPORTED png_flush_ptr output_flush_fn; /* Function for flushing output */ @@ -180,19 +310,20 @@ struct png_struct_def png_uint_32 flush_rows; /* number of rows written since last flush */ #endif -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ - png_fixed_point gamma; /* file gamma value */ png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ -#endif -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) png_bytep gamma_from_1; /* converts from 1.0 to screen */ png_bytep gamma_to_1; /* converts from file to 1.0 */ - png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) @@ -228,14 +359,7 @@ struct png_struct_def int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ -# ifdef PNG_TEXT_SUPPORTED - png_size_t current_text_size; /* current size of text input data */ - png_size_t current_text_left; /* how much text left to read in input */ - png_charp current_text; /* current text chunk buffer */ - png_charp current_text_ptr; /* current location in current_text */ -# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ - -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ +#endif /* PROGRESSIVE_READ */ #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) /* For the Borland special 64K segment handler */ @@ -251,10 +375,6 @@ struct png_struct_def png_bytep quantize_index; /* index translation for palette files */ #endif -#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) - png_uint_16p hist; /* histogram */ -#endif - #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED png_byte heuristic_method; /* heuristic for row filter selection */ png_byte num_prev_filters; /* number of weights for previous rows */ @@ -265,9 +385,17 @@ struct png_struct_def png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ #endif + /* Options */ +#ifdef PNG_SET_OPTION_SUPPORTED + png_byte options; /* On/off state (up to 4 options) */ +#endif + +#if PNG_LIBPNG_VER < 10700 +/* To do: remove this from libpng-1.7 */ #ifdef PNG_TIME_RFC1123_SUPPORTED char time_buffer[29]; /* String to hold RFC 1123 time text */ #endif +#endif /* New members added in libpng-1.0.6 */ @@ -275,27 +403,31 @@ struct png_struct_def #ifdef PNG_USER_CHUNKS_SUPPORTED png_voidp user_chunk_ptr; +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ #endif +#endif -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int num_chunk_list; - png_bytep chunk_list; +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + int unknown_default; /* As PNG_HANDLE_* */ + unsigned int num_chunk_list; /* Number of entries in the list */ + png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name + * followed by a PNG_HANDLE_* byte */ #endif /* New members added in libpng-1.0.3 */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED png_byte rgb_to_gray_status; + /* Added in libpng 1.5.5 to record setting of coefficients: */ + png_byte rgb_to_gray_coefficients_set; /* These were changed from png_byte in libpng-1.0.6 */ png_uint_16 rgb_to_gray_red_coeff; png_uint_16 rgb_to_gray_green_coeff; - png_uint_16 rgb_to_gray_blue_coeff; + /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ #endif /* New member added in libpng-1.0.4 (renamed in 1.0.9) */ -#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ - defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ - defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +#if defined(PNG_MNG_FEATURES_SUPPORTED) /* Changed from png_byte to png_uint_32 at version 1.2.0 */ png_uint_32 mng_features_permitted; #endif @@ -345,21 +477,41 @@ struct png_struct_def #endif /* New member added in libpng-1.0.25 and 1.2.17 */ -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunk that the library doesn't recognize. */ +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* Temporary storage for unknown chunk that the library doesn't recognize, + * used while reading the chunk. + */ png_unknown_chunk unknown_chunk; #endif -/* New members added in libpng-1.2.26 */ +/* New member added in libpng-1.2.26 */ png_size_t old_big_row_buf_size; - png_size_t old_prev_row_size; +#ifdef PNG_READ_SUPPORTED /* New member added in libpng-1.2.30 */ - png_charp chunkdata; /* buffer for reading chunk data */ + png_bytep read_buffer; /* buffer for reading chunk data */ + png_alloc_size_t read_buffer_size; /* current size of the buffer */ +#endif +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED + uInt IDAT_read_size; /* limit on read buffer size for IDAT */ +#endif #ifdef PNG_IO_STATE_SUPPORTED /* New member added in libpng-1.4.0 */ png_uint_32 io_state; #endif + +/* New member added in libpng-1.5.6 */ + png_bytep big_prev_row; + +/* New member added in libpng-1.5.7 */ + void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row); + +#ifdef PNG_READ_SUPPORTED +#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) + png_colorspace colorspace; +#endif +#endif }; #endif /* PNGSTRUCT_H */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtest.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtest.c index 227181fbf96..fdd51acd04d 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtest.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtest.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -61,16 +61,50 @@ #define _POSIX_SOURCE 1 -#include "zlib.h" +#include +#include +#include + +/* Defined so I can write to a file on gui/windowing platforms */ +/* #define STDERR stderr */ +#define STDERR stdout /* For DOS */ + #include "png.h" + +/* Known chunks that exist in pngtest.png must be supported or pngtest will fail + * simply as a result of re-ordering them. This may be fixed in 1.7 + * + * pngtest allocates a single row buffer for each row and overwrites it, + * therefore if the write side doesn't support the writing of interlaced images + * nothing can be done for an interlaced image (and the code below will fail + * horribly trying to write extra data after writing garbage). + */ +#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ + defined PNG_READ_bKGD_SUPPORTED &&\ + defined PNG_READ_cHRM_SUPPORTED &&\ + defined PNG_READ_gAMA_SUPPORTED &&\ + defined PNG_READ_oFFs_SUPPORTED &&\ + defined PNG_READ_pCAL_SUPPORTED &&\ + defined PNG_READ_pHYs_SUPPORTED &&\ + defined PNG_READ_sBIT_SUPPORTED &&\ + defined PNG_READ_sCAL_SUPPORTED &&\ + defined PNG_READ_sRGB_SUPPORTED &&\ + defined PNG_READ_tEXt_SUPPORTED &&\ + defined PNG_READ_tIME_SUPPORTED &&\ + defined PNG_READ_zTXt_SUPPORTED &&\ + defined PNG_WRITE_INTERLACING_SUPPORTED + +#ifdef PNG_ZLIB_HEADER +# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ +#else +# include "zlib.h" +#endif + /* Copied from pngpriv.h but only used in error messages below. */ #ifndef PNG_ZBUF_SIZE # define PNG_ZBUF_SIZE 8192 #endif -# include -# include -# include -# define FCLOSE(file) fclose(file) +#define FCLOSE(file) fclose(file) #ifndef PNG_STDIO_SUPPORTED typedef FILE * png_FILE_p; @@ -95,17 +129,6 @@ typedef FILE * png_FILE_p; # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ #endif -/* The code uses memcmp and memcpy on large objects (typically row pointers) so - * it is necessary to do soemthing special on certain architectures, note that - * the actual support for this was effectively removed in 1.4, so only the - * memory remains in this program: - */ -#define CVT_PTR(ptr) (ptr) -#define CVT_PTR_NOCHECK(ptr) (ptr) -#define png_memcmp memcmp -#define png_memcpy memcpy -#define png_memset memset - /* Turn on CPU timing #define PNGTEST_TIMING */ @@ -126,30 +149,34 @@ static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; #endif static int verbose = 0; - -int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); - -#ifdef __TURBOC__ -#include -#endif - -/* Defined so I can write to a file on gui/windowing platforms */ -/* #define STDERR stderr */ -#define STDERR stdout /* For DOS */ +static int strict = 0; +static int relaxed = 0; +static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ +static int error_count = 0; /* count calls to png_error */ +static int warning_count = 0; /* count calls to png_warning */ /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ #ifndef png_jmpbuf # define png_jmpbuf(png_ptr) png_ptr->jmpbuf #endif +/* Defines for unknown chunk handling if required. */ +#ifndef PNG_HANDLE_CHUNK_ALWAYS +# define PNG_HANDLE_CHUNK_ALWAYS 3 +#endif +#ifndef PNG_HANDLE_CHUNK_IF_SAFE +# define PNG_HANDLE_CHUNK_IF_SAFE 2 +#endif + +/* Utility to save typing/errors, the argument must be a name */ +#define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) + /* Example of using row callbacks to make a simple progress meter */ static int status_pass = 1; static int status_dots_requested = 0; static int status_dots = 1; -void PNGCBAPI -read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); -void PNGCBAPI +static void PNGCBAPI read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) { if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) @@ -173,9 +200,8 @@ read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) fprintf(stdout, "r"); } -void PNGCBAPI -write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); -void PNGCBAPI +#ifdef PNG_WRITE_SUPPORTED +static void PNGCBAPI write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) { if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) @@ -183,6 +209,7 @@ write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) fprintf(stdout, "w"); } +#endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED @@ -191,9 +218,7 @@ write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) * 5 in case illegal filter values are present.) */ static png_uint_32 filters_used[256]; -void PNGCBAPI -count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); -void PNGCBAPI +static void PNGCBAPI count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) { if (png_ptr != NULL && row_info != NULL) @@ -208,9 +233,7 @@ count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) static png_uint_32 zero_samples; -void PNGCBAPI -count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); -void PNGCBAPI +static void PNGCBAPI count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) { png_bytep dp = data; @@ -288,7 +311,8 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) png_uint_32 n, nstop; int channel; int color_channels = row_info->channels; - if (row_info->color_type > 3)color_channels--; + if (row_info->color_type > 3) + color_channels--; for (n = 0, nstop=row_info->width; nfile_name != NULL) + name = test->file_name; + + fprintf(STDERR, "%s: libpng warning: %s\n", name, message); } /* This is the default error handling function. Note that replacements for @@ -566,12 +483,14 @@ pngtest_warning(png_structp png_ptr, png_const_charp message) static void PNGCBAPI pngtest_error(png_structp png_ptr, png_const_charp message) { + ++error_count; + pngtest_warning(png_ptr, message); /* We can return because png_error calls the default handler, which is * actually OK in this case. */ } -#endif /* !PNG_STDIO_SUPPORTED */ + /* END of code to validate stdio-free compilation */ /* START of code to validate memory allocation and deallocation */ @@ -590,9 +509,9 @@ typedef struct memory_information { png_alloc_size_t size; png_voidp pointer; - struct memory_information FAR *next; + struct memory_information *next; } memory_information; -typedef memory_information FAR *memory_infop; +typedef memory_information *memory_infop; static memory_infop pinformation = NULL; static int current_allocation = 0; @@ -622,7 +541,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) memory_infop pinfo; png_set_mem_fn(png_ptr, NULL, NULL, NULL); pinfo = (memory_infop)png_malloc(png_ptr, - png_sizeof(*pinfo)); + (sizeof *pinfo)); pinfo->size = size; current_allocation += size; total_allocation += size; @@ -648,9 +567,9 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) pinfo->next = pinformation; pinformation = pinfo; /* Make sure the caller isn't assuming zeroed memory. */ - png_memset(pinfo->pointer, 0xdd, pinfo->size); + memset(pinfo->pointer, 0xdd, pinfo->size); - if (verbose) + if (verbose != 0) printf("png_malloc %lu bytes at %p\n", (unsigned long)size, pinfo->pointer); @@ -675,7 +594,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) /* Unlink the element from the list. */ { - memory_infop FAR *ppinfo = &pinformation; + memory_infop *ppinfo = &pinformation; for (;;) { @@ -689,15 +608,16 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) fprintf(STDERR, "Duplicate free of memory\n"); /* We must free the list element too, but first kill the memory that is to be freed. */ - png_memset(ptr, 0x55, pinfo->size); - png_free_default(png_ptr, pinfo); + memset(ptr, 0x55, pinfo->size); + if (pinfo != NULL) + free(pinfo); pinfo = NULL; break; } if (pinfo->next == NULL) { - fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); + fprintf(STDERR, "Pointer %p not found\n", ptr); break; } @@ -706,35 +626,84 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) } /* Finally free the data. */ - if (verbose) + if (verbose != 0) printf("Freeing %p\n", ptr); - png_free_default(png_ptr, ptr); + if (ptr != NULL) + free(ptr); ptr = NULL; } -#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ +#endif /* USER_MEM && DEBUG */ /* END of code to test memory allocation/deallocation */ +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED /* Demonstration of user chunk support of the sTER and vpAg chunks */ -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED /* (sTER is a public chunk not yet known by libpng. vpAg is a private chunk used in ImageMagick to store "virtual page" size). */ -static png_uint_32 user_chunk_data[4]; - - /* 0: sTER mode + 1 - * 1: vpAg width - * 2: vpAg height - * 3: vpAg units - */ - -static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, - png_unknown_chunkp chunk) +static struct user_chunk_data { - png_uint_32 - *my_user_chunk_data; + png_const_infop info_ptr; + png_uint_32 vpAg_width, vpAg_height; + png_byte vpAg_units; + png_byte sTER_mode; + int location[2]; +} +user_chunk_data; + +/* Used for location and order; zero means nothing. */ +#define have_sTER 0x01 +#define have_vpAg 0x02 +#define before_PLTE 0x10 +#define before_IDAT 0x20 +#define after_IDAT 0x40 + +static void +init_callback_info(png_const_infop info_ptr) +{ + MEMZERO(user_chunk_data); + user_chunk_data.info_ptr = info_ptr; +} + +static int +set_location(png_structp png_ptr, struct user_chunk_data *data, int what) +{ + int location; + + if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) + return 0; /* already have one of these */ + + /* Find where we are (the code below zeroes info_ptr to indicate that the + * chunks before the first IDAT have been read.) + */ + if (data->info_ptr == NULL) /* after IDAT */ + location = what | after_IDAT; + + else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) + location = what | before_IDAT; + + else + location = what | before_PLTE; + + if (data->location[0] == 0) + data->location[0] = location; + + else + data->location[1] = location; + + return 1; /* handled */ +} + +static int PNGCBAPI +read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) +{ + struct user_chunk_data *my_user_chunk_data = + (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); + + if (my_user_chunk_data == NULL) + png_error(png_ptr, "lost user chunk pointer"); /* Return one of the following: * return (-n); chunk had an error @@ -759,9 +728,14 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, if (chunk->data[0] != 0 && chunk->data[0] != 1) return (-1); /* Invalid mode */ - my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); - my_user_chunk_data[0]=chunk->data[0]+1; - return (1); + if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) + { + my_user_chunk_data->sTER_mode=chunk->data[0]; + return (1); + } + + else + return (0); /* duplicate sTER - give it to libpng */ } if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ @@ -773,30 +747,126 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, if (chunk->size != 9) return (-1); /* Error return */ - my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); + if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) + return (0); /* duplicate vpAg */ - my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data); - my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4); - my_user_chunk_data[3]=(png_uint_32)chunk->data[8]; + my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); + my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); + my_user_chunk_data->vpAg_units = chunk->data[8]; return (1); - } + +#ifdef PNG_WRITE_SUPPORTED +static void +write_sTER_chunk(png_structp write_ptr) +{ + png_byte sTER[5] = {115, 84, 69, 82, '\0'}; + + if (verbose != 0) + fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); + + png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); +} + +static void +write_vpAg_chunk(png_structp write_ptr) +{ + png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; + + png_byte vpag_chunk_data[9]; + + if (verbose != 0) + fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", + (unsigned long)user_chunk_data.vpAg_width, + (unsigned long)user_chunk_data.vpAg_height, + user_chunk_data.vpAg_units); + + png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); + png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); + vpag_chunk_data[8] = user_chunk_data.vpAg_units; + png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); +} + +static void +write_chunks(png_structp write_ptr, int location) +{ + int i; + + /* Notice that this preserves the original chunk order, however chunks + * intercepted by the callback will be written *after* chunks passed to + * libpng. This will actually reverse a pair of sTER chunks or a pair of + * vpAg chunks, resulting in an error later. This is not worth worrying + * about - the chunks should not be duplicated! + */ + for (i=0; i<2; ++i) + { + if (user_chunk_data.location[i] == (location | have_sTER)) + write_sTER_chunk(write_ptr); + + else if (user_chunk_data.location[i] == (location | have_vpAg)) + write_vpAg_chunk(write_ptr); + } +} +#endif /* WRITE */ +#else /* !READ_USER_CHUNKS */ +# define write_chunks(pp,loc) ((void)0) #endif /* END of code to demonstrate user chunk support */ +/* START of code to check that libpng has the required text support; this only + * checks for the write support because if read support is missing the chunk + * will simply not be reported back to pngtest. + */ +#ifdef PNG_TEXT_SUPPORTED +static void +pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, + int num_text) +{ + while (num_text > 0) + { + switch (text_ptr[--num_text].compression) + { + case PNG_TEXT_COMPRESSION_NONE: + break; + + case PNG_TEXT_COMPRESSION_zTXt: +# ifndef PNG_WRITE_zTXt_SUPPORTED + ++unsupported_chunks; +# endif + break; + + case PNG_ITXT_COMPRESSION_NONE: + case PNG_ITXT_COMPRESSION_zTXt: +# ifndef PNG_WRITE_iTXt_SUPPORTED + ++unsupported_chunks; +# endif + break; + + default: + /* This is an error */ + png_error(png_ptr, "invalid text chunk compression field"); + break; + } + } +} +#endif +/* END of code to check that libpng has the required text support */ + /* Test one file */ -int +static int test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { static png_FILE_p fpin; static png_FILE_p fpout; /* "static" prevents setjmp corruption */ + pngtest_error_parameters error_parameters; png_structp read_ptr; png_infop read_info_ptr, end_info_ptr; #ifdef PNG_WRITE_SUPPORTED png_structp write_ptr; png_infop write_info_ptr; png_infop write_end_info_ptr; + int interlace_preserved = 1; #else png_structp write_ptr = NULL; png_infop write_info_ptr = NULL; @@ -805,17 +875,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_bytep row_buf; png_uint_32 y; png_uint_32 width, height; - int num_pass, pass; + int num_pass = 1, pass; int bit_depth, color_type; -#ifdef PNG_SETJMP_SUPPORTED -#ifdef USE_FAR_KEYWORD - jmp_buf tmp_jmpbuf; -#endif -#endif - - char inbuf[256], outbuf[256]; row_buf = NULL; + error_parameters.file_name = inname; if ((fpin = fopen(inname, "rb")) == NULL) { @@ -839,20 +903,9 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif -#ifndef PNG_STDIO_SUPPORTED - png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, - pngtest_warning); -#endif + png_set_error_fn(read_ptr, &error_parameters, pngtest_error, + pngtest_warning); -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - user_chunk_data[0] = 0; - user_chunk_data[1] = 0; - user_chunk_data[2] = 0; - user_chunk_data[3] = 0; - png_set_read_user_chunk_fn(read_ptr, user_chunk_data, - read_user_chunk_callback); - -#endif #ifdef PNG_WRITE_SUPPORTED #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG write_ptr = @@ -862,10 +915,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif -#ifndef PNG_STDIO_SUPPORTED - png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, - pngtest_warning); -#endif + png_set_error_fn(write_ptr, &error_parameters, pngtest_error, + pngtest_warning); #endif pngtest_debug("Allocating read_info, write_info and end_info structures"); read_info_ptr = png_create_info_struct(read_ptr); @@ -875,13 +926,15 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) write_end_info_ptr = png_create_info_struct(write_ptr); #endif +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + init_callback_info(read_info_ptr); + png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, + read_user_chunk_callback); +#endif + #ifdef PNG_SETJMP_SUPPORTED pngtest_debug("Setting jmpbuf for read struct"); -#ifdef USE_FAR_KEYWORD - if (setjmp(tmp_jmpbuf)) -#else if (setjmp(png_jmpbuf(read_ptr))) -#endif { fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); png_free(read_ptr, row_buf); @@ -895,18 +948,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) FCLOSE(fpout); return (1); } -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif #ifdef PNG_WRITE_SUPPORTED pngtest_debug("Setting jmpbuf for write struct"); -#ifdef USE_FAR_KEYWORD - if (setjmp(tmp_jmpbuf)) -#else if (setjmp(png_jmpbuf(write_ptr))) -#endif { fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); @@ -918,12 +964,34 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) FCLOSE(fpout); return (1); } +#endif +#endif -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif + if (strict != 0) + { + /* Treat png_benign_error() as errors on read */ + png_set_benign_errors(read_ptr, 0); + +#ifdef PNG_WRITE_SUPPORTED + /* Treat them as errors on write */ + png_set_benign_errors(write_ptr, 0); #endif + + /* if strict is not set, then app warnings and errors are treated as + * warnings in release builds, but not in unstable builds; this can be + * changed with '--relaxed'. + */ + } + + else if (relaxed != 0) + { + /* Allow application (pngtest) errors and warnings to pass */ + png_set_benign_errors(read_ptr, 1); + +#ifdef PNG_WRITE_SUPPORTED + png_set_benign_errors(write_ptr, 1); #endif + } pngtest_debug("Initializing input and output streams"); #ifdef PNG_STDIO_SUPPORTED @@ -943,14 +1011,6 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) # endif #endif -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - /* Normally one would use Z_DEFAULT_STRATEGY for text compression. - * This is here just to make pngtest replicate the results from libpng - * versions prior to 1.5.4, and to test this new API. - */ - png_set_text_compression_strategy(write_ptr, Z_FILTERED); -#endif - if (status_dots_requested == 1) { #ifdef PNG_WRITE_SUPPORTED @@ -982,36 +1042,65 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_set_write_user_transform_fn(write_ptr, count_zero_samples); #endif -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -# ifndef PNG_HANDLE_CHUNK_ALWAYS -# define PNG_HANDLE_CHUNK_ALWAYS 3 -# endif +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + /* Preserve all the unknown chunks, if possible. If this is disabled then, + * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use + * libpng to *save* the unknown chunks on read (because we can't switch the + * save option on!) + * + * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all + * unknown chunks and write will write them all. + */ +#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0); #endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -# ifndef PNG_HANDLE_CHUNK_IF_SAFE -# define PNG_HANDLE_CHUNK_IF_SAFE 2 -# endif - png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, + png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0); +#endif #endif pngtest_debug("Reading info struct"); png_read_info(read_ptr, read_info_ptr); +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* This is a bit of a hack; there is no obvious way in the callback function + * to determine that the chunks before the first IDAT have been read, so + * remove the info_ptr (which is only used to determine position relative to + * PLTE) here to indicate that we are after the IDAT. + */ + user_chunk_data.info_ptr = NULL; +#endif + pngtest_debug("Transferring info struct"); { int interlace_type, compression_type, filter_type; if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, - &color_type, &interlace_type, &compression_type, &filter_type)) + &color_type, &interlace_type, &compression_type, &filter_type) != 0) { png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, -#ifdef PNG_WRITE_INTERLACING_SUPPORTED color_type, interlace_type, compression_type, filter_type); -#else - color_type, PNG_INTERLACE_NONE, compression_type, filter_type); +#ifndef PNG_READ_INTERLACING_SUPPORTED + /* num_pass will not be set below, set it here if the image is + * interlaced: what happens is that write interlacing is *not* turned + * on an the partial interlaced rows are written directly. + */ + switch (interlace_type) + { + case PNG_INTERLACE_NONE: + num_pass = 1; + break; + + case PNG_INTERLACE_ADAM7: + num_pass = 7; + break; + + default: + png_error(read_ptr, "invalid interlace type"); + /*NOT REACHED*/ + } #endif } } @@ -1022,7 +1111,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) blue_y; if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) + &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) { png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); @@ -1033,7 +1122,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_fixed_point gamma; - if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) + if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); } #endif @@ -1045,7 +1134,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) blue_y; if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y)) + &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) { png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); @@ -1056,7 +1145,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { double gamma; - if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) + if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) png_set_gAMA(write_ptr, write_info_ptr, gamma); } #endif @@ -1070,7 +1159,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int compression_type; if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen)) + &profile, &proflen) != 0) { png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, profile, proflen); @@ -1081,7 +1170,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { int intent; - if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) + if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) png_set_sRGB(write_ptr, write_info_ptr, intent); } #endif @@ -1089,14 +1178,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_colorp palette; int num_palette; - if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) + if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); } #ifdef PNG_bKGD_SUPPORTED { png_color_16p background; - if (png_get_bKGD(read_ptr, read_info_ptr, &background)) + if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) { png_set_bKGD(write_ptr, write_info_ptr, background); } @@ -1106,7 +1195,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_uint_16p hist; - if (png_get_hIST(read_ptr, read_info_ptr, &hist)) + if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) png_set_hIST(write_ptr, write_info_ptr, hist); } #endif @@ -1116,7 +1205,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int unit_type; if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, - &unit_type)) + &unit_type) != 0) { png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); } @@ -1130,7 +1219,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int type, nparams; if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms)) + &nparams, &units, ¶ms) != 0) { png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params); @@ -1142,7 +1231,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_uint_32 res_x, res_y; int unit_type; - if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) + if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, + &unit_type) != 0) png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); } #endif @@ -1150,18 +1240,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_color_8p sig_bit; - if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) + if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) png_set_sBIT(write_ptr, write_info_ptr, sig_bit); } #endif #ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) { int unit; double scal_width, scal_height; if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height)) + &scal_height) != 0) { png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); } @@ -1173,7 +1264,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_charp scal_width, scal_height; if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height)) + &scal_height) != 0) { png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height); @@ -1190,6 +1281,21 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) { pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); + + pngtest_check_text_support(read_ptr, text_ptr, num_text); + + if (verbose != 0) + { + int i; + + printf("\n"); + for (i=0; i 0) { pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); + + pngtest_check_text_support(read_ptr, text_ptr, num_text); + + if (verbose != 0) + { + int i; + + printf("\n"); + for (i=0; i 0) + { + /* We don't really expect to get here because of the setjmp handling + * above, but this is safe. + */ + fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", + inname, error_count, warning_count); + + if (strict != 0) + return (1); + } + +# ifdef PNG_WRITE_SUPPORTED + /* If there we no write support nothing was written! */ + else if (unsupported_chunks > 0) + { + fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", + inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); + } +# endif + + else if (warning_count > 0) + { + fprintf(STDERR, "\n %s: %d libpng warnings found", + inname, warning_count); + + if (strict != 0) + return (1); + } + pngtest_debug("Opening files for comparison"); if ((fpin = fopen(inname, "rb")) == NULL) { @@ -1480,61 +1629,84 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (1); } - for (;;) +#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */ + if (interlace_preserved != 0) /* else the files will be changed */ { - png_size_t num_in, num_out; - - num_in = fread(inbuf, 1, 1, fpin); - num_out = fread(outbuf, 1, 1, fpout); - - if (num_in != num_out) + for (;;) { - fprintf(STDERR, "\nFiles %s and %s are of a different size\n", - inname, outname); + static int wrote_question = 0; + png_size_t num_in, num_out; + char inbuf[256], outbuf[256]; - if (wrote_question == 0) + num_in = fread(inbuf, 1, sizeof inbuf, fpin); + num_out = fread(outbuf, 1, sizeof outbuf, fpout); + + if (num_in != num_out) { - fprintf(STDERR, - " Was %s written with the same maximum IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } + fprintf(STDERR, "\nFiles %s and %s are of a different size\n", + inname, outname); - FCLOSE(fpin); - FCLOSE(fpout); - return (0); - } - - if (!num_in) - break; - - if (png_memcmp(inbuf, outbuf, num_in)) - { - fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); - - if (wrote_question == 0) - { - fprintf(STDERR, + if (wrote_question == 0 && unsupported_chunks == 0) + { + fprintf(STDERR, " Was %s written with the same maximum IDAT chunk size (%d bytes),", inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question = 1; + } + + FCLOSE(fpin); + FCLOSE(fpout); + + if (strict != 0 && unsupported_chunks == 0) + return (1); + + else + return (0); } - FCLOSE(fpin); - FCLOSE(fpout); - return (0); + if (num_in == 0) + break; + + if (memcmp(inbuf, outbuf, num_in)) + { + fprintf(STDERR, "\nFiles %s and %s are different\n", inname, + outname); + + if (wrote_question == 0 && unsupported_chunks == 0) + { + fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", + inname, PNG_ZBUF_SIZE); + fprintf(STDERR, + "\n filtering heuristic (libpng default), compression"); + fprintf(STDERR, + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); + wrote_question = 1; + } + + FCLOSE(fpin); + FCLOSE(fpout); + + /* NOTE: the unsupported_chunks escape is permitted here because + * unsupported text chunk compression will result in the compression + * mode being changed (to NONE) yet, in the test case, the result + * can be exactly the same size! + */ + if (strict != 0 && unsupported_chunks == 0) + return (1); + + else + return (0); + } } } +#endif /* WRITE */ FCLOSE(fpin); FCLOSE(fpout); @@ -1614,6 +1786,24 @@ main(int argc, char *argv[]) inname = argv[2]; } + else if (strcmp(argv[1], "--strict") == 0) + { + status_dots_requested = 0; + verbose = 1; + inname = argv[2]; + strict++; + relaxed = 0; + } + + else if (strcmp(argv[1], "--relaxed") == 0) + { + status_dots_requested = 0; + verbose = 1; + inname = argv[2]; + strict = 0; + relaxed++; + } + else { inname = argv[1]; @@ -1621,10 +1811,11 @@ main(int argc, char *argv[]) } } - if (!multiple && argc == 3 + verbose) + if (multiple == 0 && argc == 3 + verbose) outname = argv[2 + verbose]; - if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) + if ((multiple == 0 && argc > 3 + verbose) || + (multiple != 0 && argc < 2)) { fprintf(STDERR, "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", @@ -1636,7 +1827,7 @@ main(int argc, char *argv[]) exit(1); } - if (multiple) + if (multiple != 0) { int i; #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG @@ -1646,6 +1837,9 @@ main(int argc, char *argv[]) { int kerror; fprintf(STDERR, "\n Testing %s:", argv[i]); +#if PNG_DEBUG > 0 + fprintf(STDERR, "\n"); +#endif kerror = test_one_file(argv[i], outname); if (kerror == 0) { @@ -1660,7 +1854,7 @@ main(int argc, char *argv[]) #endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED for (k = 0; k<256; k++) - if (filters_used[k]) + if (filters_used[k] != 0) fprintf(STDERR, " Filter %d was used %lu times\n", k, (unsigned long)filters_used[k]); #endif @@ -1669,7 +1863,7 @@ main(int argc, char *argv[]) fprintf(STDERR, " tIME = %s\n", tIME_string); tIME_chunk_present = 0; -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif /* TIME_RFC1123 */ } else @@ -1691,9 +1885,9 @@ main(int argc, char *argv[]) while (pinfo != NULL) { - fprintf(STDERR, " %lu bytes at %x\n", + fprintf(STDERR, " %lu bytes at %p\n", (unsigned long)pinfo->size, - (unsigned int)pinfo->pointer); + pinfo->pointer); pinfo = pinfo->next; } } @@ -1727,7 +1921,12 @@ main(int argc, char *argv[]) status_dots_requested = 0; if (i == 0 || verbose == 1 || ierror != 0) + { fprintf(STDERR, "\n Testing %s:", inname); +#if PNG_DEBUG > 0 + fprintf(STDERR, "\n"); +#endif + } kerror = test_one_file(inname, outname); @@ -1746,21 +1945,26 @@ main(int argc, char *argv[]) #endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED for (k = 0; k<256; k++) - if (filters_used[k]) + if (filters_used[k] != 0) fprintf(STDERR, " Filter %d was used %lu times\n", k, (unsigned long)filters_used[k]); #endif #ifdef PNG_TIME_RFC1123_SUPPORTED if (tIME_chunk_present != 0) fprintf(STDERR, " tIME = %s\n", tIME_string); -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif /* TIME_RFC1123 */ } } else { if (verbose == 0 && i != 2) + { fprintf(STDERR, "\n Testing %s:", inname); +#if PNG_DEBUG > 0 + fprintf(STDERR, "\n"); +#endif + } fprintf(STDERR, " FAIL\n"); ierror += kerror; @@ -1779,8 +1983,8 @@ main(int argc, char *argv[]) while (pinfo != NULL) { - fprintf(STDERR, " %lu bytes at %x\n", - (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); + fprintf(STDERR, " %lu bytes at %p\n", + (unsigned long)pinfo->size, pinfo->pointer); pinfo = pinfo->next; } } @@ -1820,6 +2024,16 @@ main(int argc, char *argv[]) return (int)(ierror != 0); } +#else +int +main(void) +{ + fprintf(STDERR, + " test ignored because libpng was not built with read support\n"); + /* And skip this test */ + return PNG_LIBPNG_VER < 10600 ? 0 : 77; +} +#endif /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4; +typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16; diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c index b59fc695bed..5b95db8c66b 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -46,7 +46,7 @@ #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Turn on BGR-to-RGB mapping */ void PNGAPI -png_set_bgr(png_structp png_ptr) +png_set_bgr(png_structrp png_ptr) { png_debug(1, "in png_set_bgr"); @@ -60,7 +60,7 @@ png_set_bgr(png_structp png_ptr) #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* Turn on 16 bit byte swapping */ void PNGAPI -png_set_swap(png_structp png_ptr) +png_set_swap(png_structrp png_ptr) { png_debug(1, "in png_set_swap"); @@ -75,7 +75,7 @@ png_set_swap(png_structp png_ptr) #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) /* Turn on pixel packing */ void PNGAPI -png_set_packing(png_structp png_ptr) +png_set_packing(png_structrp png_ptr) { png_debug(1, "in png_set_packing"); @@ -85,7 +85,9 @@ png_set_packing(png_structp png_ptr) if (png_ptr->bit_depth < 8) { png_ptr->transformations |= PNG_PACK; - png_ptr->usr_bit_depth = 8; +# ifdef PNG_WRITE_SUPPORTED + png_ptr->usr_bit_depth = 8; +# endif } } #endif @@ -93,7 +95,7 @@ png_set_packing(png_structp png_ptr) #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) /* Turn on packed pixel swapping */ void PNGAPI -png_set_packswap(png_structp png_ptr) +png_set_packswap(png_structrp png_ptr) { png_debug(1, "in png_set_packswap"); @@ -107,7 +109,7 @@ png_set_packswap(png_structp png_ptr) #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) void PNGAPI -png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) +png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) { png_debug(1, "in png_set_shift"); @@ -122,11 +124,11 @@ png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) int PNGAPI -png_set_interlace_handling(png_structp png_ptr) +png_set_interlace_handling(png_structrp png_ptr) { png_debug(1, "in png_set_interlace handling"); - if (png_ptr && png_ptr->interlaced) + if (png_ptr != 0 && png_ptr->interlaced != 0) { png_ptr->transformations |= PNG_INTERLACE; return (7); @@ -143,44 +145,91 @@ png_set_interlace_handling(png_structp png_ptr) * that don't like bytes as parameters. */ void PNGAPI -png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) +png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) { png_debug(1, "in png_set_filler"); if (png_ptr == NULL) return; + /* In libpng 1.6 it is possible to determine whether this is a read or write + * operation and therefore to do more checking here for a valid call. + */ + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { +# ifdef PNG_READ_FILLER_SUPPORTED + /* On read png_set_filler is always valid, regardless of the base PNG + * format, because other transformations can give a format where the + * filler code can execute (basically an 8 or 16-bit component RGB or G + * format.) + * + * NOTE: usr_channels is not used by the read code! (This has led to + * confusion in the past.) The filler is only used in the read code. + */ + png_ptr->filler = (png_uint_16)filler; +# else + png_app_error(png_ptr, "png_set_filler not supported on read"); + PNG_UNUSED(filler) /* not used in the write case */ + return; +# endif + } + + else /* write */ + { +# ifdef PNG_WRITE_FILLER_SUPPORTED + /* On write the usr_channels parameter must be set correctly at the + * start to record the number of channels in the app-supplied data. + */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_RGB: + png_ptr->usr_channels = 4; + break; + + case PNG_COLOR_TYPE_GRAY: + if (png_ptr->bit_depth >= 8) + { + png_ptr->usr_channels = 2; + break; + } + + else + { + /* There simply isn't any code in libpng to strip out bits + * from bytes when the components are less than a byte in + * size! + */ + png_app_error(png_ptr, + "png_set_filler is invalid for low bit depth gray output"); + return; + } + + default: + png_app_error(png_ptr, + "png_set_filler: inappropriate color type"); + return; + } +# else + png_app_error(png_ptr, "png_set_filler not supported on write"); + return; +# endif + } + + /* Here on success - libpng supports the operation, set the transformation + * and the flag to say where the filler channel is. + */ png_ptr->transformations |= PNG_FILLER; - png_ptr->filler = (png_uint_16)filler; if (filler_loc == PNG_FILLER_AFTER) png_ptr->flags |= PNG_FLAG_FILLER_AFTER; else png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; - - /* This should probably go in the "do_read_filler" routine. - * I attempted to do that in libpng-1.0.1a but that caused problems - * so I restored it in libpng-1.0.2a - */ - - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - png_ptr->usr_channels = 4; - } - - /* Also I added this in libpng-1.0.2a (what happens when we expand - * a less-than-8-bit grayscale to GA?) */ - - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) - { - png_ptr->usr_channels = 2; - } } /* Added to libpng-1.2.7 */ void PNGAPI -png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) +png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) { png_debug(1, "in png_set_add_alpha"); @@ -188,7 +237,9 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) return; png_set_filler(png_ptr, filler, filler_loc); - png_ptr->transformations |= PNG_ADD_ALPHA; + /* The above may fail to do anything. */ + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_ptr->transformations |= PNG_ADD_ALPHA; } #endif @@ -196,7 +247,7 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) void PNGAPI -png_set_swap_alpha(png_structp png_ptr) +png_set_swap_alpha(png_structrp png_ptr) { png_debug(1, "in png_set_swap_alpha"); @@ -210,7 +261,7 @@ png_set_swap_alpha(png_structp png_ptr) #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) void PNGAPI -png_set_invert_alpha(png_structp png_ptr) +png_set_invert_alpha(png_structrp png_ptr) { png_debug(1, "in png_set_invert_alpha"); @@ -223,7 +274,7 @@ png_set_invert_alpha(png_structp png_ptr) #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) void PNGAPI -png_set_invert_mono(png_structp png_ptr) +png_set_invert_mono(png_structrp png_ptr) { png_debug(1, "in png_set_invert_mono"); @@ -304,9 +355,16 @@ png_do_swap(png_row_infop row_info, png_bytep row) for (i = 0; i < istop; i++, rp += 2) { +#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED + /* Feature added to libpng-1.6.11 for testing purposes, not + * enabled by default. + */ + *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp); +#else png_byte t = *rp; *rp = *(rp + 1); *(rp + 1) = t; +#endif } } } @@ -448,7 +506,7 @@ png_do_packswap(png_row_infop row_info, png_bytep row) *rp = table[*rp]; } } -#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ +#endif /* PACKSWAP || WRITE_PACKSWAP */ #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ defined(PNG_READ_STRIP_ALPHA_SUPPORTED) @@ -480,7 +538,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) { if (row_info->bit_depth == 8) { - if (at_start) /* Skip initial filler */ + if (at_start != 0) /* Skip initial filler */ ++sp; else /* Skip initial channel and, for sp, the filler */ sp += 2, ++dp; @@ -494,7 +552,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) else if (row_info->bit_depth == 16) { - if (at_start) /* Skip initial filler */ + if (at_start != 0) /* Skip initial filler */ sp += 2; else /* Skip initial channel and, for sp, the filler */ sp += 4, dp += 2; @@ -520,7 +578,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) { if (row_info->bit_depth == 8) { - if (at_start) /* Skip initial filler */ + if (at_start != 0) /* Skip initial filler */ ++sp; else /* Skip initial channels and, for sp, the filler */ sp += 4, dp += 3; @@ -534,7 +592,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) else if (row_info->bit_depth == 16) { - if (at_start) /* Skip initial filler */ + if (at_start != 0) /* Skip initial filler */ sp += 2; else /* Skip initial channels and, for sp, the filler */ sp += 8, dp += 6; @@ -575,7 +633,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_bgr"); - if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) + if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { png_uint_32 row_width = row_info->width; if (row_info->bit_depth == 8) @@ -645,19 +703,133 @@ png_do_bgr(png_row_infop row_info, png_bytep row) #endif } } -#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ +#endif /* READ_BGR || WRITE_BGR */ + +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +/* Added at libpng-1.5.10 */ +void /* PRIVATE */ +png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) +{ + if (png_ptr->num_palette < (1 << row_info->bit_depth) && + png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ + { + /* Calculations moved outside switch in an attempt to stop different + * compiler warnings. 'padding' is in *bits* within the last byte, it is + * an 'int' because pixel_depth becomes an 'int' in the expression below, + * and this calculation is used because it avoids warnings that other + * forms produced on either GCC or MSVC. + */ + int padding = (-row_info->pixel_depth * row_info->width) & 7; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; + + switch (row_info->bit_depth) + { + case 1: + { + /* in this case, all bytes must be 0 so we don't need + * to unpack the pixels except for the rightmost one. + */ + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp >> padding != 0) + png_ptr->num_palette_max = 1; + padding = 0; + } + + break; + } + + case 2: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 2) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 6) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 4: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 8: + { + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp > png_ptr->num_palette_max) + png_ptr->num_palette_max = (int) *rp; + } + + break; + } + + default: + break; + } + } +} +#endif /* CHECK_FOR_INVALID_INDEX */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED void PNGAPI -png_set_user_transform_info(png_structp png_ptr, png_voidp +png_set_user_transform_info(png_structrp png_ptr, png_voidp user_transform_ptr, int user_transform_depth, int user_transform_channels) { png_debug(1, "in png_set_user_transform_info"); if (png_ptr == NULL) return; + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) + { + png_app_error(png_ptr, + "info change after png_start_read_image or png_read_update_info"); + return; + } +#endif + png_ptr->user_transform_ptr = user_transform_ptr; png_ptr->user_transform_depth = (png_byte)user_transform_depth; png_ptr->user_transform_channels = (png_byte)user_transform_channels; @@ -671,20 +843,20 @@ png_set_user_transform_info(png_structp png_ptr, png_voidp */ #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED png_voidp PNGAPI -png_get_user_transform_ptr(png_const_structp png_ptr) +png_get_user_transform_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) return (NULL); - return ((png_voidp)png_ptr->user_transform_ptr); + return png_ptr->user_transform_ptr; } #endif #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED png_uint_32 PNGAPI -png_get_current_row_number(png_const_structp png_ptr) +png_get_current_row_number(png_const_structrp png_ptr) { - /* See the comments in png.h - this is the sub-image row when reading and + /* See the comments in png.h - this is the sub-image row when reading an * interlaced image. */ if (png_ptr != NULL) @@ -694,13 +866,12 @@ png_get_current_row_number(png_const_structp png_ptr) } png_byte PNGAPI -png_get_current_pass_number(png_const_structp png_ptr) +png_get_current_pass_number(png_const_structrp png_ptr) { if (png_ptr != NULL) return png_ptr->pass; return 8; /* invalid */ } -#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ -#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || - PNG_WRITE_USER_TRANSFORM_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ +#endif /* USER_TRANSFORM_INFO */ +#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ +#endif /* READ || WRITE */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwio.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwio.c index 2f94f8c9572..017a9d7b31b 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwio.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwio.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.0 [January 6, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -58,11 +58,12 @@ */ void /* PRIVATE */ -png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) +png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) { /* NOTE: write_data_fn must not change the buffer! */ if (png_ptr->write_data_fn != NULL ) - (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); + (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), + length); else png_error(png_ptr, "Call to NULL write function"); @@ -74,7 +75,6 @@ png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) * write_data function and use it at run time with png_set_write_fn(), rather * than changing the library. */ -#ifndef USE_FAR_KEYWORD void PNGCBAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { @@ -88,64 +88,6 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) if (check != length) png_error(png_ptr, "Write Error"); } -#else -/* This is the model-independent version. Since the standard I/O library - * can't handle far buffers in the medium and small models, we have to copy - * the data. - */ - -#define NEAR_BUF_SIZE 1024 -#define MIN(a,b) (a <= b ? a : b) - -void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) -{ - png_uint_32 check; - png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ - png_FILE_p io_ptr; - - if (png_ptr == NULL) - return; - - /* Check if data really is near. If so, use usual code. */ - near_data = (png_byte *)CVT_PTR_NOCHECK(data); - io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); - - if ((png_bytep)near_data == data) - { - check = fwrite(near_data, 1, length, io_ptr); - } - - else - { - png_byte buf[NEAR_BUF_SIZE]; - png_size_t written, remaining, err; - check = 0; - remaining = length; - - do - { - written = MIN(NEAR_BUF_SIZE, remaining); - png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ - err = fwrite(buf, 1, written, io_ptr); - - if (err != written) - break; - - else - check += err; - - data += written; - remaining -= written; - } - while (remaining != 0); - } - - if (check != length) - png_error(png_ptr, "Write Error"); -} - -#endif #endif /* This function is called to output any data pending writing (normally @@ -154,7 +96,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) */ #ifdef PNG_WRITE_FLUSH_SUPPORTED void /* PRIVATE */ -png_flush(png_structp png_ptr) +png_flush(png_structrp png_ptr) { if (png_ptr->output_flush_fn != NULL) (*(png_ptr->output_flush_fn))(png_ptr); @@ -169,7 +111,7 @@ png_default_flush(png_structp png_ptr) if (png_ptr == NULL) return; - io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); + io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); fflush(io_ptr); } # endif @@ -205,7 +147,7 @@ png_default_flush(png_structp png_ptr) * *FILE structure. */ void PNGAPI -png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, +png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) { if (png_ptr == NULL) @@ -235,8 +177,11 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, # else png_ptr->output_flush_fn = output_flush_fn; # endif -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#else + PNG_UNUSED(output_flush_fn) +#endif /* WRITE_FLUSH */ +#ifdef PNG_READ_SUPPORTED /* It is an error to read while writing a png file */ if (png_ptr->read_data_fn != NULL) { @@ -246,37 +191,6 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, "Can't set both read_data_fn and write_data_fn in the" " same structure"); } -} - -#ifdef USE_FAR_KEYWORD -# ifdef _MSC_VER -void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) -{ - void *near_ptr; - void FAR *far_ptr; - FP_OFF(near_ptr) = FP_OFF(ptr); - far_ptr = (void FAR *)near_ptr; - - if (check != 0) - if (FP_SEG(ptr) != FP_SEG(far_ptr)) - png_error(png_ptr, "segment lost in conversion"); - - return(near_ptr); -} -# else -void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) -{ - void *near_ptr; - void FAR *far_ptr; - near_ptr = (void FAR *)ptr; - far_ptr = (void FAR *)near_ptr; - - if (check != 0) - if (far_ptr != ptr) - png_error(png_ptr, "segment lost in conversion"); - - return(near_ptr); -} -# endif #endif -#endif /* PNG_WRITE_SUPPORTED */ +} +#endif /* WRITE */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwrite.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwrite.c index bdc14670964..1d39e7490f7 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwrite.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwrite.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -40,9 +40,65 @@ */ #include "pngpriv.h" +#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) +# include +#endif #ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +/* Write out all the unknown chunks for the current given location */ +static void +write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, + unsigned int where) +{ + if (info_ptr->unknown_chunks_num != 0) + { + png_const_unknown_chunkp up; + + png_debug(5, "writing extra chunks"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + ++up) + if ((up->location & where) != 0) + { + /* If per-chunk unknown chunk handling is enabled use it, otherwise + * just write the chunks the application has set. + */ +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + int keep = png_handle_as_unknown(png_ptr, up->name); + + /* NOTE: this code is radically different from the read side in the + * matter of handling an ancillary unknown chunk. In the read side + * the default behavior is to discard it, in the code below the default + * behavior is to write it. Critical chunks are, however, only + * written if explicitly listed or if the default is set to write all + * unknown chunks. + * + * The default handling is also slightly weird - it is not possible to + * stop the writing of all unsafe-to-copy chunks! + * + * TODO: REVIEW: this would seem to be a bug. + */ + if (keep != PNG_HANDLE_CHUNK_NEVER && + ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || + keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && + png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) +#endif + { + /* TODO: review, what is wrong with a zero length unknown chunk? */ + if (up->size == 0) + png_warning(png_ptr, "Writing zero-length unknown chunk"); + + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +} +#endif /* WRITE_UNKNOWN_CHUNKS */ + /* Writes all the PNG information. This is the suggested way to use the * library. If you have a new chunk to add, make a function to write it, * and put it in the correct location here. If you want the chunk written @@ -53,21 +109,21 @@ * them in png_write_end(), and compressing them. */ void PNGAPI -png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) +png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) { png_debug(1, "in png_write_info_before_PLTE"); if (png_ptr == NULL || info_ptr == NULL) return; - if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) { /* Write PNG signature */ png_write_sig(png_ptr); #ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ - (png_ptr->mng_features_permitted)) + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ + png_ptr->mng_features_permitted != 0) { png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); png_ptr->mng_features_permitted = 0; @@ -79,75 +135,88 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, info_ptr->filter_type, #ifdef PNG_WRITE_INTERLACING_SUPPORTED - info_ptr->interlace_type); + info_ptr->interlace_type #else - 0); + 0 #endif + ); + /* The rest of these check to see if the valid field has the appropriate * flag set, and if it does, writes the chunk. + * + * 1.6.0: COLORSPACE support controls the writing of these chunks too, and + * the chunks will be written if the WRITE routine is there and information + * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c + * for where the valid flags get set.) + * + * Under certain circumstances the colorspace can be invalidated without + * syncing the info_struct 'valid' flags; this happens if libpng detects and + * error and calls png_error while the color space is being set, yet the + * application continues writing the PNG. So check the 'invalid' flag here + * too. */ -#ifdef PNG_WRITE_gAMA_SUPPORTED - if (info_ptr->valid & PNG_INFO_gAMA) - png_write_gAMA_fixed(png_ptr, info_ptr->gamma); -#endif -#ifdef PNG_WRITE_sRGB_SUPPORTED - if (info_ptr->valid & PNG_INFO_sRGB) - png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); +#ifdef PNG_GAMMA_SUPPORTED +# ifdef PNG_WRITE_gAMA_SUPPORTED + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && + (info_ptr->valid & PNG_INFO_gAMA) != 0) + png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); +# endif #endif -#ifdef PNG_WRITE_iCCP_SUPPORTED - if (info_ptr->valid & PNG_INFO_iCCP) - png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, - (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); -#endif +#ifdef PNG_COLORSPACE_SUPPORTED + /* Write only one of sRGB or an ICC profile. If a profile was supplied + * and it matches one of the known sRGB ones issue a warning. + */ +# ifdef PNG_WRITE_iCCP_SUPPORTED + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->valid & PNG_INFO_iCCP) != 0) + { +# ifdef PNG_WRITE_sRGB_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sRGB) != 0) + png_app_warning(png_ptr, + "profile matches sRGB but writing iCCP instead"); +# endif + + png_write_iCCP(png_ptr, info_ptr->iccp_name, + info_ptr->iccp_profile); + } +# ifdef PNG_WRITE_sRGB_SUPPORTED + else +# endif +# endif + +# ifdef PNG_WRITE_sRGB_SUPPORTED + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->valid & PNG_INFO_sRGB) != 0) + png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); +# endif /* WRITE_sRGB */ +#endif /* COLORSPACE */ + #ifdef PNG_WRITE_sBIT_SUPPORTED - if (info_ptr->valid & PNG_INFO_sBIT) + if ((info_ptr->valid & PNG_INFO_sBIT) != 0) png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); #endif -#ifdef PNG_WRITE_cHRM_SUPPORTED - if (info_ptr->valid & PNG_INFO_cHRM) - png_write_cHRM_fixed(png_ptr, - info_ptr->x_white, info_ptr->y_white, - info_ptr->x_red, info_ptr->y_red, - info_ptr->x_green, info_ptr->y_green, - info_ptr->x_blue, info_ptr->y_blue); + +#ifdef PNG_COLORSPACE_SUPPORTED +# ifdef PNG_WRITE_cHRM_SUPPORTED + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && + (info_ptr->valid & PNG_INFO_cHRM) != 0) + png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); +# endif #endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks_num) - { - png_unknown_chunk *up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { - int keep = png_handle_as_unknown(png_ptr, up->name); - - if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && - !(up->location & PNG_HAVE_PLTE) && - !(up->location & PNG_HAVE_IDAT) && - !(up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) - { - if (up->size == 0) - png_warning(png_ptr, "Writing zero-length unknown chunk"); - - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); #endif + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; } } void PNGAPI -png_write_info(png_structp png_ptr, png_infop info_ptr) +png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) { #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) int i; @@ -160,19 +229,19 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) png_write_info_before_PLTE(png_ptr, info_ptr); - if (info_ptr->valid & PNG_INFO_PLTE) + if ((info_ptr->valid & PNG_INFO_PLTE) != 0) png_write_PLTE(png_ptr, info_ptr->palette, (png_uint_32)info_ptr->num_palette); - else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + else if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) !=0) png_error(png_ptr, "Valid palette required for paletted images"); #ifdef PNG_WRITE_tRNS_SUPPORTED - if (info_ptr->valid & PNG_INFO_tRNS) + if ((info_ptr->valid & PNG_INFO_tRNS) !=0) { #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED /* Invert the alpha channel (in tRNS) */ - if ((png_ptr->transformations & PNG_INVERT_ALPHA) && + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { int j; @@ -186,42 +255,42 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) } #endif #ifdef PNG_WRITE_bKGD_SUPPORTED - if (info_ptr->valid & PNG_INFO_bKGD) + if ((info_ptr->valid & PNG_INFO_bKGD) != 0) png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); #endif #ifdef PNG_WRITE_hIST_SUPPORTED - if (info_ptr->valid & PNG_INFO_hIST) + if ((info_ptr->valid & PNG_INFO_hIST) != 0) png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); #endif #ifdef PNG_WRITE_oFFs_SUPPORTED - if (info_ptr->valid & PNG_INFO_oFFs) + if ((info_ptr->valid & PNG_INFO_oFFs) != 0) png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, info_ptr->offset_unit_type); #endif #ifdef PNG_WRITE_pCAL_SUPPORTED - if (info_ptr->valid & PNG_INFO_pCAL) + if ((info_ptr->valid & PNG_INFO_pCAL) != 0) png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, info_ptr->pcal_units, info_ptr->pcal_params); #endif #ifdef PNG_WRITE_sCAL_SUPPORTED - if (info_ptr->valid & PNG_INFO_sCAL) + if ((info_ptr->valid & PNG_INFO_sCAL) != 0) png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_s_width, info_ptr->scal_s_height); #endif /* sCAL */ #ifdef PNG_WRITE_pHYs_SUPPORTED - if (info_ptr->valid & PNG_INFO_pHYs) + if ((info_ptr->valid & PNG_INFO_pHYs) != 0) png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); #endif /* pHYs */ #ifdef PNG_WRITE_tIME_SUPPORTED - if (info_ptr->valid & PNG_INFO_tIME) + if ((info_ptr->valid & PNG_INFO_tIME) != 0) { png_write_tIME(png_ptr, &(info_ptr->mod_time)); png_ptr->mode |= PNG_WROTE_tIME; @@ -229,7 +298,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) #endif /* tIME */ #ifdef PNG_WRITE_sPLT_SUPPORTED - if (info_ptr->valid & PNG_INFO_sPLT) + if ((info_ptr->valid & PNG_INFO_sPLT) != 0) for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); #endif /* sPLT */ @@ -251,11 +320,14 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) info_ptr->text[i].lang, info_ptr->text[i].lang_key, info_ptr->text[i].text); + /* Mark this chunk as written */ + if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + else + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; #else - png_warning(png_ptr, "Unable to write international text"); + png_warning(png_ptr, "Unable to write international text"); #endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } /* If we want a compressed text chunk */ @@ -264,13 +336,12 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_WRITE_zTXt_SUPPORTED /* Write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0, - info_ptr->text[i].compression); + info_ptr->text[i].text, info_ptr->text[i].compression); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; #else png_warning(png_ptr, "Unable to write compressed text"); #endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; } else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) @@ -291,29 +362,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) #endif /* tEXt */ #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks_num) - { - png_unknown_chunk *up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { - int keep = png_handle_as_unknown(png_ptr, up->name); - if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && - (up->location & PNG_HAVE_PLTE) && - !(up->location & PNG_HAVE_IDAT) && - !(up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) - { - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); #endif } @@ -323,16 +372,21 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) * comments, I suggest writing them here, and compressing them. */ void PNGAPI -png_write_end(png_structp png_ptr, png_infop info_ptr) +png_write_end(png_structrp png_ptr, png_inforp info_ptr) { png_debug(1, "in png_write_end"); if (png_ptr == NULL) return; - if (!(png_ptr->mode & PNG_HAVE_IDAT)) + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) png_error(png_ptr, "No IDATs written into file"); +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + if (png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); +#endif + /* See if user wants us to write information chunks */ if (info_ptr != NULL) { @@ -341,8 +395,8 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_WRITE_tIME_SUPPORTED /* Check to see if user has supplied a time chunk */ - if ((info_ptr->valid & PNG_INFO_tIME) && - !(png_ptr->mode & PNG_WROTE_tIME)) + if ((info_ptr->valid & PNG_INFO_tIME) != 0 && + (png_ptr->mode & PNG_WROTE_tIME) == 0) png_write_tIME(png_ptr, &(info_ptr->mod_time)); #endif @@ -363,11 +417,14 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) info_ptr->text[i].lang, info_ptr->text[i].lang_key, info_ptr->text[i].text); + /* Mark this chunk as written */ + if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + else + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; #else png_warning(png_ptr, "Unable to write international text"); #endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) @@ -375,13 +432,12 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_WRITE_zTXt_SUPPORTED /* Write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0, - info_ptr->text[i].compression); + info_ptr->text[i].text, info_ptr->text[i].compression); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; #else png_warning(png_ptr, "Unable to write compressed text"); #endif - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; } else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) @@ -390,37 +446,16 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) /* Write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; #else png_warning(png_ptr, "Unable to write uncompressed text"); #endif - - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } } #endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks_num) - { - png_unknown_chunk *up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { - int keep = png_handle_as_unknown(png_ptr, up->name); - if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && - (up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) - { - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } + write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); #endif } @@ -428,6 +463,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) /* Write end of PNG file */ png_write_IEND(png_ptr); + /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, * and restored again in libpng-1.2.30, may cause some applications that * do not set png_ptr->output_flush_fn to crash. If your application @@ -443,9 +479,8 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) } #ifdef PNG_CONVERT_tIME_SUPPORTED -/* "tm" structure is not supported on WindowsCE */ void PNGAPI -png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) +png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) { png_debug(1, "in png_convert_from_struct_tm"); @@ -474,103 +509,75 @@ PNG_FUNCTION(png_structp,PNGAPI png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) { -#ifdef PNG_USER_MEM_SUPPORTED - return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL)); +#ifndef PNG_USER_MEM_SUPPORTED + png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, NULL, NULL, NULL); +#else + return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL); } /* Alternate initialize png_ptr structure, and allocate any memory needed */ -static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ - PNG_FUNCTION(png_structp,PNGAPI png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) { -#endif /* PNG_USER_MEM_SUPPORTED */ - volatile int png_cleanup_needed = 0; -#ifdef PNG_SETJMP_SUPPORTED - volatile -#endif - png_structp png_ptr; -#ifdef PNG_SETJMP_SUPPORTED -#ifdef USE_FAR_KEYWORD - jmp_buf tmp_jmpbuf; -#endif -#endif - - png_debug(1, "in png_create_write_struct"); - -#ifdef PNG_USER_MEM_SUPPORTED - png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); -#else - png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); -#endif /* PNG_USER_MEM_SUPPORTED */ - if (png_ptr == NULL) - return (NULL); - - /* Added at libpng-1.2.6 */ -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - png_ptr->user_width_max = PNG_USER_WIDTH_MAX; - png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* Applications that neglect to set up their own setjmp() and then - encounter a png_error() will longjmp here. Since the jmpbuf is - then meaningless we abort instead of returning. */ -#ifdef USE_FAR_KEYWORD - if (setjmp(tmp_jmpbuf)) -#else - if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ -#endif -#ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -#endif - PNG_ABORT(); -#endif - -#ifdef PNG_USER_MEM_SUPPORTED - png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); -#endif /* PNG_USER_MEM_SUPPORTED */ - png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); - - if (!png_user_version_check(png_ptr, user_png_ver)) - png_cleanup_needed = 1; - - /* Initialize zbuf - compression buffer */ - png_ptr->zbuf_size = PNG_ZBUF_SIZE; - - if (!png_cleanup_needed) + png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); +#endif /* USER_MEM */ + if (png_ptr != NULL) { - png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, - png_ptr->zbuf_size); - if (png_ptr->zbuf == NULL) - png_cleanup_needed = 1; + /* Set the zlib control values to defaults; they can be overridden by the + * application after the struct has been created. + */ + png_ptr->zbuffer_size = PNG_ZBUF_SIZE; + + /* The 'zlib_strategy' setting is irrelevant because png_default_claim in + * pngwutil.c defaults it according to whether or not filters will be + * used, and ignores this setting. + */ + png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; + png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; + png_ptr->zlib_mem_level = 8; + png_ptr->zlib_window_bits = 15; + png_ptr->zlib_method = 8; + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED + png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; + png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; + png_ptr->zlib_text_mem_level = 8; + png_ptr->zlib_text_window_bits = 15; + png_ptr->zlib_text_method = 8; +#endif /* WRITE_COMPRESSED_TEXT */ + + /* This is a highly dubious configuration option; by default it is off, + * but it may be appropriate for private builds that are testing + * extensions not conformant to the current specification, or of + * applications that must not fail to write at all costs! + */ +#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED + /* In stable builds only warn if an application error can be completely + * handled. + */ + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; +#endif + + /* App warnings are warnings in release (or release candidate) builds but + * are errors during development. + */ +#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; +#endif + + /* TODO: delay this, it can be done in png_init_io() (if the app doesn't + * do it itself) avoiding setting the default function if it is not + * required. + */ + png_set_write_fn(png_ptr, NULL, NULL, NULL); } - if (png_cleanup_needed) - { - /* Clean up PNG structure and deallocate any memory. */ - png_free(png_ptr, png_ptr->zbuf); - png_ptr->zbuf = NULL; -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, - (png_free_ptr)free_fn, (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)png_ptr); -#endif - return (NULL); - } - - png_set_write_fn(png_ptr, NULL, NULL, NULL); - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_reset_filter_heuristics(png_ptr); -#endif - - return (png_ptr); + return png_ptr; } @@ -580,7 +587,7 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, * "write" the image seven times. */ void PNGAPI -png_write_rows(png_structp png_ptr, png_bytepp row, +png_write_rows(png_structrp png_ptr, png_bytepp row, png_uint_32 num_rows) { png_uint_32 i; /* row counter */ @@ -602,7 +609,7 @@ png_write_rows(png_structp png_ptr, png_bytepp row, * if you are writing an interlaced image. */ void PNGAPI -png_write_image(png_structp png_ptr, png_bytepp image) +png_write_image(png_structrp png_ptr, png_bytepp image) { png_uint_32 i; /* row index */ int pass, num_pass; /* pass variables */ @@ -632,10 +639,78 @@ png_write_image(png_structp png_ptr, png_bytepp image) } } +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Performs intrapixel differencing */ +static void +png_do_write_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_intrapixel"); + + if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); + *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); + png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp + 1) = (png_byte)(red & 0xff); + *(rp + 4) = (png_byte)((blue >> 8) & 0xff); + *(rp + 5) = (png_byte)(blue & 0xff); + } + } +#endif /* WRITE_16BIT */ + } +} +#endif /* MNG_FEATURES */ + /* Called by user to write a row of image data */ void PNGAPI -png_write_row(png_structp png_ptr, png_const_bytep row) +png_write_row(png_structrp png_ptr, png_const_bytep row) { + /* 1.5.6: moved from png_struct to be a local structure: */ + png_row_info row_info; + if (png_ptr == NULL) return; @@ -646,44 +721,44 @@ png_write_row(png_structp png_ptr, png_const_bytep row) if (png_ptr->row_number == 0 && png_ptr->pass == 0) { /* Make sure we wrote the header info */ - if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) png_error(png_ptr, "png_write_info was never called before png_write_row"); /* Check for transforms that have been set but were defined out */ #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) - if (png_ptr->transformations & PNG_INVERT_MONO) + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); #endif #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) - if (png_ptr->transformations & PNG_FILLER) + if ((png_ptr->transformations & PNG_FILLER) != 0) png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); #endif #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); #endif #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) - if (png_ptr->transformations & PNG_PACK) + if ((png_ptr->transformations & PNG_PACK) != 0) png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); #endif #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) - if (png_ptr->transformations & PNG_SHIFT) + if ((png_ptr->transformations & PNG_SHIFT) != 0) png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); #endif #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) - if (png_ptr->transformations & PNG_BGR) + if ((png_ptr->transformations & PNG_BGR) != 0) png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); #endif #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) - if (png_ptr->transformations & PNG_SWAP_BYTES) + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); #endif @@ -692,12 +767,13 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* If interlaced and not interested in row, return */ - if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0) { switch (png_ptr->pass) { case 0: - if (png_ptr->row_number & 0x07) + if ((png_ptr->row_number & 0x07) != 0) { png_write_finish_row(png_ptr); return; @@ -705,7 +781,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) break; case 1: - if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5) { png_write_finish_row(png_ptr); return; @@ -721,7 +797,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) break; case 3: - if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) + if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3) { png_write_finish_row(png_ptr); return; @@ -737,7 +813,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) break; case 5: - if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) + if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2) { png_write_finish_row(png_ptr); return; @@ -745,7 +821,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) break; case 6: - if (!(png_ptr->row_number & 0x01)) + if ((png_ptr->row_number & 0x01) == 0) { png_write_finish_row(png_ptr); return; @@ -759,36 +835,31 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #endif /* Set up row info for transformations */ - png_ptr->row_info.color_type = png_ptr->color_type; - png_ptr->row_info.width = png_ptr->usr_width; - png_ptr->row_info.channels = png_ptr->usr_channels; - png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; - png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * - png_ptr->row_info.channels); + row_info.color_type = png_ptr->color_type; + row_info.width = png_ptr->usr_width; + row_info.channels = png_ptr->usr_channels; + row_info.bit_depth = png_ptr->usr_bit_depth; + row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); - - png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); - png_debug1(3, "row_info->width = %u", png_ptr->row_info.width); - png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); - png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); - png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu", - (unsigned long)png_ptr->row_info.rowbytes); + png_debug1(3, "row_info->color_type = %d", row_info.color_type); + png_debug1(3, "row_info->width = %u", row_info.width); + png_debug1(3, "row_info->channels = %d", row_info.channels); + png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); /* Copy user's row into buffer, leaving room for filter byte. */ - png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); + memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && - (png_ptr->transformations & PNG_INTERLACE)) + (png_ptr->transformations & PNG_INTERLACE) != 0) { - png_do_write_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass); + png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); /* This should always get caught above, but still ... */ - if (!(png_ptr->row_info.width)) + if (row_info.width == 0) { png_write_finish_row(png_ptr); return; @@ -798,10 +869,17 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED /* Handle other transformations */ - if (png_ptr->transformations) - png_do_write_transformations(png_ptr); + if (png_ptr->transformations != 0) + png_do_write_transformations(png_ptr, &row_info); #endif + /* At this point the row_info pixel depth must match the 'transformed' depth, + * which is also the output depth. + */ + if (row_info.pixel_depth != png_ptr->pixel_depth || + row_info.pixel_depth != png_ptr->transformed_pixel_depth) + png_error(png_ptr, "internal write transform logic error"); + #ifdef PNG_MNG_FEATURES_SUPPORTED /* Write filter_method 64 (intrapixel differencing) only if * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and @@ -812,16 +890,24 @@ png_write_row(png_structp png_ptr, png_const_bytep row) * 4. The filter_method is 64 and * 5. The color_type is RGB or RGBA */ - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ - png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); } #endif +/* Added at libpng-1.5.10 */ +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Check for out-of-range palette index */ + if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, &row_info); +#endif + /* Find a filter if necessary, filter the row and write it out. */ - png_write_find_filter(png_ptr, &(png_ptr->row_info)); + png_write_find_filter(png_ptr, &row_info); if (png_ptr->write_row_fn != NULL) (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); @@ -830,7 +916,7 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #ifdef PNG_WRITE_FLUSH_SUPPORTED /* Set the automatic flush interval or 0 to turn flushing off */ void PNGAPI -png_set_flush(png_structp png_ptr, int nrows) +png_set_flush(png_structrp png_ptr, int nrows) { png_debug(1, "in png_set_flush"); @@ -842,10 +928,8 @@ png_set_flush(png_structp png_ptr, int nrows) /* Flush the current output buffers now */ void PNGAPI -png_write_flush(png_structp png_ptr) +png_write_flush(png_structrp png_ptr) { - int wrote_IDAT; - png_debug(1, "in png_write_flush"); if (png_ptr == NULL) @@ -855,146 +939,41 @@ png_write_flush(png_structp png_ptr) if (png_ptr->row_number >= png_ptr->num_rows) return; - do - { - int ret; - - /* Compress the data */ - ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); - wrote_IDAT = 0; - - /* Check for compression errors */ - if (ret != Z_OK) - { - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - - if (!(png_ptr->zstream.avail_out)) - { - /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - wrote_IDAT = 1; - } - } while (wrote_IDAT == 1); - - /* If there is any data left to be output, write it into a new IDAT */ - if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) - { - /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); - } + png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); png_ptr->flush_rows = 0; png_flush(png_ptr); } -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#endif /* WRITE_FLUSH */ -/* Free all memory used by the write */ -void PNGAPI -png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */ +#endif + +/* Free any memory used in png_ptr struct without freeing the struct itself. */ +static void +png_write_destroy(png_structrp png_ptr) { - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; -#ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn = NULL; - png_voidp mem_ptr = NULL; -#endif - - png_debug(1, "in png_destroy_write_struct"); - - if (png_ptr_ptr != NULL) - { - png_ptr = *png_ptr_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; - mem_ptr = png_ptr->mem_ptr; -#endif - } - -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr != NULL) - { - free_fn = png_ptr->free_fn; - mem_ptr = png_ptr->mem_ptr; - } -#endif - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (info_ptr != NULL) - { - if (png_ptr != NULL) - { - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_ptr->num_chunk_list) - { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->num_chunk_list = 0; - } -#endif - } - -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)info_ptr); -#endif - *info_ptr_ptr = NULL; - } - - if (png_ptr != NULL) - { - png_write_destroy(png_ptr); -#ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); -#else - png_destroy_struct((png_voidp)png_ptr); -#endif - *png_ptr_ptr = NULL; - } -} - - -/* Free any memory used in png_ptr struct (old method) */ -void /* PRIVATE */ -png_write_destroy(png_structp png_ptr) -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf tmp_jmp; /* Save jump buffer */ -#endif - png_error_ptr error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; -#endif - png_voidp error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn; -#endif - png_debug(1, "in png_write_destroy"); /* Free any memory zlib uses */ - if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) deflateEnd(&png_ptr->zstream); /* Free our memory. png_free checks NULL for us. */ - png_free(png_ptr, png_ptr->zbuf); + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); png_free(png_ptr, png_ptr->row_buf); + png_ptr->row_buf = NULL; #ifdef PNG_WRITE_FILTER_SUPPORTED png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->sub_row); png_free(png_ptr, png_ptr->up_row); png_free(png_ptr, png_ptr->avg_row); png_free(png_ptr, png_ptr->paeth_row); + png_ptr->prev_row = NULL; + png_ptr->sub_row = NULL; + png_ptr->up_row = NULL; + png_ptr->avg_row = NULL; + png_ptr->paeth_row = NULL; #endif #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED @@ -1002,41 +981,51 @@ png_write_destroy(png_structp png_ptr) png_reset_filter_heuristics(png_ptr); png_free(png_ptr, png_ptr->filter_costs); png_free(png_ptr, png_ptr->inv_filter_costs); + png_ptr->filter_costs = NULL; + png_ptr->inv_filter_costs = NULL; #endif -#ifdef PNG_SETJMP_SUPPORTED - /* Reset structure */ - png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list = NULL; #endif - error_fn = png_ptr->error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - warning_fn = png_ptr->warning_fn; -#endif - error_ptr = png_ptr->error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; -#endif + /* The error handling and memory handling information is left intact at this + * point: the jmp_buf may still have to be freed. See png_destroy_png_struct + * for how this happens. + */ +} - png_memset(png_ptr, 0, png_sizeof(png_struct)); +/* Free all memory used by the write. + * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for + * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free + * the passed in info_structs but it would quietly fail to free any of the data + * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it + * has no png_ptr.) + */ +void PNGAPI +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +{ + png_debug(1, "in png_destroy_write_struct"); - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#endif - png_ptr->error_ptr = error_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - png_ptr->free_fn = free_fn; -#endif + if (png_ptr_ptr != NULL) + { + png_structrp png_ptr = *png_ptr_ptr; -#ifdef PNG_SETJMP_SUPPORTED - png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); -#endif + if (png_ptr != NULL) /* added in libpng 1.6.0 */ + { + png_destroy_info_struct(png_ptr, info_ptr_ptr); + + *png_ptr_ptr = NULL; + png_write_destroy(png_ptr); + png_destroy_png_struct(png_ptr); + } + } } /* Allow the application to select one or more row filters to use. */ void PNGAPI -png_set_filter(png_structp png_ptr, int method, int filters) +png_set_filter(png_structrp png_ptr, int method, int filters) { png_debug(1, "in png_set_filter"); @@ -1044,7 +1033,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) return; #ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && (method == PNG_INTRAPIXEL_DIFFERENCING)) method = PNG_FILTER_TYPE_BASE; @@ -1056,8 +1045,9 @@ png_set_filter(png_structp png_ptr, int method, int filters) #ifdef PNG_WRITE_FILTER_SUPPORTED case 5: case 6: - case 7: png_warning(png_ptr, "Unknown row filter for method 0"); -#endif /* PNG_WRITE_FILTER_SUPPORTED */ + case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); + /* FALL THROUGH */ +#endif /* WRITE_FILTER */ case PNG_FILTER_VALUE_NONE: png_ptr->do_filter = PNG_FILTER_NONE; break; @@ -1078,8 +1068,8 @@ png_set_filter(png_structp png_ptr, int method, int filters) png_ptr->do_filter = (png_byte)filters; break; #else default: - png_warning(png_ptr, "Unknown row filter for method 0"); -#endif /* PNG_WRITE_FILTER_SUPPORTED */ + png_app_error(png_ptr, "Unknown row filter for method 0"); +#endif /* WRITE_FILTER */ } /* If we have allocated the row_buf, this means we have already started @@ -1094,14 +1084,16 @@ png_set_filter(png_structp png_ptr, int method, int filters) if (png_ptr->row_buf != NULL) { #ifdef PNG_WRITE_FILTER_SUPPORTED - if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) + if ((png_ptr->do_filter & PNG_FILTER_SUB) != 0 && + png_ptr->sub_row == NULL) { png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, (png_ptr->rowbytes + 1)); png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; } - if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) + if ((png_ptr->do_filter & PNG_FILTER_UP) != 0 && + png_ptr->up_row == NULL) { if (png_ptr->prev_row == NULL) { @@ -1118,7 +1110,8 @@ png_set_filter(png_structp png_ptr, int method, int filters) } } - if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) + if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0 && + png_ptr->avg_row == NULL) { if (png_ptr->prev_row == NULL) { @@ -1135,7 +1128,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) } } - if ((png_ptr->do_filter & PNG_FILTER_PAETH) && + if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0 && png_ptr->paeth_row == NULL) { if (png_ptr->prev_row == NULL) @@ -1153,7 +1146,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) } if (png_ptr->do_filter == PNG_NO_FILTERS) -#endif /* PNG_WRITE_FILTER_SUPPORTED */ +#endif /* WRITE_FILTER */ png_ptr->do_filter = PNG_FILTER_NONE; } } @@ -1171,7 +1164,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ /* Convenience reset API. */ static void -png_reset_filter_heuristics(png_structp png_ptr) +png_reset_filter_heuristics(png_structrp png_ptr) { /* Clear out any old values in the 'weights' - this must be done because if * the app calls set_filter_heuristics multiple times with different @@ -1204,7 +1197,7 @@ png_reset_filter_heuristics(png_structp png_ptr) } static int -png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, +png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method, int num_weights) { if (png_ptr == NULL) @@ -1224,7 +1217,7 @@ png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, if (num_weights > 0) { png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_byte) * num_weights)); + (png_uint_32)((sizeof (png_byte)) * num_weights)); /* To make sure that the weighting starts out fairly */ for (i = 0; i < num_weights; i++) @@ -1233,10 +1226,10 @@ png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, } png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + (png_uint_32)((sizeof (png_uint_16)) * num_weights)); png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + (png_uint_32)((sizeof (png_uint_16)) * num_weights)); for (i = 0; i < num_weights; i++) { @@ -1254,10 +1247,10 @@ png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, if (png_ptr->filter_costs == NULL) { png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); } for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) @@ -1287,7 +1280,7 @@ png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, /* Provide floating and fixed point APIs */ #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, +png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, int num_weights, png_const_doublep filter_weights, png_const_doublep filter_costs) { @@ -1296,7 +1289,7 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, /* The internal API allocates all the arrays and ensures that the elements of * those arrays are set to the default value. */ - if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) return; /* If using the weighted method copy in the weights. */ @@ -1342,7 +1335,7 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, #ifdef PNG_FIXED_POINT_SUPPORTED void PNGAPI -png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, +png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, int num_weights, png_const_fixed_point_p filter_weights, png_const_fixed_point_p filter_costs) { @@ -1351,7 +1344,7 @@ png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, /* The internal API allocates all the arrays and ensures that the elements of * those arrays are set to the default value. */ - if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) return; /* If using the weighted method copy in the weights. */ @@ -1405,40 +1398,40 @@ png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, } } #endif /* FIXED_POINT */ -#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ +#endif /* WRITE_WEIGHTED_FILTER */ void PNGAPI -png_set_compression_level(png_structp png_ptr, int level) +png_set_compression_level(png_structrp png_ptr, int level) { png_debug(1, "in png_set_compression_level"); if (png_ptr == NULL) return; - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; png_ptr->zlib_level = level; } void PNGAPI -png_set_compression_mem_level(png_structp png_ptr, int mem_level) +png_set_compression_mem_level(png_structrp png_ptr, int mem_level) { png_debug(1, "in png_set_compression_mem_level"); if (png_ptr == NULL) return; - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; png_ptr->zlib_mem_level = mem_level; } void PNGAPI -png_set_compression_strategy(png_structp png_ptr, int strategy) +png_set_compression_strategy(png_structrp png_ptr, int strategy) { png_debug(1, "in png_set_compression_strategy"); if (png_ptr == NULL) return; + /* The flag setting here prevents the libpng dynamic selection of strategy. + */ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; png_ptr->zlib_strategy = strategy; } @@ -1447,80 +1440,81 @@ png_set_compression_strategy(png_structp png_ptr, int strategy) * smaller value of window_bits if it can do so safely. */ void PNGAPI -png_set_compression_window_bits(png_structp png_ptr, int window_bits) +png_set_compression_window_bits(png_structrp png_ptr, int window_bits) { if (png_ptr == NULL) return; + /* Prior to 1.6.0 this would warn but then set the window_bits value, this + * meant that negative window bits values could be selected which would cause + * libpng to write a non-standard PNG file with raw deflate or gzip + * compressed IDAT or ancillary chunks. Such files can be read and there is + * no warning on read, so this seems like a very bad idea. + */ if (window_bits > 15) + { png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + window_bits = 15; + } else if (window_bits < 8) + { png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + window_bits = 8; + } -#ifndef WBITS_8_OK - /* Avoid libpng bug with 256-byte windows */ - if (window_bits == 8) - { - png_warning(png_ptr, "Compression window is being reset to 512"); - window_bits = 9; - } - -#endif - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; png_ptr->zlib_window_bits = window_bits; } void PNGAPI -png_set_compression_method(png_structp png_ptr, int method) +png_set_compression_method(png_structrp png_ptr, int method) { png_debug(1, "in png_set_compression_method"); if (png_ptr == NULL) return; + /* This would produce an invalid PNG file if it worked, but it doesn't and + * deflate will fault it, so it is harmless to just warn here. + */ if (method != 8) png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; png_ptr->zlib_method = method; } /* The following were added to libpng-1.5.4 */ #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED void PNGAPI -png_set_text_compression_level(png_structp png_ptr, int level) +png_set_text_compression_level(png_structrp png_ptr, int level) { png_debug(1, "in png_set_text_compression_level"); if (png_ptr == NULL) return; - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; png_ptr->zlib_text_level = level; } void PNGAPI -png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) +png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) { png_debug(1, "in png_set_text_compression_mem_level"); if (png_ptr == NULL) return; - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; png_ptr->zlib_text_mem_level = mem_level; } void PNGAPI -png_set_text_compression_strategy(png_structp png_ptr, int strategy) +png_set_text_compression_strategy(png_structrp png_ptr, int strategy) { png_debug(1, "in png_set_text_compression_strategy"); if (png_ptr == NULL) return; - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; png_ptr->zlib_text_strategy = strategy; } @@ -1528,32 +1522,28 @@ png_set_text_compression_strategy(png_structp png_ptr, int strategy) * smaller value of window_bits if it can do so safely. */ void PNGAPI -png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) +png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) { if (png_ptr == NULL) return; if (window_bits > 15) + { png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + window_bits = 15; + } else if (window_bits < 8) + { png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + window_bits = 8; + } -#ifndef WBITS_8_OK - /* Avoid libpng bug with 256-byte windows */ - if (window_bits == 8) - { - png_warning(png_ptr, "Text compression window is being reset to 512"); - window_bits = 9; - } - -#endif - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; png_ptr->zlib_text_window_bits = window_bits; } void PNGAPI -png_set_text_compression_method(png_structp png_ptr, int method) +png_set_text_compression_method(png_structrp png_ptr, int method) { png_debug(1, "in png_set_text_compression_method"); @@ -1563,14 +1553,13 @@ png_set_text_compression_method(png_structp png_ptr, int method) if (method != 8) png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; png_ptr->zlib_text_method = method; } -#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ +#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ /* end of API added to libpng-1.5.4 */ void PNGAPI -png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) +png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) { if (png_ptr == NULL) return; @@ -1580,7 +1569,7 @@ png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED void PNGAPI -png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr +png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr write_user_transform_fn) { png_debug(1, "in png_set_write_user_transform_fn"); @@ -1596,88 +1585,899 @@ png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr #ifdef PNG_INFO_IMAGE_SUPPORTED void PNGAPI -png_write_png(png_structp png_ptr, png_infop info_ptr, +png_write_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params) { if (png_ptr == NULL || info_ptr == NULL) return; + if ((info_ptr->valid & PNG_INFO_IDAT) == 0) + { + png_app_error(png_ptr, "no rows for png_write_image to write"); + return; + } + /* Write the file header information. */ png_write_info(png_ptr, info_ptr); /* ------ these transformations don't touch the info structure ------- */ -#ifdef PNG_WRITE_INVERT_SUPPORTED /* Invert monochrome pixels */ - if (transforms & PNG_TRANSFORM_INVERT_MONO) + if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) +#ifdef PNG_WRITE_INVERT_SUPPORTED png_set_invert_mono(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); #endif -#ifdef PNG_WRITE_SHIFT_SUPPORTED /* Shift the pixels up to a legal bit depth and fill in * as appropriate to correctly scale the image. */ - if ((transforms & PNG_TRANSFORM_SHIFT) - && (info_ptr->valid & PNG_INFO_sBIT)) - png_set_shift(png_ptr, &info_ptr->sig_bit); + if ((transforms & PNG_TRANSFORM_SHIFT) != 0) +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sBIT) != 0) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); #endif -#ifdef PNG_WRITE_PACK_SUPPORTED /* Pack pixels into bytes */ - if (transforms & PNG_TRANSFORM_PACKING) - png_set_packing(png_ptr); + if ((transforms & PNG_TRANSFORM_PACKING) != 0) +#ifdef PNG_WRITE_PACK_SUPPORTED + png_set_packing(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); #endif -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED /* Swap location of alpha bytes from ARGB to RGBA */ - if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED png_set_swap_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); #endif + /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into + * RGB, note that the code expects the input color type to be G or RGB; no + * alpha channel. + */ + if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| + PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) + { #ifdef PNG_WRITE_FILLER_SUPPORTED - /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ - if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) - png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) + { + if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) + png_app_error(png_ptr, + "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); - else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + /* Continue if ignored - this is the pre-1.6.10 behavior */ + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + } + + else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); #endif + } -#ifdef PNG_WRITE_BGR_SUPPORTED /* Flip BGR pixels to RGB */ - if (transforms & PNG_TRANSFORM_BGR) + if ((transforms & PNG_TRANSFORM_BGR) != 0) +#ifdef PNG_WRITE_BGR_SUPPORTED png_set_bgr(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); #endif -#ifdef PNG_WRITE_SWAP_SUPPORTED /* Swap bytes of 16-bit files to most significant byte first */ - if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) +#ifdef PNG_WRITE_SWAP_SUPPORTED png_set_swap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); #endif -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED /* Swap bits of 1, 2, 4 bit packed pixel formats */ - if (transforms & PNG_TRANSFORM_PACKSWAP) + if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED png_set_packswap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); #endif -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED /* Invert the alpha channel from opacity to transparency */ - if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED png_set_invert_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); #endif /* ----------------------- end of transformations ------------------- */ /* Write the bits */ - if (info_ptr->valid & PNG_INFO_IDAT) - png_write_image(png_ptr, info_ptr->row_pointers); + png_write_image(png_ptr, info_ptr->row_pointers); /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); - PNG_UNUSED(transforms) /* Quiet compiler warnings */ PNG_UNUSED(params) } #endif -#endif /* PNG_WRITE_SUPPORTED */ + + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */ +/* Initialize the write structure - general purpose utility. */ +static int +png_image_write_init(png_imagep image) +{ + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, + png_safe_error, png_safe_warning); + + if (png_ptr != NULL) + { + png_infop info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr != NULL) + { + png_controlp control = png_voidcast(png_controlp, + png_malloc_warn(png_ptr, (sizeof *control))); + + if (control != NULL) + { + memset(control, 0, (sizeof *control)); + + control->png_ptr = png_ptr; + control->info_ptr = info_ptr; + control->for_write = 1; + + image->opaque = control; + return 1; + } + + /* Error clean up */ + png_destroy_info_struct(png_ptr, &info_ptr); + } + + png_destroy_write_struct(&png_ptr, NULL); + } + + return png_image_error(image, "png_image_write_: out of memory"); +} + +/* Arguments to png_image_write_main: */ +typedef struct +{ + /* Arguments: */ + png_imagep image; + png_const_voidp buffer; + png_int_32 row_stride; + png_const_voidp colormap; + int convert_to_8bit; + /* Local variables: */ + png_const_voidp first_row; + ptrdiff_t row_bytes; + png_voidp local_row; +} png_image_write_control; + +/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to + * do any necessary byte swapping. The component order is defined by the + * png_image format value. + */ +static int +png_write_image_16bit(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + + png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, + display->first_row); + png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); + png_uint_16p row_end; + const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; + int aindex = 0; + png_uint_32 y = image->height; + + if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) + { +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } + + else +# endif + aindex = channels; + } + + else + png_error(png_ptr, "png_write_image: internal call error"); + + /* Work out the output row end and count over this, note that the increment + * above to 'row' means that row_end can actually be beyond the end of the + * row; this is correct. + */ + row_end = output_row + image->width * (channels+1); + + while (y-- > 0) + { + png_const_uint_16p in_ptr = input_row; + png_uint_16p out_ptr = output_row; + + while (out_ptr < row_end) + { + const png_uint_16 alpha = in_ptr[aindex]; + png_uint_32 reciprocal = 0; + int c; + + out_ptr[aindex] = alpha; + + /* Calculate a reciprocal. The correct calculation is simply + * component/alpha*65535 << 15. (I.e. 15 bits of precision); this + * allows correct rounding by adding .5 before the shift. 'reciprocal' + * is only initialized when required. + */ + if (alpha > 0 && alpha < 65535) + reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; + + c = channels; + do /* always at least one channel */ + { + png_uint_16 component = *in_ptr++; + + /* The following gives 65535 for an alpha of 0, which is fine, + * otherwise if 0/0 is represented as some other value there is more + * likely to be a discontinuity which will probably damage + * compression when moving from a fully transparent area to a + * nearly transparent one. (The assumption here is that opaque + * areas tend not to be 0 intensity.) + */ + if (component >= alpha) + component = 65535; + + /* component 0 && alpha < 65535) + { + png_uint_32 calc = component * reciprocal; + calc += 16384; /* round to nearest */ + component = (png_uint_16)(calc >> 15); + } + + *out_ptr++ = component; + } + while (--c > 0); + + /* Skip to next component (skip the intervening alpha channel) */ + ++in_ptr; + ++out_ptr; + } + + png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); + input_row += display->row_bytes/(sizeof (png_uint_16)); + } + + return 1; +} + +/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel + * is present it must be removed from the components, the components are then + * written in sRGB encoding. No components are added or removed. + * + * Calculate an alpha reciprocal to reverse pre-multiplication. As above the + * calculation can be done to 15 bits of accuracy; however, the output needs to + * be scaled in the range 0..255*65535, so include that scaling here. + */ +#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) + +static png_byte +png_unpremultiply(png_uint_32 component, png_uint_32 alpha, + png_uint_32 reciprocal/*from the above macro*/) +{ + /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 + * is represented as some other value there is more likely to be a + * discontinuity which will probably damage compression when moving from a + * fully transparent area to a nearly transparent one. (The assumption here + * is that opaque areas tend not to be 0 intensity.) + * + * There is a rounding problem here; if alpha is less than 128 it will end up + * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the + * output change for this too. + */ + if (component >= alpha || alpha < 128) + return 255; + + /* component 0) + { + /* The test is that alpha/257 (rounded) is less than 255, the first value + * that becomes 255 is 65407. + * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, + * be exact!) [Could also test reciprocal != 0] + */ + if (alpha < 65407) + { + component *= reciprocal; + component += 64; /* round to nearest */ + component >>= 7; + } + + else + component *= 255; + + /* Convert the component to sRGB. */ + return (png_byte)PNG_sRGB_FROM_LINEAR(component); + } + + else + return 0; +} + +static int +png_write_image_8bit(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + + png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, + display->first_row); + png_bytep output_row = png_voidcast(png_bytep, display->local_row); + png_uint_32 y = image->height; + const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; + + if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + png_bytep row_end; + int aindex; + +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } + + else +# endif + aindex = channels; + + /* Use row_end in place of a loop counter: */ + row_end = output_row + image->width * (channels+1); + + while (y-- > 0) + { + png_const_uint_16p in_ptr = input_row; + png_bytep out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_16 alpha = in_ptr[aindex]; + png_byte alphabyte = (png_byte)PNG_DIV257(alpha); + png_uint_32 reciprocal = 0; + int c; + + /* Scale and write the alpha channel. */ + out_ptr[aindex] = alphabyte; + + if (alphabyte > 0 && alphabyte < 255) + reciprocal = UNP_RECIPROCAL(alpha); + + c = channels; + do /* always at least one channel */ + *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); + while (--c > 0); + + /* Skip to next component (skip the intervening alpha channel) */ + ++in_ptr; + ++out_ptr; + } /* while out_ptr < row_end */ + + png_write_row(png_ptr, png_voidcast(png_const_bytep, + display->local_row)); + input_row += display->row_bytes/(sizeof (png_uint_16)); + } /* while y */ + } + + else + { + /* No alpha channel, so the row_end really is the end of the row and it + * is sufficient to loop over the components one by one. + */ + png_bytep row_end = output_row + image->width * channels; + + while (y-- > 0) + { + png_const_uint_16p in_ptr = input_row; + png_bytep out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_32 component = *in_ptr++; + + component *= 255; + *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); + } + + png_write_row(png_ptr, output_row); + input_row += display->row_bytes/(sizeof (png_uint_16)); + } + } + + return 1; +} + +static void +png_image_set_PLTE(png_image_write_control *display) +{ + const png_imagep image = display->image; + const void *cmap = display->colormap; + const int entries = image->colormap_entries > 256 ? 256 : + (int)image->colormap_entries; + + /* NOTE: the caller must check for cmap != NULL and entries != 0 */ + const png_uint_32 format = image->format; + const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); + +# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ + defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) + const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && + (format & PNG_FORMAT_FLAG_ALPHA) != 0; +# else +# define afirst 0 +# endif + +# ifdef PNG_FORMAT_BGR_SUPPORTED + const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; +# else +# define bgr 0 +# endif + + int i, num_trans; + png_color palette[256]; + png_byte tRNS[256]; + + memset(tRNS, 255, (sizeof tRNS)); + memset(palette, 0, (sizeof palette)); + + for (i=num_trans=0; i= 3) /* RGB */ + { + palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[(2 ^ bgr)]); + palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[1]); + palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[bgr]); + } + + else /* Gray */ + palette[i].blue = palette[i].red = palette[i].green = + (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); + } + + else /* alpha */ + { + png_uint_16 alpha = entry[afirst ? 0 : channels-1]; + png_byte alphabyte = (png_byte)PNG_DIV257(alpha); + png_uint_32 reciprocal = 0; + + /* Calculate a reciprocal, as in the png_write_image_8bit code above + * this is designed to produce a value scaled to 255*65535 when + * divided by 128 (i.e. asr 7). + */ + if (alphabyte > 0 && alphabyte < 255) + reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; + + tRNS[i] = alphabyte; + if (alphabyte < 255) + num_trans = i+1; + + if (channels >= 3) /* RGB */ + { + palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], + alpha, reciprocal); + palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, + reciprocal); + palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, + reciprocal); + } + + else /* gray */ + palette[i].blue = palette[i].red = palette[i].green = + png_unpremultiply(entry[afirst], alpha, reciprocal); + } + } + + else /* Color-map has sRGB values */ + { + png_const_bytep entry = png_voidcast(png_const_bytep, cmap); + + entry += i * channels; + + switch (channels) + { + case 4: + tRNS[i] = entry[afirst ? 0 : 3]; + if (tRNS[i] < 255) + num_trans = i+1; + /* FALL THROUGH */ + case 3: + palette[i].blue = entry[afirst + (2 ^ bgr)]; + palette[i].green = entry[afirst + 1]; + palette[i].red = entry[afirst + bgr]; + break; + + case 2: + tRNS[i] = entry[1 ^ afirst]; + if (tRNS[i] < 255) + num_trans = i+1; + /* FALL THROUGH */ + case 1: + palette[i].blue = palette[i].red = palette[i].green = + entry[afirst]; + break; + + default: + break; + } + } + } + +# ifdef afirst +# undef afirst +# endif +# ifdef bgr +# undef bgr +# endif + + png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, + entries); + + if (num_trans > 0) + png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, + num_trans, NULL); + + image->colormap_entries = entries; +} + +static int +png_image_write_main(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + png_uint_32 format = image->format; + + /* The following four ints are actually booleans */ + int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); + int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ + int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); + int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); + +# ifdef PNG_BENIGN_ERRORS_SUPPORTED + /* Make sure we error out on any bad situation */ + png_set_benign_errors(png_ptr, 0/*error*/); +# endif + + /* Default the 'row_stride' parameter if required. */ + if (display->row_stride == 0) + display->row_stride = PNG_IMAGE_ROW_STRIDE(*image); + + /* Set the required transforms then write the rows in the correct order. */ + if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) + { + if (display->colormap != NULL && image->colormap_entries > 0) + { + png_uint_32 entries = image->colormap_entries; + + png_set_IHDR(png_ptr, info_ptr, image->width, image->height, + entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), + PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_image_set_PLTE(display); + } + + else + png_error(image->opaque->png_ptr, + "no color-map for color-mapped image"); + } + + else + png_set_IHDR(png_ptr, info_ptr, image->width, image->height, + write_16bit ? 16 : 8, + ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + + ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* Counter-intuitively the data transformations must be called *after* + * png_write_info, not before as in the read code, but the 'set' functions + * must still be called before. Just set the color space information, never + * write an interlaced image. + */ + + if (write_16bit != 0) + { + /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); + + if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 + ); + } + + else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) + png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); + + /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit + * space must still be gamma encoded. + */ + else + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); + + /* Write the file header. */ + png_write_info(png_ptr, info_ptr); + + /* Now set up the data transformations (*after* the header is written), + * remove the handled transformations from the 'format' flags for checking. + * + * First check for a little endian system if writing 16 bit files. + */ + if (write_16bit != 0) + { + PNG_CONST png_uint_16 le = 0x0001; + + if ((*(png_const_bytep) & le) != 0) + png_set_swap(png_ptr); + } + +# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED + if ((format & PNG_FORMAT_FLAG_BGR) != 0) + { + if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) + png_set_bgr(png_ptr); + format &= ~PNG_FORMAT_FLAG_BGR; + } +# endif + +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) + png_set_swap_alpha(png_ptr); + format &= ~PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* If there are 16 or fewer color-map entries we wrote a lower bit depth + * above, but the application data is still byte packed. + */ + if (colormap != 0 && image->colormap_entries <= 16) + png_set_packing(png_ptr); + + /* That should have handled all (both) the transforms. */ + if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | + PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) + png_error(png_ptr, "png_write_image: unsupported transformation"); + + { + png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); + ptrdiff_t row_bytes = display->row_stride; + + if (linear != 0) + row_bytes *= (sizeof (png_uint_16)); + + if (row_bytes < 0) + row += (image->height-1) * (-row_bytes); + + display->first_row = row; + display->row_bytes = row_bytes; + } + + /* Apply 'fast' options if the flag is set. */ + if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) + { + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); + /* NOTE: determined by experiment using pngstest, this reflects some + * balance between the time to write the image once and the time to read + * it about 50 times. The speed-up in pngstest was about 10-20% of the + * total (user) time on a heavily loaded system. + */ + png_set_compression_level(png_ptr, 3); + } + + /* Check for the cases that currently require a pre-transform on the row + * before it is written. This only applies when the input is 16-bit and + * either there is an alpha channel or it is converted to 8-bit. + */ + if ((linear != 0 && alpha != 0 ) || + (colormap == 0 && display->convert_to_8bit != 0)) + { + png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, + png_get_rowbytes(png_ptr, info_ptr))); + int result; + + display->local_row = row; + if (write_16bit != 0) + result = png_safe_execute(image, png_write_image_16bit, display); + else + result = png_safe_execute(image, png_write_image_8bit, display); + display->local_row = NULL; + + png_free(png_ptr, row); + + /* Skip the 'write_end' on error: */ + if (result == 0) + return 0; + } + + /* Otherwise this is the case where the input is in a format currently + * supported by the rest of the libpng write code; call it directly. + */ + else + { + png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); + ptrdiff_t row_bytes = display->row_bytes; + png_uint_32 y = image->height; + + while (y-- > 0) + { + png_write_row(png_ptr, row); + row += row_bytes; + } + } + + png_write_end(png_ptr, info_ptr); + return 1; +} + +int PNGAPI +png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, + const void *buffer, png_int_32 row_stride, const void *colormap) +{ + /* Write the image to the given (FILE*). */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file != NULL) + { + if (png_image_write_init(image) != 0) + { + png_image_write_control display; + int result; + + /* This is slightly evil, but png_init_io doesn't do anything other + * than this and we haven't changed the standard IO functions so + * this saves a 'safe' function. + */ + image->opaque->png_ptr->io_ptr = file; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.convert_to_8bit = convert_to_8bit; + + result = png_safe_execute(image, png_image_write_main, &display); + png_image_free(image); + return result; + } + + else + return 0; + } + + else + return png_image_error(image, + "png_image_write_to_stdio: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} + +int PNGAPI +png_image_write_to_file(png_imagep image, const char *file_name, + int convert_to_8bit, const void *buffer, png_int_32 row_stride, + const void *colormap) +{ + /* Write the image to the named file. */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file_name != NULL) + { + FILE *fp = fopen(file_name, "wb"); + + if (fp != NULL) + { + if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, + row_stride, colormap) != 0) + { + int error; /* from fflush/fclose */ + + /* Make sure the file is flushed correctly. */ + if (fflush(fp) == 0 && ferror(fp) == 0) + { + if (fclose(fp) == 0) + return 1; + + error = errno; /* from fclose */ + } + + else + { + error = errno; /* from fflush or ferror */ + (void)fclose(fp); + } + + (void)remove(file_name); + /* The image has already been cleaned up; this is just used to + * set the error (because the original write succeeded). + */ + return png_image_error(image, strerror(error)); + } + + else + { + /* Clean up: just the opened file. */ + (void)fclose(fp); + (void)remove(file_name); + return 0; + } + } + + else + return png_image_error(image, strerror(errno)); + } + + else + return png_image_error(image, + "png_image_write_to_file: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} +#endif /* STDIO */ +#endif /* SIMPLIFIED_WRITE */ +#endif /* WRITE */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwtran.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwtran.c index 579057dcefd..ef015aeb7b9 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwtran.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwtran.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -42,90 +42,14 @@ #include "pngpriv.h" #ifdef PNG_WRITE_SUPPORTED - #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -/* Transform the data according to the user's wishes. The order of - * transformations is significant. - */ -void /* PRIVATE */ -png_do_write_transformations(png_structp png_ptr) -{ - png_debug(1, "in png_do_write_transformations"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - if (png_ptr->transformations & PNG_USER_TRANSFORM) - if (png_ptr->write_user_transform_fn != NULL) - (*(png_ptr->write_user_transform_fn)) /* User write transform - function */ - (png_ptr, /* png_ptr */ - &(png_ptr->row_info), /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#endif - -#ifdef PNG_WRITE_FILLER_SUPPORTED - if (png_ptr->transformations & PNG_FILLER) - png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, - !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); -#endif - -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_PACK_SUPPORTED - if (png_ptr->transformations & PNG_PACK) - png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, - (png_uint_32)png_ptr->bit_depth); -#endif - -#ifdef PNG_WRITE_SWAP_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if (png_ptr->transformations & PNG_SHIFT) - png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_ALPHA) - png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_BGR_SUPPORTED - if (png_ptr->transformations & PNG_BGR) - png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); -#endif -} #ifdef PNG_WRITE_PACK_SUPPORTED /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The * row_info bit depth should be 8 (one pixel per byte). The channels * should be 1 (this only happens on grayscale and paletted images). */ -void /* PRIVATE */ +static void png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) { png_debug(1, "in png_do_pack"); @@ -270,7 +194,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) * would pass 3 as bit_depth, and this routine would translate the * data to 0 to 15. */ -void /* PRIVATE */ +static void png_do_shift(png_row_infop row_info, png_bytep row, png_const_color_8p bit_depth) { @@ -281,7 +205,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, int shift_start[4], shift_dec[4]; int channels = 0; - if (row_info->color_type & PNG_COLOR_MASK_COLOR) + if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { shift_start[channels] = row_info->bit_depth - bit_depth->red; shift_dec[channels] = bit_depth->red; @@ -303,7 +227,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, channels++; } - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) { shift_start[channels] = row_info->bit_depth - bit_depth->alpha; shift_dec[channels] = bit_depth->alpha; @@ -315,7 +239,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, { png_bytep bp = row; png_size_t i; - png_byte mask; + unsigned int mask; png_size_t row_bytes = row_info->rowbytes; if (bit_depth->gray == 1 && row_info->bit_depth == 2) @@ -329,20 +253,22 @@ png_do_shift(png_row_infop row_info, png_bytep row, for (i = 0; i < row_bytes; i++, bp++) { - png_uint_16 v; int j; + unsigned int v, out; v = *bp; - *bp = 0; + out = 0; for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) { if (j > 0) - *bp |= (png_byte)((v << j) & 0xff); + out |= v << j; else - *bp |= (png_byte)((v >> (-j)) & mask); + out |= (v >> (-j)) & mask; } + + *bp = (png_byte)(out & 0xff); } } @@ -355,21 +281,23 @@ png_do_shift(png_row_infop row_info, png_bytep row, for (i = 0; i < istop; i++, bp++) { - png_uint_16 v; + const unsigned int c = i%channels; int j; - int c = (int)(i%channels); + unsigned int v, out; v = *bp; - *bp = 0; + out = 0; for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) { if (j > 0) - *bp |= (png_byte)((v << j) & 0xff); + out |= v << j; else - *bp |= (png_byte)((v >> (-j)) & 0xff); + out |= v >> (-j); } + + *bp = (png_byte)(out & 0xff); } } @@ -381,22 +309,22 @@ png_do_shift(png_row_infop row_info, png_bytep row, for (bp = row, i = 0; i < istop; i++) { - int c = (int)(i%channels); - png_uint_16 value, v; + const unsigned int c = i%channels; int j; + unsigned int value, v; - v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); + v = png_get_uint_16(bp); value = 0; for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) { if (j > 0) - value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); + value |= v << j; else - value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); + value |= v >> (-j); } - *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)((value >> 8) & 0xff); *bp++ = (png_byte)(value & 0xff); } } @@ -405,7 +333,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, #endif #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -void /* PRIVATE */ +static void png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_write_swap_alpha"); @@ -453,7 +381,7 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) *(dp++) = save[1]; } } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ +#endif /* WRITE_16BIT */ } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) @@ -492,14 +420,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) *(dp++) = save[1]; } } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ +#endif /* WRITE_16BIT */ } } } #endif #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -void /* PRIVATE */ +static void png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_write_invert_alpha"); @@ -549,7 +477,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)(255 - *(sp++)); } } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ +#endif /* WRITE_16BIT */ } else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) @@ -587,75 +515,88 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)(255 - *(sp++)); } } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ +#endif /* WRITE_16BIT */ } } } #endif -#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing */ +/* Transform the data according to the user's wishes. The order of + * transformations is significant. + */ void /* PRIVATE */ -png_do_write_intrapixel(png_row_infop row_info, png_bytep row) +png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) { - png_debug(1, "in png_do_write_intrapixel"); + png_debug(1, "in png_do_write_transformations"); - if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; + if (png_ptr == NULL) + return; - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + if (png_ptr->write_user_transform_fn != NULL) + (*(png_ptr->write_user_transform_fn)) /* User write transform + function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#endif - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; +#ifdef PNG_WRITE_FILLER_SUPPORTED + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); +#endif - else - return; +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); - *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); - } - } +#ifdef PNG_WRITE_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0) + png_do_pack(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->bit_depth); +#endif -#ifdef PNG_WRITE_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; +#ifdef PNG_WRITE_SWAP_SUPPORTED +# ifdef PNG_16BIT_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_do_swap(row_info, png_ptr->row_buf + 1); +# endif +#endif - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_do_shift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) + png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif - else - return; +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); - png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } - } -#endif /* PNG_WRITE_16BIT_SUPPORTED */ - } +#ifdef PNG_WRITE_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif } -#endif /* PNG_MNG_FEATURES_SUPPORTED */ -#endif /* PNG_WRITE_SUPPORTED */ +#endif /* WRITE_TRANSFORMS */ +#endif /* WRITE */ diff --git a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwutil.c b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwutil.c index 91634671e7c..66a8812d790 100644 --- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwutil.c +++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwutil.c @@ -29,8 +29,8 @@ * However, the following notice accompanied the original version of this * file and, per its terms, should not be removed: * - * Last changed in libpng 1.5.4 [July 7, 2011] - * Copyright (c) 1998-2011 Glenn Randers-Pehrson + * Last changed in libpng 1.6.15 [November 20, 2014] + * Copyright (c) 1998-2014 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -57,23 +57,6 @@ png_save_uint_32(png_bytep buf, png_uint_32 i) buf[3] = (png_byte)(i & 0xff); } -#ifdef PNG_SAVE_INT_32_SUPPORTED -/* The png_save_int_32 function assumes integers are stored in two's - * complement format. If this isn't the case, then this routine needs to - * be modified to write data in two's complement format. Note that, - * the following works correctly even if png_int_32 has more than 32 bits - * (compare the more complex code required on read for sign extention.) - */ -void PNGAPI -png_save_int_32(png_bytep buf, png_int_32 i) -{ - buf[0] = (png_byte)((i >> 24) & 0xff); - buf[1] = (png_byte)((i >> 16) & 0xff); - buf[2] = (png_byte)((i >> 8) & 0xff); - buf[3] = (png_byte)(i & 0xff); -} -#endif - /* Place a 16-bit number into a buffer in PNG byte order. * The parameter is declared unsigned int, not png_uint_16, * just to avoid potential problems on pre-ANSI C compilers. @@ -93,7 +76,7 @@ png_save_uint_16(png_bytep buf, unsigned int i) * bytes have already been written. */ void PNGAPI -png_write_sig(png_structp png_ptr) +png_write_sig(png_structrp png_ptr) { png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; @@ -110,39 +93,20 @@ png_write_sig(png_structp png_ptr) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } -/* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the - * pre-defined chunk names here, and if you need a new one, define it - * where the others are defined. The length is the length of the data. - * All the data must be present. If that is not possible, use the - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ -void PNGAPI -png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name, - png_const_bytep data, png_size_t length) -{ - if (png_ptr == NULL) - return; - - png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); - png_write_chunk_data(png_ptr, data, (png_size_t)length); - png_write_chunk_end(png_ptr); -} - /* Write the start of a PNG chunk. The type is the chunk type. * The total_length is the sum of the lengths of all the data you will be * passing in png_write_chunk_data(). */ -void PNGAPI -png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, +static void +png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, png_uint_32 length) { png_byte buf[8]; - png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, - (unsigned long)length); +#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) + PNG_CSTRING_FROM_CHUNK(buf, chunk_name); + png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); +#endif if (png_ptr == NULL) return; @@ -156,16 +120,16 @@ png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, /* Write the length and the chunk name */ png_save_uint_32(buf, length); - png_memcpy(buf + 4, chunk_name, 4); - png_write_data(png_ptr, buf, (png_size_t)8); + png_save_uint_32(buf + 4, chunk_name); + png_write_data(png_ptr, buf, 8); /* Put the chunk name into png_ptr->chunk_name */ - png_memcpy(png_ptr->chunk_name, chunk_name, 4); + png_ptr->chunk_name = chunk_name; /* Reset the crc and run it over the chunk name */ png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, chunk_name, 4); + png_calculate_crc(png_ptr, buf + 4, 4); #ifdef PNG_IO_STATE_SUPPORTED /* Inform the I/O callback that chunk data will (possibly) be written. @@ -175,13 +139,20 @@ png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, #endif } -/* Write the data of a PNG chunk started with png_write_chunk_start(). +void PNGAPI +png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, + png_uint_32 length) +{ + png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); +} + +/* Write the data of a PNG chunk started with png_write_chunk_header(). * Note that multiple calls to this function are allowed, and that the * sum of the lengths from these calls *must* add up to the total_length - * given to png_write_chunk_start(). + * given to png_write_chunk_header(). */ void PNGAPI -png_write_chunk_data(png_structp png_ptr, png_const_bytep data, +png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) { /* Write the data, and run the CRC over it */ @@ -193,15 +164,15 @@ png_write_chunk_data(png_structp png_ptr, png_const_bytep data, png_write_data(png_ptr, data, length); /* Update the CRC after writing the data, - * in case that the user I/O routine alters it. + * in case the user I/O routine alters it. */ png_calculate_crc(png_ptr, data, length); } } -/* Finish a chunk started with png_write_chunk_start(). */ +/* Finish a chunk started with png_write_chunk_header(). */ void PNGAPI -png_write_chunk_end(png_structp png_ptr) +png_write_chunk_end(png_structrp png_ptr) { png_byte buf[4]; @@ -220,468 +191,601 @@ png_write_chunk_end(png_structp png_ptr) png_write_data(png_ptr, buf, (png_size_t)4); } -/* Initialize the compressor for the appropriate type of compression. */ -static void -png_zlib_claim(png_structp png_ptr, png_uint_32 state) -{ - if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) - { - /* If already initialized for 'state' do not re-init. */ - if (png_ptr->zlib_state != state) - { - int ret = Z_OK; - png_const_charp who = "-"; - - /* If actually initialized for another state do a deflateEnd. */ - if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) - { - ret = deflateEnd(&png_ptr->zstream); - who = "end"; - png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; - } - - /* zlib itself detects an incomplete state on deflateEnd */ - if (ret == Z_OK) switch (state) - { -# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - case PNG_ZLIB_FOR_TEXT: - ret = deflateInit2(&png_ptr->zstream, - png_ptr->zlib_text_level, png_ptr->zlib_text_method, - png_ptr->zlib_text_window_bits, - png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); - who = "text"; - break; -# endif - - case PNG_ZLIB_FOR_IDAT: - ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, - png_ptr->zlib_method, png_ptr->zlib_window_bits, - png_ptr->zlib_mem_level, png_ptr->zlib_strategy); - who = "IDAT"; - break; - - default: - png_error(png_ptr, "invalid zlib state"); - } - - if (ret == Z_OK) - png_ptr->zlib_state = state; - - else /* an error in deflateEnd or deflateInit2 */ - { - size_t pos = 0; - char msg[64]; - - pos = png_safecat(msg, sizeof msg, pos, - "zlib failed to initialize compressor ("); - pos = png_safecat(msg, sizeof msg, pos, who); - - switch (ret) - { - case Z_VERSION_ERROR: - pos = png_safecat(msg, sizeof msg, pos, ") version error"); - break; - - case Z_STREAM_ERROR: - pos = png_safecat(msg, sizeof msg, pos, ") stream error"); - break; - - case Z_MEM_ERROR: - pos = png_safecat(msg, sizeof msg, pos, ") memory error"); - break; - - default: - pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); - break; - } - - png_error(png_ptr, msg); - } - } - - /* Here on success, claim the zstream: */ - png_ptr->zlib_state |= PNG_ZLIB_IN_USE; - } - - else - png_error(png_ptr, "zstream already in use (internal error)"); -} - -/* The opposite: release the stream. It is also reset, this API will warn on - * error but will not fail. +/* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the + * pre-defined chunk names here, and if you need a new one, define it + * where the others are defined. The length is the length of the data. + * All the data must be present. If that is not possible, use the + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. */ static void -png_zlib_release(png_structp png_ptr) +png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, + png_const_bytep data, png_size_t length) { - if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) + if (png_ptr == NULL) + return; + + /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ + if (length > PNG_UINT_31_MAX) + png_error(png_ptr, "length exceeds PNG maximum"); + + png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* This is the API that calls the internal function above. */ +void PNGAPI +png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, + png_const_bytep data, png_size_t length) +{ + png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, + length); +} + +/* This is used below to find the size of an image to pass to png_deflate_claim, + * so it only needs to be accurate if the size is less than 16384 bytes (the + * point at which a lower LZ window size can be used.) + */ +static png_alloc_size_t +png_image_size(png_structrp png_ptr) +{ + /* Only return sizes up to the maximum of a png_uint_32; do this by limiting + * the width and height used to 15 bits. + */ + png_uint_32 h = png_ptr->height; + + if (png_ptr->rowbytes < 32768 && h < 32768) { - int ret = deflateReset(&png_ptr->zstream); - - png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; - - if (ret != Z_OK) + if (png_ptr->interlaced != 0) { - png_const_charp err; - PNG_WARNING_PARAMETERS(p) + /* Interlacing makes the image larger because of the replication of + * both the filter byte and the padding to a byte boundary. + */ + png_uint_32 w = png_ptr->width; + unsigned int pd = png_ptr->pixel_depth; + png_alloc_size_t cb_base; + int pass; - switch (ret) + for (cb_base=0, pass=0; pass<=6; ++pass) { - case Z_VERSION_ERROR: - err = "version"; - break; + png_uint_32 pw = PNG_PASS_COLS(w, pass); - case Z_STREAM_ERROR: - err = "stream"; - break; - - case Z_MEM_ERROR: - err = "memory"; - break; - - default: - err = "unknown"; - break; + if (pw > 0) + cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); } - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); - png_warning_parameter(p, 2, err); - - if (png_ptr->zstream.msg) - err = png_ptr->zstream.msg; - else - err = "[no zlib message]"; - - png_warning_parameter(p, 3, err); - - png_formatted_warning(png_ptr, p, - "zlib failed to reset compressor: @1(@2): @3"); + return cb_base; } + + else + return (png_ptr->rowbytes+1) * h; } else - png_warning(png_ptr, "zstream not in use (internal error)"); + return 0xffffffffU; +} + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* This is the code to hack the first two bytes of the deflate stream (the + * deflate header) to correct the windowBits value to match the actual data + * size. Note that the second argument is the *uncompressed* size but the + * first argument is the *compressed* data (and it must be deflate + * compressed.) + */ +static void +optimize_cmf(png_bytep data, png_alloc_size_t data_size) +{ + /* Optimize the CMF field in the zlib stream. The resultant zlib stream is + * still compliant to the stream specification. + */ + if (data_size <= 16384) /* else windowBits must be 15 */ + { + unsigned int z_cmf = data[0]; /* zlib compression method and flags */ + + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + unsigned int z_cinfo; + unsigned int half_z_window_size; + + z_cinfo = z_cmf >> 4; + half_z_window_size = 1U << (z_cinfo + 7); + + if (data_size <= half_z_window_size) /* else no change */ + { + unsigned int tmp; + + do + { + half_z_window_size >>= 1; + --z_cinfo; + } + while (z_cinfo > 0 && data_size <= half_z_window_size); + + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + + data[0] = (png_byte)z_cmf; + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; + } + } + } +} +#endif /* WRITE_OPTIMIZE_CMF */ + +/* Initialize the compressor for the appropriate type of compression. */ +static int +png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, + png_alloc_size_t data_size) +{ + if (png_ptr->zowner != 0) + { +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) + char msg[64]; + + PNG_STRING_FROM_CHUNK(msg, owner); + msg[4] = ':'; + msg[5] = ' '; + PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); + /* So the message that results is " using zstream"; this is an + * internal error, but is very useful for debugging. i18n requirements + * are minimal. + */ + (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); +#endif +#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC + png_warning(png_ptr, msg); + + /* Attempt sane error recovery */ + if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); + return Z_STREAM_ERROR; + } + + png_ptr->zowner = 0; +#else + png_error(png_ptr, msg); +#endif + } + + { + int level = png_ptr->zlib_level; + int method = png_ptr->zlib_method; + int windowBits = png_ptr->zlib_window_bits; + int memLevel = png_ptr->zlib_mem_level; + int strategy; /* set below */ + int ret; /* zlib return code */ + + if (owner == png_IDAT) + { + if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) + strategy = png_ptr->zlib_strategy; + + else if (png_ptr->do_filter != PNG_FILTER_NONE) + strategy = PNG_Z_DEFAULT_STRATEGY; + + else + strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; + } + + else + { +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + level = png_ptr->zlib_text_level; + method = png_ptr->zlib_text_method; + windowBits = png_ptr->zlib_text_window_bits; + memLevel = png_ptr->zlib_text_mem_level; + strategy = png_ptr->zlib_text_strategy; +#else + /* If customization is not supported the values all come from the + * IDAT values except for the strategy, which is fixed to the + * default. (This is the pre-1.6.0 behavior too, although it was + * implemented in a very different way.) + */ + strategy = Z_DEFAULT_STRATEGY; +#endif + } + + /* Adjust 'windowBits' down if larger than 'data_size'; to stop this + * happening just pass 32768 as the data_size parameter. Notice that zlib + * requires an extra 262 bytes in the window in addition to the data to be + * able to see the whole of the data, so if data_size+262 takes us to the + * next windowBits size we need to fix up the value later. (Because even + * though deflate needs the extra window, inflate does not!) + */ + if (data_size <= 16384) + { + /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to + * work round a Microsoft Visual C misbehavior which, contrary to C-90, + * widens the result of the following shift to 64-bits if (and, + * apparently, only if) it is used in a test. + */ + unsigned int half_window_size = 1U << (windowBits-1); + + while (data_size + 262 <= half_window_size) + { + half_window_size >>= 1; + --windowBits; + } + } + + /* Check against the previous initialized values, if any. */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && + (png_ptr->zlib_set_level != level || + png_ptr->zlib_set_method != method || + png_ptr->zlib_set_window_bits != windowBits || + png_ptr->zlib_set_mem_level != memLevel || + png_ptr->zlib_set_strategy != strategy)) + { + if (deflateEnd(&png_ptr->zstream) != Z_OK) + png_warning(png_ptr, "deflateEnd failed (ignored)"); + + png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; + } + + /* For safety clear out the input and output pointers (currently zlib + * doesn't use them on Init, but it might in the future). + */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->zstream.avail_out = 0; + + /* Now initialize if required, setting the new parameters, otherwise just + * to a simple reset to the previous parameters. + */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) + ret = deflateReset(&png_ptr->zstream); + + else + { + ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, + memLevel, strategy); + + if (ret == Z_OK) + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; + } + + /* The return code is from either deflateReset or deflateInit2; they have + * pretty much the same set of error codes. + */ + if (ret == Z_OK) + png_ptr->zowner = owner; + + else + png_zstream_error(png_ptr, ret); + + return ret; + } +} + +/* Clean up (or trim) a linked list of compression buffers. */ +void /* PRIVATE */ +png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) +{ + png_compression_bufferp list = *listp; + + if (list != NULL) + { + *listp = NULL; + + do + { + png_compression_bufferp next = list->next; + + png_free(png_ptr, list); + list = next; + } + while (list != NULL); + } } #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED /* This pair of functions encapsulates the operation of (a) compressing a * text string, and (b) issuing it later as a series of chunk data writes. * The compression_state structure is shared context for these functions - * set up by the caller in order to make the whole mess thread-safe. + * set up by the caller to allow access to the relevant local variables. + * + * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size + * temporary buffers. From 1.6.0 it is retained in png_struct so that it will + * be correctly freed in the event of a write error (previous implementations + * just leaked memory.) */ - typedef struct { - png_const_bytep input; /* The uncompressed input data */ - png_size_t input_len; /* Its length */ - int num_output_ptr; /* Number of output pointers used */ - int max_output_ptr; /* Size of output_ptr */ - png_bytep *output_ptr; /* Array of pointers to output */ + png_const_bytep input; /* The uncompressed input data */ + png_alloc_size_t input_len; /* Its length */ + png_uint_32 output_len; /* Final compressed length */ + png_byte output[1024]; /* First block of output */ } compression_state; -/* Compress given text into storage in the png_ptr structure */ -static int /* PRIVATE */ -png_text_compress(png_structp png_ptr, - png_const_charp text, png_size_t text_len, int compression, - compression_state *comp) +static void +png_text_compress_init(compression_state *comp, png_const_bytep input, + png_alloc_size_t input_len) +{ + comp->input = input; + comp->input_len = input_len; + comp->output_len = 0; +} + +/* Compress the data in the compression state input */ +static int +png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, + compression_state *comp, png_uint_32 prefix_len) { int ret; - comp->num_output_ptr = 0; - comp->max_output_ptr = 0; - comp->output_ptr = NULL; - comp->input = NULL; - comp->input_len = text_len; - - /* We may just want to pass the text right through */ - if (compression == PNG_TEXT_COMPRESSION_NONE) - { - comp->input = (png_const_bytep)text; - return((int)text_len); - } - - if (compression >= PNG_TEXT_COMPRESSION_LAST) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, - compression); - png_formatted_warning(png_ptr, p, "Unknown compression type @1"); - } - - /* We can't write the chunk until we find out how much data we have, - * which means we need to run the compressor first and save the - * output. This shouldn't be a problem, as the vast majority of - * comments should be reasonable, but we will set up an array of - * malloc'd pointers to be sure. + /* To find the length of the output it is necessary to first compress the + * input. The result is buffered rather than using the two-pass algorithm + * that is used on the inflate side; deflate is assumed to be slower and a + * PNG writer is assumed to have more memory available than a PNG reader. * - * If we knew the application was well behaved, we could simplify this - * greatly by assuming we can always malloc an output buffer large - * enough to hold the compressed text ((1001 * text_len / 1000) + 12) - * and malloc this directly. The only time this would be a bad idea is - * if we can't malloc more than 64K and we have 64K of random input - * data, or if the input string is incredibly large (although this - * wouldn't cause a failure, just a slowdown due to swapping). + * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an + * upper limit on the output size, but it is always bigger than the input + * size so it is likely to be more efficient to use this linked-list + * approach. */ - png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); + ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); - /* Set up the compression buffers */ - /* TODO: the following cast hides a potential overflow problem. */ - png_ptr->zstream.avail_in = (uInt)text_len; + if (ret != Z_OK) + return ret; - /* NOTE: assume zlib doesn't overwrite the input */ - png_ptr->zstream.next_in = (Bytef *)text; - png_ptr->zstream.avail_out = png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - - /* This is the same compression loop as in png_write_row() */ - do + /* Set up the compression buffers, we need a loop here to avoid overflowing a + * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited + * by the output buffer size, so there is no need to check that. Since this + * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits + * in size. + */ { - /* Compress the data */ - ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + png_compression_bufferp *end = &png_ptr->zbuffer_list; + png_alloc_size_t input_len = comp->input_len; /* may be zero! */ + png_uint_32 output_len; - if (ret != Z_OK) + /* zlib updates these for us: */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); + png_ptr->zstream.avail_in = 0; /* Set below */ + png_ptr->zstream.next_out = comp->output; + png_ptr->zstream.avail_out = (sizeof comp->output); + + output_len = png_ptr->zstream.avail_out; + + do { - /* Error */ - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); + uInt avail_in = ZLIB_IO_MAX; - else - png_error(png_ptr, "zlib error"); - } + if (avail_in > input_len) + avail_in = (uInt)input_len; - /* Check to see if we need more room */ - if (!(png_ptr->zstream.avail_out)) - { - /* Make sure the output array has room */ - if (comp->num_output_ptr >= comp->max_output_ptr) + input_len -= avail_in; + + png_ptr->zstream.avail_in = avail_in; + + if (png_ptr->zstream.avail_out == 0) { - int old_max; + png_compression_buffer *next; - old_max = comp->max_output_ptr; - comp->max_output_ptr = comp->num_output_ptr + 4; - if (comp->output_ptr != NULL) + /* Chunk data is limited to 2^31 bytes in length, so the prefix + * length must be counted here. + */ + if (output_len + prefix_len > PNG_UINT_31_MAX) { - png_bytepp old_ptr; - - old_ptr = comp->output_ptr; - - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t) - (comp->max_output_ptr * png_sizeof(png_charpp))); - - png_memcpy(comp->output_ptr, old_ptr, old_max - * png_sizeof(png_charp)); - - png_free(png_ptr, old_ptr); + ret = Z_MEM_ERROR; + break; } - else - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t) - (comp->max_output_ptr * png_sizeof(png_charp))); - } - /* Save the data */ - comp->output_ptr[comp->num_output_ptr] = - (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)png_ptr->zbuf_size); - - png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); - - comp->num_output_ptr++; - - /* and reset the buffer */ - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - } - /* Continue until we don't have any more to compress */ - } while (png_ptr->zstream.avail_in); - - /* Finish the compression */ - do - { - /* Tell zlib we are finished */ - ret = deflate(&png_ptr->zstream, Z_FINISH); - - if (ret == Z_OK) - { - /* Check to see if we need more room */ - if (!(png_ptr->zstream.avail_out)) - { - /* Check to make sure our output array has room */ - if (comp->num_output_ptr >= comp->max_output_ptr) + /* Need a new (malloc'ed) buffer, but there may be one present + * already. + */ + next = *end; + if (next == NULL) { - int old_max; + next = png_voidcast(png_compression_bufferp, png_malloc_base + (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); - old_max = comp->max_output_ptr; - comp->max_output_ptr = comp->num_output_ptr + 4; - if (comp->output_ptr != NULL) + if (next == NULL) { - png_bytepp old_ptr; - - old_ptr = comp->output_ptr; - - /* This could be optimized to realloc() */ - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t)(comp->max_output_ptr * - png_sizeof(png_charp))); - - png_memcpy(comp->output_ptr, old_ptr, - old_max * png_sizeof(png_charp)); - - png_free(png_ptr, old_ptr); + ret = Z_MEM_ERROR; + break; } - else - comp->output_ptr = (png_bytepp)png_malloc(png_ptr, - (png_alloc_size_t)(comp->max_output_ptr * - png_sizeof(png_charp))); + /* Link in this buffer (so that it will be freed later) */ + next->next = NULL; + *end = next; } - /* Save the data */ - comp->output_ptr[comp->num_output_ptr] = - (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)png_ptr->zbuf_size); + png_ptr->zstream.next_out = next->output; + png_ptr->zstream.avail_out = png_ptr->zbuffer_size; + output_len += png_ptr->zstream.avail_out; - png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); - - comp->num_output_ptr++; - - /* and reset the buffer pointers */ - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; + /* Move 'end' to the next buffer pointer. */ + end = &next->next; } + + /* Compress the data */ + ret = deflate(&png_ptr->zstream, + input_len > 0 ? Z_NO_FLUSH : Z_FINISH); + + /* Claw back input data that was not consumed (because avail_in is + * reset above every time round the loop). + */ + input_len += png_ptr->zstream.avail_in; + png_ptr->zstream.avail_in = 0; /* safety */ } - else if (ret != Z_STREAM_END) + while (ret == Z_OK); + + /* There may be some space left in the last output buffer. This needs to + * be subtracted from output_len. + */ + output_len -= png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out = 0; /* safety */ + comp->output_len = output_len; + + /* Now double check the output length, put in a custom message if it is + * too long. Otherwise ensure the z_stream::msg pointer is set to + * something. + */ + if (output_len + prefix_len >= PNG_UINT_31_MAX) { - /* We got an error */ - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); + png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); + ret = Z_MEM_ERROR; } - } while (ret != Z_STREAM_END); - /* Text length is number of buffers plus last buffer */ - text_len = png_ptr->zbuf_size * comp->num_output_ptr; + else + png_zstream_error(png_ptr, ret); - if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) - text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; + /* Reset zlib for another zTXt/iTXt or image data */ + png_ptr->zowner = 0; - return((int)text_len); + /* The only success case is Z_STREAM_END, input_len must be 0; if not this + * is an internal error. + */ + if (ret == Z_STREAM_END && input_len == 0) + { +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* Fix up the deflate header, if required */ + optimize_cmf(comp->output, comp->input_len); +#endif + /* But Z_OK is returned, not Z_STREAM_END; this allows the claim + * function above to return Z_STREAM_END on an error (though it never + * does in the current versions of zlib.) + */ + return Z_OK; + } + + else + return ret; + } } /* Ship the compressed text out via chunk writes */ -static void /* PRIVATE */ -png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) +static void +png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) { - int i; + png_uint_32 output_len = comp->output_len; + png_const_bytep output = comp->output; + png_uint_32 avail = (sizeof comp->output); + png_compression_buffer *next = png_ptr->zbuffer_list; - /* Handle the no-compression case */ - if (comp->input) + for (;;) { - png_write_chunk_data(png_ptr, comp->input, comp->input_len); + if (avail > output_len) + avail = output_len; - return; + png_write_chunk_data(png_ptr, output, avail); + + output_len -= avail; + + if (output_len == 0 || next == NULL) + break; + + avail = png_ptr->zbuffer_size; + output = next->output; + next = next->next; } -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if (comp->input_len >= 2 && comp->input_len < 16384) + /* This is an internal error; 'next' must have been NULL! */ + if (output_len > 0) + png_error(png_ptr, "error writing ancillary chunked compressed data"); +} +#endif /* WRITE_COMPRESSED_TEXT */ + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The 'new_key' buffer must be 80 characters in size (for the keyword plus a + * trailing '\0'). If this routine returns 0 then there was no keyword, or a + * valid one could not be generated, and the caller must png_error. + */ +static png_uint_32 +png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) +{ + png_const_charp orig_key = key; + png_uint_32 key_len = 0; + int bad_character = 0; + int space = 1; + + png_debug(1, "in png_check_keyword"); + + if (key == NULL) { - unsigned int z_cmf; /* zlib compression method and flags */ + *new_key = 0; + return 0; + } - /* Optimize the CMF field in the zlib stream. This hack of the zlib - * stream is compliant to the stream specification. - */ + while (*key && key_len < 79) + { + png_byte ch = (png_byte)(0xff & *key++); - if (comp->num_output_ptr) - z_cmf = comp->output_ptr[0][0]; - else - z_cmf = png_ptr->zbuf[0]; + if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) + *new_key++ = ch, ++key_len, space = 0; - if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + else if (space == 0) { - unsigned int z_cinfo; - unsigned int half_z_window_size; - png_size_t uncompressed_text_size = comp->input_len; + /* A space or an invalid character when one wasn't seen immediately + * before; output just a space. + */ + *new_key++ = 32, ++key_len, space = 1; - z_cinfo = z_cmf >> 4; - half_z_window_size = 1 << (z_cinfo + 7); - - while (uncompressed_text_size <= half_z_window_size && - half_z_window_size >= 256) - { - z_cinfo--; - half_z_window_size >>= 1; - } - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - if (comp->num_output_ptr) - { - - if (comp->output_ptr[0][0] != z_cmf) - { - int tmp; - - comp->output_ptr[0][0] = (png_byte)z_cmf; - tmp = comp->output_ptr[0][1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - comp->output_ptr[0][1] = (png_byte)tmp; - } - } - else - { - int tmp; - - png_ptr->zbuf[0] = (png_byte)z_cmf; - tmp = png_ptr->zbuf[1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - png_ptr->zbuf[1] = (png_byte)tmp; - } + /* If the character was not a space then it is invalid. */ + if (ch != 32) + bad_character = ch; } - else - png_error(png_ptr, - "Invalid zlib compression method or flags in non-IDAT chunk"); + else if (bad_character == 0) + bad_character = ch; /* just skip it, record the first error */ } -#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ - /* Write saved output buffers, if any */ - for (i = 0; i < comp->num_output_ptr; i++) + if (key_len > 0 && space != 0) /* trailing space */ { - png_write_chunk_data(png_ptr, comp->output_ptr[i], - (png_size_t)png_ptr->zbuf_size); - - png_free(png_ptr, comp->output_ptr[i]); + --key_len, --new_key; + if (bad_character == 0) + bad_character = 32; } - if (comp->max_output_ptr != 0) - png_free(png_ptr, comp->output_ptr); + /* Terminate the keyword */ + *new_key = 0; - /* Write anything left in zbuf */ - if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) - png_write_chunk_data(png_ptr, png_ptr->zbuf, - (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + if (key_len == 0) + return 0; - /* Reset zlib for another zTXt/iTXt or image data */ - png_zlib_release(png_ptr); +#ifdef PNG_WARNINGS_SUPPORTED + /* Try to only output one warning per keyword: */ + if (*key != 0) /* keyword too long */ + png_warning(png_ptr, "keyword truncated"); + + else if (bad_character != 0) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter(p, 1, orig_key); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); + + png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); + } +#endif /* WARNINGS */ + + return key_len; } -#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ +#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */ /* Write the IHDR chunk, and update the png_struct with the necessary * information. Note that the rest of this code depends upon this * information being correct. */ void /* PRIVATE */ -png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, +png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int compression_type, int filter_type, int interlace_type) { - PNG_IHDR; - png_byte buf[13]; /* Buffer to store the IHDR info */ png_debug(1, "in png_write_IHDR"); @@ -772,8 +876,8 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, */ if ( #ifdef PNG_MNG_FEATURES_SUPPORTED - !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) && (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && @@ -823,14 +927,9 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, buf[12] = (png_byte)interlace_type; /* Write the chunk */ - png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); + png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); - /* Initialize zlib with PNG info */ - png_ptr->zstream.zalloc = png_zalloc; - png_ptr->zstream.zfree = png_zfree; - png_ptr->zstream.opaque = (voidpf)png_ptr; - - if (!(png_ptr->do_filter)) + if ((png_ptr->do_filter) == PNG_NO_FILTERS) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || png_ptr->bit_depth < 8) @@ -840,55 +939,6 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, png_ptr->do_filter = PNG_ALL_FILTERS; } - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) - { - if (png_ptr->do_filter != PNG_FILTER_NONE) - png_ptr->zlib_strategy = Z_FILTERED; - - else - png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; - } - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) - png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) - png_ptr->zlib_mem_level = 8; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) - png_ptr->zlib_window_bits = 15; - - if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) - png_ptr->zlib_method = 8; - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) - png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) - png_ptr->zlib_text_level = png_ptr->zlib_level; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) - png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) - png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; - - if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) - png_ptr->zlib_text_method = png_ptr->zlib_method; -#else - png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; - png_ptr->zlib_text_level = png_ptr->zlib_level; - png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; - png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; - png_ptr->zlib_text_method = png_ptr->zlib_method; -#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ -#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ - - /* Record that the compressor has not yet been initialized. */ - png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; - png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ } @@ -897,10 +947,9 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, * structure. */ void /* PRIVATE */ -png_write_PLTE(png_structp png_ptr, png_const_colorp palette, +png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, png_uint_32 num_pal) { - PNG_PLTE; png_uint_32 i; png_const_colorp pal_ptr; png_byte buf[3]; @@ -909,7 +958,7 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, if (( #ifdef PNG_MNG_FEATURES_SUPPORTED - !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && + (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && #endif num_pal == 0) || num_pal > 256) { @@ -925,7 +974,7 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, } } - if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) { png_warning(png_ptr, "Ignoring request to write a PLTE chunk in grayscale PNG"); @@ -936,7 +985,7 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, png_ptr->num_palette = (png_uint_16)num_pal; png_debug1(3, "num_palette = %d", png_ptr->num_palette); - png_write_chunk_start(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); + png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); #ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) @@ -966,127 +1015,192 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, png_ptr->mode |= PNG_HAVE_PLTE; } -/* Write an IDAT chunk */ +/* This is similar to png_text_compress, above, except that it does not require + * all of the data at once and, instead of buffering the compressed result, + * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out + * because it calls the write interface. As a result it does its own error + * reporting and does not return an error code. In the event of error it will + * just call png_error. The input data length may exceed 32-bits. The 'flush' + * parameter is exactly the same as that to deflate, with the following + * meanings: + * + * Z_NO_FLUSH: normal incremental output of compressed data + * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush + * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up + * + * The routine manages the acquire and release of the png_ptr->zstream by + * checking and (at the end) clearing png_ptr->zowner; it does some sanity + * checks on the 'mode' flags while doing this. + */ void /* PRIVATE */ -png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) +png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, + png_alloc_size_t input_len, int flush) { - PNG_IDAT; - - png_debug(1, "in png_write_IDAT"); - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if (!(png_ptr->mode & PNG_HAVE_IDAT) && - png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + if (png_ptr->zowner != png_IDAT) { - /* Optimize the CMF field in the zlib stream. This hack of the zlib - * stream is compliant to the stream specification. + /* First time. Ensure we have a temporary buffer for compression and + * trim the buffer list if it has more than one entry to free memory. + * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been + * created at this point, but the check here is quick and safe. */ - unsigned int z_cmf = data[0]; /* zlib compression method and flags */ - - if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + if (png_ptr->zbuffer_list == NULL) { - /* Avoid memory underflows and multiplication overflows. - * - * The conditions below are practically always satisfied; - * however, they still must be checked. - */ - if (length >= 2 && - png_ptr->height < 16384 && png_ptr->width < 16384) - { - /* Compute the maximum possible length of the datastream */ - - /* Number of pixels, plus for each row a filter byte - * and possibly a padding byte, so increase the maximum - * size to account for these. - */ - unsigned int z_cinfo; - unsigned int half_z_window_size; - png_uint_32 uncompressed_idat_size = png_ptr->height * - ((png_ptr->width * - png_ptr->channels * png_ptr->bit_depth + 15) >> 3); - - /* If it's interlaced, each block of 8 rows is sent as up to - * 14 rows, i.e., 6 additional rows, each with a filter byte - * and possibly a padding byte - */ - if (png_ptr->interlaced) - uncompressed_idat_size += ((png_ptr->height + 7)/8) * - (png_ptr->bit_depth < 8 ? 12 : 6); - - z_cinfo = z_cmf >> 4; - half_z_window_size = 1 << (z_cinfo + 7); - - while (uncompressed_idat_size <= half_z_window_size && - half_z_window_size >= 256) - { - z_cinfo--; - half_z_window_size >>= 1; - } - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - if (data[0] != z_cmf) - { - int tmp; - data[0] = (png_byte)z_cmf; - tmp = data[1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - data[1] = (png_byte)tmp; - } - } + png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, + png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); + png_ptr->zbuffer_list->next = NULL; } else - png_error(png_ptr, - "Invalid zlib compression method or flags in IDAT"); + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); + + /* It is a terminal error if we can't claim the zstream. */ + if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + /* The output state is maintained in png_ptr->zstream, so it must be + * initialized here after the claim. + */ + png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; + png_ptr->zstream.avail_out = png_ptr->zbuffer_size; } -#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ - png_write_chunk(png_ptr, png_IDAT, data, length); - png_ptr->mode |= PNG_HAVE_IDAT; - - /* Prior to 1.5.4 this code was replicated in every caller (except at the - * end, where it isn't technically necessary). Since this function has - * flushed the data we can safely reset the zlib output buffer here. + /* Now loop reading and writing until all the input is consumed or an error + * terminates the operation. The _out values are maintained across calls to + * this function, but the input must be reset each time. */ - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); + png_ptr->zstream.avail_in = 0; /* set below */ + for (;;) + { + int ret; + + /* INPUT: from the row data */ + uInt avail = ZLIB_IO_MAX; + + if (avail > input_len) + avail = (uInt)input_len; /* safe because of the check */ + + png_ptr->zstream.avail_in = avail; + input_len -= avail; + + ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); + + /* Include as-yet unconsumed input */ + input_len += png_ptr->zstream.avail_in; + png_ptr->zstream.avail_in = 0; + + /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note + * that these two zstream fields are preserved across the calls, therefore + * there is no need to set these up on entry to the loop. + */ + if (png_ptr->zstream.avail_out == 0) + { + png_bytep data = png_ptr->zbuffer_list->output; + uInt size = png_ptr->zbuffer_size; + + /* Write an IDAT containing the data then reset the buffer. The + * first IDAT may need deflate header optimization. + */ +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + optimize_cmf(data, png_image_size(png_ptr)); +#endif + + png_write_complete_chunk(png_ptr, png_IDAT, data, size); + png_ptr->mode |= PNG_HAVE_IDAT; + + png_ptr->zstream.next_out = data; + png_ptr->zstream.avail_out = size; + + /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with + * the same flush parameter until it has finished output, for NO_FLUSH + * it doesn't matter. + */ + if (ret == Z_OK && flush != Z_NO_FLUSH) + continue; + } + + /* The order of these checks doesn't matter much; it just affects which + * possible error might be detected if multiple things go wrong at once. + */ + if (ret == Z_OK) /* most likely return code! */ + { + /* If all the input has been consumed then just return. If Z_FINISH + * was used as the flush parameter something has gone wrong if we get + * here. + */ + if (input_len == 0) + { + if (flush == Z_FINISH) + png_error(png_ptr, "Z_OK on Z_FINISH with output space"); + + return; + } + } + + else if (ret == Z_STREAM_END && flush == Z_FINISH) + { + /* This is the end of the IDAT data; any pending output must be + * flushed. For small PNG files we may still be at the beginning. + */ + png_bytep data = png_ptr->zbuffer_list->output; + uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + optimize_cmf(data, png_image_size(png_ptr)); +#endif + + png_write_complete_chunk(png_ptr, png_IDAT, data, size); + png_ptr->zstream.avail_out = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; + + png_ptr->zowner = 0; /* Release the stream */ + return; + } + + else + { + /* This is an error condition. */ + png_zstream_error(png_ptr, ret); + png_error(png_ptr, png_ptr->zstream.msg); + } + } } /* Write an IEND chunk */ void /* PRIVATE */ -png_write_IEND(png_structp png_ptr) +png_write_IEND(png_structrp png_ptr) { - PNG_IEND; - png_debug(1, "in png_write_IEND"); - png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } #ifdef PNG_WRITE_gAMA_SUPPORTED /* Write a gAMA chunk */ void /* PRIVATE */ -png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) +png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) { - PNG_gAMA; png_byte buf[4]; png_debug(1, "in png_write_gAMA"); /* file_gamma is saved in 1/100,000ths */ png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); + png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); } #endif #ifdef PNG_WRITE_sRGB_SUPPORTED /* Write a sRGB chunk */ void /* PRIVATE */ -png_write_sRGB(png_structp png_ptr, int srgb_intent) +png_write_sRGB(png_structrp png_ptr, int srgb_intent) { - PNG_sRGB; png_byte buf[1]; png_debug(1, "in png_write_sRGB"); @@ -1096,104 +1210,79 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) "Invalid sRGB rendering intent specified"); buf[0]=(png_byte)srgb_intent; - png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); + png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); } #endif #ifdef PNG_WRITE_iCCP_SUPPORTED /* Write an iCCP chunk */ void /* PRIVATE */ -png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, - png_const_charp profile, int profile_len) +png_write_iCCP(png_structrp png_ptr, png_const_charp name, + png_const_bytep profile) { - PNG_iCCP; - png_size_t name_len; - png_charp new_name; + png_uint_32 name_len; + png_uint_32 profile_len; + png_byte new_name[81]; /* 1 byte for the compression byte */ compression_state comp; - int embedded_profile_len = 0; + png_uint_32 temp; png_debug(1, "in png_write_iCCP"); - comp.num_output_ptr = 0; - comp.max_output_ptr = 0; - comp.output_ptr = NULL; - comp.input = NULL; - comp.input_len = 0; - - if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) - return; - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - png_warning(png_ptr, "Unknown compression type in iCCP chunk"); - + /* These are all internal problems: the profile should have been checked + * before when it was stored. + */ if (profile == NULL) - profile_len = 0; + png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ - if (profile_len > 3) - embedded_profile_len = - ((*( (png_const_bytep)profile ))<<24) | - ((*( (png_const_bytep)profile + 1))<<16) | - ((*( (png_const_bytep)profile + 2))<< 8) | - ((*( (png_const_bytep)profile + 3)) ); + profile_len = png_get_uint_32(profile); + + if (profile_len < 132) + png_error(png_ptr, "ICC profile too short"); + + temp = (png_uint_32) (*(profile+8)); + if (temp > 3 && (profile_len & 0x03)) + png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); - if (embedded_profile_len < 0) { - png_warning(png_ptr, - "Embedded profile length in iCCP chunk is negative"); + png_uint_32 embedded_profile_len = png_get_uint_32(profile); - png_free(png_ptr, new_name); - return; + if (profile_len != embedded_profile_len) + png_error(png_ptr, "Profile length does not match profile"); } - if (profile_len < embedded_profile_len) - { - png_warning(png_ptr, - "Embedded profile length too large in iCCP chunk"); + name_len = png_check_keyword(png_ptr, name, new_name); - png_free(png_ptr, new_name); - return; - } + if (name_len == 0) + png_error(png_ptr, "iCCP: invalid keyword"); - if (profile_len > embedded_profile_len) - { - png_warning(png_ptr, - "Truncating profile to actual length in iCCP chunk"); - - profile_len = embedded_profile_len; - } - - if (profile_len) - profile_len = png_text_compress(png_ptr, profile, - (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); + new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; /* Make sure we include the NULL after the name and the compression type */ - png_write_chunk_start(png_ptr, png_iCCP, - (png_uint_32)(name_len + profile_len + 2)); + ++name_len; - new_name[name_len + 1] = 0x00; + png_text_compress_init(&comp, profile, profile_len); - png_write_chunk_data(png_ptr, (png_bytep)new_name, - (png_size_t)(name_len + 2)); + /* Allow for keyword terminator and compression byte */ + if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); - if (profile_len) - { - comp.input_len = profile_len; - png_write_compressed_data_out(png_ptr, &comp); - } + png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); + + png_write_chunk_data(png_ptr, new_name, name_len); + + png_write_compressed_data_out(png_ptr, &comp); png_write_chunk_end(png_ptr); - png_free(png_ptr, new_name); } #endif #ifdef PNG_WRITE_sPLT_SUPPORTED /* Write a sPLT chunk */ void /* PRIVATE */ -png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) +png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) { - PNG_sPLT; - png_size_t name_len; - png_charp new_name; + png_uint_32 name_len; + png_byte new_name[80]; png_byte entrybuf[10]; png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); png_size_t palette_size = entry_size * spalette->nentries; @@ -1204,11 +1293,13 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) png_debug(1, "in png_write_sPLT"); - if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) - return; + name_len = png_check_keyword(png_ptr, spalette->name, new_name); + + if (name_len == 0) + png_error(png_ptr, "sPLT: invalid keyword"); /* Make sure we include the NULL after the name */ - png_write_chunk_start(png_ptr, png_sPLT, + png_write_chunk_header(png_ptr, png_sPLT, (png_uint_32)(name_len + 2 + palette_size)); png_write_chunk_data(png_ptr, (png_bytep)new_name, @@ -1238,7 +1329,7 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) png_save_uint_16(entrybuf + 8, ep->frequency); } - png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + png_write_chunk_data(png_ptr, entrybuf, entry_size); } #else ep=spalette->entries; @@ -1262,28 +1353,26 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) png_save_uint_16(entrybuf + 8, ep[i].frequency); } - png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + png_write_chunk_data(png_ptr, entrybuf, entry_size); } #endif png_write_chunk_end(png_ptr); - png_free(png_ptr, new_name); } #endif #ifdef PNG_WRITE_sBIT_SUPPORTED /* Write the sBIT chunk */ void /* PRIVATE */ -png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) +png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) { - PNG_sBIT; png_byte buf[4]; png_size_t size; png_debug(1, "in png_write_sBIT"); /* Make sure we don't depend upon the order of PNG_COLOR_8 */ - if (color_type & PNG_COLOR_MASK_COLOR) + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) { png_byte maxbits; @@ -1316,7 +1405,7 @@ png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) size = 1; } - if (color_type & PNG_COLOR_MASK_ALPHA) + if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) { if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) { @@ -1327,53 +1416,42 @@ png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) buf[size++] = sbit->alpha; } - png_write_chunk(png_ptr, png_sBIT, buf, size); + png_write_complete_chunk(png_ptr, png_sBIT, buf, size); } #endif #ifdef PNG_WRITE_cHRM_SUPPORTED /* Write the cHRM chunk */ void /* PRIVATE */ -png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, - png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, - png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, - png_fixed_point blue_y) +png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) { - PNG_cHRM; png_byte buf[32]; png_debug(1, "in png_write_cHRM"); /* Each value is saved in 1/100,000ths */ -#ifdef PNG_CHECK_cHRM_SUPPORTED - if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, - green_x, green_y, blue_x, blue_y)) -#endif - { - png_save_uint_32(buf, (png_uint_32)white_x); - png_save_uint_32(buf + 4, (png_uint_32)white_y); + png_save_int_32(buf, xy->whitex); + png_save_int_32(buf + 4, xy->whitey); - png_save_uint_32(buf + 8, (png_uint_32)red_x); - png_save_uint_32(buf + 12, (png_uint_32)red_y); + png_save_int_32(buf + 8, xy->redx); + png_save_int_32(buf + 12, xy->redy); - png_save_uint_32(buf + 16, (png_uint_32)green_x); - png_save_uint_32(buf + 20, (png_uint_32)green_y); + png_save_int_32(buf + 16, xy->greenx); + png_save_int_32(buf + 20, xy->greeny); - png_save_uint_32(buf + 24, (png_uint_32)blue_x); - png_save_uint_32(buf + 28, (png_uint_32)blue_y); + png_save_int_32(buf + 24, xy->bluex); + png_save_int_32(buf + 28, xy->bluey); - png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); - } + png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); } #endif #ifdef PNG_WRITE_tRNS_SUPPORTED /* Write the tRNS chunk */ void /* PRIVATE */ -png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, +png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, png_const_color_16p tran, int num_trans, int color_type) { - PNG_tRNS; png_byte buf[6]; png_debug(1, "in png_write_tRNS"); @@ -1382,12 +1460,14 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, { if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) { - png_warning(png_ptr, "Invalid number of transparent colors specified"); + png_app_warning(png_ptr, + "Invalid number of transparent colors specified"); return; } /* Write the chunk out as it is */ - png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); + png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, + (png_size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) @@ -1395,14 +1475,14 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, /* One 16 bit value */ if (tran->gray >= (1 << png_ptr->bit_depth)) { - png_warning(png_ptr, + png_app_warning(png_ptr, "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); return; } png_save_uint_16(buf, tran->gray); - png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); } else if (color_type == PNG_COLOR_TYPE_RGB) @@ -1412,22 +1492,22 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, png_save_uint_16(buf + 2, tran->green); png_save_uint_16(buf + 4, tran->blue); #ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) #else - if (buf[0] | buf[2] | buf[4]) + if ((buf[0] | buf[2] | buf[4]) != 0) #endif { - png_warning(png_ptr, + png_app_warning(png_ptr, "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); return; } - png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); } else { - png_warning(png_ptr, "Can't write tRNS with an alpha channel"); + png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); } } #endif @@ -1435,9 +1515,8 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, #ifdef PNG_WRITE_bKGD_SUPPORTED /* Write the background chunk */ void /* PRIVATE */ -png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) +png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) { - PNG_bKGD; png_byte buf[6]; png_debug(1, "in png_write_bKGD"); @@ -1446,8 +1525,8 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) { if ( #ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->num_palette || - (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && + (png_ptr->num_palette != 0 || + (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && #endif back->index >= png_ptr->num_palette) { @@ -1456,18 +1535,18 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) } buf[0] = back->index; - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); } - else if (color_type & PNG_COLOR_MASK_COLOR) + else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) { png_save_uint_16(buf, back->red); png_save_uint_16(buf + 2, back->green); png_save_uint_16(buf + 4, back->blue); #ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) #else - if (buf[0] | buf[2] | buf[4]) + if ((buf[0] | buf[2] | buf[4]) != 0) #endif { png_warning(png_ptr, @@ -1476,7 +1555,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) return; } - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); } else @@ -1490,7 +1569,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) } png_save_uint_16(buf, back->gray); - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); } } #endif @@ -1498,9 +1577,8 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) #ifdef PNG_WRITE_hIST_SUPPORTED /* Write the histogram */ void /* PRIVATE */ -png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) +png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) { - PNG_hIST; int i; png_byte buf[3]; @@ -1515,7 +1593,7 @@ png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) return; } - png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); for (i = 0; i < num_hist; i++) { @@ -1527,236 +1605,93 @@ png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) } #endif -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ - defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) -/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, - * and if invalid, correct the keyword rather than discarding the entire - * chunk. The PNG 1.0 specification requires keywords 1-79 characters in - * length, forbids leading or trailing whitespace, multiple internal spaces, - * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. - * - * The new_key is allocated to hold the corrected keyword and must be freed - * by the calling routine. This avoids problems with trying to write to - * static keywords without having to have duplicate copies of the strings. - */ -png_size_t /* PRIVATE */ -png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) -{ - png_size_t key_len; - png_const_charp ikp; - png_charp kp, dp; - int kflag; - int kwarn=0; - - png_debug(1, "in png_check_keyword"); - - *new_key = NULL; - - if (key == NULL || (key_len = png_strlen(key)) == 0) - { - png_warning(png_ptr, "zero length keyword"); - return ((png_size_t)0); - } - - png_debug1(2, "Keyword to be checked is '%s'", key); - - *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); - - if (*new_key == NULL) - { - png_warning(png_ptr, "Out of memory while procesing keyword"); - return ((png_size_t)0); - } - - /* Replace non-printing characters with a blank and print a warning */ - for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) - { - if ((png_byte)*ikp < 0x20 || - ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, - (png_byte)*ikp); - png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); - *dp = ' '; - } - - else - { - *dp = *ikp; - } - } - *dp = '\0'; - - /* Remove any trailing white space. */ - kp = *new_key + key_len - 1; - if (*kp == ' ') - { - png_warning(png_ptr, "trailing spaces removed from keyword"); - - while (*kp == ' ') - { - *(kp--) = '\0'; - key_len--; - } - } - - /* Remove any leading white space. */ - kp = *new_key; - if (*kp == ' ') - { - png_warning(png_ptr, "leading spaces removed from keyword"); - - while (*kp == ' ') - { - kp++; - key_len--; - } - } - - png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); - - /* Remove multiple internal spaces. */ - for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) - { - if (*kp == ' ' && kflag == 0) - { - *(dp++) = *kp; - kflag = 1; - } - - else if (*kp == ' ') - { - key_len--; - kwarn = 1; - } - - else - { - *(dp++) = *kp; - kflag = 0; - } - } - *dp = '\0'; - if (kwarn) - png_warning(png_ptr, "extra interior spaces removed from keyword"); - - if (key_len == 0) - { - png_free(png_ptr, *new_key); - png_warning(png_ptr, "Zero length keyword"); - } - - if (key_len > 79) - { - png_warning(png_ptr, "keyword length must be 1 - 79 characters"); - (*new_key)[79] = '\0'; - key_len = 79; - } - - return (key_len); -} -#endif - #ifdef PNG_WRITE_tEXt_SUPPORTED /* Write a tEXt chunk */ void /* PRIVATE */ -png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, +png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, png_size_t text_len) { - PNG_tEXt; - png_size_t key_len; - png_charp new_key; + png_uint_32 key_len; + png_byte new_key[80]; png_debug(1, "in png_write_tEXt"); - if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) - return; + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "tEXt: invalid keyword"); if (text == NULL || *text == '\0') text_len = 0; else - text_len = png_strlen(text); + text_len = strlen(text); + + if (text_len > PNG_UINT_31_MAX - (key_len+1)) + png_error(png_ptr, "tEXt: text too long"); /* Make sure we include the 0 after the key */ - png_write_chunk_start(png_ptr, png_tEXt, - (png_uint_32)(key_len + text_len + 1)); + png_write_chunk_header(png_ptr, png_tEXt, + (png_uint_32)/*checked above*/(key_len + text_len + 1)); /* * We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, - (png_size_t)(key_len + 1)); + png_write_chunk_data(png_ptr, new_key, key_len + 1); - if (text_len) - png_write_chunk_data(png_ptr, (png_const_bytep)text, - (png_size_t)text_len); + if (text_len != 0) + png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); png_write_chunk_end(png_ptr); - png_free(png_ptr, new_key); } #endif #ifdef PNG_WRITE_zTXt_SUPPORTED /* Write a compressed text chunk */ void /* PRIVATE */ -png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, - png_size_t text_len, int compression) +png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, + int compression) { - PNG_zTXt; - png_size_t key_len; - png_byte buf; - png_charp new_key; + png_uint_32 key_len; + png_byte new_key[81]; compression_state comp; png_debug(1, "in png_write_zTXt"); - comp.num_output_ptr = 0; - comp.max_output_ptr = 0; - comp.output_ptr = NULL; - comp.input = NULL; - comp.input_len = 0; - - if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) + if (compression == PNG_TEXT_COMPRESSION_NONE) { - png_free(png_ptr, new_key); + png_write_tEXt(png_ptr, key, text, 0); return; } - if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) - { - png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); - png_free(png_ptr, new_key); - return; - } + if (compression != PNG_TEXT_COMPRESSION_zTXt) + png_error(png_ptr, "zTXt: invalid compression type"); - text_len = png_strlen(text); + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "zTXt: invalid keyword"); + + /* Add the compression method and 1 for the keyword separator. */ + new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; + ++key_len; /* Compute the compressed data; do it now for the length */ - text_len = png_text_compress(png_ptr, text, text_len, compression, - &comp); + png_text_compress_init(&comp, (png_const_bytep)text, + text == NULL ? 0 : strlen(text)); + + if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); /* Write start of chunk */ - png_write_chunk_start(png_ptr, png_zTXt, - (png_uint_32)(key_len+text_len + 2)); + png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); /* Write key */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, - (png_size_t)(key_len + 1)); - - png_free(png_ptr, new_key); - - buf = (png_byte)compression; - - /* Write compression */ - png_write_chunk_data(png_ptr, &buf, (png_size_t)1); + png_write_chunk_data(png_ptr, new_key, key_len); /* Write the compressed data */ - comp.input_len = text_len; png_write_compressed_data_out(png_ptr, &comp); /* Close the chunk */ @@ -1767,104 +1702,109 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, #ifdef PNG_WRITE_iTXt_SUPPORTED /* Write an iTXt chunk */ void /* PRIVATE */ -png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, +png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, png_const_charp lang, png_const_charp lang_key, png_const_charp text) { - PNG_iTXt; - png_size_t lang_len, key_len, lang_key_len, text_len; - png_charp new_lang; - png_charp new_key = NULL; - png_byte cbuf[2]; + png_uint_32 key_len, prefix_len; + png_size_t lang_len, lang_key_len; + png_byte new_key[82]; compression_state comp; png_debug(1, "in png_write_iTXt"); - comp.num_output_ptr = 0; - comp.max_output_ptr = 0; - comp.output_ptr = NULL; - comp.input = NULL; + key_len = png_check_keyword(png_ptr, key, new_key); - if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) - return; + if (key_len == 0) + png_error(png_ptr, "iTXt: invalid keyword"); - if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) + /* Set the compression flag */ + switch (compression) { - png_warning(png_ptr, "Empty language field in iTXt chunk"); - new_lang = NULL; - lang_len = 0; + case PNG_ITXT_COMPRESSION_NONE: + case PNG_TEXT_COMPRESSION_NONE: + compression = new_key[++key_len] = 0; /* no compression */ + break; + + case PNG_TEXT_COMPRESSION_zTXt: + case PNG_ITXT_COMPRESSION_zTXt: + compression = new_key[++key_len] = 1; /* compressed */ + break; + + default: + png_error(png_ptr, "iTXt: invalid compression"); } - if (lang_key == NULL) - lang_key_len = 0; - - else - lang_key_len = png_strlen(lang_key); - - if (text == NULL) - text_len = 0; - - else - text_len = png_strlen(text); - - /* Compute the compressed data; do it now for the length */ - text_len = png_text_compress(png_ptr, text, text_len, compression - 2, - &comp); - - - /* Make sure we include the compression flag, the compression byte, - * and the NULs after the key, lang, and lang_key parts - */ - - png_write_chunk_start(png_ptr, png_iTXt, (png_uint_32)( - 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ - + key_len - + lang_len - + lang_key_len - + text_len)); + new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; + ++key_len; /* for the keywod separator */ /* We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, + * specifies that the text is UTF-8 and this really doesn't require any + * checking. + * * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + * + * TODO: validate the language tag correctly (see the spec.) */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); + if (lang == NULL) lang = ""; /* empty language is valid */ + lang_len = strlen(lang)+1; + if (lang_key == NULL) lang_key = ""; /* may be empty */ + lang_key_len = strlen(lang_key)+1; + if (text == NULL) text = ""; /* may be empty */ - /* Set the compression flag */ - if (compression == PNG_ITXT_COMPRESSION_NONE || - compression == PNG_TEXT_COMPRESSION_NONE) - cbuf[0] = 0; + prefix_len = key_len; + if (lang_len > PNG_UINT_31_MAX-prefix_len) + prefix_len = PNG_UINT_31_MAX; + else + prefix_len = (png_uint_32)(prefix_len + lang_len); - else /* compression == PNG_ITXT_COMPRESSION_zTXt */ - cbuf[0] = 1; + if (lang_key_len > PNG_UINT_31_MAX-prefix_len) + prefix_len = PNG_UINT_31_MAX; + else + prefix_len = (png_uint_32)(prefix_len + lang_key_len); - /* Set the compression method */ - cbuf[1] = 0; + png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); - png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); + if (compression != 0) + { + if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + } - cbuf[0] = 0; - png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), - (png_size_t)(lang_len + 1)); + else + { + if (comp.input_len > PNG_UINT_31_MAX-prefix_len) + png_error(png_ptr, "iTXt: uncompressed text too long"); - png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), - (png_size_t)(lang_key_len + 1)); + /* So the string will fit in a chunk: */ + comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; + } - png_write_compressed_data_out(png_ptr, &comp); + png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); + + png_write_chunk_data(png_ptr, new_key, key_len); + + png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); + + png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); + + if (compression != 0) + png_write_compressed_data_out(png_ptr, &comp); + + else + png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len); png_write_chunk_end(png_ptr); - - png_free(png_ptr, new_key); - png_free(png_ptr, new_lang); } #endif #ifdef PNG_WRITE_oFFs_SUPPORTED /* Write the oFFs chunk */ void /* PRIVATE */ -png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, +png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type) { - PNG_oFFs; png_byte buf[9]; png_debug(1, "in png_write_oFFs"); @@ -1876,52 +1816,57 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_save_int_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); + png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); } #endif #ifdef PNG_WRITE_pCAL_SUPPORTED /* Write the pCAL chunk (described in the PNG extensions document) */ void /* PRIVATE */ -png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, +png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_const_charp units, png_charpp params) { - PNG_pCAL; - png_size_t purpose_len, units_len, total_len; - png_uint_32p params_len; + png_uint_32 purpose_len; + png_size_t units_len, total_len; + png_size_tp params_len; png_byte buf[10]; - png_charp new_purpose; + png_byte new_purpose[80]; int i; png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); if (type >= PNG_EQUATION_LAST) - png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); + png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); + + purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); + + if (purpose_len == 0) + png_error(png_ptr, "pCAL: invalid keyword"); + + ++purpose_len; /* terminator */ - purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); - units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); + units_len = strlen(units) + (nparams == 0 ? 0 : 1); png_debug1(3, "pCAL units length = %d", (int)units_len); total_len = purpose_len + units_len + 10; - params_len = (png_uint_32p)png_malloc(png_ptr, - (png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); + params_len = (png_size_tp)png_malloc(png_ptr, + (png_alloc_size_t)(nparams * (sizeof (png_size_t)))); /* Find the length of each parameter, making sure we don't count the * null terminator for the last parameter. */ for (i = 0; i < nparams; i++) { - params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); + params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); png_debug2(3, "pCAL parameter %d length = %lu", i, (unsigned long)params_len[i]); - total_len += (png_size_t)params_len[i]; + total_len += params_len[i]; } png_debug1(3, "pCAL total length = %d", (int)total_len); - png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, - (png_size_t)purpose_len); + png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, new_purpose, purpose_len); png_save_int_32(buf, X0); png_save_int_32(buf + 4, X1); buf[8] = (png_byte)type; @@ -1929,12 +1874,9 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, png_write_chunk_data(png_ptr, buf, (png_size_t)10); png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); - png_free(png_ptr, new_purpose); - for (i = 0; i < nparams; i++) { - png_write_chunk_data(png_ptr, (png_const_bytep)params[i], - (png_size_t)params_len[i]); + png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); } png_free(png_ptr, params_len); @@ -1945,17 +1887,16 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, #ifdef PNG_WRITE_sCAL_SUPPORTED /* Write the sCAL chunk */ void /* PRIVATE */ -png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, +png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, png_const_charp height) { - PNG_sCAL; png_byte buf[64]; png_size_t wlen, hlen, total_len; png_debug(1, "in png_write_sCAL_s"); - wlen = png_strlen(width); - hlen = png_strlen(height); + wlen = strlen(width); + hlen = strlen(height); total_len = wlen + hlen + 2; if (total_len > 64) @@ -1965,22 +1906,21 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, } buf[0] = (png_byte)unit; - png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ - png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ + memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ + memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_chunk(png_ptr, png_sCAL, buf, total_len); + png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); } #endif #ifdef PNG_WRITE_pHYs_SUPPORTED /* Write the pHYs chunk */ void /* PRIVATE */ -png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, +png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int unit_type) { - PNG_pHYs; png_byte buf[9]; png_debug(1, "in png_write_pHYs"); @@ -1992,7 +1932,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_save_uint_32(buf + 4, y_pixels_per_unit); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); + png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); } #endif @@ -2001,9 +1941,8 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, * or png_convert_from_time_t(), or fill in the structure yourself. */ void /* PRIVATE */ -png_write_tIME(png_structp png_ptr, png_const_timep mod_time) +png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) { - PNG_tIME; png_byte buf[7]; png_debug(1, "in png_write_tIME"); @@ -2023,40 +1962,44 @@ png_write_tIME(png_structp png_ptr, png_const_timep mod_time) buf[5] = mod_time->minute; buf[6] = mod_time->second; - png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); + png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); } #endif /* Initializes the row writing capability of libpng */ void /* PRIVATE */ -png_write_start_row(png_structp png_ptr) +png_write_start_row(png_structrp png_ptr) { #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif - png_size_t buf_size; + png_alloc_size_t buf_size; + int usr_pixel_depth; png_debug(1, "in png_write_start_row"); - buf_size = (png_size_t)(PNG_ROWBYTES( - png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); + usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; + buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; + + /* 1.5.6: added to allow checking in the row write code. */ + png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; + png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; /* Set up row buffer */ - png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)buf_size); + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; @@ -2070,13 +2013,13 @@ png_write_start_row(png_structp png_ptr) } /* We only need to keep the previous row if we are using one of these. */ - if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) + if ((png_ptr->do_filter & + (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) { /* Set up previous row buffer */ - png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)buf_size); + png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); - if (png_ptr->do_filter & PNG_FILTER_UP) + if ((png_ptr->do_filter & PNG_FILTER_UP) != 0) { png_ptr->up_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); @@ -2084,7 +2027,7 @@ png_write_start_row(png_structp png_ptr) png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; } - if (png_ptr->do_filter & PNG_FILTER_AVG) + if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0) { png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); @@ -2092,7 +2035,7 @@ png_write_start_row(png_structp png_ptr) png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; } - if (png_ptr->do_filter & PNG_FILTER_PAETH) + if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0) { png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); @@ -2100,13 +2043,13 @@ png_write_start_row(png_structp png_ptr) png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } -#endif /* PNG_WRITE_FILTER_SUPPORTED */ +#endif /* WRITE_FILTER */ #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* If interlaced, we need to set up width and height of pass */ - if (png_ptr->interlaced) + if (png_ptr->interlaced != 0) { - if (!(png_ptr->transformations & PNG_INTERLACE)) + if ((png_ptr->transformations & PNG_INTERLACE) == 0) { png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - png_pass_ystart[0]) / png_pass_yinc[0]; @@ -2128,34 +2071,28 @@ png_write_start_row(png_structp png_ptr) png_ptr->num_rows = png_ptr->height; png_ptr->usr_width = png_ptr->width; } - - png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; } /* Internal use only. Called when finished processing a row of data. */ void /* PRIVATE */ -png_write_finish_row(png_structp png_ptr) +png_write_finish_row(png_structrp png_ptr) { #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif - int ret; - png_debug(1, "in png_write_finish_row"); /* Next row */ @@ -2167,10 +2104,10 @@ png_write_finish_row(png_structp png_ptr) #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* If interlaced, go to next pass */ - if (png_ptr->interlaced) + if (png_ptr->interlaced != 0) { png_ptr->row_number = 0; - if (png_ptr->transformations & PNG_INTERLACE) + if ((png_ptr->transformations & PNG_INTERLACE) != 0) { png_ptr->pass++; } @@ -2195,7 +2132,7 @@ png_write_finish_row(png_structp png_ptr) png_pass_ystart[png_ptr->pass]) / png_pass_yinc[png_ptr->pass]; - if (png_ptr->transformations & PNG_INTERLACE) + if ((png_ptr->transformations & PNG_INTERLACE) != 0) break; } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); @@ -2206,7 +2143,7 @@ png_write_finish_row(png_structp png_ptr) if (png_ptr->pass < 7) { if (png_ptr->prev_row != NULL) - png_memset(png_ptr->prev_row, 0, + memset(png_ptr->prev_row, 0, (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* png_ptr->usr_bit_depth, png_ptr->width)) + 1); @@ -2217,42 +2154,7 @@ png_write_finish_row(png_structp png_ptr) /* If we get here, we've just written the last row, so we need to flush the compressor */ - do - { - /* Tell the compressor we are done */ - ret = deflate(&png_ptr->zstream, Z_FINISH); - - /* Check for an error */ - if (ret == Z_OK) - { - /* Check to see if we need more room */ - if (!(png_ptr->zstream.avail_out)) - { - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - } - } - - else if (ret != Z_STREAM_END) - { - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - } while (ret != Z_STREAM_END); - - /* Write any extra space */ - if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) - { - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - - png_ptr->zstream.avail_out); - } - - png_zlib_release(png_ptr); - png_ptr->zstream.data_type = Z_BINARY; + png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); } #ifdef PNG_WRITE_INTERLACING_SUPPORTED @@ -2269,10 +2171,10 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_write_interlace"); @@ -2416,7 +2318,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) /* Move the pixel */ if (dp != sp) - png_memcpy(dp, sp, pixel_bytes); + memcpy(dp, sp, pixel_bytes); /* Next pixel */ dp += pixel_bytes; @@ -2440,14 +2342,16 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) * been specified by the application, and then writes the row out with the * chosen filter. */ -static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row); +static void +png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, + png_size_t row_bytes); #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) #define PNG_HISHIFT 10 #define PNG_LOMASK ((png_uint_32)0xffffL) #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) void /* PRIVATE */ -png_write_find_filter(png_structp png_ptr, png_row_infop row_info) +png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) { png_bytep best_row; #ifdef PNG_WRITE_FILTER_SUPPORTED @@ -2456,7 +2360,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_byte filter_to_do = png_ptr->do_filter; png_size_t row_bytes = row_info->rowbytes; #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - int num_p_filters = (int)png_ptr->num_prev_filters; + int num_p_filters = png_ptr->num_prev_filters; #endif png_debug(1, "in png_write_find_filter"); @@ -2507,7 +2411,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) /* We don't need to test the 'no filter' case if this is the only filter * that has been chosen, as it doesn't actually do anything to the data. */ - if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) + if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE) { png_bytep rp; png_uint_32 sum = 0; @@ -2583,7 +2487,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->sub_row; } - else if (filter_to_do & PNG_FILTER_SUB) + else if ((filter_to_do & PNG_FILTER_SUB) != 0) { png_bytep rp, dp, lp; png_uint_32 sum = 0, lmins = mins; @@ -2704,7 +2608,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->up_row; } - else if (filter_to_do & PNG_FILTER_UP) + else if ((filter_to_do & PNG_FILTER_UP) != 0) { png_bytep rp, dp, pp; png_uint_32 sum = 0, lmins = mins; @@ -2818,7 +2722,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->avg_row; } - else if (filter_to_do & PNG_FILTER_AVG) + else if ((filter_to_do & PNG_FILTER_AVG) != 0) { png_bytep rp, dp, pp, lp; png_uint_32 sum = 0, lmins = mins; @@ -2920,7 +2824,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) } /* Paeth filter */ - if (filter_to_do == PNG_FILTER_PAETH) + if ((filter_to_do == PNG_FILTER_PAETH) != 0) { png_bytep rp, dp, pp, cp, lp; png_size_t i; @@ -2959,7 +2863,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->paeth_row; } - else if (filter_to_do & PNG_FILTER_PAETH) + else if ((filter_to_do & PNG_FILTER_PAETH) != 0) { png_bytep rp, dp, pp, cp, lp; png_uint_32 sum = 0, lmins = mins; @@ -3029,7 +2933,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) pc = (p + pc) < 0 ? -(p + pc) : p + pc; #endif p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; -#else /* PNG_SLOW_PAETH */ +#else /* SLOW_PAETH */ p = a + b - c; pa = abs(p - a); pb = abs(p - b); @@ -3043,7 +2947,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) else p = c; -#endif /* PNG_SLOW_PAETH */ +#endif /* SLOW_PAETH */ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); @@ -3092,10 +2996,10 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->paeth_row; } } -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - /* Do the actual writing of the filtered row data from the chosen filter. */ +#endif /* WRITE_FILTER */ - png_write_filtered_row(png_ptr, best_row); + /* Do the actual writing of the filtered row data from the chosen filter. */ + png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); #ifdef PNG_WRITE_FILTER_SUPPORTED #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED @@ -3112,74 +3016,20 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_ptr->prev_filters[j] = best_row[0]; } #endif -#endif /* PNG_WRITE_FILTER_SUPPORTED */ +#endif /* WRITE_FILTER */ } /* Do the actual writing of a previously filtered row. */ static void -png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) +png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, + png_size_t full_row_length/*includes filter byte*/) { - png_size_t avail; - png_debug(1, "in png_write_filtered_row"); png_debug1(2, "filter = %d", filtered_row[0]); - /* Set up the zlib input buffer */ - png_ptr->zstream.next_in = filtered_row; - png_ptr->zstream.avail_in = 0; - avail = png_ptr->row_info.rowbytes + 1; - /* Repeat until we have compressed all the data */ - do - { - int ret; /* Return of zlib */ - - /* Record the number of bytes available - zlib supports at least 65535 - * bytes at one step, depending on the size of the zlib type 'uInt', the - * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). - * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. - * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a - * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called - * with smaller chunks of data. - */ - if (png_ptr->zstream.avail_in == 0) - { - if (avail > ZLIB_IO_MAX) - { - png_ptr->zstream.avail_in = ZLIB_IO_MAX; - avail -= ZLIB_IO_MAX; - } - - else - { - /* So this will fit in the available uInt space: */ - png_ptr->zstream.avail_in = (uInt)avail; - avail = 0; - } - } - - /* Compress the data */ - ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); - - /* Check for compression errors */ - if (ret != Z_OK) - { - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - - else - png_error(png_ptr, "zlib error"); - } - - /* See if it is time to write another IDAT */ - if (!(png_ptr->zstream.avail_out)) - { - /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); - } - /* Repeat until all data has been compressed */ - } while (avail > 0 || png_ptr->zstream.avail_in > 0); + png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); /* Swap the current and previous rows */ if (png_ptr->prev_row != NULL) @@ -3202,6 +3052,6 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) { png_write_flush(png_ptr); } -#endif +#endif /* WRITE_FLUSH */ } -#endif /* PNG_WRITE_SUPPORTED */ +#endif /* WRITE */ diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java index fad3b3b6c09..8c0dc54a3b8 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java @@ -29,6 +29,7 @@ import java.awt.peer.FileDialogPeer; import java.io.File; import java.io.FilenameFilter; import sun.awt.AWTAccessor; +import sun.misc.ManagedLocalsThread; /** * FileDialogPeer for the GtkFileChooser. @@ -111,13 +112,16 @@ final class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { XToolkit.awtLock(); try { if (b) { - Thread t = new Thread() { - public void run() { - showNativeDialog(); - fd.setVisible(false); - } + Runnable task = () -> { + showNativeDialog(); + fd.setVisible(false); }; - t.start(); + if (System.getSecurityManager() == null) { + new Thread(task).start(); + } else { + new ManagedLocalsThread(task).start(); + } + } else { quit(); fd.setVisible(false); diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java index 41d0ef0f2d0..33cc44fccec 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java @@ -29,6 +29,9 @@ import java.awt.*; import java.awt.event.*; import java.awt.peer.TrayIconPeer; import sun.awt.*; +import sun.misc.InnocuousThread; +import sun.misc.ManagedLocalsThread; + import java.awt.image.*; import java.text.BreakIterator; import java.util.concurrent.ArrayBlockingQueue; @@ -338,7 +341,7 @@ public abstract class InfoWindow extends Window { lineLabels[i].setBackground(Color.white); } - displayer.start(); + displayer.thread.start(); } public void display(String caption, String text, String messageType) { @@ -415,7 +418,7 @@ public abstract class InfoWindow extends Window { } public void dispose() { - displayer.interrupt(); + displayer.thread.interrupt(); super.dispose(); } @@ -444,16 +447,23 @@ public abstract class InfoWindow extends Window { } } - private class Displayer extends Thread { + private class Displayer implements Runnable { final int MAX_CONCURRENT_MSGS = 10; ArrayBlockingQueue messageQueue = new ArrayBlockingQueue(MAX_CONCURRENT_MSGS); boolean isDisplayed; + final Thread thread; Displayer() { - setDaemon(true); + if (System.getSecurityManager() == null) { + this.thread = new Thread(this); + } else { + this.thread = new ManagedLocalsThread(this); + } + this.thread.setDaemon(true); } + @Override public void run() { while (true) { Message msg = null; diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index bfe94c9f27c..3adbc8d35c5 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -266,21 +266,26 @@ public final class XToolkit extends UNIXToolkit implements Runnable { awtUnlock(); } PrivilegedAction a = () -> { - Thread shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), "XToolkt-Shutdown-Thread") { - public void run() { - XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); - if (peer != null) { - peer.dispose(); - } - if (xs != null) { - ((XAWTXSettings)xs).dispose(); - } - freeXKB(); - if (log.isLoggable(PlatformLogger.Level.FINE)) { - dumpPeers(); - } - } - }; + Runnable r = () -> { + XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); + if (peer != null) { + peer.dispose(); + } + if (xs != null) { + ((XAWTXSettings)xs).dispose(); + } + freeXKB(); + if (log.isLoggable(PlatformLogger.Level.FINE)) { + dumpPeers(); + } + }; + String name = "XToolkt-Shutdown-Thread"; + Thread shutdownThread; + if (System.getSecurityManager() == null) { + shutdownThread = new Thread(ThreadGroupUtils.getRootThreadGroup(), r, name); + } else { + shutdownThread = new InnocuousThread(r, name); + } shutdownThread.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(shutdownThread); return null; @@ -326,7 +331,13 @@ public final class XToolkit extends UNIXToolkit implements Runnable { XWM.init(); toolkitThread = AccessController.doPrivileged((PrivilegedAction) () -> { - Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, "AWT-XAWT"); + String name = "AWT-XAWT"; + Thread thread; + if (System.getSecurityManager() == null) { + thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), XToolkit.this, name); + } else { + thread = new InnocuousThread(XToolkit.this, name); + } thread.setContextClassLoader(null); thread.setPriority(Thread.NORM_PRIORITY + 1); thread.setDaemon(true); diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java index 009035326d9..93511617183 100644 --- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java @@ -43,6 +43,7 @@ import sun.java2d.xr.XRGraphicsConfig; import sun.java2d.loops.SurfaceType; import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; /** * This is an implementation of a GraphicsDevice object for a single @@ -428,7 +429,6 @@ public class X11GraphicsDevice // hook will have no effect) shutdownHookRegistered = true; PrivilegedAction a = () -> { - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); Runnable r = () -> { Window old = getFullScreenWindow(); if (old != null) { @@ -436,7 +436,13 @@ public class X11GraphicsDevice setDisplayMode(origDisplayMode); } }; - Thread t = new Thread(rootTG, r,"Display-Change-Shutdown-Thread-"+screen); + String name = "Display-Change-Shutdown-Thread-" + screen; + Thread t; + if (System.getSecurityManager() == null) { + t = new Thread(ThreadGroupUtils.getRootThreadGroup(), r, name); + } else { + t = new InnocuousThread(r, name); + } t.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(t); return null; diff --git a/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java index 96acd53d58a..e40ba274b46 100644 --- a/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java +++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java @@ -25,6 +25,8 @@ package sun.print; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; @@ -211,7 +213,12 @@ public class PrintServiceLookupProvider extends PrintServiceLookup public PrintServiceLookupProvider() { // start the printer listener thread if (pollServices) { - PrinterChangeListener thr = new PrinterChangeListener(); + Thread thr; + if (System.getSecurityManager() == null) { + thr = new Thread(new PrinterChangeListener()); + } else { + thr = new ManagedLocalsThread(new PrinterChangeListener()); + } thr.setDaemon(true); thr.start(); IPPPrintService.debug_println(debugPrefix+"polling turned on"); @@ -934,8 +941,9 @@ public class PrintServiceLookupProvider extends PrintServiceLookup } } - private class PrinterChangeListener extends Thread { + private class PrinterChangeListener implements Runnable { + @Override public void run() { int refreshSecs; while (true) { @@ -954,7 +962,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup refreshSecs = minRefreshTime; } try { - sleep(refreshSecs * 1000); + Thread.sleep(refreshSecs * 1000); } catch (InterruptedException e) { break; } diff --git a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c index 85a93042f1d..ed3bfaa1108 100644 --- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c +++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -281,9 +281,7 @@ SplashCreateWindow(Splash * splash) { /* for changing the visible shape of a window to an nonrectangular form */ void SplashUpdateShape(Splash * splash) { - if (!shapeSupported) - return; - if (!splash->maskRequired) { + if (splash->currentFrame < 0 || !shapeSupported || !splash->maskRequired) { return; } XShapeCombineRectangles(splash->display, splash->window, ShapeClip, 0, 0, @@ -324,6 +322,10 @@ ByteOrderToX(int byteOrder) { void SplashRedrawWindow(Splash * splash) { + if (splash->currentFrame < 0) { + return; + } + XImage *ximage; // making this method redraw a part of the image does not make diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index 1f3e2c3e987..52d198f034c 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -41,6 +41,7 @@ import java.util.stream.Stream; import static sun.awt.shell.Win32ShellFolder2.*; import sun.awt.OSInfo; import sun.awt.util.ThreadGroupUtils; +import sun.misc.InnocuousThread; // NOTE: This class supersedes Win32ShellFolderManager, which was removed // from distribution after version 1.4.2. @@ -516,26 +517,22 @@ final class Win32ShellFolderManager2 extends ShellFolderManager { private static Thread comThread; private ComInvoker() { - super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue()); + super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<>()); allowCoreThreadTimeOut(false); setThreadFactory(this); - final Runnable shutdownHook = new Runnable() { - public void run() { - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - shutdownNow(); - return null; - } - }); - } - }; - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - Runtime.getRuntime().addShutdownHook( - new Thread(shutdownHook) - ); - return null; + final Runnable shutdownHook = () -> AccessController.doPrivileged((PrivilegedAction) () -> { + shutdownNow(); + return null; + }); + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread t; + if (System.getSecurityManager() == null) { + t = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownHook); + } else { + t = new InnocuousThread(shutdownHook); } + Runtime.getRuntime().addShutdownHook(t); + return null; }); } @@ -550,17 +547,22 @@ final class Win32ShellFolderManager2 extends ShellFolderManager { } } }; - comThread = AccessController.doPrivileged((PrivilegedAction) () -> { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - Thread thread = new Thread(rootTG, comRun, "Swing-Shell"); - thread.setDaemon(true); - return thread; - } - ); + comThread = AccessController.doPrivileged((PrivilegedAction) () -> { + String name = "Swing-Shell"; + Thread thread; + if (System.getSecurityManager() == null) { + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), comRun, name); + } else { + /* InnocuousThread is a member of a correct TG by default */ + thread = new InnocuousThread(comRun, name); + } + thread.setDaemon(true); + return thread; + }); return comThread; } diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java index beeb1031332..81a28c6b7d3 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java @@ -36,6 +36,7 @@ import java.util.MissingResourceException; import java.util.Vector; import sun.awt.CausedFocusEvent; import sun.awt.AWTAccessor; +import sun.misc.ManagedLocalsThread; final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { @@ -97,12 +98,11 @@ final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer { @Override public void show() { - new Thread(new Runnable() { - @Override - public void run() { - _show(); - } - }).start(); + if (System.getSecurityManager() == null) { + new Thread(this::_show).start(); + } else { + new ManagedLocalsThread(this::_show).start(); + } } @Override diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java index 78a1c04cf12..7a146d965cd 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java @@ -25,6 +25,8 @@ package sun.awt.windows; +import sun.misc.ManagedLocalsThread; + final class WPageDialogPeer extends WPrintDialogPeer { WPageDialogPeer(WPageDialog target) { @@ -39,20 +41,22 @@ final class WPageDialogPeer extends WPrintDialogPeer { @Override public void show() { - new Thread(new Runnable() { - @Override - public void run() { - // Call pageSetup even with no printer installed, this - // will display Windows error dialog and return false. - try { - ((WPrintDialog)target).setRetVal(_show()); - } catch (Exception e) { - // No exception should be thrown by native dialog code, - // but if it is we need to trap it so the thread does - // not hide is called and the thread doesn't hang. - } - ((WPrintDialog)target).setVisible(false); - } - }).start(); + Runnable runnable = () -> { + // Call pageSetup even with no printer installed, this + // will display Windows error dialog and return false. + try { + ((WPrintDialog)target).setRetVal(_show()); + } catch (Exception e) { + // No exception should be thrown by native dialog code, + // but if it is we need to trap it so the thread does + // not hide is called and the thread doesn't hang. + } + ((WPrintDialog)target).setVisible(false); + }; + if (System.getSecurityManager() == null) { + new Thread(runnable).start(); + } else { + new ManagedLocalsThread(runnable).start(); + } } } diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java index d1efab01404..2f728f18899 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java @@ -32,6 +32,7 @@ import java.awt.dnd.DropTarget; import java.util.Vector; import sun.awt.CausedFocusEvent; import sun.awt.AWTAccessor; +import sun.misc.ManagedLocalsThread; class WPrintDialogPeer extends WWindowPeer implements DialogPeer { @@ -67,19 +68,21 @@ class WPrintDialogPeer extends WWindowPeer implements DialogPeer { @Override public void show() { - new Thread(new Runnable() { - @Override - public void run() { - try { - ((WPrintDialog)target).setRetVal(_show()); - } catch (Exception e) { - // No exception should be thrown by native dialog code, - // but if it is we need to trap it so the thread does - // not hide is called and the thread doesn't hang. - } - ((WPrintDialog)target).setVisible(false); + Runnable runnable = () -> { + try { + ((WPrintDialog)target).setRetVal(_show()); + } catch (Exception e) { + // No exception should be thrown by native dialog code, + // but if it is we need to trap it so the thread does + // not hide is called and the thread doesn't hang. } - }).start(); + ((WPrintDialog)target).setVisible(false); + }; + if (System.getSecurityManager() == null) { + new Thread(runnable).start(); + } else { + new ManagedLocalsThread(runnable).start(); + } } synchronized void setHWnd(long hwnd) { diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java index 7915982c95a..50207fd0f52 100644 --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java @@ -49,6 +49,7 @@ import sun.awt.datatransfer.DataTransferer; import sun.java2d.d3d.D3DRenderQueue; import sun.java2d.opengl.OGLRenderQueue; +import sun.misc.InnocuousThread; import sun.print.PrintJob2D; import java.awt.dnd.DragSource; @@ -247,11 +248,17 @@ public final class WToolkit extends SunToolkit implements Runnable { */ AWTAutoShutdown.notifyToolkitThreadBusy(); - // Find a root TG and attach Appkit thread to it + // Find a root TG and attach toolkit thread to it ThreadGroup rootTG = AccessController.doPrivileged( (PrivilegedAction) ThreadGroupUtils::getRootThreadGroup); if (!startToolkitThread(this, rootTG)) { - Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows"); + String name = "AWT-Windows"; + Thread toolkitThread; + if (System.getSecurityManager() == null) { + toolkitThread = new Thread(rootTG, this, name); + } else { + toolkitThread = new InnocuousThread(this, name); + } toolkitThread.setDaemon(true); toolkitThread.start(); } @@ -278,7 +285,12 @@ public final class WToolkit extends SunToolkit implements Runnable { private void registerShutdownHook() { AccessController.doPrivileged((PrivilegedAction) () -> { - Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown); + Thread shutdown; + if (System.getSecurityManager() == null) { + shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown); + } else { + shutdown = new InnocuousThread(this::shutdown); + } shutdown.setContextClassLoader(null); Runtime.getRuntime().addShutdownHook(shutdown); return null; diff --git a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java index 1ab30124296..fd4bd592402 100644 --- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java +++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java @@ -48,6 +48,7 @@ import sun.java2d.SurfaceData; import sun.java2d.windows.GDIWindowSurfaceData; import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData; import sun.java2d.windows.WindowsFlags; +import sun.misc.InnocuousThread; /** * This class handles rendering to the screen with the D3D pipeline. @@ -92,22 +93,25 @@ public class D3DScreenUpdateManager extends ScreenUpdateManager public D3DScreenUpdateManager() { done = false; - AccessController.doPrivileged( - (PrivilegedAction) () -> { - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - Thread shutdown = new Thread(rootTG, () -> { - done = true; - wakeUpUpdateThread(); - }); - shutdown.setContextClassLoader(null); - try { - Runtime.getRuntime().addShutdownHook(shutdown); - } catch (Exception e) { - done = true; - } - return null; - } - ); + AccessController.doPrivileged((PrivilegedAction) () -> { + Runnable shutdownRunnable = () -> { + done = true; + wakeUpUpdateThread(); + }; + Thread shutdown; + if (System.getSecurityManager() == null) { + shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable); + } else { + shutdown = new InnocuousThread(shutdownRunnable); + } + shutdown.setContextClassLoader(null); + try { + Runtime.getRuntime().addShutdownHook(shutdown); + } catch (Exception e) { + done = true; + } + return null; + }); } /** @@ -345,17 +349,21 @@ public class D3DScreenUpdateManager extends ScreenUpdateManager */ private synchronized void startUpdateThread() { if (screenUpdater == null) { - screenUpdater = AccessController.doPrivileged( - (PrivilegedAction) () -> { - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - Thread t = new Thread(rootTG, - D3DScreenUpdateManager.this, - "D3D Screen Updater"); - // REMIND: should it be higher? - t.setPriority(Thread.NORM_PRIORITY + 2); - t.setDaemon(true); - return t; - }); + screenUpdater = AccessController.doPrivileged((PrivilegedAction) () -> { + Thread t; + String name = "D3D Screen Updater"; + if (System.getSecurityManager() == null) { + t = new Thread(ThreadGroupUtils.getRootThreadGroup(), + D3DScreenUpdateManager.this, + name); + } else { + t = new InnocuousThread(D3DScreenUpdateManager.this, name); + } + // REMIND: should it be higher? + t.setPriority(Thread.NORM_PRIORITY + 2); + t.setDaemon(true); + return t; + }); screenUpdater.start(); } else { wakeUpUpdateThread(); diff --git a/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java index b3f56c8b55c..903673efdbf 100644 --- a/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java +++ b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java @@ -25,6 +25,8 @@ package sun.print; +import sun.misc.ManagedLocalsThread; + import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -97,7 +99,12 @@ public class PrintServiceLookupProvider extends PrintServiceLookup { return; } // start the printer listener thread - PrinterChangeListener thr = new PrinterChangeListener(); + Thread thr; + if (System.getSecurityManager() == null) { + thr = new Thread(new PrinterChangeListener()); + } else { + thr = new ManagedLocalsThread(new PrinterChangeListener()); + } thr.setDaemon(true); thr.start(); } /* else condition ought to never happen! */ @@ -316,12 +323,13 @@ public class PrintServiceLookupProvider extends PrintServiceLookup { return defaultPrintService; } - class PrinterChangeListener extends Thread { + class PrinterChangeListener implements Runnable { long chgObj; PrinterChangeListener() { chgObj = notifyFirstPrinterChange(null); } + @Override public void run() { if (chgObj != -1) { while (true) { diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_InputTextInfor.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_InputTextInfor.cpp index 4ccf0d55e3e..de9248f1372 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_InputTextInfor.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_InputTextInfor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -310,6 +310,8 @@ int AwtInputTextInfor::GetClauseInfor(int*& lpBndClauseW, jstring*& lpReadingCla readingMergedClauseW = new jstring[cMergedClauseW]; } catch (std::bad_alloc&) { delete [] bndMergedClauseW; + delete [] bndClauseW; + delete [] readingClauseW; throw; } @@ -394,6 +396,8 @@ int AwtInputTextInfor::GetAttributeInfor(int*& lpBndAttrW, BYTE*& lpValAttrW) { valMergedAttrW = new BYTE[cMergedAttrW]; } catch (std::bad_alloc&) { delete [] bndMergedAttrW; + delete [] bndAttrW; + delete [] valAttrW; throw; } bndMergedAttrW[0] = 0; diff --git a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp index 7952f1e7382..ef376f31a3b 100644 --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp @@ -709,7 +709,7 @@ void AwtTrayIcon::SetToolTip(LPCTSTR tooltip) { if (tooltip == NULL) { m_nid.szTip[0] = '\0'; - } else if (lstrlen(tooltip) > TRAY_ICON_TOOLTIP_MAX_SIZE) { + } else if (lstrlen(tooltip) >= TRAY_ICON_TOOLTIP_MAX_SIZE) { _tcsncpy(m_nid.szTip, tooltip, TRAY_ICON_TOOLTIP_MAX_SIZE); m_nid.szTip[TRAY_ICON_TOOLTIP_MAX_SIZE - 1] = '\0'; } else { @@ -814,7 +814,7 @@ void AwtTrayIcon::DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType) if (caption[0] == '\0') { m_nid.szInfoTitle[0] = '\0'; - } else if (lstrlen(caption) > TRAY_ICON_BALLOON_TITLE_MAX_SIZE) { + } else if (lstrlen(caption) >= TRAY_ICON_BALLOON_TITLE_MAX_SIZE) { _tcsncpy(m_nid.szInfoTitle, caption, TRAY_ICON_BALLOON_TITLE_MAX_SIZE); m_nid.szInfoTitle[TRAY_ICON_BALLOON_TITLE_MAX_SIZE - 1] = '\0'; @@ -827,7 +827,7 @@ void AwtTrayIcon::DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType) m_nid.szInfo[0] = ' '; m_nid.szInfo[1] = '\0'; - } else if (lstrlen(text) > TRAY_ICON_BALLOON_INFO_MAX_SIZE) { + } else if (lstrlen(text) >= TRAY_ICON_BALLOON_INFO_MAX_SIZE) { _tcsncpy(m_nid.szInfo, text, TRAY_ICON_BALLOON_INFO_MAX_SIZE); m_nid.szInfo[TRAY_ICON_BALLOON_INFO_MAX_SIZE - 1] = '\0'; diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java index 0f536b202e9..972b74a7efb 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -34,6 +34,7 @@ import java.lang.ref.WeakReference; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import sun.misc.JavaAWTAccess; +import sun.misc.ManagedLocalsThread; import sun.misc.SharedSecrets; /** @@ -248,7 +249,7 @@ public class LogManager { // This private class is used as a shutdown hook. // It does a "reset" to close all open handlers. - private class Cleaner extends Thread { + private class Cleaner extends ManagedLocalsThread { private Cleaner() { /* Set context class loader to null in order to avoid diff --git a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java index b8549f255a9..85f248311cb 100644 --- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java +++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java @@ -30,6 +30,7 @@ import java.io.InterruptedIOException; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; +import sun.misc.ManagedLocalsThread; public abstract class ClientCommunicatorAdmin { private static volatile long threadNo = 1; @@ -40,7 +41,11 @@ public abstract class ClientCommunicatorAdmin { if (period > 0) { checker = new Checker(); - Thread t = new Thread(checker, "JMX client heartbeat " + ++threadNo); + Thread t = new ManagedLocalsThread( + checker, + "JMX client heartbeat " + (++threadNo) + ); + t.setDaemon(true); t.start(); } else diff --git a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java index 4d3ba6db0d8..05abd0ceeb5 100644 --- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java +++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java @@ -52,6 +52,7 @@ import javax.management.remote.TargetedNotification; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; import java.rmi.UnmarshalException; +import sun.misc.ManagedLocalsThread; public abstract class ClientNotifForwarder { @@ -90,10 +91,8 @@ public abstract class ClientNotifForwarder { throw new IllegalArgumentException("More than one command"); this.command = command; if (thread == null) { - thread = new Thread() { - - @Override - public void run() { + thread = new ManagedLocalsThread( + ()-> { while (true) { Runnable r; synchronized (LinearExecutor.this) { @@ -107,10 +106,10 @@ public abstract class ClientNotifForwarder { } r.run(); } - } - }; + }, + "ClientNotifForwarder-" + ++threadId + ); thread.setDaemon(true); - thread.setName("ClientNotifForwarder-" + ++threadId); thread.start(); } } diff --git a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java index bb09f62bdb9..f943bf5ce68 100644 --- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java +++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java @@ -25,9 +25,9 @@ package com.sun.jmx.remote.internal; -import java.io.IOException; import com.sun.jmx.remote.util.ClassLogger; +import sun.misc.ManagedLocalsThread; public abstract class ServerCommunicatorAdmin { public ServerCommunicatorAdmin(long timeout) { @@ -42,7 +42,7 @@ public abstract class ServerCommunicatorAdmin { timestamp = 0; if (timeout < Long.MAX_VALUE) { Runnable timeoutTask = new Timeout(); - final Thread t = new Thread(timeoutTask); + final Thread t = new ManagedLocalsThread(timeoutTask); t.setName("JMX server connection timeout " + t.getId()); // If you change this name you will need to change a unit test // (NoServerTimeoutTest) diff --git a/jdk/src/java.management/share/classes/javax/management/AttributeValueExp.java b/jdk/src/java.management/share/classes/javax/management/AttributeValueExp.java index f2d6f7684db..66475a899bf 100644 --- a/jdk/src/java.management/share/classes/javax/management/AttributeValueExp.java +++ b/jdk/src/java.management/share/classes/javax/management/AttributeValueExp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,11 +93,10 @@ public class AttributeValueExp implements ValueExp { * * @return The ValueExp. * - * @exception BadAttributeValueExpException - * @exception InvalidApplicationException - * @exception BadStringOperationException - * @exception BadBinaryOpValueExpException - * + * @throws BadStringOperationException {@inheritDoc} + * @throws BadBinaryOpValueExpException {@inheritDoc} + * @throws BadAttributeValueExpException {@inheritDoc} + * @throws InvalidApplicationException {@inheritDoc} */ @Override public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, diff --git a/jdk/src/java.management/share/classes/javax/management/DescriptorKey.java b/jdk/src/java.management/share/classes/javax/management/DescriptorKey.java index c9bd8b2963c..814e234d35c 100644 --- a/jdk/src/java.management/share/classes/javax/management/DescriptorKey.java +++ b/jdk/src/java.management/share/classes/javax/management/DescriptorKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,5 +168,9 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DescriptorKey { + /** + * Returns the descriptor key. + * @return the descriptor key + */ String value(); } diff --git a/jdk/src/java.management/share/classes/javax/management/DynamicMBean.java b/jdk/src/java.management/share/classes/javax/management/DynamicMBean.java index 80e3007e7fd..129fb99a3f5 100644 --- a/jdk/src/java.management/share/classes/javax/management/DynamicMBean.java +++ b/jdk/src/java.management/share/classes/javax/management/DynamicMBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ public interface DynamicMBean { * * @return The value of the attribute retrieved. * - * @exception AttributeNotFoundException + * @exception AttributeNotFoundException if specified attribute does not exist or cannot be retrieved * @exception MBeanException Wraps a java.lang.Exception thrown by the MBean's getter. * @exception ReflectionException Wraps a java.lang.Exception thrown while trying to invoke the getter. * @@ -58,8 +58,8 @@ public interface DynamicMBean { * @param attribute The identification of the attribute to * be set and the value it is to be set to. * - * @exception AttributeNotFoundException - * @exception InvalidAttributeValueException + * @exception AttributeNotFoundException if specified attribute does not exist or cannot be retrieved + * @exception InvalidAttributeValueException if value specified is not valid for the attribute * @exception MBeanException Wraps a java.lang.Exception thrown by the MBean's setter. * @exception ReflectionException Wraps a java.lang.Exception thrown while trying to invoke the MBean's setter. * diff --git a/jdk/src/java.management/share/classes/javax/management/ImmutableDescriptor.java b/jdk/src/java.management/share/classes/javax/management/ImmutableDescriptor.java index 60e75fab315..eb0a02d41dd 100644 --- a/jdk/src/java.management/share/classes/javax/management/ImmutableDescriptor.java +++ b/jdk/src/java.management/share/classes/javax/management/ImmutableDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,8 @@ public class ImmutableDescriptor implements Descriptor { /** * Construct a descriptor containing the given fields and values. * + * @param fieldNames the field names + * @param fieldValues the field values * @throws IllegalArgumentException if either array is null, or * if the arrays have different sizes, or * if a field name is null or empty, or if the same field name @@ -81,6 +83,7 @@ public class ImmutableDescriptor implements Descriptor { * is {@code a=b=c} then the field name is {@code a} and its value * is {@code b=c}. * + * @param fields the field names * @throws IllegalArgumentException if the parameter is null, or * if a field name is empty, or if the same field name appears * more than once, or if one of the strings does not contain @@ -94,6 +97,7 @@ public class ImmutableDescriptor implements Descriptor { *

                                  Construct a descriptor where the names and values of the fields * are the keys and values of the given Map.

                                  * + * @param fields the field names and values * @throws IllegalArgumentException if the parameter is null, or * if a field name is null or empty, or if the same field name appears * more than once (which can happen because field names are not case diff --git a/jdk/src/java.management/share/classes/javax/management/QueryExp.java b/jdk/src/java.management/share/classes/javax/management/QueryExp.java index e4f76577a6f..819855ee5e4 100644 --- a/jdk/src/java.management/share/classes/javax/management/QueryExp.java +++ b/jdk/src/java.management/share/classes/javax/management/QueryExp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,10 +53,13 @@ public interface QueryExp extends Serializable { * * @return True if the query was successfully applied to the MBean, false otherwise * - * @exception BadStringOperationException - * @exception BadBinaryOpValueExpException - * @exception BadAttributeValueExpException - * @exception InvalidApplicationException + * @throws BadStringOperationException when an invalid string + * operation is passed to a method for constructing a query + * @throws BadBinaryOpValueExpException when an invalid expression + * is passed to a method for constructing a query + * @throws BadAttributeValueExpException when an invalid MBean + * attribute is passed to a query constructing method + * @throws InvalidApplicationException when an invalid apply is attempted */ public boolean apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException ; diff --git a/jdk/src/java.management/share/classes/javax/management/StandardEmitterMBean.java b/jdk/src/java.management/share/classes/javax/management/StandardEmitterMBean.java index 250d109679a..c4ead04d5f4 100644 --- a/jdk/src/java.management/share/classes/javax/management/StandardEmitterMBean.java +++ b/jdk/src/java.management/share/classes/javax/management/StandardEmitterMBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,6 +91,7 @@ public class StandardEmitterMBean extends StandardMBean * that will have no effect on this object's * {@code getNotificationInfo()}.

                                  * + * @param the implementation type of the MBean * @param implementation the implementation of the MBean interface. * @param mbeanInterface a Standard MBean interface. * @param emitter the object that will handle notifications. @@ -129,6 +130,7 @@ public class StandardEmitterMBean extends StandardMBean * that will have no effect on this object's * {@code getNotificationInfo()}.

                                  * + * @param the implementation type of the MBean * @param implementation the implementation of the MBean interface. * @param mbeanInterface a Standard MBean interface. * @param isMXBean If true, the {@code mbeanInterface} parameter diff --git a/jdk/src/java.management/share/classes/javax/management/StringValueExp.java b/jdk/src/java.management/share/classes/javax/management/StringValueExp.java index 629117fb228..ed9b3c3539e 100644 --- a/jdk/src/java.management/share/classes/javax/management/StringValueExp.java +++ b/jdk/src/java.management/share/classes/javax/management/StringValueExp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,11 +95,12 @@ public class StringValueExp implements ValueExp { * * @return The ValueExp. * - * @exception BadStringOperationException - * @exception BadBinaryOpValueExpException - * @exception BadAttributeValueExpException - * @exception InvalidApplicationException + * @throws BadStringOperationException {@inheritDoc} + * @throws BadBinaryOpValueExpException {@inheritDoc} + * @throws BadAttributeValueExpException {@inheritDoc} + * @throws InvalidApplicationException {@inheritDoc} */ + @Override public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { return this; diff --git a/jdk/src/java.management/share/classes/javax/management/ValueExp.java b/jdk/src/java.management/share/classes/javax/management/ValueExp.java index 7a0619122de..1afe1b6a44f 100644 --- a/jdk/src/java.management/share/classes/javax/management/ValueExp.java +++ b/jdk/src/java.management/share/classes/javax/management/ValueExp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,10 +80,13 @@ public interface ValueExp extends java.io.Serializable { * * @return The ValueExp. * - * @exception BadStringOperationException - * @exception BadBinaryOpValueExpException - * @exception BadAttributeValueExpException - * @exception InvalidApplicationException + * @throws BadStringOperationException when an invalid string + * operation is passed to a method for constructing a query + * @throws BadBinaryOpValueExpException when an invalid expression + * is passed to a method for constructing a query + * @throws BadAttributeValueExpException when an invalid MBean + * attribute is passed to a query constructing method + * @throws InvalidApplicationException when an invalid apply is attempted */ public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, diff --git a/jdk/src/java.management/share/classes/javax/management/modelmbean/ModelMBeanInfo.java b/jdk/src/java.management/share/classes/javax/management/modelmbean/ModelMBeanInfo.java index 8894ae882f7..642cddd3d27 100644 --- a/jdk/src/java.management/share/classes/javax/management/modelmbean/ModelMBeanInfo.java +++ b/jdk/src/java.management/share/classes/javax/management/modelmbean/ModelMBeanInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -307,6 +307,7 @@ public interface ModelMBeanInfo /** * Creates and returns a copy of this object. + * @return a copy of this object */ public java.lang.Object clone(); diff --git a/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java b/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java index bf89b06cb9f..6276fb33b50 100644 --- a/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java +++ b/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,6 +61,7 @@ import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; import javax.management.ReflectionException; import static javax.management.monitor.MonitorNotification.*; +import sun.misc.ManagedLocalsThread; /** * Defines the part common to all monitor MBeans. @@ -386,7 +387,7 @@ public abstract class Monitor * * @return The name of the monitor MBean registered. * - * @exception Exception + * @exception Exception if something goes wrong */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { @@ -415,7 +416,7 @@ public abstract class Monitor *

                                  * Stops the monitor. * - * @exception Exception + * @exception Exception if something goes wrong */ public void preDeregister() throws Exception { @@ -1636,12 +1637,12 @@ public abstract class Monitor } public Thread newThread(Runnable r) { - Thread t = new Thread(group, - r, - namePrefix + - threadNumber.getAndIncrement() + - nameSuffix, - 0); + Thread t = new ManagedLocalsThread( + group, + r, + namePrefix + threadNumber.getAndIncrement() + nameSuffix + ); + t.setDaemon(true); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); diff --git a/jdk/src/java.management/share/classes/javax/management/openmbean/ArrayType.java b/jdk/src/java.management/share/classes/javax/management/openmbean/ArrayType.java index 2d12347044a..53665e8f2f9 100644 --- a/jdk/src/java.management/share/classes/javax/management/openmbean/ArrayType.java +++ b/jdk/src/java.management/share/classes/javax/management/openmbean/ArrayType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -793,6 +793,7 @@ public class ArrayType extends OpenType { * array type description = 3-dimension array of java.lang.String * } * + * @param the Java type that described instances must have * @param elementType the open type of element values contained * in the arrays described by this ArrayType * instance; must be an instance of either @@ -800,7 +801,7 @@ public class ArrayType extends OpenType { * TabularType or another ArrayType * with a SimpleType, CompositeType * or TabularType as its elementType. - * + * @return an {@code ArrayType} instance * @throws OpenDataException if elementType's className is not * one of the allowed Java class names for open * data. @@ -834,12 +835,14 @@ public class ArrayType extends OpenType { * array type description = 3-dimension array of int * } * + * @param the Java type that described instances must have * @param arrayClass a primitive array class such as {@code int[].class}, * {@code boolean[][].class}, etc. The {@link * #getElementOpenType()} method of the returned * {@code ArrayType} returns the {@link SimpleType} * corresponding to the wrapper type of the primitive * type of the array. + * @return an {@code ArrayType} instance * * @throws IllegalArgumentException if arrayClass is not * a primitive array. diff --git a/jdk/src/java.management/share/classes/javax/management/timer/Timer.java b/jdk/src/java.management/share/classes/javax/management/timer/Timer.java index 461b68e0dbd..b199e8e258a 100644 --- a/jdk/src/java.management/share/classes/javax/management/timer/Timer.java +++ b/jdk/src/java.management/share/classes/javax/management/timer/Timer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -195,7 +195,7 @@ public class Timer extends NotificationBroadcasterSupport * * @return The name of the timer MBean registered. * - * @exception java.lang.Exception + * @exception java.lang.Exception if something goes wrong */ public ObjectName preRegister(MBeanServer server, ObjectName name) throws java.lang.Exception { @@ -217,7 +217,7 @@ public class Timer extends NotificationBroadcasterSupport *

                                  * Stops the timer. * - * @exception java.lang.Exception + * @exception java.lang.Exception if something goes wrong */ public void preDeregister() throws java.lang.Exception { diff --git a/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java b/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java index a22873a0700..a90705d577a 100644 --- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java +++ b/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java @@ -34,6 +34,7 @@ import java.lang.management.RuntimeMXBean; import java.lang.reflect.Field; import java.lang.reflect.Method; import sun.management.VMManagement; +import sun.misc.ManagedLocalsThread; /** * JdpController is responsible to create and manage a broadcast loop @@ -219,7 +220,7 @@ public final class JdpController { controller = new JDPControllerRunner(bcast, packet, pause); - Thread t = new Thread(controller, "JDP broadcaster"); + Thread t = new ManagedLocalsThread(controller, "JDP broadcaster"); t.setDaemon(true); t.start(); } diff --git a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java index 40b2b56cf42..5abbc9de0e8 100644 --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java @@ -26,9 +26,6 @@ package com.sun.jndi.ldap; import javax.naming.*; -import javax.naming.directory.*; -import javax.naming.spi.*; -import java.net.URL; import java.net.MalformedURLException; import java.io.UnsupportedEncodingException; import java.util.StringTokenizer; @@ -211,44 +208,53 @@ final public class LdapURL extends Uri { // query begins with a '?' or is null - if (query == null) { + if (query == null || query.length() < 2) { return; } - int qmark2 = query.indexOf('?', 1); + int currentIndex = 1; + int nextQmark; + int endIndex; - if (qmark2 < 0) { - attributes = query.substring(1); + // attributes: + nextQmark = query.indexOf('?', currentIndex); + endIndex = nextQmark == -1 ? query.length() : nextQmark; + if (endIndex - currentIndex > 0) { + attributes = query.substring(currentIndex, endIndex); + } + currentIndex = endIndex + 1; + if (currentIndex >= query.length()) { return; - } else if (qmark2 != 1) { - attributes = query.substring(1, qmark2); } - int qmark3 = query.indexOf('?', qmark2 + 1); - - if (qmark3 < 0) { - scope = query.substring(qmark2 + 1); + // scope: + nextQmark = query.indexOf('?', currentIndex); + endIndex = nextQmark == -1 ? query.length() : nextQmark; + if (endIndex - currentIndex > 0) { + scope = query.substring(currentIndex, endIndex); + } + currentIndex = endIndex + 1; + if (currentIndex >= query.length()) { return; - } else if (qmark3 != qmark2 + 1) { - scope = query.substring(qmark2 + 1, qmark3); } - int qmark4 = query.indexOf('?', qmark3 + 1); - - if (qmark4 < 0) { - filter = query.substring(qmark3 + 1); - } else { - if (qmark4 != qmark3 + 1) { - filter = query.substring(qmark3 + 1, qmark4); - } - extensions = query.substring(qmark4 + 1); - if (extensions.length() > 0) { - extensions = UrlUtil.decode(extensions, "UTF8"); - } - } - if (filter != null && filter.length() > 0) { + // filter: + nextQmark = query.indexOf('?', currentIndex); + endIndex = nextQmark == -1 ? query.length() : nextQmark; + if (endIndex - currentIndex > 0) { + filter = query.substring(currentIndex, endIndex); filter = UrlUtil.decode(filter, "UTF8"); } + currentIndex = endIndex + 1; + if (currentIndex >= query.length()) { + return; + } + + // extensions: + if (query.length() - currentIndex > 0) { + extensions = query.substring(currentIndex); + extensions = UrlUtil.decode(extensions, "UTF8"); + } } /* diff --git a/jdk/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java b/jdk/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java index 6553ff6ed78..dc54a0d539b 100644 --- a/jdk/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java +++ b/jdk/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java @@ -31,6 +31,7 @@ import java.util.Iterator; import java.util.Timer; import java.util.TimerTask; import java.lang.ref.WeakReference; +import sun.misc.ManagedLocalsThread; /* @@ -343,7 +344,7 @@ class MacOSXPreferencesFile { { if (timer == null) { timer = new Timer(true); // daemon - Thread flushThread = new Thread() { + Thread flushThread = new ManagedLocalsThread() { @Override public void run() { flushWorld(); diff --git a/jdk/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java b/jdk/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java index a840dffab95..fd3ba69902a 100644 --- a/jdk/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java +++ b/jdk/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java @@ -29,6 +29,7 @@ import java.util.*; import java.io.*; import java.security.AccessController; import java.security.PrivilegedAction; +import sun.misc.ManagedLocalsThread; // These imports needed only as a workaround for a JavaDoc bug import java.lang.Integer; import java.lang.Long; @@ -1470,7 +1471,7 @@ public abstract class AbstractPreferences extends Preferences { * A single background thread ("the event notification thread") monitors * the event queue and delivers events that are placed on the queue. */ - private static class EventDispatchThread extends Thread { + private static class EventDispatchThread extends ManagedLocalsThread { public void run() { while(true) { // Wait on eventQueue till an event is present diff --git a/jdk/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java b/jdk/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java index 7bcd1d3ad24..9d412ed7f67 100644 --- a/jdk/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java +++ b/jdk/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java @@ -30,7 +30,7 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; - +import sun.misc.ManagedLocalsThread; import sun.util.logging.PlatformLogger; /** @@ -450,7 +450,7 @@ class FileSystemPreferences extends AbstractPreferences { // Add shutdown hook to flush cached prefs on normal termination AccessController.doPrivileged(new PrivilegedAction() { public Void run() { - Runtime.getRuntime().addShutdownHook(new Thread() { + Runtime.getRuntime().addShutdownHook(new ManagedLocalsThread() { public void run() { syncTimer.cancel(); syncWorld(); diff --git a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSCredential.java b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSCredential.java index 115ee74a41b..6c304bed59a 100644 --- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSCredential.java +++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSCredential.java @@ -35,7 +35,7 @@ package org.ietf.jgss; * may be used to perform context initiation, acceptance, or both.

                                  * * Credentials are instantiated using one of the - * createCredential methods in the {@link GSSManager + * {@code createCredential} methods in the {@link GSSManager * GSSManager} class. GSS-API credential creation is not * intended to provide a "login to the network" function, as such a * function would involve the creation of new credentials rather than @@ -75,7 +75,7 @@ package org.ietf.jgss; * * Oid [] mechs = cred.getMechs(); * if (mechs != null) { - * for (int i = 0; i < mechs.length; i++) + * for (int i = 0; i{@literal <} mechs.length; i++) * System.out.println(mechs[i].toString()); * } * @@ -297,8 +297,8 @@ public interface GSSCredential extends Cloneable{ * with a variety of clients using different security mechanisms.

                                  * * This routine adds the new credential element "in-place". To add the - * element in a new credential, first call clone to obtain a - * copy of this credential, then call its add method.

                                  + * element in a new credential, first call {@code clone} to obtain a + * copy of this credential, then call its {@code add} method.

                                  * * As always, GSS-API implementations must impose a local access-control * policy on callers to prevent unauthorized callers from acquiring @@ -311,7 +311,7 @@ public interface GSSCredential extends Cloneable{ * getRemainingAcceptLifetime} on the credential. * * @param name the name of the principal for whom this credential is to - * be acquired. Use null to specify the default + * be acquired. Use {@code null} to specify the default * principal. * @param initLifetime the number of seconds that the credential element * should remain valid for initiating of security contexts. Use {@link @@ -354,8 +354,8 @@ public interface GSSCredential extends Cloneable{ * object. The two credentials must be acquired over the same * mechanisms and must refer to the same principal. * - * @return true if the two GSSCredentials assert the same - * entity; false otherwise. + * @return {@code true} if the two GSSCredentials assert the same + * entity; {@code false} otherwise. * @param another another GSSCredential for comparison to this one */ public boolean equals(Object another); diff --git a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/Card.java b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/Card.java index b91738f0056..49ec9d48edc 100644 --- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/Card.java +++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/Card.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,6 +69,7 @@ public abstract class Card { * Returns the CardChannel for the basic logical channel. The basic * logical channel has a channel number of 0. * + * @return the CardChannel for the basic logical channel * @throws SecurityException if a SecurityManager exists and the * caller does not have the required * {@linkplain CardPermission permission} @@ -82,6 +83,7 @@ public abstract class Card { * opened by issuing a MANAGE CHANNEL command that should use * the format [00 70 00 00 01]. * + * @return the logical channel which has been opened * @throws SecurityException if a SecurityManager exists and the * caller does not have the required * {@linkplain CardPermission permission} @@ -137,6 +139,7 @@ public abstract class Card { * * @param controlCode the control code of the command * @param command the command data + * @return the response from the terminal device * * @throws SecurityException if a SecurityManager exists and the * caller does not have the required diff --git a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminal.java b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminal.java index 740681890f6..eb5f305ffcd 100644 --- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminal.java +++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,7 @@ public abstract class CardTerminal { * @throws SecurityException if a SecurityManager exists and the * caller does not have the required * {@linkplain CardPermission permission} + * @return the card the connection has been established with */ public abstract Card connect(String protocol) throws CardException; diff --git a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminals.java b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminals.java index 94801368e79..f471b43b547 100644 --- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminals.java +++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardTerminals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,7 @@ public abstract class CardTerminals { * Returns the terminal with the specified name or null if no such * terminal exists. * + * @param name the terminal name * @return the terminal with the specified name or null if no such * terminal exists. * diff --git a/jdk/src/java.transaction/share/classes/javax/transaction/InvalidTransactionException.java b/jdk/src/java.transaction/share/classes/javax/transaction/InvalidTransactionException.java index 5d0c699b887..761b577fc6c 100644 --- a/jdk/src/java.transaction/share/classes/javax/transaction/InvalidTransactionException.java +++ b/jdk/src/java.transaction/share/classes/javax/transaction/InvalidTransactionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,17 @@ package javax.transaction; @SuppressWarnings("serial") // serialVersionUID intentionally omitted public class InvalidTransactionException extends java.rmi.RemoteException { + /** + * Constructs an {@code InvalidTransactionException}. + */ public InvalidTransactionException() { super(); } + /** + * Constructs an {@code InvalidTransactionException}. + * @param msg the detail message + */ public InvalidTransactionException(String msg) { super(msg); } diff --git a/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRequiredException.java b/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRequiredException.java index ee2ccbb8040..7be9b2b6c6b 100644 --- a/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRequiredException.java +++ b/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRequiredException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,10 +38,17 @@ package javax.transaction; @SuppressWarnings("serial") // serialVersionUID intentionally omitted public class TransactionRequiredException extends java.rmi.RemoteException { + /** + * Constructs a {@code TransactionRequiredException}. + */ public TransactionRequiredException() { super(); } + /** + * Constructs a {@code TransactionRequiredException}. + * @param msg the detail message + */ public TransactionRequiredException(String msg) { super(msg); } diff --git a/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRolledbackException.java b/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRolledbackException.java index 73ee335beee..2b4f6ad865d 100644 --- a/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRolledbackException.java +++ b/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRolledbackException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,10 +41,17 @@ package javax.transaction; @SuppressWarnings("serial") // serialVersionUID intentionally omitted public class TransactionRolledbackException extends java.rmi.RemoteException { + /** + * Constructs a {@code TransactionRolledbackException}. + */ public TransactionRolledbackException() { super(); } + /** + * Constructs a {@code TransactionRolledbackException}. + * @param msg the detail message + */ public TransactionRolledbackException(String msg) { super(msg); } diff --git a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dom/package.html b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dom/package.html index 4758373df04..7ee201a8dea 100644 --- a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dom/package.html +++ b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dom/package.html @@ -44,11 +44,7 @@ XML-Signature Syntax and Processing: W3C Recommendation RFC 3275: XML-Signature Syntax and Processing -

                                  -

                                  -
                                  Since:
                                  -
                                  1.6
                                  -
                                  +@since 1.6 diff --git a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/dom/package.html b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/dom/package.html index 7449617e8fa..b8f6d68155a 100644 --- a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/dom/package.html +++ b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/dom/package.html @@ -44,11 +44,7 @@ XML-Signature Syntax and Processing: W3C Recommendation RFC 3275: XML-Signature Syntax and Processing -

                                  -

                                  -
                                  Since:
                                  -
                                  1.6
                                  -
                                  +@since 1.6 diff --git a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/package.html b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/package.html index c97c98fc29f..21f985b5785 100644 --- a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/package.html +++ b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/keyinfo/package.html @@ -55,11 +55,7 @@ XML-Signature Syntax and Processing: W3C Recommendation RFC 3275: XML-Signature Syntax and Processing -

                                  -

                                  -
                                  Since:
                                  -
                                  1.6
                                  -
                                  +@since 1.6 diff --git a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/package.html b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/package.html index 2ba62e50fe7..9cb8e1610e0 100644 --- a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/package.html +++ b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/package.html @@ -65,11 +65,7 @@ XML-Signature Syntax and Processing: W3C Recommendation RFC 3275: XML-Signature Syntax and Processing -

                                  -

                                  -
                                  Since:
                                  -
                                  1.6
                                  -
                                  +@since 1.6 diff --git a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/spec/package.html b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/spec/package.html index b52895705c1..0a3b3faa7fd 100644 --- a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/spec/package.html +++ b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/spec/package.html @@ -49,11 +49,7 @@ Exclusive XML Canonicalization algorithm: W3C Recommendation XPath Filter 2.0 Transform Algorithm: W3C Recommendation -

                                  -

                                  -
                                  Since:
                                  -
                                  1.6
                                  -
                                  +@since 1.6 diff --git a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/package.html b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/package.html index e5fc99ed9cf..05610a235ec 100644 --- a/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/package.html +++ b/jdk/src/java.xml.crypto/share/classes/javax/xml/crypto/package.html @@ -42,11 +42,7 @@ XML-Signature Syntax and Processing: W3C Recommendation RFC 3275: XML-Signature Syntax and Processing -

                                  -

                                  -
                                  Since:
                                  -
                                  1.6
                                  -
                                  +@since 1.6 diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java new file mode 100644 index 00000000000..7b0f8c29e06 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java @@ -0,0 +1,1526 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; +import javax.swing.*; +import javax.swing.event.*; +import sun.awt.AWTPermissions; + +/** + *

                                  The {@code AWTEventMonitor} implements a suite of listeners that are + * conditionally installed on every AWT component instance in the Java + * Virtual Machine. The events captured by these listeners are made + * available through a unified set of listeners supported by {@code AWTEventMonitor}. + * With this, all the individual events on each of the AWT component + * instances are funneled into one set of listeners broken down by category + * (see {@link EventID} for the categories). + *

                                  This class depends upon {@link EventQueueMonitor}, which provides the base + * level support for capturing the top-level containers as they are created. + */ + +@jdk.Exported +public class AWTEventMonitor { + + static private boolean runningOnJDK1_4 = false; + + /** + * The current component with keyboard focus. + * + * @see #getComponentWithFocus + * + * @deprecated This field is unused; to get the component with focus use the + * getComponentWithFocus method. + */ + @Deprecated + static protected Component componentWithFocus = null; + + static private Component componentWithFocus_private = null; + + // Low-level listeners + /** + * The current list of registered ComponentListener classes. + * + * @see #addComponentListener + * @see #removeComponentListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ComponentListener componentListener = null; + + static private ComponentListener componentListener_private = null; + + /** + * The current list of registered ContainerListener classes. + * + * @see #addContainerListener + * @see #removeContainerListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ContainerListener containerListener = null; + + static private ContainerListener containerListener_private = null; + + /** + * The current list of registered FocusListener classes. + * + * @see #addFocusListener + * @see #removeFocusListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected FocusListener focusListener = null; + + static private FocusListener focusListener_private = null; + + /** + * The current list of registered KeyListener classes. + * + * @see #addKeyListener + * @see #removeKeyListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected KeyListener keyListener = null; + + static private KeyListener keyListener_private = null; + + /** + * The current list of registered MouseListener classes. + * + * @see #addMouseListener + * @see #removeMouseListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected MouseListener mouseListener = null; + + static private MouseListener mouseListener_private = null; + + /** + * The current list of registered MouseMotionListener classes. + * + * @see #addMouseMotionListener + * @see #removeMouseMotionListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected MouseMotionListener mouseMotionListener = null; + + static private MouseMotionListener mouseMotionListener_private = null; + + /** + * The current list of registered WindowListener classes. + * + * @see #addWindowListener + * @see #removeWindowListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected WindowListener windowListener = null; + + static private WindowListener windowListener_private = null; + + + // Semantic listeners + /** + * The current list of registered ActionListener classes. + * + * @see #addActionListener + * @see #removeActionListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ActionListener actionListener = null; + + static private ActionListener actionListener_private = null; + + /** + * The current list of registered AdjustmentListener classes. + * + * @see #addAdjustmentListener + * @see #removeAdjustmentListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected AdjustmentListener adjustmentListener = null; + + static private AdjustmentListener adjustmentListener_private = null; + + /** + * The current list of registered ItemListener classes. + * + * @see #addItemListener + * @see #removeItemListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected ItemListener itemListener = null; + + static private ItemListener itemListener_private = null; + + /** + * The current list of registered TextListener classes. + * + * @see #addTextListener + * @see #removeTextListener + * + * @deprecated This field is unused. + */ + @Deprecated + static protected TextListener textListener = null; + + static private TextListener textListener_private = null; + + + /** + * The actual listener that is installed on the component instances. + * This listener calls the other registered listeners when an event + * occurs. By doing things this way, the actual number of listeners + * installed on a component instance is drastically reduced. + * + * @deprecated This field is unused. + */ + @Deprecated + static protected AWTEventsListener awtListener = new AWTEventsListener(); + + static private final AWTEventsListener awtListener_private = new AWTEventsListener(); + + /** + * Returns the component that currently has keyboard focus. The return + * value can be null. + * + * @return the component that has keyboard focus + */ + static public Component getComponentWithFocus() { + return componentWithFocus_private; + } + + /* + * Check permissions + */ + static private void checkInstallPermission() { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#COMPONENT COMPONENT} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeComponentListener + */ + static public void addComponentListener(ComponentListener l) { + if (componentListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.COMPONENT); + } + componentListener_private = AWTEventMulticaster.add(componentListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#COMPONENT COMPONENT} events when they occur. + * + * @param l the listener to remove + * @see #addComponentListener + */ + static public void removeComponentListener(ComponentListener l) { + componentListener_private = AWTEventMulticaster.remove(componentListener_private, l); + if (componentListener_private == null) { + awtListener_private.removeListeners(EventID.COMPONENT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#CONTAINER CONTAINER} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeContainerListener + */ + static public void addContainerListener(ContainerListener l) { + containerListener_private = AWTEventMulticaster.add(containerListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CONTAINER CONTAINER} events when they occur. + * + * @param l the listener to remove + * @see #addContainerListener + */ + static public void removeContainerListener(ContainerListener l) { + containerListener_private = AWTEventMulticaster.remove(containerListener_private, l); + } + + /** + * Adds the specified listener to receive all {@link EventID#FOCUS FOCUS} events + * on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeFocusListener + */ + static public void addFocusListener(FocusListener l) { + focusListener_private = AWTEventMulticaster.add(focusListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#FOCUS FOCUS} + * events when they occur. + * + * @param l the listener to remove + * @see #addFocusListener + */ + static public void removeFocusListener(FocusListener l) { + focusListener_private = AWTEventMulticaster.remove(focusListener_private, l); + } + + /** + * Adds the specified listener to receive all {@link EventID#KEY KEY} events on each + * component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeKeyListener + */ + static public void addKeyListener(KeyListener l) { + if (keyListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.KEY); + } + keyListener_private = AWTEventMulticaster.add(keyListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#KEY KEY} + * events when they occur. + * + * @param l the listener to remove + * @see #addKeyListener + */ + static public void removeKeyListener(KeyListener l) { + keyListener_private = AWTEventMulticaster.remove(keyListener_private, l); + if (keyListener_private == null) { + awtListener_private.removeListeners(EventID.KEY); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#MOUSE MOUSE} events + * on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeMouseListener + */ + static public void addMouseListener(MouseListener l) { + if (mouseListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.MOUSE); + } + mouseListener_private = AWTEventMulticaster.add(mouseListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#MOUSE MOUSE} events when they occur. + * + * @param l the listener to remove + * @see #addMouseListener + */ + static public void removeMouseListener(MouseListener l) { + mouseListener_private = AWTEventMulticaster.remove(mouseListener_private, l); + if (mouseListener_private == null) { + awtListener_private.removeListeners(EventID.MOUSE); + } + } + + /** + * Adds the specified listener to receive all mouse {@link EventID#MOTION MOTION} + * events on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeMouseMotionListener + */ + static public void addMouseMotionListener(MouseMotionListener l) { + if (mouseMotionListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.MOTION); + } + mouseMotionListener_private = AWTEventMulticaster.add(mouseMotionListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#MOTION MOTION} events when they occur. + * + * @param l the listener to remove + * @see #addMouseMotionListener + */ + static public void removeMouseMotionListener(MouseMotionListener l) { + mouseMotionListener_private = AWTEventMulticaster.remove(mouseMotionListener_private, l); + if (mouseMotionListener_private == null) { + awtListener_private.removeListeners(EventID.MOTION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#WINDOW WINDOW} + * events on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeWindowListener + */ + static public void addWindowListener(WindowListener l) { + if (windowListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.WINDOW); + } + windowListener_private = AWTEventMulticaster.add(windowListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#WINDOW WINDOW} events when they occur. + * + * @param l the listener to remove + * @see #addWindowListener + */ + static public void removeWindowListener(WindowListener l) { + windowListener_private = AWTEventMulticaster.remove(windowListener_private, l); + if (windowListener_private == null) { + awtListener_private.removeListeners(EventID.WINDOW); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#ACTION ACTION} + * events on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeActionListener + */ + static public void addActionListener(ActionListener l) { + if (actionListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.ACTION); + } + actionListener_private = AWTEventMulticaster.add(actionListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#ACTION ACTION} events when they occur. + * + * @param l the listener to remove + * @see #addActionListener + */ + static public void removeActionListener(ActionListener l) { + actionListener_private = AWTEventMulticaster.remove(actionListener_private, l); + if (actionListener_private == null) { + awtListener_private.removeListeners(EventID.ACTION); + } + } + + /** + * Adds the specified listener to receive all + * {@link EventID#ADJUSTMENT ADJUSTMENT} events on each component instance + * in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeAdjustmentListener + */ + static public void addAdjustmentListener(AdjustmentListener l) { + if (adjustmentListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.ADJUSTMENT); + } + adjustmentListener_private = AWTEventMulticaster.add(adjustmentListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#ADJUSTMENT ADJUSTMENT} events when they occur. + * + * @param l the listener to remove + * @see #addAdjustmentListener + */ + static public void removeAdjustmentListener(AdjustmentListener l) { + adjustmentListener_private = AWTEventMulticaster.remove(adjustmentListener_private, l); + if (adjustmentListener_private == null) { + awtListener_private.removeListeners(EventID.ADJUSTMENT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#ITEM ITEM} events + * on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeItemListener + */ + static public void addItemListener(ItemListener l) { + if (itemListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.ITEM); + } + itemListener_private = AWTEventMulticaster.add(itemListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#ITEM ITEM} + * events when they occur. + * + * @param l the listener to remove + * @see #addItemListener + */ + static public void removeItemListener(ItemListener l) { + itemListener_private = AWTEventMulticaster.remove(itemListener_private, l); + if (itemListener_private == null) { + awtListener_private.removeListeners(EventID.ITEM); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TEXT TEXT} events + * on each component instance in the Java Virtual Machine when they occur. + *

                                  Note: this listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTextListener + */ + static public void addTextListener(TextListener l) { + if (textListener_private == null) { + checkInstallPermission(); + awtListener_private.installListeners(EventID.TEXT); + } + textListener_private = AWTEventMulticaster.add(textListener_private, l); + } + + /** + * Removes the specified listener so it no longer receives {@link EventID#TEXT TEXT} + * events when they occur. + * + * @param l the listener to remove + * @see #addTextListener + */ + static public void removeTextListener(TextListener l) { + textListener_private = AWTEventMulticaster.remove(textListener_private, l); + if (textListener_private == null) { + awtListener_private.removeListeners(EventID.TEXT); + } + } + + + /** + * AWTEventsListener is the class that does all the work for AWTEventMonitor. + * It is not intended for use by any other class except AWTEventMonitor. + * + */ + + static class AWTEventsListener implements TopLevelWindowListener, + ActionListener, AdjustmentListener, ComponentListener, + ContainerListener, FocusListener, ItemListener, KeyListener, + MouseListener, MouseMotionListener, TextListener, WindowListener, + ChangeListener { + + /** + * internal variables for Action introspection + */ + private java.lang.Class[] actionListeners; + private java.lang.reflect.Method removeActionMethod; + private java.lang.reflect.Method addActionMethod; + private java.lang.Object[] actionArgs; + + /** + * internal variables for Item introspection + */ + private java.lang.Class[] itemListeners; + private java.lang.reflect.Method removeItemMethod; + private java.lang.reflect.Method addItemMethod; + private java.lang.Object[] itemArgs; + + /** + * internal variables for Text introspection + */ + private java.lang.Class[] textListeners; + private java.lang.reflect.Method removeTextMethod; + private java.lang.reflect.Method addTextMethod; + private java.lang.Object[] textArgs; + + /** + * internal variables for Window introspection + */ + private java.lang.Class[] windowListeners; + private java.lang.reflect.Method removeWindowMethod; + private java.lang.reflect.Method addWindowMethod; + private java.lang.Object[] windowArgs; + + /** + * Create a new instance of this class and install it on each component + * instance in the virtual machine that supports any of the currently + * registered listeners in AWTEventMonitor. Also registers itself + * as a TopLevelWindowListener with EventQueueMonitor so it can + * automatically add new listeners to new components. + * + * @see EventQueueMonitor + * @see AWTEventMonitor + */ + public AWTEventsListener() { + String version = System.getProperty("java.version"); + if (version != null) { + runningOnJDK1_4 = (version.compareTo("1.4") >= 0); + } + initializeIntrospection(); + installListeners(); + if (runningOnJDK1_4) { + MenuSelectionManager.defaultManager().addChangeListener(this); + } + EventQueueMonitor.addTopLevelWindowListener(this); + } + + /** + * Set up all of the variables needed for introspection + */ + private boolean initializeIntrospection() { + actionListeners = new java.lang.Class[1]; + actionArgs = new java.lang.Object[1]; + actionListeners[0] = java.awt.event.ActionListener.class; + actionArgs[0] = this; + + itemListeners = new java.lang.Class[1]; + itemArgs = new java.lang.Object[1]; + itemListeners[0] = java.awt.event.ItemListener.class; + itemArgs[0] = this; + + textListeners = new java.lang.Class[1]; + textArgs = new java.lang.Object[1]; + textListeners[0] = java.awt.event.TextListener.class; + textArgs[0] = this; + + windowListeners = new java.lang.Class[1]; + windowArgs = new java.lang.Object[1]; + windowListeners[0] = java.awt.event.WindowListener.class; + windowArgs[0] = this; + + return true; + } + + /** + * Installs all currently registered listeners on all components based + * upon the current topLevelWindows cached by EventQueueMonitor. + * + * @see EventQueueMonitor + * @see AWTEventMonitor + */ + protected void installListeners() { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + installListeners(topLevelWindows[i]); + } + } + } + + /** + * Installs listeners for the given event ID on all components based + * upon the current topLevelWindows cached by EventQueueMonitor. + * + * @param eventID the event ID + * @see EventID + */ + protected void installListeners(int eventID) { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + installListeners(topLevelWindows[i], eventID); + } + } + } + + /** + * Installs all currently registered listeners to just the component. + * @param c the component to add listeners to + */ + protected void installListeners(Component c) { + + // Container and focus listeners are always installed for our own use. + // + installListeners(c,EventID.CONTAINER); + installListeners(c,EventID.FOCUS); + + // conditionally install low-level listeners + // + if (AWTEventMonitor.componentListener_private != null) { + installListeners(c,EventID.COMPONENT); + } + if (AWTEventMonitor.keyListener_private != null) { + installListeners(c,EventID.KEY); + } + if (AWTEventMonitor.mouseListener_private != null) { + installListeners(c,EventID.MOUSE); + } + if (AWTEventMonitor.mouseMotionListener_private != null) { + installListeners(c,EventID.MOTION); + } + if (AWTEventMonitor.windowListener_private != null) { + installListeners(c,EventID.WINDOW); + } + + // conditionally install Semantic listeners + // + if (AWTEventMonitor.actionListener_private != null) { + installListeners(c,EventID.ACTION); + } + if (AWTEventMonitor.adjustmentListener_private != null) { + installListeners(c,EventID.ADJUSTMENT); + } + if (AWTEventMonitor.itemListener_private != null) { + installListeners(c,EventID.ITEM); + } + if (AWTEventMonitor.textListener_private != null) { + installListeners(c,EventID.TEXT); + } + } + + public void stateChanged(ChangeEvent e) { + processFocusGained(); + } + + private void processFocusGained() { + Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner == null) { + return; + } + MenuSelectionManager.defaultManager().removeChangeListener(this); + MenuSelectionManager.defaultManager().addChangeListener(this); + + // Only menus and popup selections are handled by the JRootPane. + if (focusOwner instanceof JRootPane) { + MenuElement [] path = + MenuSelectionManager.defaultManager().getSelectedPath(); + if (path.length > 1) { + Component penult = path[path.length-2].getComponent(); + Component last = path[path.length-1].getComponent(); + + if (last instanceof JPopupMenu || + last instanceof JMenu) { + // This is a popup with nothing in the popup + // selected. The menu itself is selected. + componentWithFocus_private = last; + } else if (penult instanceof JPopupMenu) { + // This is a popup with an item selected + componentWithFocus_private = penult; + } + } + } else { + // The focus owner has the selection. + componentWithFocus_private = focusOwner; + } + } + + /** + * Installs the given listener on the component and any of its children. + * As a precaution, it always attempts to remove itself as a listener + * first so it's always guaranteed to have installed itself just once. + * + * @param c the component to add listeners to + * @param eventID the eventID to add listeners for + * @see EventID + */ + protected void installListeners(Component c, int eventID) { + + // install the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.ACTION: + try { + removeActionMethod = c.getClass().getMethod( + "removeActionListener", actionListeners); + addActionMethod = c.getClass().getMethod( + "addActionListener", actionListeners); + try { + removeActionMethod.invoke(c, actionArgs); + addActionMethod.invoke(c, actionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.ADJUSTMENT: + if (c instanceof Adjustable) { + ((Adjustable) c).removeAdjustmentListener(this); + ((Adjustable) c).addAdjustmentListener(this); + } + break; + + case EventID.COMPONENT: + c.removeComponentListener(this); + c.addComponentListener(this); + break; + + case EventID.CONTAINER: + if (c instanceof Container) { + ((Container) c).removeContainerListener(this); + ((Container) c).addContainerListener(this); + } + break; + + case EventID.FOCUS: + c.removeFocusListener(this); + c.addFocusListener(this); + + if (runningOnJDK1_4) { + processFocusGained(); + + } else { // not runningOnJDK1_4 + if ((c != componentWithFocus_private) && c.hasFocus()) { + componentWithFocus_private = c; + } + } + break; + + case EventID.ITEM: + try { + removeItemMethod = c.getClass().getMethod( + "removeItemListener", itemListeners); + addItemMethod = c.getClass().getMethod( + "addItemListener", itemListeners); + try { + removeItemMethod.invoke(c, itemArgs); + addItemMethod.invoke(c, itemArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + // [PK] CheckboxMenuItem isn't a component but it does + // implement Interface ItemSelectable!! + // if (c instanceof CheckboxMenuItem) { + // ((CheckboxMenuItem) c).removeItemListener(this); + // ((CheckboxMenuItem) c).addItemListener(this); + break; + + case EventID.KEY: + c.removeKeyListener(this); + c.addKeyListener(this); + break; + + case EventID.MOUSE: + c.removeMouseListener(this); + c.addMouseListener(this); + break; + + case EventID.MOTION: + c.removeMouseMotionListener(this); + c.addMouseMotionListener(this); + break; + + case EventID.TEXT: + try { + removeTextMethod = c.getClass().getMethod( + "removeTextListener", textListeners); + addTextMethod = c.getClass().getMethod( + "addTextListener", textListeners); + try { + removeTextMethod.invoke(c, textArgs); + addTextMethod.invoke(c, textArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.WINDOW: + try { + removeWindowMethod = c.getClass().getMethod( + "removeWindowListener", windowListeners); + addWindowMethod = c.getClass().getMethod( + "addWindowListener", windowListeners); + try { + removeWindowMethod.invoke(c, windowArgs); + addWindowMethod.invoke(c, windowArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + // Don't bother recursing the children if this isn't going to + // accomplish anything. + // + default: + return; + } + + // if this component is a container, recurse through children + // + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + installListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /** + * Removes all listeners for the given event ID on all components based + * upon the topLevelWindows cached by EventQueueMonitor. + * + * @param eventID the event ID + * @see EventID + */ + protected void removeListeners(int eventID) { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + removeListeners(topLevelWindows[i], eventID); + } + } + } + + /** + * Removes all listeners for the given component and all its children. + * @param c the component + */ + protected void removeListeners(Component c) { + + // conditionally remove low-level listeners + // + if (AWTEventMonitor.componentListener_private != null) { + removeListeners(c,EventID.COMPONENT); + } + if (AWTEventMonitor.keyListener_private != null) { + removeListeners(c,EventID.KEY); + } + if (AWTEventMonitor.mouseListener_private != null) { + removeListeners(c,EventID.MOUSE); + } + if (AWTEventMonitor.mouseMotionListener_private != null) { + removeListeners(c,EventID.MOTION); + } + if (AWTEventMonitor.windowListener_private != null) { + removeListeners(c,EventID.WINDOW); + } + + // Remove semantic listeners + // + if (AWTEventMonitor.actionListener_private != null) { + removeListeners(c,EventID.ACTION); + } + if (AWTEventMonitor.adjustmentListener_private != null) { + removeListeners(c,EventID.ADJUSTMENT); + } + if (AWTEventMonitor.itemListener_private != null) { + removeListeners(c,EventID.ITEM); + } + if (AWTEventMonitor.textListener_private != null) { + removeListeners(c,EventID.TEXT); + } + } + + /** + * Removes all listeners for the event ID from the component and all + * of its children. + * + * @param c the component to remove listeners from + * @see EventID + */ + protected void removeListeners(Component c, int eventID) { + + // remove the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.ACTION: + try { + removeActionMethod = c.getClass().getMethod( + "removeActionListener", + actionListeners); + try { + removeActionMethod.invoke(c, actionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.ADJUSTMENT: + if (c instanceof Adjustable) { + ((Adjustable) c).removeAdjustmentListener(this); + } + break; + + case EventID.COMPONENT: + c.removeComponentListener(this); + break; + + // Never remove these because we're always interested in them + // for our own use. + //case EventID.CONTAINER: + // if (c instanceof Container) { + // ((Container) c).removeContainerListener(this); + // } + // break; + // + //case EventID.FOCUS: + // c.removeFocusListener(this); + // break; + + case EventID.ITEM: + try { + removeItemMethod = c.getClass().getMethod( + "removeItemListener", itemListeners); + try { + removeItemMethod.invoke(c, itemArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + // [PK] CheckboxMenuItem isn't a component but it does + // implement Interface ItemSelectable!! + // if (c instanceof CheckboxMenuItem) { + // ((CheckboxMenuItem) c).removeItemListener(this); + break; + + case EventID.KEY: + c.removeKeyListener(this); + break; + + case EventID.MOUSE: + c.removeMouseListener(this); + break; + + case EventID.MOTION: + c.removeMouseMotionListener(this); + break; + + case EventID.TEXT: + try { + removeTextMethod = c.getClass().getMethod( + "removeTextListener", textListeners); + try { + removeTextMethod.invoke(c, textArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.WINDOW: + try { + removeWindowMethod = c.getClass().getMethod( + "removeWindowListener", windowListeners); + try { + removeWindowMethod.invoke(c, windowArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + default: + return; + } + + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + removeListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /********************************************************************/ + /* */ + /* Listener Interface Methods */ + /* */ + /********************************************************************/ + + /* TopLevelWindow Methods ***************************************/ + + /** + * Called when top level window is created. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowCreated(Window w) { + installListeners(w); + } + + /** + * Called when top level window is destroyed. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowDestroyed(Window w) { + } + + /* ActionListener Methods ***************************************/ + + /** + * Called when an action is performed. + * + * @see AWTEventMonitor#addActionListener + */ + public void actionPerformed(ActionEvent e) { + if (AWTEventMonitor.actionListener_private != null) { + AWTEventMonitor.actionListener_private.actionPerformed(e); + } + } + + /* AdjustmentListener Methods ***********************************/ + + /** + * Called when an adjustment is made. + * + * @see AWTEventMonitor#addAdjustmentListener + */ + public void adjustmentValueChanged(AdjustmentEvent e) { + if (AWTEventMonitor.adjustmentListener_private != null) { + AWTEventMonitor.adjustmentListener_private.adjustmentValueChanged(e); + } + } + + /* ComponentListener Methods ************************************/ + + /** + * Called when a component is hidden. + * + * @see AWTEventMonitor#addComponentListener + */ + public void componentHidden(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentHidden(e); + } + } + + /** + * Called when a component is moved. + * + * @see AWTEventMonitor#addComponentListener + */ + public void componentMoved(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentMoved(e); + } + } + + /** + * Called when a component is resized. + * + * @see AWTEventMonitor#addComponentListener + */ + public void componentResized(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentResized(e); + } + } + + /** + * Called when a component is shown. + * + * @see AWTEventMonitor#addComponentListener + */ + public void componentShown(ComponentEvent e) { + if (AWTEventMonitor.componentListener_private != null) { + AWTEventMonitor.componentListener_private.componentShown(e); + } + } + + /* ContainerListener Methods ************************************/ + + /** + * Called when a component is added to a container. + * + * @see AWTEventMonitor#addContainerListener + */ + public void componentAdded(ContainerEvent e) { + installListeners(e.getChild()); + if (AWTEventMonitor.containerListener_private != null) { + AWTEventMonitor.containerListener_private.componentAdded(e); + } + } + + /** + * Called when a component is removed from a container. + * + * @see AWTEventMonitor#addContainerListener + */ + public void componentRemoved(ContainerEvent e) { + removeListeners(e.getChild()); + if (AWTEventMonitor.containerListener_private != null) { + AWTEventMonitor.containerListener_private.componentRemoved(e); + } + } + + /* FocusListener Methods ****************************************/ + + /** + * Called when a component gains keyboard focus. + * + * @see AWTEventMonitor#addFocusListener + */ + public void focusGained(FocusEvent e) { + AWTEventMonitor.componentWithFocus_private = (Component) e.getSource(); + if (AWTEventMonitor.focusListener_private != null) { + AWTEventMonitor.focusListener_private.focusGained(e); + } + } + + /** + * Called when a component loses keyboard focus. + * + * @see AWTEventMonitor#addFocusListener + */ + public void focusLost(FocusEvent e) { + AWTEventMonitor.componentWithFocus_private = null; + if (AWTEventMonitor.focusListener_private != null) { + AWTEventMonitor.focusListener_private.focusLost(e); + } + } + + /* ItemListener Methods *****************************************/ + + /** + * Called when an item's state changes. + * + * @see AWTEventMonitor#addItemListener + */ + public void itemStateChanged(ItemEvent e) { + if (AWTEventMonitor.itemListener_private != null) { + AWTEventMonitor.itemListener_private.itemStateChanged(e); + } + } + + /* KeyListener Methods ******************************************/ + + /** + * Called when a key is pressed. + * + * @see AWTEventMonitor#addKeyListener + */ + public void keyPressed(KeyEvent e) { + if (AWTEventMonitor.keyListener_private != null) { + AWTEventMonitor.keyListener_private.keyPressed(e); + } + } + + /** + * Called when a key is typed. + * + * @see AWTEventMonitor#addKeyListener + */ + public void keyReleased(KeyEvent e) { + if (AWTEventMonitor.keyListener_private != null) { + AWTEventMonitor.keyListener_private.keyReleased(e); + } + } + + /** + * Called when a key is released. + * + * @see AWTEventMonitor#addKeyListener + */ + public void keyTyped(KeyEvent e) { + if (AWTEventMonitor.keyListener_private != null) { + AWTEventMonitor.keyListener_private.keyTyped(e); + } + } + + /* MouseListener Methods ****************************************/ + + /** + * Called when the mouse is clicked. + * + * @see AWTEventMonitor#addMouseListener + */ + public void mouseClicked(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseClicked(e); + } + } + + /** + * Called when the mouse enters a component. + * + * @see AWTEventMonitor#addMouseListener + */ + public void mouseEntered(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseEntered(e); + } + } + + /** + * Called when the mouse leaves a component. + * + * @see AWTEventMonitor#addMouseListener + */ + public void mouseExited(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseExited(e); + } + } + + /** + * Called when the mouse is pressed. + * + * @see AWTEventMonitor#addMouseListener + */ + public void mousePressed(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mousePressed(e); + } + } + + /** + * Called when the mouse is released. + * + * @see AWTEventMonitor#addMouseListener + */ + public void mouseReleased(MouseEvent e) { + if (AWTEventMonitor.mouseListener_private != null) { + AWTEventMonitor.mouseListener_private.mouseReleased(e); + } + } + + /* MouseMotionListener Methods **********************************/ + + /** + * Called when the mouse is dragged. + * + * @see AWTEventMonitor#addMouseMotionListener + */ + public void mouseDragged(MouseEvent e) { + if (AWTEventMonitor.mouseMotionListener_private != null) { + AWTEventMonitor.mouseMotionListener_private.mouseDragged(e); + } + } + + /** + * Called when the mouse is moved. + * + * @see AWTEventMonitor#addMouseMotionListener + */ + public void mouseMoved(MouseEvent e) { + if (AWTEventMonitor.mouseMotionListener_private != null) { + AWTEventMonitor.mouseMotionListener_private.mouseMoved(e); + } + } + + /* TextListener Methods *****************************************/ + + /** + * Called when a component's text value changed. + * + * @see AWTEventMonitor#addTextListener + */ + public void textValueChanged(TextEvent e) { + if (AWTEventMonitor.textListener_private != null) { + AWTEventMonitor.textListener_private.textValueChanged(e); + } + } + + /* WindowListener Methods ***************************************/ + + /** + * Called when a window is opened. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowOpened(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowOpened(e); + } + } + + /** + * Called when a window is in the process of closing. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowClosing(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowClosing(e); + } + } + + /** + * Called when a window is closed. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowClosed(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowClosed(e); + } + } + + /** + * Called when a window is iconified. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowIconified(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowIconified(e); + } + } + + /** + * Called when a window is deiconified. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowDeiconified(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowDeiconified(e); + } + } + + /** + * Called when a window is activated. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowActivated(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowActivated(e); + } + } + + /** + * Called when a window is deactivated. + * + * @see AWTEventMonitor#addWindowListener + */ + public void windowDeactivated(WindowEvent e) { + if (AWTEventMonitor.windowListener_private != null) { + AWTEventMonitor.windowListener_private.windowDeactivated(e); + } + } + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java new file mode 100644 index 00000000000..4719e7c12de --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityEventMonitor.java @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.beans.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; + +/** + *

                                  {@code AccessibilityEventMonitor} implements a PropertyChange listener + * on every UI object that implements interface {@code Accessible} in the Java + * Virtual Machine. The events captured by these listeners are made available + * through listeners supported by {@code AccessibilityEventMonitor}. + * With this, all the individual events on each of the UI object + * instances are funneled into one set of PropertyChange listeners. + *

                                  This class depends upon {@link EventQueueMonitor}, which provides the base + * level support for capturing the top-level containers as they are created. + * + */ + +@jdk.Exported +public class AccessibilityEventMonitor { + + // listeners + /** + * The current list of registered {@link java.beans.PropertyChangeListener + * PropertyChangeListener} classes. + * + * @see #addPropertyChangeListener + * @see #removePropertyChangeListener + */ + static protected final AccessibilityListenerList listenerList = + new AccessibilityListenerList(); + + + /** + * The actual listener that is installed on the component instances. + * This listener calls the other registered listeners when an event + * occurs. By doing things this way, the actual number of listeners + * installed on a component instance is drastically reduced. + */ + static protected final AccessibilityEventListener accessibilityListener = + new AccessibilityEventListener(); + + /** + * Adds the specified listener to receive all PropertyChange events on + * each UI object instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to UI object instances that support this listener type. + * + * @param l the listener to add + * + * @see #removePropertyChangeListener + */ + static public void addPropertyChangeListener(PropertyChangeListener l) { + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + accessibilityListener.installListeners(); + } + listenerList.add(PropertyChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives PropertyChange + * events when they occur. + * @see #addPropertyChangeListener + * @param l the listener to remove + */ + static public void removePropertyChangeListener(PropertyChangeListener l) { + listenerList.remove(PropertyChangeListener.class, l); + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + accessibilityListener.removeListeners(); + } + } + + + /** + * AccessibilityEventListener is the class that does all the work for + * AccessibilityEventMonitor. It is not intended for use by any other + * class except AccessibilityEventMonitor. + * + */ + + static class AccessibilityEventListener implements TopLevelWindowListener, + PropertyChangeListener { + + /** + * Create a new instance of this class and install it on each component + * instance in the virtual machine that supports any of the currently + * registered listeners in AccessibilityEventMonitor. Also registers + * itself as a TopLevelWindowListener with EventQueueMonitor so it can + * automatically add new listeners to new components. + * @see EventQueueMonitor + * @see AccessibilityEventMonitor + */ + public AccessibilityEventListener() { + EventQueueMonitor.addTopLevelWindowListener(this); + } + + /** + * Installs PropertyChange listeners on all Accessible objects based + * upon the current topLevelWindows cached by EventQueueMonitor. + * @see EventQueueMonitor + * @see AWTEventMonitor + */ + protected void installListeners() { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + if (topLevelWindows[i] instanceof Accessible) { + installListeners((Accessible) topLevelWindows[i]); + } + } + } + } + + /** + * Installs PropertyChange listeners to the Accessible object, and it's + * children (so long as the object isn't of TRANSIENT state). + * @param a the Accessible object to add listeners to + */ + protected void installListeners(Accessible a) { + installListeners(a.getAccessibleContext()); + } + + /** + * Installs PropertyChange listeners to the AccessibleContext object, + * and it's * children (so long as the object isn't of TRANSIENT state). + * @param a the Accessible object to add listeners to + */ + private void installListeners(AccessibleContext ac) { + + if (ac != null) { + AccessibleStateSet states = ac.getAccessibleStateSet(); + if (!states.contains(AccessibleState.TRANSIENT)) { + ac.addPropertyChangeListener(this); + /* + * Don't add listeners to transient children. Components + * with transient children should return an AccessibleStateSet + * containing AccessibleState.MANAGES_DESCENDANTS. Components + * may not explicitly return the MANAGES_DESCENDANTS state. + * In this case, don't add listeners to the children of + * lists, tables and trees. + */ + AccessibleStateSet set = ac.getAccessibleStateSet(); + if (set.contains(_AccessibleState.MANAGES_DESCENDANTS)) { + return; + } + AccessibleRole role = ac.getAccessibleRole(); + if (role == AccessibleRole.LIST || + role == AccessibleRole.TREE) { + return; + } + if (role == AccessibleRole.TABLE) { + // handle Oracle tables containing tables + Accessible child = ac.getAccessibleChild(0); + if (child != null) { + AccessibleContext ac2 = child.getAccessibleContext(); + if (ac2 != null) { + role = ac2.getAccessibleRole(); + if (role != null && role != AccessibleRole.TABLE) { + return; + } + } + } + } + int count = ac.getAccessibleChildrenCount(); + for (int i = 0; i < count; i++) { + Accessible child = ac.getAccessibleChild(i); + if (child != null) { + installListeners(child); + } + } + } + } + } + + /** + * Removes PropertyChange listeners on all Accessible objects based + * upon the topLevelWindows cached by EventQueueMonitor. + * @param eventID the event ID + * @see EventID + */ + protected void removeListeners() { + Window topLevelWindows[] = EventQueueMonitor.getTopLevelWindows(); + if (topLevelWindows != null) { + for (int i = 0; i < topLevelWindows.length; i++) { + if (topLevelWindows[i] instanceof Accessible) { + removeListeners((Accessible) topLevelWindows[i]); + } + } + } + } + + /** + * Removes PropertyChange listeners for the given Accessible object, + * it's children (so long as the object isn't of TRANSIENT state). + * @param a the Accessible object to remove listeners from + */ + protected void removeListeners(Accessible a) { + removeListeners(a.getAccessibleContext()); + } + + /** + * Removes PropertyChange listeners for the given AccessibleContext + * object, it's children (so long as the object isn't of TRANSIENT + * state). + * @param a the Accessible object to remove listeners from + */ + private void removeListeners(AccessibleContext ac) { + + + if (ac != null) { + // Listeners are not added to transient components. + AccessibleStateSet states = ac.getAccessibleStateSet(); + if (!states.contains(AccessibleState.TRANSIENT)) { + ac.removePropertyChangeListener(this); + /* + * Listeners are not added to transient children. Components + * with transient children should return an AccessibleStateSet + * containing AccessibleState.MANAGES_DESCENDANTS. Components + * may not explicitly return the MANAGES_DESCENDANTS state. + * In this case, don't remove listeners from the children of + * lists, tables and trees. + */ + if (states.contains(_AccessibleState.MANAGES_DESCENDANTS)) { + return; + } + AccessibleRole role = ac.getAccessibleRole(); + if (role == AccessibleRole.LIST || + role == AccessibleRole.TABLE || + role == AccessibleRole.TREE) { + return; + } + int count = ac.getAccessibleChildrenCount(); + for (int i = 0; i < count; i++) { + Accessible child = ac.getAccessibleChild(i); + if (child != null) { + removeListeners(child); + } + } + } + } + } + + /********************************************************************/ + /* */ + /* Listener Interface Methods */ + /* */ + /********************************************************************/ + + /* TopLevelWindow Methods ***************************************/ + + /** + * Called when top level window is created. + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowCreated(Window w) { + if (w instanceof Accessible) { + installListeners((Accessible) w); + } + } + + /** + * Called when top level window is destroyed. + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + */ + public void topLevelWindowDestroyed(Window w) { + if (w instanceof Accessible) { + removeListeners((Accessible) w); + } + } + + + /* PropertyChangeListener Methods **************************************/ + + public void propertyChange(PropertyChangeEvent e) { + // propogate the event + Object[] listeners = + AccessibilityEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PropertyChangeListener.class) { + ((PropertyChangeListener)listeners[i+1]).propertyChange(e); + } + } + + // handle childbirth/death + String name = e.getPropertyName(); + if (name.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) { + Object oldValue = e.getOldValue(); + Object newValue = e.getNewValue(); + + if ((oldValue == null) ^ (newValue == null)) { // one null, not both + if (oldValue != null) { + // this Accessible is a child that's going away + if (oldValue instanceof Accessible) { + Accessible a = (Accessible) oldValue; + removeListeners(a.getAccessibleContext()); + } else if (oldValue instanceof AccessibleContext) { + removeListeners((AccessibleContext) oldValue); + } + } else if (newValue != null) { + // this Accessible is a child was just born + if (newValue instanceof Accessible) { + Accessible a = (Accessible) newValue; + installListeners(a.getAccessibleContext()); + } else if (newValue instanceof AccessibleContext) { + installListeners((AccessibleContext) newValue); + } + } + } else { + System.out.println("ERROR in usage of PropertyChangeEvents for: " + e.toString()); + } + } + } + } +} + +/* + * workaround for no public AccessibleState constructor + */ +class _AccessibleState extends AccessibleState { + /** + * Indicates this object is responsible for managing its + * subcomponents. This is typically used for trees and tables + * that have a large number of subcomponents and where the + * objects are created only when needed and otherwise remain virtual. + * The application should not manage the subcomponents directly. + */ + public static final _AccessibleState MANAGES_DESCENDANTS + = new _AccessibleState ("managesDescendants"); + + /** + * Creates a new AccessibleState using the given locale independent key. + * This should not be a public method. Instead, it is used to create + * the constants in this file to make it a strongly typed enumeration. + * Subclasses of this class should enforce similar policy. + *

                                  + * The key String should be a locale independent key for the state. + * It is not intended to be used as the actual String to display + * to the user. To get the localized string, use toDisplayString. + * + * @param key the locale independent name of the state. + * @see AccessibleBundle#toDisplayString + */ + protected _AccessibleState(String key) { + super(key); + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java new file mode 100644 index 00000000000..76c7147ea09 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AccessibilityListenerList.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.beans.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; + +/** + *

                                  The {@code AccessibilityListenerList} is a copy of the Swing + * {@link javax.swing.event.EventListenerList EventListerList} class. + * + */ + +@jdk.Exported +public class AccessibilityListenerList { + /* A null array to be shared by all empty listener lists */ + private final static Object[] NULL_ARRAY = new Object[0]; + + /** + * The list of listener type, listener pairs + */ + protected transient Object[] listenerList = NULL_ARRAY; + + /** + * Passes back the event listener list as an array of listener type, listener pairs. + * Note that for performance reasons, this implementation passes back the actual + * data structure in which the listener data is stored internally. This method + * is guaranteed to pass back a non-null array, so that no null-checking + * is required in fire methods. A zero-length array of Object is returned if + * there are currently no listeners. + *

                                  + * Absolutely no modification of the data contained in this array should be + * made. If any such manipulation is necessary, it should be done on a copy + * of the array returned rather than the array itself. + * + * @return an array of listener type, listener pairs. + */ + public Object[] getListenerList() { + return listenerList; + } + + /** + * Returns the total number of listeners for this listener list. + * + * @return the total number of listeners for this listener list. + */ + public int getListenerCount() { + return listenerList.length/2; + } + + /** + * Return the total number of listeners of the supplied type + * for this listener list. + * + * @param t the type of the listener to be counted + * @return the number of listeners found + */ + public int getListenerCount(Class t) { + int count = 0; + Object[] lList = listenerList; + for (int i = 0; i < lList.length; i+=2) { + if (t == (Class)lList[i]) + count++; + } + return count; + } + + /** + * Add the listener as a listener of the specified type. + * + * @param t the type of the listener to be added + * @param l the listener to be added + */ + public synchronized void add(Class t, EventListener l) { + if (!t.isInstance(l)) { + throw new IllegalArgumentException("Listener " + l + + " is not of type " + t); + } + if (l ==null) { + throw new IllegalArgumentException("Listener " + l + + " is null"); + } + if (listenerList == NULL_ARRAY) { + // if this is the first listener added, + // initialize the lists + listenerList = new Object[] { t, l }; + } else { + // Otherwise copy the array and add the new listener + int i = listenerList.length; + Object[] tmp = new Object[i+2]; + System.arraycopy(listenerList, 0, tmp, 0, i); + + tmp[i] = t; + tmp[i+1] = l; + + listenerList = tmp; + } + } + + /** + * Remove the listener as a listener of the specified type. + * + * @param t the type of the listener to be removed + * @param l the listener to be removed + */ + public synchronized void remove(Class t, EventListener l) { + if (!t.isInstance(l)) { + throw new IllegalArgumentException("Listener " + l + + " is not of type " + t); + } + if (l ==null) { + throw new IllegalArgumentException("Listener " + l + + " is null"); + } + + // Is l on the list? + int index = -1; + for (int i = listenerList.length-2; i>=0; i-=2) { + if ((listenerList[i]==t) && (listenerList[i+1] == l)) { + index = i; + break; + } + } + + // If so, remove it + if (index != -1) { + Object[] tmp = new Object[listenerList.length-2]; + // Copy the list up to index + System.arraycopy(listenerList, 0, tmp, 0, index); + // Copy from two past the index, up to + // the end of tmp (which is two elements + // shorter than the old list) + if (index < tmp.length) + System.arraycopy(listenerList, index+2, tmp, index, + tmp.length - index); + // set the listener array to the new array or null + listenerList = (tmp.length == 0) ? NULL_ARRAY : tmp; + } + } + + /** + * Return a string representation of the {@code AccessibilityListenerList}. + * + * @return a string representation of the {@code AccessibilityListenerList}. + */ + public String toString() { + Object[] lList = listenerList; + String s = "EventListenerList: "; + s += lList.length/2 + " listeners: "; + for (int i = 0 ; i <= lList.length-2 ; i+=2) { + s += " type " + ((Class)lList[i]).getName(); + s += " listener " + lList[i+1]; + } + return s; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventID.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventID.java new file mode 100644 index 00000000000..bbd08f534e9 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventID.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +/** + * EventID contains integer constants that map to event support in + * AWT and Swing. They are used by primarily by AWTEventMonitor, + * AWTEventsListener, SwingEventMonitor, and SwingEventListener, but + * can be freely used by any other class. + * + * @see AWTEventMonitor + * @see SwingEventMonitor + * + */ +@jdk.Exported +public class EventID { + + /** + * Maps to AWT Action support (i.e., ActionListener and ActionEvent) + */ + static public final int ACTION = 0; + + /** + * Maps to AWT Adjustment support (i.e., AdjustmentListener + * and AdjustmentEvent) + */ + static public final int ADJUSTMENT = 1; + + /** + * Maps to AWT Component support (i.e., ComponentListener + * and ComponentEvent) + */ + static public final int COMPONENT = 2; + + /** + * Maps to AWT Container support (i.e., ContainerListener + * and ContainerEvent) + */ + static public final int CONTAINER = 3; + + /** + * Maps to AWT Focus support (i.e., FocusListener and FocusEvent) + */ + static public final int FOCUS = 4; + + /** + * Maps to AWT Item support (i.e., ItemListener and ItemEvent) + */ + static public final int ITEM = 5; + + /** + * Maps to AWT Key support (i.e., KeyListener and KeyEvent) + */ + static public final int KEY = 6; + + /** + * Maps to AWT Mouse support (i.e., MouseListener and MouseEvent) + */ + static public final int MOUSE = 7; + + /** + * Maps to AWT MouseMotion support (i.e., MouseMotionListener + * and MouseMotionEvent) + */ + static public final int MOTION = 8; + + /** + * Maps to AWT Text support (i.e., TextListener and TextEvent) + */ + static public final int TEXT = 10; + + /** + * Maps to AWT Window support (i.e., WindowListener and WindowEvent) + */ + static public final int WINDOW = 11; + + /** + * Maps to Swing Ancestor support (i.e., AncestorListener and + * AncestorEvent) + */ + static public final int ANCESTOR = 12; + + /** + * Maps to Swing Text Caret support (i.e., CaretListener and + * CaretEvent) + */ + static public final int CARET = 13; + + /** + * Maps to Swing CellEditor support (i.e., CellEditorListener and + * CellEditorEvent) + */ + static public final int CELLEDITOR = 14; + + /** + * Maps to Swing Change support (i.e., ChangeListener and + * ChangeEvent) + */ + static public final int CHANGE = 15; + + /** + * Maps to Swing TableColumnModel support (i.e., + * TableColumnModelListener and TableColumnModelEvent) + */ + static public final int COLUMNMODEL = 16; + + /** + * Maps to Swing Document support (i.e., DocumentListener and + * DocumentEvent) + */ + static public final int DOCUMENT = 17; + + /** + * Maps to Swing ListData support (i.e., ListDataListener and + * ListDataEvent) + */ + static public final int LISTDATA = 18; + + /** + * Maps to Swing ListSelection support (i.e., ListSelectionListener and + * ListSelectionEvent) + */ + static public final int LISTSELECTION = 19; + + /** + * Maps to Swing Menu support (i.e., MenuListener and + * MenuEvent) + */ + static public final int MENU = 20; + + /** + * Maps to Swing PopupMenu support (i.e., PopupMenuListener and + * PopupMenuEvent) + */ + static public final int POPUPMENU = 21; + + /** + * Maps to Swing TableModel support (i.e., TableModelListener and + * TableModelEvent) + */ + static public final int TABLEMODEL = 22; + + /** + * Maps to Swing TreeExpansion support (i.e., TreeExpansionListener and + * TreeExpansionEvent) + */ + static public final int TREEEXPANSION = 23; + + /** + * Maps to Swing TreeModel support (i.e., TreeModelListener and + * TreeModelEvent) + */ + static public final int TREEMODEL = 24; + + /** + * Maps to Swing TreeSelection support (i.e., TreeSelectionListener and + * TreeSelectionEvent) + */ + static public final int TREESELECTION = 25; + + /** + * Maps to Swing UndoableEdit support (i.e., UndoableEditListener and + * UndoableEditEvent) + */ + static public final int UNDOABLEEDIT = 26; + + /** + * Maps to Beans PropertyChange support (i.e., PropertyChangeListener + * and PropertyChangeEvent) + */ + static public final int PROPERTYCHANGE = 27; + + /** + * Maps to Beans VetoableChange support (i.e., VetoableChangeListener + * and VetoableChangeEvent) + */ + static public final int VETOABLECHANGE = 28; + + /** + * Maps to Swing InternalFrame support (i.e., InternalFrameListener) + */ + static public final int INTERNALFRAME = 29; +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java new file mode 100644 index 00000000000..aa87860bb48 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.accessibility.*; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * The {@code EventQueueMonitor} class provides key core functionality for Assistive + * Technologies (and other system-level technologies that need some of the same + * things that Assistive Technology needs). + * + * @see AWTEventMonitor + * @see SwingEventMonitor + */ +@jdk.Exported +public class EventQueueMonitor + implements AWTEventListener { + + // NOTE: All of the following properties are static. The reason + // for this is that there may be multiple EventQueue instances + // in use in the same VM. By making these properties static, + // we can guarantee we get the information from all of the + // EventQueue instances. + + // The stuff that is cached. + // + static VectortopLevelWindows = new Vector<>(); + static Window topLevelWindowWithFocus = null; + static Point currentMousePosition = null; + static Component currentMouseComponent = null; + + // Low-level listener interfaces + // + static GUIInitializedListener guiInitializedListener = null; + static TopLevelWindowListener topLevelWindowListener = null; + static MouseMotionListener mouseMotionListener = null; + + /** + * Class variable stating whether the assistive technologies have + * been loaded yet or not. The assistive technologies won't be + * loaded until the first event is posted to the EventQueue. This + * gives the toolkit a chance to do all the necessary initialization + * it needs to do. + */ + + /** + * Class variable stating whether the GUI subsystem has been initialized + * or not. + * + * @see #isGUIInitialized + */ + static boolean guiInitialized = false; + + /** + * Queue that holds events for later processing. + */ + static EventQueueMonitorItem componentEventQueue = null; + + /** + * Class that tells us what the component event dispatch thread is. + */ + static private ComponentEvtDispatchThread cedt = null; + + /** + * Handle the synchronization between the thing that populates the + * component event dispatch thread ({@link #queueComponentEvent}) + * and the thing that processes the events ({@link ComponentEvtDispatchThread}). + */ + static Object componentEventQueueLock = new Object(); + + /** + * Create a new {@code EventQueueMonitor} instance. Normally, this will + * be called only by the AWT Toolkit during initialization time. + * Assistive technologies should not create instances of + * EventQueueMonitor by themselves. Instead, they should either + * refer to it directly via the static methods in this class, e.g., + * {@link #getCurrentMousePosition} or obtain the instance by asking the + * Toolkit, e.g., {@link java.awt.Toolkit#getSystemEventQueue}. + */ + public EventQueueMonitor() { + if (cedt == null) { + cedt = new ComponentEvtDispatchThread("EventQueueMonitor-ComponentEvtDispatch"); + + cedt.setDaemon(true); + cedt.start(); + } + } + + /** + * Queue up a {@link java.awt.event.ComponentEvent ComponentEvent} for later + * processing by the {@link ComponentEvtDispatch} thread. + * + * @param e a {@code ComponentEvent} + */ + static void queueComponentEvent(ComponentEvent e) { + synchronized(componentEventQueueLock) { + EventQueueMonitorItem eqi = new EventQueueMonitorItem(e); + if (componentEventQueue == null) { + componentEventQueue = eqi; + } else { + EventQueueMonitorItem q = componentEventQueue; + while (true) { + if (q.next != null) { + q = q.next; + } else { + break; + } + } + q.next = eqi; + } + componentEventQueueLock.notifyAll(); + } + } + + /** + * Tell the {@code EventQueueMonitor} to start listening for events. + */ + public static void maybeInitialize() { + if (cedt == null) { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + try { + long eventMask = AWTEvent.WINDOW_EVENT_MASK | + AWTEvent.FOCUS_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK; + + Toolkit.getDefaultToolkit().addAWTEventListener(new EventQueueMonitor(), eventMask); + } catch (Exception e) { + } + return null; + } + } + ); + } + } + + /** + * Handle events as a result of registering a listener + * on the {@link java.awt.EventQueue EventQueue} in {@link #maybeInitialize}. + */ + public void eventDispatched(AWTEvent theEvent) { + processEvent(theEvent); + } + + /** + * Assisitive technologies that have + * registered a {@link GUIInitializedListener} will be notified. + * + * @see #addGUIInitializedListener + */ + static void maybeNotifyAssistiveTechnologies() { + + if (!guiInitialized) { + guiInitialized = true; + if (guiInitializedListener != null) { + guiInitializedListener.guiInitialized(); + } + } + + } + + /********************************************************************/ + /* */ + /* Package Private Methods */ + /* */ + /********************************************************************/ + + /** + * Add a Container to the list of top-level containers + * in the cache. This follows the object's hierarchy up the + * tree until it finds the top most parent. If the parent is + * not already in the list of Containers, it adds it to the list. + * + * @param c the Container + */ + static void addTopLevelWindow(Component c) { + Container parent; + + if (c == null) { + return; + } + + if (!(c instanceof Window)) { + addTopLevelWindow(c.getParent()); + return; + } + + if ((c instanceof Dialog) || (c instanceof Window)) { + parent = (Container) c; + } else { + parent = c.getParent(); + if (parent != null) { + addTopLevelWindow(parent); + return; + } + } + + if (parent == null) { + parent = (Container) c; + } + + // Because this method is static, do not make it synchronized because + // it can lock the whole class. Instead, just lock what needs to be + // locked. + // + synchronized (topLevelWindows) { + if ((parent != null) && !topLevelWindows.contains(parent)) { + topLevelWindows.addElement(parent); + if (topLevelWindowListener != null) { + topLevelWindowListener.topLevelWindowCreated((Window) parent); + } + } + } + } + + /** + * Removes a container from the list of top level containers in the cache. + * + * @param c the top level container to remove + */ + static void removeTopLevelWindow(Window w) { + + // Because this method is static, do not make it synchronized because + // it can lock the whole class. Instead, just lock what needs to be + // locked. + // + synchronized (topLevelWindows) { + if (topLevelWindows.contains(w)) { + topLevelWindows.removeElement(w); + if (topLevelWindowListener != null) { + topLevelWindowListener.topLevelWindowDestroyed(w); + } + } + } + } + + /** + * Update current mouse position. + * + * @param mouseEvent the MouseEvent that holds the new mouse position. + */ + static void updateCurrentMousePosition(MouseEvent mouseEvent) { + Point oldMousePos = currentMousePosition; + // Be careful here. The component in the event might be + // hidden by the time we process the event. + try { + Point eventPoint = mouseEvent.getPoint(); + currentMouseComponent = (Component) (mouseEvent.getSource()); + currentMousePosition = currentMouseComponent.getLocationOnScreen(); + currentMousePosition.translate(eventPoint.x,eventPoint.y); + } catch (Exception e) { + currentMousePosition = oldMousePos; + } + } + + /** + * Process the event. This maintains the event cache in addition + * to calling all the registered listeners. NOTE: The events that + * come through here are from peered Components. + * + * @param theEvent the AWTEvent + */ + static void processEvent(AWTEvent theEvent) { + switch (theEvent.getID()) { + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + case FocusEvent.FOCUS_GAINED: + case WindowEvent.WINDOW_DEACTIVATED: + queueComponentEvent((ComponentEvent) theEvent); + break; + + case WindowEvent.WINDOW_ACTIVATED: + // Dialogs fire WINDOW_ACTIVATED and FOCUS_GAINED events + // before WINDOW_OPENED so we need to add topLevelListeners + // for the dialog when it is first activated to get a + // focus gained event for the focus component in the dialog. + if (theEvent instanceof ComponentEvent) { + ComponentEvent ce = (ComponentEvent)theEvent; + if (ce.getComponent() instanceof Window) { + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + } else { + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + } + } + queueComponentEvent((ComponentEvent) theEvent); + break; + + // handle WINDOW_OPENED and WINDOW_CLOSED events synchronously + case WindowEvent.WINDOW_OPENED: + if (theEvent instanceof ComponentEvent) { + ComponentEvent ce = (ComponentEvent)theEvent; + if (ce.getComponent() instanceof Window) { + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + } else { + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + EventQueueMonitor.addTopLevelWindow(ce.getComponent()); + } + } + break; + case WindowEvent.WINDOW_CLOSED: + if (theEvent instanceof ComponentEvent) { + ComponentEvent ce = (ComponentEvent)theEvent; + EventQueueMonitor.removeTopLevelWindow((Window) (ce.getComponent())); + } + break; + + default: + break; + } + } + + /** + * Internal test + */ + static synchronized Component getShowingComponentAt(Container c, int x, int y) { + if (!c.contains(x, y)) { + return null; + } + int ncomponents = c.getComponentCount(); + for (int i = 0 ; i < ncomponents ; i++) { + Component comp = c.getComponent(i); + if (comp != null && comp.isShowing()) { + Point location = comp.getLocation(); + if (comp.contains(x - location.x, y - location.y)) { + return comp; + } + } + } + return c; + } + + /** + * Return the Component at the given Point on the screen in the + * given Container. + * + * @param c the Container to search + * @param p the Point in screen coordinates + * @return the Component at the given Point on the screen in the + * given Container -- can be null if no Component is at that Point + */ + static synchronized Component getComponentAt(Container c, Point p) { + if (!c.isShowing()) { + return null; + } + + Component comp; + Point containerLoc = c.getLocationOnScreen(); + Point containerPoint = new Point(p.x - containerLoc.x, + p.y - containerLoc.y); + + comp = getShowingComponentAt(c, containerPoint.x, containerPoint.y); + + if ((comp != c) && (comp instanceof Container)) { + return getComponentAt((Container)comp,p); + } else { + return comp; + } + } + + /** + * Obtain the {@link javax.accessibility.Accessible Accessible} object at the given point on the Screen. + * The return value may be null if an {@code Accessible} object cannot be + * found at the particular point. + * + * @param p the point to be accessed + * @return the {@code Accessible} at the specified point + */ + static public Accessible getAccessibleAt(Point p) { + Window w = getTopLevelWindowWithFocus(); + Window[] wins = getTopLevelWindows(); + Component c = null; + + // See if the point we're being asked about is the + // currentMousePosition. If so, start with the component + // that we know the currentMousePostion is over + // + if (currentMousePosition == null) { + return null; + } + if (currentMousePosition.equals(p)) { + if (currentMouseComponent instanceof Container) { + c = getComponentAt((Container) currentMouseComponent, p); + } + } + + // Try the window with focus next + // + if (c == null && w != null) { + c = getComponentAt(w,p); + } + + // Try the other windows next. [[[WDW: Stacking order???]]] + if (c == null) { + for (int i = 0; i < wins.length; i++) { + c = getComponentAt(wins[i],p); + if (c != null) { + break; + } + } + } + + if (c instanceof Accessible) { + AccessibleContext ac = ((Accessible) c).getAccessibleContext(); + if (ac != null) { + AccessibleComponent acmp = ac.getAccessibleComponent(); + if ((acmp != null) && (ac.getAccessibleChildrenCount() != 0)) { + Point location = acmp.getLocationOnScreen(); + location.move(p.x - location.x, p.y - location.y); + return acmp.getAccessibleAt(location); + } + } + return (Accessible) c; + } else { + return Translator.getAccessible(c); + } + } + + /********************************************************************/ + /* */ + /* Public Methods */ + /* */ + /********************************************************************/ + + /** + * Says whether the GUI subsystem has been initialized or not. + * If this returns true, the assistive technology can freely + * create GUI component instances. If the return value is false, + * the assistive technology should register a {@link GUIInitializedListener} + * and wait to create GUI component instances until the listener is + * called. + * + * @return true if the GUI subsystem has been initialized + * @see #addGUIInitializedListener + */ + static public boolean isGUIInitialized() { + maybeInitialize(); + return guiInitialized; + } + + /** + * Adds the specified listener to be notified when the GUI subsystem + * is initialized. Assistive technologies should get the results of + * {@link #isGUIInitialized} before calling this method. + * + * @param l the listener to add + * @see #isGUIInitialized + * @see #removeTopLevelWindowListener + */ + static public void addGUIInitializedListener(GUIInitializedListener l) { + maybeInitialize(); + guiInitializedListener = + GUIInitializedMulticaster.add(guiInitializedListener,l); + } + + /** + * Removes the specified listener to be notified when the GUI subsystem + * is initialized. + * + * @param l the listener to remove + * @see #addGUIInitializedListener + */ + static public void removeGUIInitializedListener(GUIInitializedListener l) { + guiInitializedListener = + GUIInitializedMulticaster.remove(guiInitializedListener,l); + } + + /** + * Adds the specified listener to be notified when a top level window + * is created or destroyed. + * + * @param l the listener to add + * @see #removeTopLevelWindowListener + */ + static public void addTopLevelWindowListener(TopLevelWindowListener l) { + topLevelWindowListener = + TopLevelWindowMulticaster.add(topLevelWindowListener,l); + } + + /** + * Removes the specified listener to be notified when a top level window + * is created or destroyed. + * + * @param l the listener to remove + * @see #addTopLevelWindowListener + */ + static public void removeTopLevelWindowListener(TopLevelWindowListener l) { + topLevelWindowListener = + TopLevelWindowMulticaster.remove(topLevelWindowListener,l); + } + + /** + * Return the last recorded position of the mouse in screen coordinates. + * + * @return the last recorded position of the mouse in screen coordinates + */ + static public Point getCurrentMousePosition() { + return currentMousePosition; + } + + /** + * Return the list of top level Windows in use in the Java Virtual Machine. + * + * @return an array of top level {@code Window}s in use in the Java Virtual Machine + */ + static public Window[] getTopLevelWindows() { + + // Because this method is static, do not make it synchronized because + // it can lock the whole class. Instead, just lock what needs to be + // locked. + // + synchronized (topLevelWindows) { + int count = topLevelWindows.size(); + if (count > 0) { + Window[] w = new Window[count]; + for (int i = 0; i < count; i++) { + w[i] = (Window)topLevelWindows.elementAt(i); + } + return w; + } else { + return new Window[0]; + } + } + } + + /** + * Return the top level {@code Window} that currently has keyboard focus. + * + * @return the top level {@code Window} that currently has keyboard focus + */ + static public Window getTopLevelWindowWithFocus() { + return topLevelWindowWithFocus; + } +} + +/** + * Handle all Component events in a separate thread. The reason for this is + * that WindowEvents tend to be used to do lots of processing on the Window + * hierarchy. As a result, it can frequently result in deadlock situations. + */ +class ComponentEvtDispatchThread extends Thread { + public ComponentEvtDispatchThread(String name) { + super(name); + } + public void run() { + ComponentEvent ce = null; + while (true) { + synchronized(EventQueueMonitor.componentEventQueueLock) { + while (EventQueueMonitor.componentEventQueue == null) { + try { + EventQueueMonitor.componentEventQueueLock.wait(); + } catch (InterruptedException e) { + } + } + ce = (ComponentEvent)EventQueueMonitor.componentEventQueue.event; + EventQueueMonitor.componentEventQueue = + EventQueueMonitor.componentEventQueue.next; + } + switch (ce.getID()) { + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + EventQueueMonitor.updateCurrentMousePosition((MouseEvent) ce); + break; + case WindowEvent.WINDOW_ACTIVATED: + EventQueueMonitor.maybeNotifyAssistiveTechnologies(); + EventQueueMonitor.topLevelWindowWithFocus = ((WindowEvent) ce).getWindow(); + break; + + default: + break; + } + } + } +} + +/** + * EventQueueMonitorItem is the basic type that handles the + * queue for queueComponentEvent and the ComponentEvtDispatchThread. + */ +class EventQueueMonitorItem { + AWTEvent event; + EventQueueMonitorItem next; + + EventQueueMonitorItem(AWTEvent evt) { + event = evt; + next = null; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/GUIInitializedListener.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/GUIInitializedListener.java new file mode 100644 index 00000000000..9a4474d3e6b --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/GUIInitializedListener.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.*; +import javax.accessibility.*; + +/** + * The {@code GUIInitializedListener} interface is used by the {@link EventQueueMonitor} + * class to notify an interested party when the GUI subsystem has been + * initialized. This is necessary because assistive technologies can + * be loaded before the GUI subsystem is initialized. As a result, + * assistive technologies should check the + * {@link EventQueueMonitor#isGUIInitialized isGUIInitialized} method + * of {@code EventQueueMonitor} before creating any GUI components. If the + * return value is true, assistive technologies can create GUI components + * following the same thread restrictions as any other application. If + * the return value is false, the assistive technology should register + * a {@code GUIInitializedListener} with the {@code EventQueueMonitor} to be notified + * when the GUI subsystem is initialized. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#isGUIInitialized + * @see EventQueueMonitor#addGUIInitializedListener + * @see EventQueueMonitor#removeGUIInitializedListener + * + */ +@jdk.Exported +public interface GUIInitializedListener extends EventListener { + + /** + * Invoked when the GUI subsystem is initialized and it's OK for + * the assisitive technology to create instances of GUI objects. + */ + public void guiInitialized(); + +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java new file mode 100644 index 00000000000..900b6078f7e --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/GUIInitializedMulticaster.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.EventListener; +import javax.accessibility.*; + + +/** + * The GUIInitializedMulticaster class is used to maintain a list of + * GUIInitializedListener classes. It is intended to be used primarily + * for internal support in the EventQueueMonitor class, and is not intended + * to be used by classes outside the Java Accessibility Utility package. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addGUIInitializedListener + * @see EventQueueMonitor#removeGUIInitializedListener + * + */ +class GUIInitializedMulticaster + extends AWTEventMulticaster implements GUIInitializedListener +{ + protected GUIInitializedMulticaster(EventListener a, EventListener b) { + super(a, b); + } + + public void guiInitialized() { + ((GUIInitializedListener)a).guiInitialized(); + ((GUIInitializedListener)b).guiInitialized(); + } + + public static GUIInitializedListener add(GUIInitializedListener a, GUIInitializedListener b) { + return (GUIInitializedListener)addInternal(a, b); + } + + public static GUIInitializedListener remove(GUIInitializedListener l, GUIInitializedListener oldl) { + return (GUIInitializedListener)removeInternal(l, oldl); + } + + protected static EventListener addInternal(EventListener a, EventListener b) { + if (a == null) return b; + if (b == null) return a; + return new GUIInitializedMulticaster(a, b); + } + + protected static EventListener removeInternal(EventListener l, EventListener oldl) { + if (l == oldl || l == null) { + return null; + } else if (l instanceof GUIInitializedMulticaster) { + return ((GUIInitializedMulticaster)l).remove(oldl); + } else { + return l; // it's not here + } + } + +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java new file mode 100644 index 00000000000..c2150cd78f8 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java @@ -0,0 +1,2530 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.util.*; +import java.beans.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.table.*; +import javax.swing.tree.*; +import javax.swing.text.*; +import javax.swing.undo.*; +import javax.accessibility.*; + + +/** + *

                                  {@code SwingEventMonitor} extends {@link AWTEventMonitor} by adding a suite of + * listeners conditionally installed on every Swing component instance + * in the Java Virtual Machine. The events captured by these listeners + * are made available through a unified set of listeners supported by + * {@code SwingEventMonitor}. With this, all the individual events on each of the + * AWT and Swing component instances are funneled into one set of listeners + * broken down by category (see {@link EventID} for the categories). + *

                                  This class depends upon {@link EventQueueMonitor}, which provides the base + * level support for capturing the top-level containers as they are created. + *

                                  Because this class extends {@code AWTEventMonitor}, it is not + * necessary to use this class and {@code AWTEventMonitor} at the same time. + * If you want to monitor both AWT and Swing components, you should + * use just this class. + * + * @see AWTEventMonitor + * + */ +@jdk.Exported +public class SwingEventMonitor extends AWTEventMonitor { + + /** + * The master list of all listeners registered by other classes. + * This can only be publicly modified by calling the add or + * remove listener methods in this class. + */ + static protected final EventListenerList listenerList = new EventListenerList(); + + /** + * The actual listener that is installed on the component instances. + * This listener calls the other registered listeners when an event + * occurs. By doing things this way, the actual number of listeners + * installed on a component instance is drastically reduced. + */ + static protected final SwingEventListener swingListener = new SwingEventListener(); + + /** + * Adds the specified listener to receive all {@link EventID#ANCESTOR ANCESTOR} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeAncestorListener + */ + static public void addAncestorListener(AncestorListener l) { + if (listenerList.getListenerCount(AncestorListener.class) == 0) { + swingListener.installListeners(EventID.ANCESTOR); + } + listenerList.add(AncestorListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#ANCESTOR ANCESTOR} events when they occur. + * + * @param l the listener to remove + * @see #addAncestorListener + */ + static public void removeAncestorListener(AncestorListener l) { + listenerList.remove(AncestorListener.class, l); + if (listenerList.getListenerCount(AncestorListener.class) == 0) { + swingListener.removeListeners(EventID.ANCESTOR); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#CARET CARET} events + * on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeCaretListener + */ + static public void addCaretListener(CaretListener l) { + if (listenerList.getListenerCount(CaretListener.class) == 0) { + swingListener.installListeners(EventID.CARET); + } + listenerList.add(CaretListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CARET CARET} events when they occur. + * + * @param l the listener to remove + * @see #addCaretListener + */ + static public void removeCaretListener(CaretListener l) { + listenerList.remove(CaretListener.class, l); + if (listenerList.getListenerCount(CaretListener.class) == 0) { + swingListener.removeListeners(EventID.CARET); + } + } + + /** + * Adds the specified listener to receive all + * {@link EventID#CELLEDITOR CELLEDITOR} events on each + * component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeCellEditorListener + */ + static public void addCellEditorListener(CellEditorListener l) { + if (listenerList.getListenerCount(CellEditorListener.class) == 0) { + swingListener.installListeners(EventID.CELLEDITOR); + } + listenerList.add(CellEditorListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CELLEDITOR CELLEDITOR} events when they occur. + * + * @param l the listener to remove + * @see #addCellEditorListener + */ + static public void removeCellEditorListener(CellEditorListener l) { + listenerList.remove(CellEditorListener.class, l); + if (listenerList.getListenerCount(CellEditorListener.class) == 0) { + swingListener.removeListeners(EventID.CELLEDITOR); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#CHANGE CHANGE} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeChangeListener + */ + static public void addChangeListener(ChangeListener l) { + if (listenerList.getListenerCount(ChangeListener.class) == 0) { + swingListener.installListeners(EventID.CHANGE); + } + listenerList.add(ChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#CHANGE CHANGE} events when they occur. + * + * @param l the listener to remove + * @see #addChangeListener + */ + static public void removeChangeListener(ChangeListener l) { + listenerList.remove(ChangeListener.class, l); + if (listenerList.getListenerCount(ChangeListener.class) == 0) { + swingListener.removeListeners(EventID.CHANGE); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#COLUMNMODEL COLUMNMODEL} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeColumnModelListener + */ + static public void addColumnModelListener(TableColumnModelListener l) { + if (listenerList.getListenerCount(TableColumnModelListener.class) == 0) { + swingListener.installListeners(EventID.COLUMNMODEL); + } + listenerList.add(TableColumnModelListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#COLUMNMODEL COLUMNMODEL} events when they occur. + * + * @param l the listener to remove + * @see #addColumnModelListener + */ + static public void removeColumnModelListener(TableColumnModelListener l) { + listenerList.remove(TableColumnModelListener.class, l); + if (listenerList.getListenerCount(TableColumnModelListener.class) == 0) { + swingListener.removeListeners(EventID.COLUMNMODEL); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#DOCUMENT DOCUMENT} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeDocumentListener + */ + static public void addDocumentListener(DocumentListener l) { + if (listenerList.getListenerCount(DocumentListener.class) == 0) { + swingListener.installListeners(EventID.DOCUMENT); + } + listenerList.add(DocumentListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#DOCUMENT DOCUMENT} events when they occur. + * + * @param l the listener to remove + * @see #addDocumentListener + */ + static public void removeDocumentListener(DocumentListener l) { + listenerList.remove(DocumentListener.class, l); + if (listenerList.getListenerCount(DocumentListener.class) == 0) { + swingListener.removeListeners(EventID.DOCUMENT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#LISTDATA LISTDATA} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeListDataListener + */ + static public void addListDataListener(ListDataListener l) { + if (listenerList.getListenerCount(ListDataListener.class) == 0) { + swingListener.installListeners(EventID.LISTDATA); + } + listenerList.add(ListDataListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#LISTDATA LISTDATA} events when they occur. + * + * @param l the listener to remove + * @see #addListDataListener + */ + static public void removeListDataListener(ListDataListener l) { + listenerList.remove(ListDataListener.class, l); + if (listenerList.getListenerCount(ListDataListener.class) == 0) { + swingListener.removeListeners(EventID.LISTDATA); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#LISTSELECTION LISTSELECTION} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeListSelectionListener + */ + static public void addListSelectionListener(ListSelectionListener l) { + if (listenerList.getListenerCount(ListSelectionListener.class) == 0) { + swingListener.installListeners(EventID.LISTSELECTION); + } + listenerList.add(ListSelectionListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#LISTSELECTION LISTSELECTION} events when they occur. + * + * @param l the listener to remove + * @see #addListSelectionListener + */ + static public void removeListSelectionListener(ListSelectionListener l) { + listenerList.remove(ListSelectionListener.class, l); + if (listenerList.getListenerCount(ListSelectionListener.class) == 0) { + swingListener.removeListeners(EventID.LISTSELECTION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#MENU MENU} events + * on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeMenuListener + */ + static public void addMenuListener(MenuListener l) { + if (listenerList.getListenerCount(MenuListener.class) == 0) { + swingListener.installListeners(EventID.MENU); + } + listenerList.add(MenuListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#MENU MENU} events when they occur. + * + * @param l the listener to remove + * @see #addMenuListener + */ + static public void removeMenuListener(MenuListener l) { + listenerList.remove(MenuListener.class, l); + if (listenerList.getListenerCount(MenuListener.class) == 0) { + swingListener.removeListeners(EventID.MENU); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#POPUPMENU POPUPMENU} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removePopupMenuListener + */ + static public void addPopupMenuListener(PopupMenuListener l) { + if (listenerList.getListenerCount(PopupMenuListener.class) == 0) { + swingListener.installListeners(EventID.POPUPMENU); + } + listenerList.add(PopupMenuListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#POPUPMENU POPUPMENU} events when they occur. + * + * @param l the listener to remove + * @see #addPopupMenuListener + */ + static public void removePopupMenuListener(PopupMenuListener l) { + listenerList.remove(PopupMenuListener.class, l); + if (listenerList.getListenerCount(PopupMenuListener.class) == 0) { + swingListener.removeListeners(EventID.POPUPMENU); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TABLEMODEL TABLEMODEL} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTableModelListener + */ + static public void addTableModelListener(TableModelListener l) { + if (listenerList.getListenerCount(TableModelListener.class) == 0) { + swingListener.installListeners(EventID.TABLEMODEL); + } + listenerList.add(TableModelListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TABLEMODEL TABLEMODEL} events when they occur. + * + * @param l the listener to remove + * @see #addTableModelListener + */ + static public void removeTableModelListener(TableModelListener l) { + listenerList.remove(TableModelListener.class, l); + if (listenerList.getListenerCount(TableModelListener.class) == 0) { + swingListener.removeListeners(EventID.TABLEMODEL); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TREEEXPANSION TREEEXPANSION} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTreeExpansionListener + */ + static public void addTreeExpansionListener(TreeExpansionListener l) { + if (listenerList.getListenerCount(TreeExpansionListener.class) == 0) { + swingListener.installListeners(EventID.TREEEXPANSION); + } + listenerList.add(TreeExpansionListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TREEEXPANSION TREEEXPANSION} events when they occur. + * + * @param l the listener to remove + * @see #addTreeExpansionListener + */ + static public void removeTreeExpansionListener(TreeExpansionListener l) { + listenerList.remove(TreeExpansionListener.class, l); + if (listenerList.getListenerCount(TreeExpansionListener.class) == 0) { + swingListener.removeListeners(EventID.TREEEXPANSION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TREEMODEL TREEMODEL} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTreeModelListener + */ + static public void addTreeModelListener(TreeModelListener l) { + if (listenerList.getListenerCount(TreeModelListener.class) == 0) { + swingListener.installListeners(EventID.TREEMODEL); + } + listenerList.add(TreeModelListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TREEMODEL TREEMODEL} events when they occur. + * + * @param l the listener to remove + * @see #addTreeModelListener + */ + static public void removeTreeModelListener(TreeModelListener l) { + listenerList.remove(TreeModelListener.class, l); + if (listenerList.getListenerCount(TreeModelListener.class) == 0) { + swingListener.removeListeners(EventID.TREEMODEL); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#TREESELECTION TREESELECTION} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeTreeSelectionListener + */ + static public void addTreeSelectionListener(TreeSelectionListener l) { + if (listenerList.getListenerCount(TreeSelectionListener.class) == 0) { + swingListener.installListeners(EventID.TREESELECTION); + } + listenerList.add(TreeSelectionListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#TREESELECTION TREESELECTION} events when they occur. + * @see #addTreeSelectionListener + * @param l the listener to remove + */ + static public void removeTreeSelectionListener(TreeSelectionListener l) { + listenerList.remove(TreeSelectionListener.class, l); + if (listenerList.getListenerCount(TreeSelectionListener.class) == 0) { + swingListener.removeListeners(EventID.TREESELECTION); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#UNDOABLEEDIT UNDOABLEEDIT} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeUndoableEditListener + */ + static public void addUndoableEditListener(UndoableEditListener l) { + if (listenerList.getListenerCount(UndoableEditListener.class) == 0) { + swingListener.installListeners(EventID.UNDOABLEEDIT); + } + listenerList.add(UndoableEditListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#UNDOABLEEDIT UNDOABLEEDIT} events when they occur. + * + * @param l the listener to remove + * @see #addUndoableEditListener + */ + static public void removeUndoableEditListener(UndoableEditListener l) { + listenerList.remove(UndoableEditListener.class, l); + if (listenerList.getListenerCount(UndoableEditListener.class) == 0) { + swingListener.removeListeners(EventID.UNDOABLEEDIT); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#INTERNALFRAME INTERNALFRAME} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeInternalFrameListener + */ + static public void addInternalFrameListener(InternalFrameListener l) { + if (listenerList.getListenerCount(InternalFrameListener.class) == 0) { + swingListener.installListeners(EventID.INTERNALFRAME); + } + listenerList.add(InternalFrameListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#INTERNALFRAME INTERNALFRAME} events when they occur. + * + * @param l the listener to remove + * @see #addInternalFrameListener + */ + static public void removeInternalFrameListener(InternalFrameListener l) { + listenerList.remove(InternalFrameListener.class, l); + if (listenerList.getListenerCount(InternalFrameListener.class) == 0) { + swingListener.removeListeners(EventID.INTERNALFRAME); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#PROPERTYCHANGE PROPERTYCHANGE} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removePropertyChangeListener + */ + static public void addPropertyChangeListener(PropertyChangeListener l) { + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + swingListener.installListeners(EventID.PROPERTYCHANGE); + } + listenerList.add(PropertyChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#PROPERTYCHANGE PROPERTYCHANGE} events when they occur. + * @see #addPropertyChangeListener + * @param l the listener to remove + */ + static public void removePropertyChangeListener(PropertyChangeListener l) { + listenerList.remove(PropertyChangeListener.class, l); + if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) { + swingListener.removeListeners(EventID.PROPERTYCHANGE); + } + } + + /** + * Adds the specified listener to receive all {@link EventID#VETOABLECHANGE VETOABLECHANGE} + * events on each component instance in the Java Virtual Machine as they occur. + *

                                  Note: This listener is automatically added to all component + * instances created after this method is called. In addition, it + * is only added to component instances that support this listener type. + * + * @param l the listener to add + * @see #removeVetoableChangeListener + */ + static public void addVetoableChangeListener(VetoableChangeListener l) { + if (listenerList.getListenerCount(VetoableChangeListener.class) == 0) { + swingListener.installListeners(EventID.VETOABLECHANGE); + } + listenerList.add(VetoableChangeListener.class, l); + } + + /** + * Removes the specified listener so it no longer receives + * {@link EventID#VETOABLECHANGE VETOABLECHANGE} events when they occur. + * + * @param l the listener to remove + * @see #addVetoableChangeListener + */ + static public void removeVetoableChangeListener(VetoableChangeListener l) { + listenerList.remove(VetoableChangeListener.class, l); + if (listenerList.getListenerCount(VetoableChangeListener.class) == 0) { + swingListener.removeListeners(EventID.VETOABLECHANGE); + } + } + + + /** + * SwingEventListener is the class that does all the work for + * SwingEventMonitor. It is not intended for use by any other class + * except SwingEventMonitor. + * + */ + static class SwingEventListener extends AWTEventsListener + implements AncestorListener, CaretListener, CellEditorListener, + ChangeListener, DocumentListener, ListDataListener, + ListSelectionListener, MenuListener, PopupMenuListener, + TableColumnModelListener, TableModelListener, TreeExpansionListener, + TreeModelListener, TreeSelectionListener, UndoableEditListener, + InternalFrameListener, + PropertyChangeListener, VetoableChangeListener { + + /** + * internal variables for Caret introspection + */ + private java.lang.Class[] caretListeners; + private java.lang.reflect.Method removeCaretMethod; + private java.lang.reflect.Method addCaretMethod; + private java.lang.Object[] caretArgs; + + /** + * internal variables for CellEditor introspection + */ + private java.lang.Class[] cellEditorListeners; + private java.lang.reflect.Method removeCellEditorMethod; + private java.lang.reflect.Method addCellEditorMethod; + private java.lang.Object[] cellEditorArgs; + private java.lang.reflect.Method getCellEditorMethod; + + /** + * internal variables for Change introspection + */ + private java.lang.Class[] changeListeners; + private java.lang.reflect.Method removeChangeMethod; + private java.lang.reflect.Method addChangeMethod; + private java.lang.Object[] changeArgs; + + /** + * internal variable for ColumnModel introspection + */ + private java.lang.reflect.Method getColumnModelMethod; + + /** + * internal variables for Document introspection + */ + private java.lang.Class[] documentListeners; + private java.lang.reflect.Method removeDocumentMethod; + private java.lang.reflect.Method addDocumentMethod; + private java.lang.Object[] documentArgs; + private java.lang.reflect.Method getDocumentMethod; + + /** + * internal variable for ListData, Table, and Tree introspection + */ + private java.lang.reflect.Method getModelMethod; + + /** + * internal variables for ListSelection introspection + */ + private java.lang.Class[] listSelectionListeners; + private java.lang.reflect.Method removeListSelectionMethod; + private java.lang.reflect.Method addListSelectionMethod; + private java.lang.Object[] listSelectionArgs; + private java.lang.reflect.Method getSelectionModelMethod; + + /** + * internal variables for Menu introspection + */ + private java.lang.Class[] menuListeners; + private java.lang.reflect.Method removeMenuMethod; + private java.lang.reflect.Method addMenuMethod; + private java.lang.Object[] menuArgs; + + /** + * internal variables for PopupMenu introspection + */ + private java.lang.Class[] popupMenuListeners; + private java.lang.reflect.Method removePopupMenuMethod; + private java.lang.reflect.Method addPopupMenuMethod; + private java.lang.Object[] popupMenuArgs; + private java.lang.reflect.Method getPopupMenuMethod; + + /** + * internal variables for TreeExpansion introspection + */ + private java.lang.Class[] treeExpansionListeners; + private java.lang.reflect.Method removeTreeExpansionMethod; + private java.lang.reflect.Method addTreeExpansionMethod; + private java.lang.Object[] treeExpansionArgs; + + /** + * internal variables for TreeSelection introspection + */ + private java.lang.Class[] treeSelectionListeners; + private java.lang.reflect.Method removeTreeSelectionMethod; + private java.lang.reflect.Method addTreeSelectionMethod; + private java.lang.Object[] treeSelectionArgs; + + /** + * internal variables for UndoableEdit introspection + */ + private java.lang.Class[] undoableEditListeners; + private java.lang.reflect.Method removeUndoableEditMethod; + private java.lang.reflect.Method addUndoableEditMethod; + private java.lang.Object[] undoableEditArgs; + + /** + * internal variables for InternalFrame introspection + */ + private java.lang.Class[] internalFrameListeners; + private java.lang.reflect.Method removeInternalFrameMethod; + private java.lang.reflect.Method addInternalFrameMethod; + private java.lang.Object[] internalFrameArgs; + + /** + * internal variables for PropertyChange introspection + */ + private java.lang.Class[] propertyChangeListeners; + private java.lang.reflect.Method removePropertyChangeMethod; + private java.lang.reflect.Method addPropertyChangeMethod; + private java.lang.Object[] propertyChangeArgs; + + /** + * internal variables for a variety of change introspections + */ + private java.lang.Class[] nullClass; + private java.lang.Object[] nullArgs; + + /** + * Create a new instance of this class and install it on each component + * instance in the virtual machine that supports any of the currently + * registered listeners in SwingEventMonitor. Also registers itself + * as a TopLevelWindowListener with EventQueueMonitor so it can + * automatically add new listeners to new components. + * @see EventQueueMonitor + * @see SwingEventMonitor + */ + public SwingEventListener() { + initializeIntrospection(); + installListeners(); + EventQueueMonitor.addTopLevelWindowListener(this); + } + + /** + * Set up all of the variables needed for introspection + */ + private boolean initializeIntrospection() { + caretListeners = new java.lang.Class[1]; + caretArgs = new java.lang.Object[1]; + caretListeners[0] = javax.swing.event.CaretListener.class; + caretArgs[0] = this; + + cellEditorListeners = new java.lang.Class[1]; + cellEditorArgs = new java.lang.Object[1]; + cellEditorListeners[0] = javax.swing.event.CellEditorListener.class; + cellEditorArgs[0] = this; + + changeListeners = new java.lang.Class[1]; + changeArgs = new java.lang.Object[1]; + changeListeners[0] = javax.swing.event.ChangeListener.class; + changeArgs[0] = this; + + documentListeners = new java.lang.Class[1]; + documentArgs = new java.lang.Object[1]; + documentListeners[0] = javax.swing.event.DocumentListener.class; + documentArgs[0] = this; + + listSelectionListeners = new java.lang.Class[1]; + listSelectionArgs = new java.lang.Object[1]; + listSelectionListeners[0] = javax.swing.event.ListSelectionListener.class; + listSelectionArgs[0] = this; + + menuListeners = new java.lang.Class[1]; + menuArgs = new java.lang.Object[1]; + menuListeners[0] = javax.swing.event.MenuListener.class; + menuArgs[0] = this; + + popupMenuListeners = new java.lang.Class[1]; + popupMenuArgs = new java.lang.Object[1]; + popupMenuListeners[0] = javax.swing.event.PopupMenuListener.class; + popupMenuArgs[0] = this; + + treeExpansionListeners = new java.lang.Class[1]; + treeExpansionArgs = new java.lang.Object[1]; + treeExpansionListeners[0] = javax.swing.event.TreeExpansionListener.class; + treeExpansionArgs[0] = this; + + treeSelectionListeners = new java.lang.Class[1]; + treeSelectionArgs = new java.lang.Object[1]; + treeSelectionListeners[0] = javax.swing.event.TreeSelectionListener.class; + treeSelectionArgs[0] = this; + + undoableEditListeners = new java.lang.Class[1]; + undoableEditArgs = new java.lang.Object[1]; + undoableEditListeners[0] = javax.swing.event.UndoableEditListener.class; + undoableEditArgs[0] = this; + + internalFrameListeners = new java.lang.Class[1]; + internalFrameArgs = new java.lang.Object[1]; + internalFrameListeners[0] = javax.swing.event.InternalFrameListener.class; + internalFrameArgs[0] = this; + + nullClass = new java.lang.Class[0]; + nullArgs = new java.lang.Object[0]; + + propertyChangeListeners = new java.lang.Class[1]; + propertyChangeArgs = new java.lang.Object[1]; + propertyChangeListeners[0] = java.beans.PropertyChangeListener.class; + propertyChangeArgs[0] = this; + + return true; + } + + /** + * Installs all appropriate Swing listeners to just the component. + * Also calls super (AWTEventsListener.installListeners()) to install + * the requested AWT listeners. + * @param c the component to add listeners to + */ + protected void installListeners(Component c) { + + // This SwingEventListener needs to be notified when a new + // Swing component has been added so it can add Swing listeners + // to these components. As a result, we always need a Container + // listener on every Container. + // + installListeners(c,EventID.CONTAINER); + + // conditionally install Swing listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(AncestorListener.class) > 0) { + installListeners(c,EventID.ANCESTOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(CaretListener.class) > 0) { + installListeners(c,EventID.CARET); + } + if (SwingEventMonitor.listenerList.getListenerCount(CellEditorListener.class) > 0) { + installListeners(c,EventID.CELLEDITOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(ChangeListener.class) > 0) { + installListeners(c,EventID.CHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableColumnModelListener.class) > 0) { + installListeners(c,EventID.COLUMNMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(DocumentListener.class) > 0) { + installListeners(c,EventID.DOCUMENT); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListDataListener.class) > 0) { + installListeners(c,EventID.LISTDATA); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListSelectionListener.class) > 0) { + installListeners(c,EventID.LISTSELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(MenuListener.class) > 0) { + installListeners(c,EventID.MENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(PopupMenuListener.class) > 0) { + installListeners(c,EventID.POPUPMENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableModelListener.class) > 0) { + installListeners(c,EventID.TABLEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeExpansionListener.class) > 0) { + installListeners(c,EventID.TREEEXPANSION); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeModelListener.class) > 0) { + installListeners(c,EventID.TREEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeSelectionListener.class) > 0) { + installListeners(c,EventID.TREESELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(UndoableEditListener.class) > 0) { + installListeners(c,EventID.UNDOABLEEDIT); + } + if (SwingEventMonitor.listenerList.getListenerCount(InternalFrameListener.class) > 0) { + installListeners(c,EventID.INTERNALFRAME); + } + + // Conditionally install Beans listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(PropertyChangeListener.class) > 0) { + installListeners(c,EventID.PROPERTYCHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(VetoableChangeListener.class) > 0) { + installListeners(c,EventID.VETOABLECHANGE); + } + + // Now install the AWT listeners if needed. + // + super.installListeners(c); + } + + /** + * Installs all appropriate Swing listeners to the component and all its + * children. As a precaution, it always attempts to remove itself as + * a listener first so we're always guaranteed it will installed itself + * just once. + * @param c the component to add listeners to + * @param eventID the eventID to add listeners for + */ + protected void installListeners(Component c, int eventID) { + + // install the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.CONTAINER: + if (c instanceof Container) { + ((Container) c).removeContainerListener(this); + ((Container) c).addContainerListener(this); + } + break; + + case EventID.ANCESTOR: + if (c instanceof JComponent) { + ((JComponent) c).removeAncestorListener(this); + ((JComponent) c).addAncestorListener(this); + } + break; + + case EventID.CARET: + try { + removeCaretMethod = c.getClass().getMethod( + "removeCaretListener", caretListeners); + addCaretMethod = c.getClass().getMethod( + "addCaretListener", caretListeners); + try { + removeCaretMethod.invoke(c, caretArgs); + addCaretMethod.invoke(c, caretArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CELLEDITOR: + // Look for components which support the getCellEditor method + // (e.g. JTable, JTree) + // + try { + getCellEditorMethod = c.getClass().getMethod( + "getCellEditorMethod", nullClass); + try { + Object o = getCellEditorMethod.invoke(c, nullArgs); + if (o != null && o instanceof CellEditor) { + ((CellEditor) o).removeCellEditorListener(this); + ((CellEditor) o).addCellEditorListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support CellEditor listeners + // (no current example) + // + try { + removeCellEditorMethod = c.getClass().getMethod( + "removeCellEditorListener", cellEditorListeners); + addCellEditorMethod = c.getClass().getMethod( + "addCellEditorListener", cellEditorListeners); + try { + removeCellEditorMethod.invoke(c, cellEditorArgs); + addCellEditorMethod.invoke(c, cellEditorArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CHANGE: + // [[[FIXME: Need to add support for Style, StyleContext -pk]]] + + // Look for components which support Change listeners + // (e.g. AbstractButton, Caret, JProgressBar, JSlider, + // JTabbedpane, JTextComponent, JViewport) + // + try { + removeChangeMethod = c.getClass().getMethod( + "removeChangeListener", changeListeners); + addChangeMethod = c.getClass().getMethod( + "addChangeListener", changeListeners); + try { + removeChangeMethod.invoke(c, changeArgs); + addChangeMethod.invoke(c, changeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getModel method + // whose model supports Change listeners + // (e.g. BoundedRangeModel, ButtonModel, SingleSelectionModel) + // + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + removeChangeMethod = o.getClass().getMethod( + "removeChangeListener", changeListeners); + addChangeMethod = o.getClass().getMethod( + "addChangeListener", changeListeners); + removeChangeMethod.invoke(o, changeArgs); + addChangeMethod.invoke(o, changeArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + break; + + case EventID.COLUMNMODEL: + try { + getColumnModelMethod = c.getClass().getMethod( + "getTableColumnModel", nullClass); + try { + Object o = getColumnModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TableColumnModel) { + ((TableColumnModel) o).removeColumnModelListener(this); + ((TableColumnModel) o).addColumnModelListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.DOCUMENT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeDocumentListener(this); + ((Document) o).addDocumentListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support Document listeners + // (no current example) + // + try { + removeDocumentMethod = c.getClass().getMethod( + "removeDocumentListener", documentListeners); + addDocumentMethod = c.getClass().getMethod( + "addDocumentListener", documentListeners); + try { + removeDocumentMethod.invoke(c, documentArgs); + addDocumentMethod.invoke(c, documentArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + // Add the monitor as a PropertyChangeListener for document + // change events from text components. + // + if (c instanceof JTextComponent) { + try { + removePropertyChangeMethod = c.getClass().getMethod( + "removePropertyChangeListener", + propertyChangeListeners); + addPropertyChangeMethod = c.getClass().getMethod( + "addPropertyChangeListener", + propertyChangeListeners); + try { + removePropertyChangeMethod.invoke(c, + propertyChangeArgs); + addPropertyChangeMethod.invoke(c, + propertyChangeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + } + break; + + case EventID.LISTDATA: + case EventID.TABLEMODEL: + case EventID.TREEMODEL: + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + if (eventID == EventID.LISTDATA && + o instanceof ListModel) { + ((ListModel) o).removeListDataListener(this); + ((ListModel) o).addListDataListener(this); + } else if (eventID == EventID.TABLEMODEL && + o instanceof TableModel) { + ((TableModel) o).removeTableModelListener(this); + ((TableModel) o).addTableModelListener(this); + } else if ( + o instanceof TreeModel) { + ((TreeModel) o).removeTreeModelListener(this); + ((TreeModel) o).addTreeModelListener(this); + } + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.LISTSELECTION: + // Look for components which support ListSelectionListeners + // (e.g. JList) + // + try { + removeListSelectionMethod = c.getClass().getMethod( + "removeListSelectionListener", listSelectionListeners); + addListSelectionMethod = c.getClass().getMethod( + "addListSelectionListener", listSelectionListeners); + try { + removeListSelectionMethod.invoke(c, listSelectionArgs); + addListSelectionMethod.invoke(c, listSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for selection models which support ListSelectionListeners + // (e.g. JTable's selection model) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof ListSelectionModel) { + ((ListSelectionModel) o).removeListSelectionListener(this); + ((ListSelectionModel) o).addListSelectionListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.MENU: + try { + removeMenuMethod = c.getClass().getMethod( + "removeMenuListener", menuListeners); + addMenuMethod = c.getClass().getMethod( + "addMenuListener", menuListeners); + try { + removeMenuMethod.invoke(c, menuArgs); + addMenuMethod.invoke(c, menuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.POPUPMENU: + // Look for components which support PopupMenuListeners + // (e.g. JPopupMenu) + // + try { + removePopupMenuMethod = c.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + addPopupMenuMethod = c.getClass().getMethod( + "addPopupMenuListener", popupMenuListeners); + try { + removePopupMenuMethod.invoke(c, popupMenuArgs); + addPopupMenuMethod.invoke(c, popupMenuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support getPopupMenu + // (e.g. JMenu) + // + try { + getPopupMenuMethod = c.getClass().getMethod( + "getPopupMenu", nullClass); + try { + Object o = getPopupMenuMethod.invoke(c, nullArgs); + if (o != null) { + removePopupMenuMethod = o.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + addPopupMenuMethod = o.getClass().getMethod( + "addPopupMenuListener", popupMenuListeners); + removePopupMenuMethod.invoke(o, popupMenuArgs); + addPopupMenuMethod.invoke(o, popupMenuArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREEEXPANSION: + try { + removeTreeExpansionMethod = c.getClass().getMethod( + "removeTreeExpansionListener", treeExpansionListeners); + addTreeExpansionMethod = c.getClass().getMethod( + "addTreeExpansionListener", treeExpansionListeners); + try { + removeTreeExpansionMethod.invoke(c, treeExpansionArgs); + addTreeExpansionMethod.invoke(c, treeExpansionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREESELECTION: + try { + removeTreeSelectionMethod = c.getClass().getMethod( + "removeTreeSelectionListener", treeSelectionListeners); + addTreeSelectionMethod = c.getClass().getMethod( + "addTreeSelectionListener", treeSelectionListeners); + try { + removeTreeSelectionMethod.invoke(c, treeSelectionArgs); + addTreeSelectionMethod.invoke(c, treeSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.UNDOABLEEDIT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeUndoableEditListener(this); + ((Document) o).addUndoableEditListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support UndoableEdit listeners + // (no current example) + // + try { + removeUndoableEditMethod = c.getClass().getMethod( + "removeUndoableEditListener", undoableEditListeners); + addUndoableEditMethod = c.getClass().getMethod( + "addUndoableEditListener", undoableEditListeners); + try { + removeUndoableEditMethod.invoke(c, undoableEditArgs); + addUndoableEditMethod.invoke(c, undoableEditArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.INTERNALFRAME: + // Look for components which support InternalFrame listeners + // (e.g. JInternalFrame) + // + try { + removeInternalFrameMethod = c.getClass().getMethod( + "removeInternalFrameListener", internalFrameListeners); + addInternalFrameMethod = c.getClass().getMethod( + "addInternalFrameListener", internalFrameListeners); + try { + removeInternalFrameMethod.invoke(c, internalFrameArgs); + addInternalFrameMethod.invoke(c, internalFrameArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.PROPERTYCHANGE: + // Look for components which support PropertyChange listeners + // (e.g. JComponent) + // + try { + removePropertyChangeMethod = c.getClass().getMethod( + "removePropertyChangeListener", propertyChangeListeners); + addPropertyChangeMethod = c.getClass().getMethod( + "addPropertyChangeListener", propertyChangeListeners); + try { + removePropertyChangeMethod.invoke(c, propertyChangeArgs); + addPropertyChangeMethod.invoke(c, propertyChangeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getSelectionModel method + // (e.g. JTextComponent) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TreeSelectionModel) { + ((TreeSelectionModel) o).removePropertyChangeListener(this); + ((TreeSelectionModel) o).addPropertyChangeListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.VETOABLECHANGE: + if (c instanceof JComponent) { + ((JComponent) c).removeVetoableChangeListener(this); + ((JComponent) c).addVetoableChangeListener(this); + } + break; + + // Don't bother recursing the children if this isn't going to + // accomplish anything. + // + default: + return; + } + + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + installListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /** + * Removes all listeners for the given component and all its children. + * @param c the component + */ + protected void removeListeners(Component c) { + + // conditionaly remove the Swing listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(AncestorListener.class) > 0) { + removeListeners(c,EventID.ANCESTOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(CaretListener.class) > 0) { + removeListeners(c,EventID.CARET); + } + if (SwingEventMonitor.listenerList.getListenerCount(CellEditorListener.class) > 0) { + removeListeners(c,EventID.CELLEDITOR); + } + if (SwingEventMonitor.listenerList.getListenerCount(ChangeListener.class) > 0) { + removeListeners(c,EventID.CHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableColumnModelListener.class) > 0) { + removeListeners(c,EventID.COLUMNMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(DocumentListener.class) > 0) { + removeListeners(c,EventID.DOCUMENT); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListDataListener.class) > 0) { + removeListeners(c,EventID.LISTDATA); + } + if (SwingEventMonitor.listenerList.getListenerCount(ListSelectionListener.class) > 0) { + removeListeners(c,EventID.LISTSELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(MenuListener.class) > 0) { + removeListeners(c,EventID.MENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(PopupMenuListener.class) > 0) { + removeListeners(c,EventID.POPUPMENU); + } + if (SwingEventMonitor.listenerList.getListenerCount(TableModelListener.class) > 0) { + removeListeners(c,EventID.TABLEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeExpansionListener.class) > 0) { + removeListeners(c,EventID.TREEEXPANSION); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeModelListener.class) > 0) { + removeListeners(c,EventID.TREEMODEL); + } + if (SwingEventMonitor.listenerList.getListenerCount(TreeSelectionListener.class) > 0) { + removeListeners(c,EventID.TREESELECTION); + } + if (SwingEventMonitor.listenerList.getListenerCount(UndoableEditListener.class) > 0) { + removeListeners(c,EventID.UNDOABLEEDIT); + } + if (SwingEventMonitor.listenerList.getListenerCount(InternalFrameListener.class) > 0) { + removeListeners(c,EventID.INTERNALFRAME); + } + + // conditionaly remove the beans listeners + // + if (SwingEventMonitor.listenerList.getListenerCount(PropertyChangeListener.class) > 0) { + removeListeners(c,EventID.PROPERTYCHANGE); + } + if (SwingEventMonitor.listenerList.getListenerCount(VetoableChangeListener.class) > 0) { + removeListeners(c,EventID.VETOABLECHANGE); + } + + // Now remove the AWT listeners if needed. + // + super.removeListeners(c); + } + + /** + * Removes all Swing listeners for the event ID from the component and + * all of its children. + * @param c the component to remove listeners from + */ + protected void removeListeners(Component c, int eventID) { + + // remove the appropriate listener hook into this component + // + switch (eventID) { + + case EventID.CONTAINER: + //Never remove these because we're always interested in them + // for our own use. + break; + + case EventID.ANCESTOR: + if (c instanceof JComponent) { + ((JComponent) c).removeAncestorListener(this); + } + break; + + case EventID.CARET: + try { + removeCaretMethod = c.getClass().getMethod( + "removeCaretListener", caretListeners); + try { + removeCaretMethod.invoke(c, caretArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CELLEDITOR: + // Look for components which support the getCellEditor method + // (e.g. JTable, JTree) + // + try { + getCellEditorMethod = c.getClass().getMethod( + "getCellEditorMethod", nullClass); + try { + Object o = getCellEditorMethod.invoke(c, nullArgs); + if (o != null && o instanceof CellEditor) { + ((CellEditor) o).removeCellEditorListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support CellEditor listeners + // (no current example) + // + try { + removeCellEditorMethod = c.getClass().getMethod( + "removeCellEditorListener", cellEditorListeners); + try { + removeCellEditorMethod.invoke(c, cellEditorArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.CHANGE: + // [[[FIXME: Need to add support for Style, StyleContext -pk ]]] + + // Look for components which support Change listeners + // (e.g. AbstractButton, Caret, JProgressBar, JSlider, + // JTabbedpane, JTextComponent, JViewport) + // + try { + removeChangeMethod = c.getClass().getMethod( + "removeChangeListener", changeListeners); + try { + removeChangeMethod.invoke(c, changeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getModel method + // whose model supports Change listeners + // (e.g. BoundedRangeModel, ButtonModel, SingleSelectionModel) + // + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + removeChangeMethod = o.getClass().getMethod( + "removeChangeListener", changeListeners); + removeChangeMethod.invoke(o, changeArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.COLUMNMODEL: + try { + getColumnModelMethod = c.getClass().getMethod( + "getTableColumnModel", nullClass); + try { + Object o = getColumnModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TableColumnModel) { + ((TableColumnModel) o).removeColumnModelListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.DOCUMENT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeDocumentListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support Document listeners + // (no current example) + // + try { + removeDocumentMethod = c.getClass().getMethod( + "removeDocumentListener", documentListeners); + try { + removeDocumentMethod.invoke(c, documentArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.LISTDATA: + case EventID.TABLEMODEL: + case EventID.TREEMODEL: + try { + getModelMethod = c.getClass().getMethod( + "getModel", nullClass); + try { + Object o = getModelMethod.invoke(c, nullArgs); + if (o != null) { + if (eventID == EventID.LISTDATA && + o instanceof ListModel) { + ((ListModel) o).removeListDataListener(this); + } else if (eventID == EventID.TABLEMODEL && + o instanceof TableModel) { + ((TableModel) o).removeTableModelListener(this); + } else if ( + o instanceof TreeModel) { + ((TreeModel) o).removeTreeModelListener(this); + } + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.LISTSELECTION: + // Look for components which support ListSelectionListeners + // (e.g. JList) + // + try { + removeListSelectionMethod = c.getClass().getMethod( + "removeListSelectionListener", listSelectionListeners); + try { + removeListSelectionMethod.invoke(c, listSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for selection models which support + // ListSelectionListeners (e.g. JTable's selection model) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof ListSelectionModel) { + ((ListSelectionModel) o).removeListSelectionListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.MENU: + try { + removeMenuMethod = c.getClass().getMethod( + "removeMenuListener", menuListeners); + try { + removeMenuMethod.invoke(c, menuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.POPUPMENU: + // Look for components which support PopupMenuListeners + // (e.g. JPopupMenu) + // + try { + removePopupMenuMethod = c.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + try { + removePopupMenuMethod.invoke(c, popupMenuArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support getPopupMenu + // (e.g. JMenu) + // + try { + getPopupMenuMethod = c.getClass().getMethod( + "getPopupMenu", nullClass); + try { + Object o = getPopupMenuMethod.invoke(c, nullArgs); + if (o != null) { + removePopupMenuMethod = o.getClass().getMethod( + "removePopupMenuListener", popupMenuListeners); + removePopupMenuMethod.invoke(o, popupMenuArgs); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREEEXPANSION: + try { + removeTreeExpansionMethod = c.getClass().getMethod( + "removeTreeExpansionListener", treeExpansionListeners); + try { + removeTreeExpansionMethod.invoke(c, treeExpansionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.TREESELECTION: + try { + removeTreeSelectionMethod = c.getClass().getMethod( + "removeTreeSelectionListener", treeSelectionListeners); + try { + removeTreeSelectionMethod.invoke(c, treeSelectionArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.UNDOABLEEDIT: + // Look for components which support the getDocument method + // (e.g. JTextComponent) + // + try { + getDocumentMethod = c.getClass().getMethod( + "getDocument", nullClass); + try { + Object o = getDocumentMethod.invoke(c, nullArgs); + if (o != null && o instanceof Document) { + ((Document) o).removeUndoableEditListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support UndoableEdit listeners + // (no current example) + // + try { + removeUndoableEditMethod = c.getClass().getMethod( + "removeUndoableEditListener", undoableEditListeners); + try { + removeUndoableEditMethod.invoke(c, undoableEditArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.INTERNALFRAME: + try { + removeInternalFrameMethod = c.getClass().getMethod( + "removeInternalFrameListener", internalFrameListeners); + try { + removeInternalFrameMethod.invoke(c, internalFrameArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.PROPERTYCHANGE: + // Look for components which support PropertyChange listeners + // (e.g. JComponent) + // + try { + removePropertyChangeMethod = c.getClass().getMethod( + "removePropertyChangeListener", propertyChangeListeners); + try { + removePropertyChangeMethod.invoke(c, propertyChangeArgs); + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + + // Look for components which support the getSelectionModel + // method (e.g. JTextComponent) + // + try { + getSelectionModelMethod = c.getClass().getMethod( + "getSelectionModel", nullClass); + try { + Object o = getSelectionModelMethod.invoke(c, nullArgs); + if (o != null && o instanceof TreeSelectionModel) { + ((TreeSelectionModel) o).removePropertyChangeListener(this); + } + } catch (java.lang.reflect.InvocationTargetException e) { + System.out.println("Exception: " + e.toString()); + } catch (IllegalAccessException e) { + System.out.println("Exception: " + e.toString()); + } + } catch (NoSuchMethodException e) { + // System.out.println("Exception: " + e.toString()); + } catch (SecurityException e) { + System.out.println("Exception: " + e.toString()); + } + break; + + case EventID.VETOABLECHANGE: + if (c instanceof JComponent) { + ((JComponent) c).removeVetoableChangeListener(this); + } + break; + + default: + return; + } + + if (c instanceof Container) { + int count = ((Container) c).getComponentCount(); + for (int i = 0; i < count; i++) { + removeListeners(((Container) c).getComponent(i), eventID); + } + } + } + + /********************************************************************/ + /* */ + /* Listener Interface Methods */ + /* */ + /********************************************************************/ + + /* ContainerListener Methods ************************************/ + + public void componentAdded(ContainerEvent e) { + installListeners(e.getChild()); + } + public void componentRemoved(ContainerEvent e) { + removeListeners(e.getChild()); + } + + /* AncestorListener Methods ******************************************/ + + public void ancestorAdded(AncestorEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==AncestorListener.class) { + ((AncestorListener)listeners[i+1]).ancestorAdded(e); + } + } + } + + public void ancestorRemoved(AncestorEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==AncestorListener.class) { + ((AncestorListener)listeners[i+1]).ancestorRemoved(e); + } + } + } + + public void ancestorMoved(AncestorEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==AncestorListener.class) { + ((AncestorListener)listeners[i+1]).ancestorMoved(e); + } + } + } + + /* CaretListener Methods ******************************************/ + + public void caretUpdate(CaretEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==CaretListener.class) { + ((CaretListener)listeners[i+1]).caretUpdate(e); + } + } + } + + /* CellEditorListener Methods *****************************************/ + + public void editingStopped(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==CellEditorListener.class) { + ((CellEditorListener)listeners[i+1]).editingStopped(e); + } + } + } + + public void editingCanceled(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==CellEditorListener.class) { + ((CellEditorListener)listeners[i+1]).editingCanceled(e); + } + } + } + + /* ChangeListener Methods *****************************************/ + + public void stateChanged(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ChangeListener.class) { + ((ChangeListener)listeners[i+1]).stateChanged(e); + } + } + } + + /* TableColumnModelListener Methods *******************************/ + + public void columnAdded(TableColumnModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnAdded(e); + } + } + } + public void columnMarginChanged(ChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnMarginChanged(e); + } + } + } + public void columnMoved(TableColumnModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnMoved(e); + } + } + } + public void columnRemoved(TableColumnModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnRemoved(e); + } + } + } + public void columnSelectionChanged(ListSelectionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableColumnModelListener.class) { + ((TableColumnModelListener)listeners[i+1]).columnSelectionChanged(e); + } + } + } + + /* DocumentListener Methods **************************************/ + + public void changedUpdate(DocumentEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==DocumentListener.class) { + ((DocumentListener)listeners[i+1]).changedUpdate(e); + } + } + } + public void insertUpdate(DocumentEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==DocumentListener.class) { + ((DocumentListener)listeners[i+1]).insertUpdate(e); + } + } + } + public void removeUpdate(DocumentEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==DocumentListener.class) { + ((DocumentListener)listeners[i+1]).removeUpdate(e); + } + } + } + + /* ListDataListener Methods *****************************************/ + + public void contentsChanged(ListDataEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListDataListener.class) { + ((ListDataListener)listeners[i+1]).contentsChanged(e); + } + } + } + public void intervalAdded(ListDataEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListDataListener.class) { + ((ListDataListener)listeners[i+1]).intervalAdded(e); + } + } + } + public void intervalRemoved(ListDataEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListDataListener.class) { + ((ListDataListener)listeners[i+1]).intervalRemoved(e); + } + } + } + + /* ListSelectionListener Methods ***********************************/ + + public void valueChanged(ListSelectionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ListSelectionListener.class) { + ((ListSelectionListener)listeners[i+1]).valueChanged(e); + } + } + } + + /* MenuListener Methods *****************************************/ + + public void menuCanceled(MenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==MenuListener.class) { + ((MenuListener)listeners[i+1]).menuCanceled(e); + } + } + } + public void menuDeselected(MenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==MenuListener.class) { + ((MenuListener)listeners[i+1]).menuDeselected(e); + } + } + } + public void menuSelected(MenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==MenuListener.class) { + ((MenuListener)listeners[i+1]).menuSelected(e); + } + } + } + + /* PopupMenuListener Methods **************************************/ + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PopupMenuListener.class) { + ((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeVisible(e); + } + } + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PopupMenuListener.class) { + ((PopupMenuListener)listeners[i+1]).popupMenuWillBecomeInvisible(e); + } + } + } + + public void popupMenuCanceled(PopupMenuEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PopupMenuListener.class) { + ((PopupMenuListener)listeners[i+1]).popupMenuCanceled(e); + } + } + } + + /* TableModelListener Methods **************************************/ + + public void tableChanged(TableModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TableModelListener.class) { + ((TableModelListener)listeners[i+1]).tableChanged(e); + } + } + } + + /* TreeExpansionListener Methods **********************************/ + + public void treeCollapsed(TreeExpansionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeExpansionListener.class) { + ((TreeExpansionListener)listeners[i+1]).treeCollapsed(e); + } + } + } + public void treeExpanded(TreeExpansionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeExpansionListener.class) { + ((TreeExpansionListener)listeners[i+1]).treeExpanded(e); + } + } + } + + /* TreeModelListener Methods **********************************/ + + public void treeNodesChanged(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeNodesChanged(e); + } + } + } + public void treeNodesInserted(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeNodesInserted(e); + } + } + } + public void treeNodesRemoved(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e); + } + } + } + public void treeStructureChanged(TreeModelEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + ((TreeModelListener)listeners[i+1]).treeStructureChanged(e); + } + } + } + + /* TreeSelectionListener Methods ***********************************/ + + public void valueChanged(TreeSelectionEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeSelectionListener.class) { + ((TreeSelectionListener)listeners[i+1]).valueChanged(e); + } + } + } + + /* UndoableEditListener Methods **************************************/ + + public void undoableEditHappened(UndoableEditEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==UndoableEditListener.class) { + ((UndoableEditListener)listeners[i+1]).undoableEditHappened(e); + } + } + } + + /* InternalFrame Methods **********************************/ + + public void internalFrameOpened(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e); + } + } + } + + public void internalFrameActivated(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e); + } + } + } + + public void internalFrameDeactivated(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e); + } + } + } + + public void internalFrameIconified(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameIconified(e); + } + } + } + + public void internalFrameDeiconified(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameDeiconified(e); + } + } + } + + public void internalFrameClosing(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e); + } + } + } + + public void internalFrameClosed(InternalFrameEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==InternalFrameListener.class) { + ((InternalFrameListener)listeners[i+1]).internalFrameClosed(e); + } + } + } + + /* PropertyChangeListener Methods **********************************/ + + public void propertyChange(PropertyChangeEvent e) { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==PropertyChangeListener.class) { + ((PropertyChangeListener)listeners[i+1]).propertyChange(e); + } + } + // Re-add the monitor as a DocumentChangeListener if + // the document changed in the text component. + if (e.getSource() instanceof JTextComponent) { + Document c = ((JTextComponent)e.getSource()).getDocument(); + if (c == null) { + return; + } + try { + removeDocumentMethod = c.getClass().getMethod( + "removeDocumentListener", documentListeners); + addDocumentMethod = c.getClass().getMethod( + "addDocumentListener", documentListeners); + try { + removeDocumentMethod.invoke(c, documentArgs); + addDocumentMethod.invoke(c, documentArgs); + } catch (java.lang.reflect.InvocationTargetException e2) { + System.out.println("Exception: " + e2.toString()); + } catch (IllegalAccessException e2) { + System.out.println("Exception: " + e2.toString()); + } + } catch (NoSuchMethodException e2) { + // System.out.println("Exception: " + e2.toString()); + } catch (SecurityException e2) { + System.out.println("Exception: " + e2.toString()); + } + } + + } + + /* VetoableChangeListener Methods **********************************/ + + public void vetoableChange(PropertyChangeEvent e) + throws PropertyVetoException { + Object[] listeners = SwingEventMonitor.listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==VetoableChangeListener.class) { + ((VetoableChangeListener)listeners[i+1]).vetoableChange(e); + } + } + } + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java new file mode 100644 index 00000000000..94d03307a7a --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/TopLevelWindowListener.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.*; +import javax.accessibility.*; + +/** + * The {@code TopLevelWindowListener} interface is used by the {@link EventQueueMonitor} + * class to notify an interested party when a top level window is created + * or destroyed in the Java Virtual Machine. Classes wishing to express + * an interest in top level window events should implement this interface + * and register themselves with the {@code EventQueueMonitor} by calling the + * {@link EventQueueMonitor#addTopLevelWindowListener EventQueueMonitor.addTopLevelWindowListener} + * class method. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + * @see EventQueueMonitor#removeTopLevelWindowListener + * + */ +@jdk.Exported +public interface TopLevelWindowListener extends EventListener { + + /** + * Invoked when a new top level window has been created. + * + * @param w the Window that was created + */ + public void topLevelWindowCreated(Window w); + + /** + * Invoked when a top level window has been destroyed. + * + * @param w the Window that was destroyed + */ + public void topLevelWindowDestroyed(Window w); +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java new file mode 100644 index 00000000000..31ca38020ea --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/TopLevelWindowMulticaster.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util; + +import java.awt.*; +import java.util.EventListener; +import javax.accessibility.*; + + +/** + * The TopLevelWindowMulticaster class is used to maintain a list of + * TopLevelWindowListener classes. It is intended to be used primarily + * for internal support in the EventQueueMonitor class, and is not intended + * to be used by classes outside the Java Accessibility Utility package. + * + * @see EventQueueMonitor + * @see EventQueueMonitor#addTopLevelWindowListener + * @see EventQueueMonitor#removeTopLevelWindowListener + * + */ +class TopLevelWindowMulticaster + extends AWTEventMulticaster implements TopLevelWindowListener +{ + protected TopLevelWindowMulticaster(EventListener a, EventListener b) { + super(a, b); + } + + public void topLevelWindowCreated(Window w) { + ((TopLevelWindowListener)a).topLevelWindowCreated(w); + ((TopLevelWindowListener)b).topLevelWindowCreated(w); + } + + public void topLevelWindowDestroyed(Window w) { + ((TopLevelWindowListener)a).topLevelWindowDestroyed(w); + ((TopLevelWindowListener)b).topLevelWindowDestroyed(w); + } + + public static TopLevelWindowListener add(TopLevelWindowListener a, TopLevelWindowListener b) { + return (TopLevelWindowListener)addInternal(a, b); + } + + public static TopLevelWindowListener remove(TopLevelWindowListener l, TopLevelWindowListener oldl) { + return (TopLevelWindowListener)removeInternal(l, oldl); + } + + protected static EventListener addInternal(EventListener a, EventListener b) { + if (a == null) return b; + if (b == null) return a; + return new TopLevelWindowMulticaster(a, b); + } + + protected static EventListener removeInternal(EventListener l, EventListener oldl) { + if (l == oldl || l == null) { + return null; + } else if (l instanceof TopLevelWindowMulticaster) { + return ((TopLevelWindowMulticaster)l).remove(oldl); + } else { + return l; // it's not here + } + } + +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java new file mode 100644 index 00000000000..2112bd2ea3b --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java @@ -0,0 +1,744 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package com.sun.java.accessibility.util; + +import java.lang.*; +import java.beans.*; +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +// Do not import Swing classes. This module is intended to work +// with both Swing and AWT. +// import javax.swing.*; +import javax.accessibility.*; + +/** + *

                                  The {@code Translator} class provides a translation to interface + * {@link javax.accessibility.Accessible Accessible} + * for objects that do not implement interface {@code Accessible}. Assistive + * technologies can use the {@link #getAccessible getAccessible} class method of + * {@code Translator} to obtain an object that implements interface {@code Accessible}. + * If the object passed in already implements interface {@code Accessible}, + * {@code getAccessible} merely returns the object. + * + *

                                  An example of how an assistive technology might use the {@code Translator} + * class is as follows: + * + *

                                  + *    Accessible accessible = Translator.getAccessible(someObj);
                                  + *    // obtain information from the 'accessible' object.
                                  + * 
                                  + * + *

                                  Note: This implementation is missing many things and is not a recommended way + * to implement accessibility features for a toolkit. Instead of relying upon this + * code, a toolkit's components should implement interface {@code Accessible} directly. + */ +@jdk.Exported +public class Translator extends AccessibleContext + implements Accessible, AccessibleComponent { + + /** The source object needing translating. */ + protected Object source; + + /** + * Find a translator for this class. If one doesn't exist for this + * class explicitly, try its superclass and so on. + * + * @param c a Class + * @return the {@code Translator} Class for the Class passed in + */ + protected static Class getTranslatorClass(Class c) { + Class t = null; + if (c == null) { + return null; + } + try { + t = Class.forName("com.sun.java.accessibility.util." + + c.getName() + + "Translator"); + return t; + } catch (Exception e) { + return getTranslatorClass(c.getSuperclass()); + } + } + + /** + * Obtain an object that implements interface {@code Accessible}. If the object + * passed in already implements interface {@code Accessible}, {@code getAccessible} + * merely returns the object. + * + * @param o an Object; if a null is passed in a null is returned + * @return an {@code Object}, possibly the {@code Object} passed in, that + * implements the {@code Accessible} interface for the {@code Object} + * which was passed in + */ + public static Accessible getAccessible(Object o) { + Accessible a = null; + + if (o == null) { + return null; + } + if (o instanceof Accessible) { + a = (Accessible)o; + } else { + Class translatorClass = getTranslatorClass(o.getClass()); + if (translatorClass != null) { + try { + Translator t = (Translator)translatorClass.newInstance(); + t.setSource(o); + a = t; + } catch (Exception e) { + } + } + } + if (a == null) { + a = new Translator(o); + } + return a; + } + + /** + * Create a new {@code Translator}. You must call the {@link #setSource setSource} + * method to set the object to be translated after calling this constructor. + */ + public Translator() { + } + + /** + * Create a new {@code Translator} with the source object o. + * + * @param o the Component that does not implement interface + * {@link javax.accessibility.Accessible Accessible} + */ + public Translator(Object o) { + source = o; + } + + /** + * Get the source {@code Object} of the {@code Translator}. + * + * @return the source {@code Object} of the {@code Translator} + */ + public Object getSource() { + return source; + } + + /** + * Set the source object of the {@code Translator}. + * + * @param o the Component that does not implement interface Accessible + */ + public void setSource(Object o) { + source = o; + } + + /** + * Returns true if this object is the same as the one passed in. + * + * @param o the {@code Object} to check against + * @return true if this is the same object + */ + public boolean equals(Object o) { + if (o instanceof Translator) { + return java.util.Objects.equals(source, o); + } else { + return false; + } + } + + /** + * Return hashcode. + * + * @return hashcode + */ + public int hashCode() { + return java.util.Objects.hashCode(source); + } + + +// Accessible methods + + /** + * Returns this object. + */ + public AccessibleContext getAccessibleContext() { + return this; + } + +// AccessibleContext methods + + /** + * Get the accessible name of this object. + * + * @return the localized name of the object; can be null if this object + * does not have a name + */ + public String getAccessibleName() { + if (source instanceof MenuItem) { + return ((MenuItem) source).getLabel(); + } else if (source instanceof Component) { + return ((Component) source).getName(); + } else { + return null; + } + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + if (source instanceof MenuItem) { + ((MenuItem) source).setLabel(s); + } else if (source instanceof Component) { + ((Component) source).setName(s); + } + } + + /** + * Get the accessible description of this object. + * + * @return the description of the object; can be null if this object does + * not have a description + */ + public String getAccessibleDescription() { + return null; + } + + /** + * Set the accessible description of this object. + * + * @param s the new localized description of the object + */ + public void setAccessibleDescription(String s) { + } + + /** + * Get the role of this object. + * + * @return an instance of AccessibleRole describing the role of the object + */ + public AccessibleRole getAccessibleRole() { + return AccessibleRole.UNKNOWN; + } + + + /** + * Get the state of this object, given an already populated state. + * This method is intended for use by subclasses so they don't have + * to check for everything. + * + * @return an instance of {@code AccessibleStateSet} + * containing the current state of the object + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = new AccessibleStateSet(); + if (source instanceof Component) { + Component c = (Component) source; + for (Container p = c.getParent(); p != null; p = p.getParent()) { + if (p instanceof Window) { + if (((Window)p).getFocusOwner() == c) { + states.add(AccessibleState.FOCUSED); + } + } + } + } + if (isEnabled()) { + states.add(AccessibleState.ENABLED); + } + if (isFocusTraversable()) { + states.add(AccessibleState.FOCUSABLE); + } + if (source instanceof MenuItem) { + states.add(AccessibleState.FOCUSABLE); + } + return states; + } + + /** + * Get the accessible parent of this object. + * + * @return the accessible parent of this object; can be null if this + * object does not have an accessible parent + */ + public Accessible getAccessibleParent() { + if (accessibleParent != null) { + return accessibleParent; + } else if (source instanceof Component) { + return getAccessible(((Component) source).getParent()); + } else { + return null; + } + } + + /** + * Get the index of this object in its accessible parent. + * + * @return -1 of this object does not have an accessible parent; otherwise, + * the index of the child in its accessible parent + */ + public int getAccessibleIndexInParent() { + if (source instanceof Component) { + Container parent = ((Component) source).getParent(); + if (parent != null) { + Component ca[] = parent.getComponents(); + for (int i = 0; i < ca.length; i++) { + if (source.equals(ca[i])) { + return i; + } + } + } + } + return -1; + } + + /** + * Returns the number of accessible children in the object. + * + * @return the number of accessible children in the object + */ + public int getAccessibleChildrenCount() { + if (source instanceof Container) { + Component[] children = ((Container) source).getComponents(); + int count = 0; + for (int i = 0; i < children.length; i++) { + Accessible a = getAccessible(children[i]); + if (a != null) { + count++; + } + } + return count; + } else { + return 0; + } + } + + /** + * Return the nth accessible child of the object. + * + * @param i zero-based index of child + * @return the nth accessible child of the object + */ + public Accessible getAccessibleChild(int i) { + if (source instanceof Container) { + Component[] children = ((Container) source).getComponents(); + int count = 0; + + for (int j = 0; j < children.length; j++) { + Accessible a = getAccessible(children[j]); + if (a != null) { + if (count == i) { + AccessibleContext ac = a.getAccessibleContext(); + if (ac != null) { + ac.setAccessibleParent(this); + } + return a; + } else { + count++; + } + } + } + } + return null; + } + + /** + * Gets the {@code Locale} of the component. If the component does not have a + * locale, the locale of its parent is returned. + * + * @return the {@code Locale} of the object + */ + public Locale getLocale() throws IllegalComponentStateException { + if (source instanceof Component) { + return ((Component) source).getLocale(); + } else { + return null; + } + } + + /** + * Add a {@code PropertyChangeListener} to the listener list. The listener + * is registered for all properties. + */ + public void addPropertyChangeListener(PropertyChangeListener l) { + } + + /** + * Remove the {@code PropertyChangeListener} from the listener list. + */ + public void removePropertyChangeListener(PropertyChangeListener l) { + } + +// AccessibleComponent methods + + /** + * Get the background {@code Color} of this object. + * + * @return if supported, the background {@code Color} of the object; + * otherwise, null + * + */ + public Color getBackground() { + if (source instanceof Component) { // MenuComponent doesn't do background + return ((Component) source).getBackground(); + } else { + return null; + } + } + + /** + * Set the background {@code Color} of this object. + * + * @param c the new {@code Color} for the background + */ + public void setBackground(Color c) { + if (source instanceof Component) { // MenuComponent doesn't do background + ((Component) source).setBackground(c); + } + } + + /** + * Get the foreground {@code Color} of this object. + * + * @return if supported, the foreground {@code Color} of the object; otherwise, null + */ + public Color getForeground() { + if (source instanceof Component) { // MenuComponent doesn't do foreground + return ((Component) source).getForeground(); + } else { + return null; + } + } + + /** + * Set the foreground {@code Color} of this object. + * + * @param c the new {@code Color} for the foreground + */ + public void setForeground(Color c) { + if (source instanceof Component) { // MenuComponent doesn't do foreground + ((Component) source).setForeground(c); + } + } + + /** + * Get the {@code Cursor} of this object. + * + * @return if supported, the Cursor of the object; otherwise, null + */ + public Cursor getCursor() { + if (source instanceof Component) { // MenuComponent doesn't do cursor + return ((Component) source).getCursor(); + } else { + return null; + } + } + + /** + * Set the {@code Cursor} of this object. + * @param c the new {@code Cursor} for the object + */ + public void setCursor(Cursor c) { + if (source instanceof Component) { // MenuComponent doesn't do cursor + ((Component) source).setCursor(c); + } + } + + /** + * Get the {@code Font} of this object. + * + * @return if supported, the {@code Font} for the object; otherwise, null + */ + public Font getFont() { + if (source instanceof Component) { + return ((Component) source).getFont(); + } else if (source instanceof MenuComponent) { + return ((MenuComponent) source).getFont(); + } else { + return null; + } + } + + /** + * Set the {@code Font} of this object. + * + * @param f the new {@code Font} for the object + */ + public void setFont(Font f) { + if (source instanceof Component) { + ((Component) source).setFont(f); + } else if (source instanceof MenuComponent) { + ((MenuComponent) source).setFont(f); + } + } + + /** + * Get the {@code FontMetrics} of this object. + * + * @param f the {@code Font} + * @return if supported, the {@code FontMetrics} the object; otherwise, null + * @see #getFont + */ + public FontMetrics getFontMetrics(Font f) { + if (source instanceof Component) { + return ((Component) source).getFontMetrics(f); + } else { + return null; + } + } + + /** + * Determine if the object is enabled. + * + * @return true if object is enabled; otherwise, false + */ + public boolean isEnabled() { + if (source instanceof Component) { + return ((Component) source).isEnabled(); + } else if (source instanceof MenuItem) { + return ((MenuItem) source).isEnabled(); + } else { + return true; + } + } + + /** + * Set the enabled state of the object. + * + * @param b if true, enables this object; otherwise, disables it + */ + public void setEnabled(boolean b) { + if (source instanceof Component) { + ((Component) source).setEnabled(b); + } else if (source instanceof MenuItem) { + ((MenuItem) source).setEnabled(b); + } + } + + /** + * Determine if the object is visible. + * + * @return true if object is visible; otherwise, false + */ + public boolean isVisible() { + if (source instanceof Component) { + return ((Component) source).isVisible(); + } else { + return false; + } + } + + /** + * Set the visible state of the object. + * + * @param b if true, shows this object; otherwise, hides it + */ + public void setVisible(boolean b) { + if (source instanceof Component) { + ((Component) source).setVisible(b); + } + } + + /** + * Determine if the object is showing. This is determined by checking + * the visibility of the object and ancestors of the object. + * + * @return true if object is showing; otherwise, false + */ + public boolean isShowing() { + if (source instanceof Component) { + return ((Component) source).isShowing(); + } else { + return false; + } + } + + /** + * Checks whether the specified {@code Point} is within this + * object's bounds, where the {@code Point} is relative to the coordinate + * system of the object. + * + * @param p the {@code Point} relative to the coordinate system of the object + * @return true if object contains {@code Point}; otherwise false + */ + public boolean contains(Point p) { + if (source instanceof Component) { + return ((Component) source).contains(p); + } else { + return false; + } + } + + /** + * Returns the location of the object on the screen. + * + * @return location of object on screen; can be null if this object + * is not on the screen + */ + public Point getLocationOnScreen() { + if (source instanceof Component) { + return ((Component) source).getLocationOnScreen(); + } else { + return null; + } + } + + /** + * Returns the location of the object relative to parent. + * + * @return location of object relative to parent; can be null if + * this object or its parent are not on the screen + */ + public Point getLocation() { + if (source instanceof Component) { + return ((Component) source).getLocation(); + } else { + return null; + } + } + + /** + * Sets the location of the object relative to parent. + */ + public void setLocation(Point p) { + if (source instanceof Component) { + ((Component) source).setLocation(p); + } + } + + /** + * Returns the current bounds of this object. + * + * @return current bounds of object; can be null if this object + * is not on the screen + */ + public Rectangle getBounds() { + if (source instanceof Component) { + return ((Component) source).getBounds(); + } else { + return null; + } + } + + /** + * Sets the current bounds of this object. + */ + public void setBounds(Rectangle r) { + if (source instanceof Component) { + ((Component) source).setBounds(r); + } + } + + /** + * Returns the current size of this object. + * + * @return current size of object; can be null if this object is + * not on the screen + */ + public Dimension getSize() { + if (source instanceof Component) { + return ((Component) source).getSize(); + } else { + return null; + } + } + + /** + * Sets the current size of this object. + */ + public void setSize(Dimension d) { + if (source instanceof Component) { + ((Component) source).setSize(d); + } + } + + /** + * Returns the accessible child contained at the local coordinate + * Point, if one exists. + * + * @return the Accessible at the specified location, if it exists + */ + public Accessible getAccessibleAt(Point p) { + if (source instanceof Component) { + Component c = ((Component) source).getComponentAt(p); + if (c != null) { + return (getAccessible(c)); + } + } + return null; + } + + /** + * Returns whether this object can accept focus or not. + * + * @return true if object can accept focus; otherwise false + */ + @SuppressWarnings("deprecation") + public boolean isFocusTraversable() { + if (source instanceof Component) { + return ((Component) source).isFocusTraversable(); + } else { + return false; + } + } + + /** + * Requests focus for this object. + */ + public void requestFocus() { + if (source instanceof Component) { + ((Component) source).requestFocus(); + } + } + + /** + * Adds the specified {@code FocusListener} to receive focus events from + * this component. + * + * @param l the focus listener + */ + public synchronized void addFocusListener(FocusListener l) { + if (source instanceof Component) { + ((Component) source).addFocusListener(l); + } + } + + /** + * Removes the specified focus listener so it no longer receives focus + * events from this component. + * + * @param l the focus listener; this method performs no function, nor does it + * throw an exception if the listener specified was not previously added + * to this component; if listener is null, no exception is thrown and no + * action is performed. + */ + public synchronized void removeFocusListener(FocusListener l) { + if (source instanceof Component) { + ((Component) source).removeFocusListener(l); + } + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java new file mode 100644 index 00000000000..d775e6e475e --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ButtonTranslator.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

                                  The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

                                  An example of how an assistive technology might use the Translator + * class is as follows: + * + *

                                  + *    Accessible accessible = Translator.getAccessible(someObj);
                                  + *    // obtain information from the 'accessible' object.
                                  + * 
                                  + * + *

                                  This class extends the Translator class to provide specific support + * for the Button class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Button. + * + */ +public class ButtonTranslator extends Translator { + + /** + * Get the name of this object. + * @return the name of the object -- can be null if this object does + * not have a name + */ + public String getAccessibleName() { + return ((Button) source).getLabel(); + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + ((Button) source).setLabel(s); + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.PUSH_BUTTON; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java new file mode 100644 index 00000000000..2f131e2c733 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/CheckboxTranslator.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

                                  The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

                                  An example of how an assistive technology might use the Translator + * class is as follows: + * + *

                                  + *    Accessible accessible = Translator.getAccessible(someObj);
                                  + *    // obtain information from the 'accessible' object.
                                  + * 
                                  + * + *

                                  This class extends the Translator class to provide specific support + * for the Checkbox class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Checkbox. + * + */ +public class CheckboxTranslator extends Translator { + + /** + * Get the state of this object. + * @return an instance of AccessibleState containing the current state of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = super.getAccessibleStateSet(); + if (((Checkbox) source).getState()) { + states.add(AccessibleState.CHECKED); + } + return states; + } + + /** + * Get the name of this object. + * @return the name of the object -- can be null if this object does + * not have a name + */ + public String getAccessibleName() { + return ((Checkbox) source).getLabel(); + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + ((Checkbox) source).setLabel(s); + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.CHECK_BOX; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java new file mode 100644 index 00000000000..33a27897c78 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/LabelTranslator.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

                                  The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

                                  An example of how an assistive technology might use the Translator + * class is as follows: + * + *

                                  + *    Accessible accessible = Translator.getAccessible(someObj);
                                  + *    // obtain information from the 'accessible' object.
                                  + * 
                                  + * + *

                                  This class extends the Translator class to provide specific support + * for the Label class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for Label. + * + */ +public class LabelTranslator extends Translator { + + public String getAccessibleName() { + return ((Label) source).getText(); + } + + /** + * Set the name of this object. + */ + public void setAccessibleName(String s) { + ((Label) source).setText(s); + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.LABEL; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java new file mode 100644 index 00000000000..de1c469928e --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/ListTranslator.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

                                  The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

                                  An example of how an assistive technology might use the Translator + * class is as follows: + * + *

                                  + *    Accessible accessible = Translator.getAccessible(someObj);
                                  + *    // obtain information from the 'accessible' object.
                                  + * 
                                  + * + *

                                  This class extends the Translator class to provide specific support + * for the List class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for List. + * + */ +public class ListTranslator extends Translator { + + /** + * Get the state of this object. + * @return an instance of AccessibleState containing the current state of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + AccessibleStateSet states = super.getAccessibleStateSet(); + if (((java.awt.List) source).isMultipleMode()) { + states.add(AccessibleState.MULTISELECTABLE); + } + if (((java.awt.List) source).getSelectedItems().length > 0) { + states.add(AccessibleState.SELECTED); + } + return states; + } + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.LIST; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java new file mode 100644 index 00000000000..3ac3fabb708 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/java/awt/TextComponentTranslator.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility.util.java.awt; + +import java.lang.*; +import java.util.*; +import java.awt.*; +import java.awt.image.*; +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; + +/** + *

                                  The Translator class provides a translation to interface Accessible + * for objects that do not implement interface Accessible. Assistive + * technologies can use the 'getAccessible' class method of Translator to + * obtain an object that implements interface Accessible. If the object + * passed in already implements interface Accessible, getAccessible merely + * returns the object. + * + *

                                  An example of how an assistive technology might use the Translator + * class is as follows: + * + *

                                  + *    Accessible accessible = Translator.getAccessible(someObj);
                                  + *    // obtain information from the 'accessible' object.
                                  + * 
                                  + * + *

                                  This class extends the Translator class to provide specific support + * for the TextComponent class. Translator.getAccessible() will automatically + * load this class when an assistive technology asks for an accessible + * translator for TextComponent. + * + */ +public class TextComponentTranslator extends Translator { + + public AccessibleRole getAccessibleRole() { + return AccessibleRole.TEXT; + } +} diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/package-info.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/package-info.java new file mode 100644 index 00000000000..f3b0a62dd36 --- /dev/null +++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/package-info.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Provides a collection of interfaces and classes that compose the Java Accessibility + * Utilities. The classes are used by Assistive Technologies, such as the screen + * readers which are used by those who are blind, and help provide access to GUI + * toolkits that implement the Java Accessibility API. An overview of the important + * classes follows. + * + *

                                  The class {@code AccessibilityEventMonitor} implements a PropertyChange + * listener on every UI object that implements interface {@code Accessible} in the Java + * Virtual Machine. + * + *

                                  The class {@code AWTEventMonitor} implements a suite of listeners that are + * conditionally installed on every AWT component instance in the Java Virtual Machine. + * + *

                                  The class {@code EventQueueMonitor} provides key core functionality for + * Assistive Technologies (and other system-level technologies that need some of + * the same things that Assistive Technology needs). + * + *

                                  The class {@code GUIInitializedMulticaster} is used to maintain a list of + * {@code GUIInitializedListener} classes which are used by the {@code EventQueueMonitor} + * class to notify an interested party when the GUI subsystem has been initialized. + * Note that this class is intended to be used primarily for internal support in + * the {@code EventQueueMonitor} class, and is not intended to be used by classes + * outside the Java Accessibility Utility package. + * + *

                                  The class {@code SwingEventMonitor} extends {@code AWTEventMonitor} by adding + * a suite of listeners conditionally installed on every Swing component instance + * in the Java Virtual Machine. + * + *

                                  The class {@code TopLevelWindowMulticaster} is used to maintain a list of + * {@code TopLevelWindowListener} classes which are used by the {@code EventQueueMonitor} + * class to notify an interested party when a top level window is created or destroyed + * in the Java Virtual Machine Note that this class is intended to be used primarily + * for internal support in the {@code EventQueueMonitor} class, and is not intended + * to be used by classes outside the Java Accessibility Utility package. + * + *

                                  The class {@code Translator} provides a translation to interface {@code Accessible} + * for objects that do not implement interface {@code Accessible}. + * + * @since JDK1.7 + */ +package com.sun.java.accessibility.util; diff --git a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/AccessBridge.java b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/AccessBridge.java new file mode 100644 index 00000000000..5c47d382324 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/AccessBridge.java @@ -0,0 +1,7170 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.accessibility; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.lang.*; +import java.lang.reflect.*; + +import java.beans.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import javax.swing.tree.*; +import javax.swing.table.*; +import javax.swing.plaf.TreeUI; + +import javax.accessibility.*; +import com.sun.java.accessibility.util.*; +import sun.awt.AWTAccessor; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; + +/* + * Note: This class has to be public. It's loaded from the VM like this: + * Class.forName(atName).newInstance(); + */ +@jdk.Exported(false) +final public class AccessBridge { + + private static AccessBridge theAccessBridge; + private ObjectReferences references; + private EventHandler eventHandler; + + // Maps AccessibleRoles strings to AccessibleRoles. + private ConcurrentHashMap accessibleRoleMap = new ConcurrentHashMap<>(); + + /** + If the object's role is in the following array getVirtualAccessibleName + will use the extended search algorithm. + */ + private ArrayList extendedVirtualNameSearchRoles = new ArrayList<>(); + /** + If the role of the object's parent is in the following array + getVirtualAccessibleName will NOT use the extended search + algorithm even if the object's role is in the + extendedVirtualNameSearchRoles array. + */ + private ArrayList noExtendedVirtualNameSearchParentRoles = new ArrayList<>(); + + private static native boolean isSysWow(); + + + /** + * Load DLLs + */ + static { + // Load the appropriate DLLs + boolean is32on64 = false; + if (System.getProperty("os.arch").equals("x86")) { + // 32 bit JRE + // Load jabsysinfo.dll so can determine Win bitness + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("jabsysinfo"); + return null; + } + }, null, new java.lang.RuntimePermission("loadLibrary.jabsysinfo") + ); + if (isSysWow()) { + // 32 bit JRE on 64 bit OS + is32on64 = true; + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("javaaccessbridge-32"); + return null; + } + }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge-32") + ); + } + } + if (!is32on64) { + // 32 bit JRE on 32 bit OS or 64 bit JRE on 64 bit OS + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + System.loadLibrary("javaaccessbridge"); + return null; + } + }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge") + ); + } + } + + /** + * AccessBridge constructor + * + * Note: This constructor has to be public. It's called from the VM like this: + * Class.forName(atName).newInstance(); + */ + public AccessBridge() { + theAccessBridge = this; + references = new ObjectReferences(); + + // initialize shutdown hook + Runtime runTime = Runtime.getRuntime(); + shutdownHook hook = new shutdownHook(); + runTime.addShutdownHook(new Thread(hook)); + + // initialize AccessibleRole map + initAccessibleRoleMap(); + + // determine which version of the JDK is running + String version = getJavaVersionProperty(); + debugString("JDK version = "+version); + + // initialize the methods that map HWNDs and Java top-level + // windows + initHWNDcalls(); + + // is this a JVM we can use? + // install JDK 1.2 and later Swing ToolKit listener + EventQueueMonitor.isGUIInitialized(); + + // start the Java event handler + eventHandler = new EventHandler(this); + + // register for menu selection events + MenuSelectionManager.defaultManager().addChangeListener(eventHandler); + + // register as a NativeWindowHandler + addNativeWindowHandler(new DefaultNativeWindowHandler()); + + // start in a new thread + Thread abthread = new Thread(new dllRunner()); + abthread.setDaemon(true); + abthread.start(); + debugString("AccessBridge started"); + } + + /* + * adaptor to run the AccessBridge DLL + */ + private class dllRunner implements Runnable { + public void run() { + runDLL(); + } + } + + /* + * shutdown hook + */ + private class shutdownHook implements Runnable { + + public void run() { + debugString("***** shutdownHook: shutting down..."); + javaShutdown(); + } + } + + + /* + * Initialize the hashtable that maps Strings to AccessibleRoles. + */ + private void initAccessibleRoleMap() { + /* + * Initialize the AccessibleRoles map. This code uses methods in + * java.lang.reflect.* to build the map. + */ + try { + Class clAccessibleRole = Class.forName ("javax.accessibility.AccessibleRole"); + if (null != clAccessibleRole) { + AccessibleRole roleUnknown = AccessibleRole.UNKNOWN; + Field [] fields = clAccessibleRole.getFields (); + int i = 0; + for (i = 0; i < fields.length; i ++) { + Field f = fields [i]; + if (javax.accessibility.AccessibleRole.class == f.getType ()) { + AccessibleRole nextRole = (AccessibleRole) (f.get (roleUnknown)); + String nextRoleString = nextRole.toDisplayString (Locale.US); + accessibleRoleMap.put (nextRoleString, nextRole); + } + } + } + } catch (Exception e) {} + + /* + Build the extendedVirtualNameSearchRoles array list. I chose this method + because some of the Accessible Roles that need to be added to it are not + available in all versions of the J2SE that we want to support. + */ + extendedVirtualNameSearchRoles.add (AccessibleRole.COMBO_BOX); + try { + /* + Added in J2SE 1.4 + */ + extendedVirtualNameSearchRoles.add (AccessibleRole.DATE_EDITOR); + } catch (NoSuchFieldError e) {} + extendedVirtualNameSearchRoles.add (AccessibleRole.LIST); + extendedVirtualNameSearchRoles.add (AccessibleRole.PASSWORD_TEXT); + extendedVirtualNameSearchRoles.add (AccessibleRole.SLIDER); + try { + /* + Added in J2SE 1.3 + */ + extendedVirtualNameSearchRoles.add (AccessibleRole.SPIN_BOX); + } catch (NoSuchFieldError e) {} + extendedVirtualNameSearchRoles.add (AccessibleRole.TABLE); + extendedVirtualNameSearchRoles.add (AccessibleRole.TEXT); + extendedVirtualNameSearchRoles.add (AccessibleRole.UNKNOWN); + + noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TABLE); + noExtendedVirtualNameSearchParentRoles.add (AccessibleRole.TOOL_BAR); + } + + /** + * start the AccessBridge DLL running in its own thread + */ + private native void runDLL(); + + /** + * debugging output (goes to OutputDebugStr()) + */ + private native void sendDebugString(String debugStr); + + /** + * debugging output (goes to OutputDebugStr()) + */ + private void debugString(String debugStr) { + sendDebugString(debugStr); + } + + /* ===== utility methods ===== */ + + /** + * decrement the reference to the object (called by native code) + */ + private void decrementReference(Object o) { + references.decrement(o); + } + + /** + * get the java.version property from the JVM + */ + private String getJavaVersionProperty() { + String s = System.getProperty("java.version"); + if (s != null) { + references.increment(s); + return s; + } + return null; + } + + /* ===== HWND/Java window mapping methods ===== */ + + // Java toolkit methods for mapping HWNDs to Java components + private Method javaGetComponentFromNativeWindowHandleMethod; + private Method javaGetNativeWindowHandleFromComponentMethod; + + // native jawt methods for mapping HWNDs to Java components + private native int jawtGetNativeWindowHandleFromComponent(Component comp); + + private native Component jawtGetComponentFromNativeWindowHandle(int handle); + + Toolkit toolkit; + + /** + * map an HWND to an AWT Component + */ + private void initHWNDcalls() { + Class integerParemter[] = new Class[1]; + integerParemter[0] = Integer.TYPE; + Class componentParemter[] = new Class[1]; + try { + componentParemter[0] = Class.forName("java.awt.Component"); + } catch (ClassNotFoundException e) { + debugString("Exception: " + e.toString()); + } + toolkit = Toolkit.getDefaultToolkit(); + return; + } + + // native window handler interface + private interface NativeWindowHandler { + public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle); + } + + // hash table of native window handle to AccessibleContext mappings + static private ConcurrentHashMap windowHandleToContextMap = new ConcurrentHashMap<>(); + + // hash table of AccessibleContext to native window handle mappings + static private ConcurrentHashMap contextToWindowHandleMap = new ConcurrentHashMap<>(); + + /* + * adds a virtual window handler to our hash tables + */ + static private void registerVirtualFrame(final Accessible a, + Integer nativeWindowHandle ) { + if (a != null) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, a); + windowHandleToContextMap.put(nativeWindowHandle, ac); + contextToWindowHandleMap.put(ac, nativeWindowHandle); + } + } + + /* + * removes a virtual window handler to our hash tables + */ + static private void revokeVirtualFrame(final Accessible a, + Integer nativeWindowHandle ) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, a); + windowHandleToContextMap.remove(nativeWindowHandle); + contextToWindowHandleMap.remove(ac); + } + + // vector of native window handlers + private static Vector nativeWindowHandlers = new Vector<>(); + + /* + * adds a native window handler to our list + */ + private static void addNativeWindowHandler(NativeWindowHandler handler) { + if (handler == null) { + throw new IllegalArgumentException(); + } + nativeWindowHandlers.addElement(handler); + } + + /* + * removes a native window handler to our list + */ + private static boolean removeNativeWindowHandler(NativeWindowHandler handler) { + if (handler == null) { + throw new IllegalArgumentException(); + } + return nativeWindowHandlers.removeElement(handler); + } + + /** + * verifies that a native window handle is a Java window + */ + private boolean isJavaWindow(int nativeHandle) { + AccessibleContext ac = getContextFromNativeWindowHandle(nativeHandle); + if (ac != null) { + saveContextToWindowHandleMapping(ac, nativeHandle); + return true; + } + return false; + } + + /* + * saves the mapping between an AccessibleContext and a window handle + */ + private void saveContextToWindowHandleMapping(AccessibleContext ac, + int nativeHandle) { + debugString("saveContextToWindowHandleMapping..."); + if (ac == null) { + return; + } + if (! contextToWindowHandleMap.containsKey(ac)) { + debugString("saveContextToWindowHandleMapping: ac = "+ac+"; handle = "+nativeHandle); + contextToWindowHandleMap.put(ac, nativeHandle); + } + } + + /** + * maps a native window handle to an Accessible Context + */ + private AccessibleContext getContextFromNativeWindowHandle(int nativeHandle) { + // First, look for the Accessible in our hash table of + // virtual window handles. + AccessibleContext ac = windowHandleToContextMap.get(nativeHandle); + if(ac!=null) { + saveContextToWindowHandleMapping(ac, nativeHandle); + return ac; + } + + // Next, look for the native window handle in our vector + // of native window handles. + int numHandlers = nativeWindowHandlers.size(); + for (int i = 0; i < numHandlers; i++) { + NativeWindowHandler nextHandler = nativeWindowHandlers.elementAt(i); + final Accessible a = nextHandler.getAccessibleFromNativeWindowHandle(nativeHandle); + if (a != null) { + ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, a); + saveContextToWindowHandleMapping(ac, nativeHandle); + return ac; + } + } + // Not found. + return null; + } + + /** + * maps an AccessibleContext to a native window handle + * returns 0 on error + */ + private int getNativeWindowHandleFromContext(AccessibleContext ac) { + debugString("getNativeWindowHandleFromContext: ac = "+ac); + try { + return contextToWindowHandleMap.get(ac); + } catch (Exception ex) { + return 0; + } + } + + private class DefaultNativeWindowHandler implements NativeWindowHandler { + /* + * returns the Accessible associated with a native window + */ + public Accessible getAccessibleFromNativeWindowHandle(int nativeHandle) { + final Component c = jawtGetComponentFromNativeWindowHandle(nativeHandle); + if (c instanceof Accessible) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return c.getAccessibleContext(); + } + }, c); + saveContextToWindowHandleMapping(ac, nativeHandle); + return (Accessible)c; + } else { + return null; + } + } + } + + /* ===== AccessibleContext methods =====*/ + + /* + * returns the inner-most AccessibleContext in parent at Point(x, y) + */ + private AccessibleContext getAccessibleContextAt(int x, int y, + AccessibleContext parent) { + if (parent == null) { + return null; + } + if (windowHandleToContextMap != null && + windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) { + // Path for applications that register their top-level + // windows with the AccessBridge (e.g., StarOffice 6.1) + return getAccessibleContextAt_1(x, y, parent); + } else { + // Path for applications that do not register + // their top-level windows with the AccessBridge + // (e.g., Swing/AWT applications) + return getAccessibleContextAt_2(x, y, parent); + } + } + + /* + * returns the root accessible context + */ + private AccessibleContext getRootAccessibleContext(final AccessibleContext ac) { + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible parent = ac.getAccessibleParent(); + if (parent == null) { + return ac; + } + Accessible tmp = parent.getAccessibleContext().getAccessibleParent(); + while (tmp != null) { + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + } + return parent.getAccessibleContext(); + } + }, ac); + } + + /* + * StarOffice version that does not use the EventQueueMonitor + */ + private AccessibleContext getAccessibleContextAt_1(final int x, final int y, + final AccessibleContext parent) { + debugString(" : getAccessibleContextAt_1 called"); + debugString(" -> x = " + x + " y = " + y + " parent = " + parent); + + if (parent == null) return null; + final AccessibleComponent acmp = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleComponent call() throws Exception { + return parent.getAccessibleComponent(); + } + }, parent); + if (acmp!=null) { + final Point loc = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Point call() throws Exception { + return acmp.getLocation(); + } + }, parent); + final Accessible a = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return acmp.getAccessibleAt(new Point(x - loc.x, y - loc.y)); + } + }, parent); + if (a != null) { + AccessibleContext foundAC = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, parent); + if (foundAC != null) { + if (foundAC != parent) { + // recurse down into the child + return getAccessibleContextAt_1(x - loc.x, y - loc.y, + foundAC); + } else + return foundAC; + } + } + } + return parent; + } + + /* + * AWT/Swing version + */ + private AccessibleContext getAccessibleContextAt_2(final int x, final int y, + AccessibleContext parent) { + debugString("getAccessibleContextAt_2 called"); + debugString(" -> x = " + x + " y = " + y + " parent = " + parent); + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = EventQueueMonitor.getAccessibleAt(new Point(x, y)); + if (a != null) { + AccessibleContext childAC = a.getAccessibleContext(); + if (childAC != null) { + debugString(" returning childAC = " + childAC); + return childAC; + } + } + return null; + } + }, parent); + } + + /** + * returns the Accessible that has focus + */ + private AccessibleContext getAccessibleContextWithFocus() { + Component c = AWTEventMonitor.getComponentWithFocus(); + if (c != null) { + final Accessible a = Translator.getAccessible(c); + if (a != null) { + AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return a.getAccessibleContext(); + } + }, c); + if (ac != null) { + return ac; + } + } + } + return null; + } + + /** + * returns the AccessibleName from an AccessibleContext + */ + private String getAccessibleNameFromContext(final AccessibleContext ac) { + debugString("***** ac = "+ac.getClass()); + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + if (s != null) { + references.increment(s); + debugString("Returning AccessibleName from Context: " + s); + return s; + } else { + return null; + } + } else { + debugString("getAccessibleNameFromContext; ac = null!"); + return null; + } + } + + /** + * Returns an AccessibleName for a component using an algorithm optimized + * for the JAWS screen reader. This method is only intended for JAWS. All + * other uses are entirely optional. + */ + private String getVirtualAccessibleNameFromContext(final AccessibleContext ac) { + if (null != ac) { + /* + Step 1: + ======= + Determine if we can obtain the Virtual Accessible Name from the + Accessible Name or Accessible Description of the object. + */ + String nameString = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + if ( ( null != nameString ) && ( 0 != nameString.length () ) ) { + debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName."); + references.increment (nameString); + return nameString; + } + String descriptionString = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleDescription(); + } + }, ac); + if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) { + debugString ("bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription."); + references.increment (descriptionString); + return descriptionString; + } + + debugString ("The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName"); + /* + Step 2: + ======= + Decide whether the extended name search algorithm should be + used for this object. + */ + boolean bExtendedSearch = false; + AccessibleRole role = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return ac.getAccessibleRole(); + } + }, ac); + AccessibleContext parentContext = null; + AccessibleRole parentRole = AccessibleRole.UNKNOWN; + + if ( extendedVirtualNameSearchRoles.contains (role) ) { + parentContext = getAccessibleParentFromContext (ac); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + parentRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return parentContextInnerTemp.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.UNKNOWN != parentRole ) { + bExtendedSearch = true; + if ( noExtendedVirtualNameSearchParentRoles.contains (parentRole) ) { + bExtendedSearch = false; + } + } + } + } + + if (false == bExtendedSearch) { + debugString ("bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm. role = " + role.toDisplayString (Locale.US) ); + /* + Step 3: + ======= + We have determined that we should not use the extended name + search algorithm for this object (we must obtain the name of + the object from the object itself and not from neighboring + objects). However the object name cannot be obtained from + the Accessible Name or Accessible Description of the object. + + Handle several special cases here that might yield a value for + the Virtual Accessible Name. Return null if the object does + not match the criteria for any of these special cases. + */ + if (AccessibleRole.LABEL == role) { + /* + Does the label support the Accessible Text Interface? + */ + final AccessibleText at = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleText call() throws Exception { + return ac.getAccessibleText(); + } + }, ac); + if (null != at) { + int charCount = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getCharCount(); + } + }, ac); + String text = getAccessibleTextRangeFromContext (ac, 0, charCount); + if (null != text) { + debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object."); + references.increment (text); + return text; + } + } + /* + Does the label support the Accessible Icon Interface? + */ + debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); + final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleIcon[] call() throws Exception { + return ac.getAccessibleIcon(); + } + }, ac); + if ( (null != ai) && (ai.length > 0) ) { + String iconDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ai[0].getAccessibleIconDescription(); + } + }, ac); + if (iconDescription != null){ + debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object."); + references.increment (iconDescription); + return iconDescription; + } + } else { + parentContext = getAccessibleParentFromContext (ac); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + parentRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return parentContextInnerTemp.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.TABLE == parentRole ) { + int indexInParent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleIndexInParent(); + } + }, ac); + final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent); + debugString ("bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell."); + if (acTableCell != null) { + final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleIcon[] call() throws Exception { + return acTableCell.getAccessibleIcon(); + } + }, ac); + if ( (null != aiRet) && (aiRet.length > 0) ) { + String iconDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return aiRet[0].getAccessibleIconDescription(); + } + }, ac); + if (iconDescription != null){ + debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object."); + references.increment (iconDescription); + return iconDescription; + } + } + } + } + } + } + } else if ( (AccessibleRole.TOGGLE_BUTTON == role) || + (AccessibleRole.PUSH_BUTTON == role) ) { + /* + Does the button support the Accessible Icon Interface? + */ + debugString ("bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information."); + final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleIcon[] call() throws Exception { + return ac.getAccessibleIcon(); + } + }, ac); + if ( (null != ai) && (ai.length > 0) ) { + String iconDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ai[0].getAccessibleIconDescription(); + } + }, ac); + if (iconDescription != null){ + debugString ("bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object."); + references.increment (iconDescription); + return iconDescription; + } + } + } else if ( AccessibleRole.CHECK_BOX == role ) { + /* + NOTE: The only case I know of in which a check box does not + have a name is when that check box is contained in a table. + + In this case it would be appropriate to use the display string + of the check box object as the name (in US English the display + string is typically either "true" or "false"). + + I am using the AccessibleValue interface to obtain the display + string of the check box. If the Accessible Value is 1, I am + returning Boolean.TRUE.toString (), If the Accessible Value is + 0, I am returning Boolean.FALSE.toString (). If the Accessible + Value is some other number, I will return the display string of + the current numerical value of the check box. + */ + final AccessibleValue av = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleValue call() throws Exception { + return ac.getAccessibleValue(); + } + }, ac); + if ( null != av ) { + nameString = null; + Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + return av.getCurrentAccessibleValue(); + } + }, ac); + if ( null != value ) { + if ( 1 == value.intValue () ) { + nameString = Boolean.TRUE.toString (); + } else if ( 0 == value.intValue () ) { + nameString = Boolean.FALSE.toString (); + } else { + nameString = value.toString (); + } + if ( null != nameString ) { + references.increment (nameString); + return nameString; + } + } + } + } + return null; + } + + /* + + + Beginning of the extended name search + + + */ + final AccessibleContext parentContextOuterTemp = parentContext; + String parentName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return parentContextOuterTemp.getAccessibleName(); + } + }, ac); + String parentDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return parentContextOuterTemp.getAccessibleDescription(); + } + }, ac); + + /* + Step 4: + ======= + Special case for Slider Bar objects. + */ + if ( (AccessibleRole.SLIDER == role) && + (AccessibleRole.PANEL == parentRole) && + (null != parentName) ) { + debugString ("bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object."); + references.increment (parentName); + return parentName; + } + + boolean bIsEditCombo = false; + + AccessibleContext testContext = ac; + /* + Step 5: + ======= + Special case for Edit Combo Boxes + */ + if ( (AccessibleRole.TEXT == role) && + (AccessibleRole.COMBO_BOX == parentRole) ) { + bIsEditCombo = true; + if (null != parentName) { + debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object."); + references.increment (parentName); + return parentName; + } else if (null != parentDescription) { + debugString ("bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object."); + references.increment (parentDescription); + return parentDescription; + } + testContext = parentContext; + parentRole = AccessibleRole.UNKNOWN; + parentContext = getAccessibleParentFromContext (testContext); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + parentRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return parentContextInnerTemp.getAccessibleRole(); + } + }, ac); + } + } + + /* + Step 6: + ======= + Attempt to get the Virtual Accessible Name of the object using the + Accessible Relation Set Info (the LABELED_BY Accessible Relation). + */ + { + final AccessibleContext parentContextTempInner = parentContext; + AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRelationSet call() throws Exception { + return parentContextTempInner.getAccessibleRelationSet(); + } + }, ac); + if ( ars != null && (ars.size () > 0) && (ars.contains (AccessibleRelation.LABELED_BY)) ) { + AccessibleRelation labeledByRelation = ars.get (AccessibleRelation.LABELED_BY); + if (labeledByRelation != null) { + Object [] targets = labeledByRelation.getTarget (); + Object o = targets [0]; + if (o instanceof Accessible) { + AccessibleContext labelContext = ((Accessible)o).getAccessibleContext (); + if (labelContext != null) { + String labelName = labelContext.getAccessibleName (); + String labelDescription = labelContext.getAccessibleDescription (); + if (null != labelName) { + debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case."); + references.increment (labelName); + return labelName; + } else if (null != labelDescription) { + debugString ("bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case."); + references.increment (labelDescription); + return labelDescription; + } + } + } + } + } + } + + //Note: add AccessibleContext to use InvocationUtils.invokeAndWait + /* + Step 7: + ======= + Search for a label object that is positioned either just to the left + or just above the object and get the Accessible Name of the Label + object. + */ + int testIndexMax = 0; + int testX = 0; + int testY = 0; + int testWidth = 0; + int testHeight = 0; + int targetX = 0; + int targetY = 0; + final AccessibleContext tempContext = testContext; + int testIndex = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return tempContext.getAccessibleIndexInParent(); + } + }, ac); + if ( null != parentContext ) { + final AccessibleContext parentContextInnerTemp = parentContext; + testIndexMax = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return parentContextInnerTemp.getAccessibleChildrenCount() - 1; + } + }, ac); + } + testX = getAccessibleXcoordFromContext (testContext); + testY = getAccessibleYcoordFromContext (testContext); + testWidth = getAccessibleWidthFromContext (testContext); + testHeight = getAccessibleHeightFromContext (testContext); + targetX = testX + 2; + targetY = testY + 2; + + int childIndex = testIndex - 1; + /*Accessible child = null; + AccessibleContext childContext = null; + AccessibleRole childRole = AccessibleRole.UNKNOWN;*/ + int childX = 0; + int childY = 0; + int childWidth = 0; + int childHeight = 0; + String childName = null; + String childDescription = null; + while (childIndex >= 0) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.LABEL == childRole ) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleDescription(); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } else if ( (childY < targetY) && + ((childX <= targetX) && (targetX <= (childX + childWidth))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleDescription(); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex --; + } + childIndex = testIndex + 1; + while (childIndex <= testIndexMax) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( AccessibleRole.LABEL == childRole ) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleDescription(); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } else if ( (childY < targetY) && + ((childX <= targetX) && (targetX <= (childX + childWidth))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleDescription(); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex ++; + } + /* + Step 8: + ======= + Special case for combo boxes and text objects, based on a + similar special case I found in some of our internal JAWS code. + + Search for a button object that is positioned either just to the left + or just above the object and get the Accessible Name of the button + object. + */ + if ( (AccessibleRole.TEXT == role) || + (AccessibleRole.COMBO_BOX == role) || + (bIsEditCombo) ) { + childIndex = testIndex - 1; + while (childIndex >= 0) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( ( AccessibleRole.PUSH_BUTTON == childRole ) || + ( AccessibleRole.TOGGLE_BUTTON == childRole )) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleDescription(); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex --; + } + childIndex = testIndex + 1; + while (childIndex <= testIndexMax) { + final int childIndexTemp = childIndex; + final AccessibleContext parentContextInnerTemp = parentContext; + final Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return parentContextInnerTemp.getAccessibleChild(childIndexTemp); + } + }, ac); + if ( null != child ) { + final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return child.getAccessibleContext(); + } + }, ac); + if ( null != childContext ) { + AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return childContext.getAccessibleRole(); + } + }, ac); + if ( ( AccessibleRole.PUSH_BUTTON == childRole ) || + ( AccessibleRole.TOGGLE_BUTTON == childRole ) ) { + childX = getAccessibleXcoordFromContext (childContext); + childY = getAccessibleYcoordFromContext (childContext); + childWidth = getAccessibleWidthFromContext (childContext); + childHeight = getAccessibleHeightFromContext (childContext); + if ( (childX < testX) && + ((childY <= targetY) && (targetY <= (childY + childHeight))) ) { + childName = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleName(); + } + }, ac); + if ( null != childName ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childName); + return childName; + } + childDescription = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return childContext.getAccessibleDescription(); + } + }, ac); + if ( null != childDescription ) { + debugString ("bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object."); + references.increment (childDescription); + return childDescription; + } + } + } + } + } + childIndex ++; + } + } + return null; + } else { + debugString ("AccessBridge::getVirtualAccessibleNameFromContext error - ac == null."); + return null; + } + } + + /** + * returns the AccessibleDescription from an AccessibleContext + */ + private String getAccessibleDescriptionFromContext(final AccessibleContext ac) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleDescription(); + } + }, ac); + if (s != null) { + references.increment(s); + debugString("Returning AccessibleDescription from Context: " + s); + return s; + } + } else { + debugString("getAccessibleDescriptionFromContext; ac = null"); + } + return null; + } + + /** + * returns the AccessibleRole from an AccessibleContext + */ + private String getAccessibleRoleStringFromContext(final AccessibleContext ac) { + if (ac != null) { + AccessibleRole role = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRole call() throws Exception { + return ac.getAccessibleRole(); + } + }, ac); + if (role != null) { + String s = role.toDisplayString(Locale.US); + if (s != null) { + references.increment(s); + debugString("Returning AccessibleRole from Context: " + s); + return s; + } + } + } else { + debugString("getAccessibleRoleStringFromContext; ac = null"); + } + return null; + } + + /** + * return the AccessibleRole from an AccessibleContext in the en_US locale + */ + private String getAccessibleRoleStringFromContext_en_US(final AccessibleContext ac) { + return getAccessibleRoleStringFromContext(ac); + } + + /** + * return the AccessibleStates from an AccessibleContext + */ + private String getAccessibleStatesStringFromContext(final AccessibleContext ac) { + if (ac != null) { + AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleStateSet call() throws Exception { + return ac.getAccessibleStateSet(); + } + }, ac); + if (stateSet != null) { + String s = stateSet.toString(); + if (s != null && + s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) { + // Indicate whether this component manages its own + // children + AccessibleRole role = ac.getAccessibleRole(); + if (role == AccessibleRole.LIST || + role == AccessibleRole.TABLE || + role == AccessibleRole.TREE) { + s += ","; + s += AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US); + } + references.increment(s); + debugString("Returning AccessibleStateSet from Context: " + s); + return s; + } + } + } else { + debugString("getAccessibleStatesStringFromContext; ac = null"); + } + return null; + } + + /** + * returns the AccessibleStates from an AccessibleContext in the en_US locale + */ + private String getAccessibleStatesStringFromContext_en_US(final AccessibleContext ac) { + if (ac != null) { + AccessibleStateSet stateSet = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleStateSet call() throws Exception { + return ac.getAccessibleStateSet(); + } + }, ac); + if (stateSet != null) { + String s = ""; + AccessibleState[] states = stateSet.toArray(); + if (states != null && states.length > 0) { + s = states[0].toDisplayString(Locale.US); + for (int i = 1; i < states.length; i++) { + s = s + "," + states[i].toDisplayString(Locale.US); + } + } + references.increment(s); + debugString("Returning AccessibleStateSet en_US from Context: " + s); + return s; + } + } + debugString("getAccessibleStatesStringFromContext; ac = null"); + return null; + } + + /** + * returns the AccessibleParent from an AccessibleContext + */ + private AccessibleContext getAccessibleParentFromContext(final AccessibleContext ac) { + if (ac==null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleParent(); + if (a != null) { + AccessibleContext apc = a.getAccessibleContext(); + if (apc != null) { + return apc; + } + } + return null; + } + }, ac); + } + + /** + * returns the AccessibleIndexInParent from an AccessibleContext + */ + private int getAccessibleIndexInParentFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleIndexInParent(); + } + }, ac); + } + + /** + * returns the AccessibleChild count from an AccessibleContext + */ + private int getAccessibleChildrenCountFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleChildrenCount(); + } + }, ac); + } + + /** + * returns the AccessibleChild Context from an AccessibleContext + */ + private AccessibleContext getAccessibleChildFromContext(final AccessibleContext ac, final int index) { + + if (ac == null) { + return null; + } + + final JTable table = InvocationUtils.invokeAndWait(new Callable() { + @Override + public JTable call() throws Exception { + // work-around for AccessibleJTable.getCurrentAccessibleContext returning + // wrong renderer component when cell contains more than one component + Accessible parent = ac.getAccessibleParent(); + if (parent != null) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JTable) { + return (JTable) child; + } + } + return null; + } + }, ac); + + if (table == null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleChild(index); + if (a != null) { + return a.getAccessibleContext(); + } + return null; + } + }, ac); + } + + final AccessibleTable at = getAccessibleTableFromContext(ac); + + final int row = getAccessibleTableRow(at, index); + final int column = getAccessibleTableColumn(at, index); + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + TableCellRenderer renderer = table.getCellRenderer(row, column); + if (renderer == null) { + Class columnClass = table.getColumnClass(column); + renderer = table.getDefaultRenderer(columnClass); + } + Component component = + renderer.getTableCellRendererComponent(table, table.getValueAt(row, column), + false, false, row, column); + if (component instanceof Accessible) { + return component.getAccessibleContext(); + } + return null; + } + }, ac); + } + + /** + * returns the AccessibleComponent bounds on screen from an AccessibleContext + */ + private Rectangle getAccessibleBoundsOnScreenFromContext(final AccessibleContext ac) { + if(ac==null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Rectangle call() throws Exception { + AccessibleComponent acmp = ac.getAccessibleComponent(); + if (acmp != null) { + Rectangle r = acmp.getBounds(); + if (r != null) { + try { + Point p = acmp.getLocationOnScreen(); + if (p != null) { + r.x = p.x; + r.y = p.y; + return r; + } + } catch (Exception e) { + return null; + } + } + } + return null; + } + }, ac); + } + + /** + * returns the AccessibleComponent x-coord from an AccessibleContext + */ + private int getAccessibleXcoordFromContext(AccessibleContext ac) { + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + debugString(" - Returning Accessible x coord from Context: " + r.x); + return r.x; + } + } else { + debugString("getAccessibleXcoordFromContext ac = null"); + } + return -1; + } + + /** + * returns the AccessibleComponent y-coord from an AccessibleContext + */ + private int getAccessibleYcoordFromContext(AccessibleContext ac) { + debugString("getAccessibleYcoordFromContext() called"); + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + return r.y; + } + } else { + debugString("getAccessibleYcoordFromContext; ac = null"); + } + return -1; + } + + /** + * returns the AccessibleComponent height from an AccessibleContext + */ + private int getAccessibleHeightFromContext(AccessibleContext ac) { + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + return r.height; + } + } else { + debugString("getAccessibleHeightFromContext; ac = null"); + } + return -1; + } + + /** + * returns the AccessibleComponent width from an AccessibleContext + */ + private int getAccessibleWidthFromContext(AccessibleContext ac) { + if (ac != null) { + Rectangle r = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null) { + return r.width; + } + } else { + debugString("getAccessibleWidthFromContext; ac = null"); + } + return -1; + } + + + /** + * returns the AccessibleComponent from an AccessibleContext + */ + private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) { + if (ac != null) { + AccessibleComponent acmp = ac.getAccessibleComponent(); + if (acmp != null) { + debugString("Returning AccessibleComponent Context"); + return acmp; + } + } else { + debugString("getAccessibleComponentFromContext; ac = null"); + } + return null; + } + + /** + * returns the AccessibleAction from an AccessibleContext + */ + private AccessibleAction getAccessibleActionFromContext(final AccessibleContext ac) { + debugString("Returning AccessibleAction Context"); + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleAction call() throws Exception { + return ac.getAccessibleAction(); + } + }, ac); + } + + /** + * returns the AccessibleSelection from an AccessibleContext + */ + private AccessibleSelection getAccessibleSelectionFromContext(final AccessibleContext ac) { + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleSelection call() throws Exception { + return ac.getAccessibleSelection(); + } + }, ac); + } + + /** + * return the AccessibleText from an AccessibleContext + */ + private AccessibleText getAccessibleTextFromContext(final AccessibleContext ac) { + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleText call() throws Exception { + return ac.getAccessibleText(); + } + }, ac); + } + + /** + * return the AccessibleComponent from an AccessibleContext + */ + private AccessibleValue getAccessibleValueFromContext(final AccessibleContext ac) { + return ac == null ? null : InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleValue call() throws Exception { + return ac.getAccessibleValue(); + } + }, ac); + } + + /* ===== AccessibleText methods ===== */ + + /** + * returns the bounding rectangle for the text cursor + * XXX + */ + private Rectangle getCaretLocation(final AccessibleContext ac) { + debugString("getCaretLocation"); + if (ac==null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Rectangle call() throws Exception { + // workaround for JAAPI not returning cursor bounding rectangle + Rectangle r = null; + Accessible parent = ac.getAccessibleParent(); + if (parent instanceof Accessible) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + + if (child instanceof JTextComponent) { + JTextComponent text = (JTextComponent) child; + try { + r = text.modelToView(text.getCaretPosition()); + if (r != null) { + Point p = text.getLocationOnScreen(); + r.translate(p.x, p.y); + } + } catch (BadLocationException ble) { + } + } + } + return r; + } + }, ac); + } + + /** + * returns the x-coordinate for the text cursor rectangle + */ + private int getCaretLocationX(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.x; + } else { + return -1; + } + } + + /** + * returns the y-coordinate for the text cursor rectangle + */ + private int getCaretLocationY(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.y; + } else { + return -1; + } + } + + /** + * returns the height for the text cursor rectangle + */ + private int getCaretLocationHeight(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.height; + } else { + return -1; + } + } + + /** + * returns the width for the text cursor rectangle + */ + private int getCaretLocationWidth(AccessibleContext ac) { + Rectangle r = getCaretLocation(ac); + if (r != null) { + return r.width; + } else { + return -1; + } + } + + /** + * returns the character count from an AccessibleContext + */ + private int getAccessibleCharCountFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getCharCount(); + } + return -1; + } + }, ac); + } + + /** + * returns the caret position from an AccessibleContext + */ + private int getAccessibleCaretPositionFromContext(final AccessibleContext ac) { + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getCaretPosition(); + } + return -1; + } + }, ac); + } + + /** + * Return the index at a specific point from an AccessibleContext + * Point(x, y) is in screen coordinates. + */ + private int getAccessibleIndexAtPointFromContext(final AccessibleContext ac, + final int x, final int y) { + debugString("getAccessibleIndexAtPointFromContext: x = "+x+"; y = "+y); + if (ac==null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + AccessibleComponent acomp = ac.getAccessibleComponent(); + if (at != null && acomp != null) { + // Convert x and y from screen coordinates to + // local coordinates. + try { + Point p = acomp.getLocationOnScreen(); + int x1, y1; + if (p != null) { + x1 = x - p.x; + if (x1 < 0) { + x1 = 0; + } + y1 = y - p.y; + if (y1 < 0) { + y1 = 0; + } + + Point newPoint = new Point(x1, y1); + int indexAtPoint = at.getIndexAtPoint(new Point(x1, y1)); + return indexAtPoint; + } + } catch (Exception e) { + } + } + return -1; + } + }, ac); + } + + /** + * return the letter at a specific point from an AccessibleContext + */ + private String getAccessibleLetterAtIndexFromContext(final AccessibleContext ac, final int index) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getAtIndex(AccessibleText.CHARACTER, index); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleLetterAtIndexFromContext; ac = null"); + } + return null; + } + + /** + * return the word at a specific point from an AccessibleContext + */ + private String getAccessibleWordAtIndexFromContext(final AccessibleContext ac, final int index) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getAtIndex(AccessibleText.WORD, index); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleWordAtIndexFromContext; ac = null"); + } + return null; + } + + /** + * return the sentence at a specific point from an AccessibleContext + */ + private String getAccessibleSentenceAtIndexFromContext(final AccessibleContext ac, final int index) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getAtIndex(AccessibleText.SENTENCE, index); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleSentenceAtIndexFromContext; ac = null"); + } + return null; + } + + /** + * return the text selection start from an AccessibleContext + */ + private int getAccessibleTextSelectionStartFromContext(final AccessibleContext ac) { + if (ac == null) return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getSelectionStart(); + } + return -1; + } + }, ac); + } + + /** + * return the text selection end from an AccessibleContext + */ + private int getAccessibleTextSelectionEndFromContext(final AccessibleContext ac) { + if (ac == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getSelectionEnd(); + } + return -1; + } + }, ac); + } + + /** + * return the selected text from an AccessibleContext + */ + private String getAccessibleTextSelectedTextFromContext(final AccessibleContext ac) { + if (ac != null) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at == null) return null; + return at.getSelectedText(); + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getAccessibleTextSelectedTextFromContext; ac = null"); + } + return null; + } + + /** + * return the attribute string at a given index from an AccessibleContext + */ + private String getAccessibleAttributesAtIndexFromContext(final AccessibleContext ac, + final int index) { + if (ac == null) + return null; + AttributeSet as = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AttributeSet call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + return at.getCharacterAttribute(index); + } + return null; + } + }, ac); + String s = expandStyleConstants(as); + if (s != null) { + references.increment(s); + return s; + } + return null; + } + + /** + * Get line info: left index of line + * + * algorithm: cast back, doubling each time, + * 'till find line boundaries + * + * return -1 if we can't get the info (e.g. index or at passed in + * is bogus; etc.) + */ + private int getAccessibleTextLineLeftBoundsFromContext(final AccessibleContext ac, + final int index) { + if (ac == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + int lineStart; + int offset; + Rectangle charRect; + Rectangle indexRect = at.getCharacterBounds(index); + int textLen = at.getCharCount(); + if (indexRect == null) { + return -1; + } + // find the start of the line + // + offset = 1; + lineStart = index - offset < 0 ? 0 : index - offset; + charRect = at.getCharacterBounds(lineStart); + // slouch behind beginning of line + while (charRect != null + && charRect.y >= indexRect.y + && lineStart > 0) { + offset = offset << 1; + lineStart = index - offset < 0 ? 0 : index - offset; + charRect = at.getCharacterBounds(lineStart); + } + if (lineStart == 0) { // special case: we're on the first line! + // we found it! + } else { + offset = offset >> 1; // know boundary within last expansion + // ground forward to beginning of line + while (offset > 0) { + charRect = at.getCharacterBounds(lineStart + offset); + if (charRect.y < indexRect.y) { // still before line + lineStart += offset; + } else { + // leave lineStart alone, it's close! + } + offset = offset >> 1; + } + // subtract one 'cause we're already too far... + lineStart += 1; + } + return lineStart; + } + return -1; + } + }, ac); + } + + /** + * Get line info: right index of line + * + * algorithm: cast back, doubling each time, + * 'till find line boundaries + * + * return -1 if we can't get the info (e.g. index or at passed in + * is bogus; etc.) + */ + private int getAccessibleTextLineRightBoundsFromContext(final AccessibleContext ac, final int index) { + if(ac == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + int lineEnd; + int offset; + Rectangle charRect; + Rectangle indexRect = at.getCharacterBounds(index); + int textLen = at.getCharCount(); + if (indexRect == null) { + return -1; + } + // find the end of the line + // + offset = 1; + lineEnd = index + offset > textLen - 1 + ? textLen - 1 : index + offset; + charRect = at.getCharacterBounds(lineEnd); + // push past end of line + while (charRect != null && + charRect.y <= indexRect.y && + lineEnd < textLen - 1) { + offset = offset << 1; + lineEnd = index + offset > textLen - 1 + ? textLen - 1 : index + offset; + charRect = at.getCharacterBounds(lineEnd); + } + if (lineEnd == textLen - 1) { // special case: on the last line! + // we found it! + } else { + offset = offset >> 1; // know boundary within last expansion + // pull back to end of line + while (offset > 0) { + charRect = at.getCharacterBounds(lineEnd - offset); + if (charRect.y > indexRect.y) { // still beyond line + lineEnd -= offset; + } else { + // leave lineEnd alone, it's close! + } + offset = offset >> 1; + } + // subtract one 'cause we're already too far... + lineEnd -= 1; + } + return lineEnd; + } + return -1; + } + }, ac); + } + + /** + * Get a range of text; null if indicies are bogus + */ + private String getAccessibleTextRangeFromContext(final AccessibleContext ac, + final int start, final int end) { + String s = InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + if (ac != null) { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + // start - end is inclusive + if (start > end) { + return null; + } + if (end >= at.getCharCount()) { + return null; + } + StringBuffer buf = new StringBuffer(end - start + 1); + for (int i = start; i <= end; i++) { + buf.append(at.getAtIndex(AccessibleText.CHARACTER, i)); + } + return buf.toString(); + } + } + return null; + } + }, ac); + if (s != null) { + references.increment(s); + return s; + } else { + return null; + } + } + + /** + * return the AttributeSet object at a given index from an AccessibleContext + */ + private AttributeSet getAccessibleAttributeSetAtIndexFromContext(final AccessibleContext ac, + final int index) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AttributeSet call() throws Exception { + if (ac != null) { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + AttributeSet as = at.getCharacterAttribute(index); + if (as != null) { + AccessBridge.this.references.increment(as); + return as; + } + } + } + return null; + } + }, ac); + } + + + /** + * return the bounding rectangle at index from an AccessibleContext + */ + private Rectangle getAccessibleTextRectAtIndexFromContext(final AccessibleContext ac, + final int index) { + // want to do this in global coords, so need to combine w/ac global coords + Rectangle r = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Rectangle call() throws Exception { + // want to do this in global coords, so need to combine w/ac global coords + if (ac != null) { + AccessibleText at = ac.getAccessibleText(); + if (at != null) { + Rectangle rect = at.getCharacterBounds(index); + if (rect != null) { + String s = at.getAtIndex(AccessibleText.CHARACTER, index); + if (s != null && s.equals("\n")) { + rect.width = 0; + } + return rect; + } + } + } + return null; + } + }, ac); + Rectangle acRect = getAccessibleBoundsOnScreenFromContext(ac); + if (r != null && acRect != null) { + r.translate(acRect.x, acRect.y); + return r; + } + return null; + } + + /** + * return the AccessibleText character x-coord at index from an AccessibleContext + */ + private int getAccessibleXcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.x; + } + } else { + debugString("getAccessibleXcoordTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /** + * return the AccessibleText character y-coord at index from an AccessibleContext + */ + private int getAccessibleYcoordTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.y; + } + } else { + debugString("getAccessibleYcoordTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /** + * return the AccessibleText character height at index from an AccessibleContext + */ + private int getAccessibleHeightTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.height; + } + } else { + debugString("getAccessibleHeightTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /** + * return the AccessibleText character width at index from an AccessibleContext + */ + private int getAccessibleWidthTextRectAtIndexFromContext(AccessibleContext ac, int index) { + if (ac != null) { + Rectangle r = getAccessibleTextRectAtIndexFromContext(ac, index); + if (r != null) { + return r.width; + } + } else { + debugString("getAccessibleWidthTextRectAtIndexFromContext; ac = null"); + } + return -1; + } + + /* ===== AttributeSet methods for AccessibleText ===== */ + + /** + * return the bold setting from an AttributeSet + */ + private boolean getBoldFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isBold(as); + } else { + debugString("getBoldFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the italic setting from an AttributeSet + */ + private boolean getItalicFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isItalic(as); + } else { + debugString("getItalicFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the underline setting from an AttributeSet + */ + private boolean getUnderlineFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isUnderline(as); + } else { + debugString("getUnderlineFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the strikethrough setting from an AttributeSet + */ + private boolean getStrikethroughFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isStrikeThrough(as); + } else { + debugString("getStrikethroughFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the superscript setting from an AttributeSet + */ + private boolean getSuperscriptFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isSuperscript(as); + } else { + debugString("getSuperscriptFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the subscript setting from an AttributeSet + */ + private boolean getSubscriptFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.isSubscript(as); + } else { + debugString("getSubscriptFromAttributeSet; as = null"); + } + return false; + } + + /** + * return the background color from an AttributeSet + */ + private String getBackgroundColorFromAttributeSet(AttributeSet as) { + if (as != null) { + String s = StyleConstants.getBackground(as).toString(); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getBackgroundColorFromAttributeSet; as = null"); + } + return null; + } + + /** + * return the foreground color from an AttributeSet + */ + private String getForegroundColorFromAttributeSet(AttributeSet as) { + if (as != null) { + String s = StyleConstants.getForeground(as).toString(); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getForegroundColorFromAttributeSet; as = null"); + } + return null; + } + + /** + * return the font family from an AttributeSet + */ + private String getFontFamilyFromAttributeSet(AttributeSet as) { + if (as != null) { + String s = StyleConstants.getFontFamily(as).toString(); + if (s != null) { + references.increment(s); + return s; + } + } else { + debugString("getFontFamilyFromAttributeSet; as = null"); + } + return null; + } + + /** + * return the font size from an AttributeSet + */ + private int getFontSizeFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getFontSize(as); + } else { + debugString("getFontSizeFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the alignment from an AttributeSet + */ + private int getAlignmentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getAlignment(as); + } else { + debugString("getAlignmentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the BiDi level from an AttributeSet + */ + private int getBidiLevelFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getBidiLevel(as); + } else { + debugString("getBidiLevelFromAttributeSet; as = null"); + } + return -1; + } + + + /** + * return the first line indent from an AttributeSet + */ + private float getFirstLineIndentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getFirstLineIndent(as); + } else { + debugString("getFirstLineIndentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the left indent from an AttributeSet + */ + private float getLeftIndentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getLeftIndent(as); + } else { + debugString("getLeftIndentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the right indent from an AttributeSet + */ + private float getRightIndentFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getRightIndent(as); + } else { + debugString("getRightIndentFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the line spacing from an AttributeSet + */ + private float getLineSpacingFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getLineSpacing(as); + } else { + debugString("getLineSpacingFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the space above from an AttributeSet + */ + private float getSpaceAboveFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getSpaceAbove(as); + } else { + debugString("getSpaceAboveFromAttributeSet; as = null"); + } + return -1; + } + + /** + * return the space below from an AttributeSet + */ + private float getSpaceBelowFromAttributeSet(AttributeSet as) { + if (as != null) { + return StyleConstants.getSpaceBelow(as); + } else { + debugString("getSpaceBelowFromAttributeSet; as = null"); + } + return -1; + } + + /** + * Enumerate all StyleConstants in the AttributeSet + * + * We need to check explicitly, 'cause of the HTML package conversion + * mechanism (they may not be stored as StyleConstants, just translated + * to them when asked). + * + * (Use convenience methods where they are defined...) + * + * Not checking the following (which the IBM SNS guidelines says + * should be defined): + * - ComponentElementName + * - IconElementName + * - NameAttribute + * - ResolveAttribute + */ + private String expandStyleConstants(AttributeSet as) { + Color c; + Object o; + String attrString = ""; + + // ---------- check for various Character Constants + + attrString += "BidiLevel = " + StyleConstants.getBidiLevel(as); + + final Component comp = StyleConstants.getComponent(as); + if (comp != null) { + if (comp instanceof Accessible) { + final AccessibleContext ac = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return comp.getAccessibleContext(); + } + }, comp); + if (ac != null) { + attrString += "; Accessible Component = " + InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + } else { + attrString += "; Innaccessible Component = " + comp; + } + } else { + attrString += "; Innaccessible Component = " + comp; + } + } + + Icon i = StyleConstants.getIcon(as); + if (i != null) { + if (i instanceof ImageIcon) { + attrString += "; ImageIcon = " + ((ImageIcon) i).getDescription(); + } else { + attrString += "; Icon = " + i; + } + } + + attrString += "; FontFamily = " + StyleConstants.getFontFamily(as); + + attrString += "; FontSize = " + StyleConstants.getFontSize(as); + + if (StyleConstants.isBold(as)) { + attrString += "; bold"; + } + + if (StyleConstants.isItalic(as)) { + attrString += "; italic"; + } + + if (StyleConstants.isUnderline(as)) { + attrString += "; underline"; + } + + if (StyleConstants.isStrikeThrough(as)) { + attrString += "; strikethrough"; + } + + if (StyleConstants.isSuperscript(as)) { + attrString += "; superscript"; + } + + if (StyleConstants.isSubscript(as)) { + attrString += "; subscript"; + } + + c = StyleConstants.getForeground(as); + if (c != null) { + attrString += "; Foreground = " + c; + } + + c = StyleConstants.getBackground(as); + if (c != null) { + attrString += "; Background = " + c; + } + + attrString += "; FirstLineIndent = " + StyleConstants.getFirstLineIndent(as); + + attrString += "; RightIndent = " + StyleConstants.getRightIndent(as); + + attrString += "; LeftIndent = " + StyleConstants.getLeftIndent(as); + + attrString += "; LineSpacing = " + StyleConstants.getLineSpacing(as); + + attrString += "; SpaceAbove = " + StyleConstants.getSpaceAbove(as); + + attrString += "; SpaceBelow = " + StyleConstants.getSpaceBelow(as); + + attrString += "; Alignment = " + StyleConstants.getAlignment(as); + + TabSet ts = StyleConstants.getTabSet(as); + if (ts != null) { + attrString += "; TabSet = " + ts; + } + + return attrString; + } + + + /* ===== AccessibleValue methods ===== */ + + /** + * return the AccessibleValue current value from an AccessibleContext + * returned using a String 'cause the value is a java Number + * + */ + private String getCurrentAccessibleValueFromContext(final AccessibleContext ac) { + if (ac != null) { + final Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + AccessibleValue av = ac.getAccessibleValue(); + if (av == null) return null; + return av.getCurrentAccessibleValue(); + } + }, ac); + if (value != null) { + String s = value.toString(); + if (s != null) { + references.increment(s); + return s; + } + } + } else { + debugString("getCurrentAccessibleValueFromContext; ac = null"); + } + return null; + } + + /** + * return the AccessibleValue maximum value from an AccessibleContext + * returned using a String 'cause the value is a java Number + * + */ + private String getMaximumAccessibleValueFromContext(final AccessibleContext ac) { + if (ac != null) { + final Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + AccessibleValue av = ac.getAccessibleValue(); + if (av == null) return null; + return av.getMaximumAccessibleValue(); + } + }, ac); + if (value != null) { + String s = value.toString(); + if (s != null) { + references.increment(s); + return s; + } + } + } else { + debugString("getMaximumAccessibleValueFromContext; ac = null"); + } + return null; + } + + /** + * return the AccessibleValue minimum value from an AccessibleContext + * returned using a String 'cause the value is a java Number + * + */ + private String getMinimumAccessibleValueFromContext(final AccessibleContext ac) { + if (ac != null) { + final Number value = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Number call() throws Exception { + AccessibleValue av = ac.getAccessibleValue(); + if (av == null) return null; + return av.getMinimumAccessibleValue(); + } + }, ac); + if (value != null) { + String s = value.toString(); + if (s != null) { + references.increment(s); + return s; + } + } + } else { + debugString("getMinimumAccessibleValueFromContext; ac = null"); + } + return null; + } + + + /* ===== AccessibleSelection methods ===== */ + + /** + * add to the AccessibleSelection of an AccessibleContext child i + * + */ + private void addAccessibleSelectionFromContext(final AccessibleContext ac, final int i) { + try { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.addAccessibleSelection(i); + } + } + return null; + } + }, ac); + } catch(Exception e){} + } + + /** + * clear all of the AccessibleSelection of an AccessibleContex + * + */ + private void clearAccessibleSelectionFromContext(final AccessibleContext ac) { + try { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.clearAccessibleSelection(); + } + return null; + } + }, ac); + } catch(Exception e){} + + } + + /** + * get the AccessibleContext of the i-th AccessibleSelection of an AccessibleContext + * + */ + private AccessibleContext getAccessibleSelectionFromContext(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + Accessible a = as.getAccessibleSelection(i); + if (a == null) + return null; + else + return a.getAccessibleContext(); + } + } + return null; + } + }, ac); + } + + /** + * get number of things selected in the AccessibleSelection of an AccessibleContext + * + */ + private int getAccessibleSelectionCountFromContext(final AccessibleContext ac) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + return as.getAccessibleSelectionCount(); + } + } + return -1; + } + }, ac); + } + + /** + * return true if the i-th child of the AccessibleSelection of an AccessibleContext is selected + * + */ + private boolean isAccessibleChildSelectedFromContext(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + return as.isAccessibleChildSelected(i); + } + } + return false; + } + }, ac); + } + + /** + * remove the i-th child from the AccessibleSelection of an AccessibleContext + * + */ + private void removeAccessibleSelectionFromContext(final AccessibleContext ac, final int i) { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.removeAccessibleSelection(i); + } + } + return null; + } + }, ac); + } + + /** + * select all (if possible) of the children of the AccessibleSelection of an AccessibleContext + * + */ + private void selectAllAccessibleSelectionFromContext(final AccessibleContext ac) { + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Object call() throws Exception { + if (ac != null) { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as != null) { + as.selectAllAccessibleSelection(); + } + } + return null; + } + }, ac); + } + + // ======== AccessibleTable ======== + + ConcurrentHashMap hashtab = new ConcurrentHashMap<>(); + + /** + * returns the AccessibleTable for an AccessibleContext + */ + private AccessibleTable getAccessibleTableFromContext(final AccessibleContext ac) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleTable call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + AccessBridge.this.hashtab.put(at, ac); + return at; + } + } + return null; + } + }, ac); + } + + + /* + * returns the AccessibleContext that contains an AccessibleTable + */ + private AccessibleContext getContextFromAccessibleTable(AccessibleTable at) { + return hashtab.get(at); + } + + /* + * returns the row count for an AccessibleTable + */ + private int getAccessibleTableRowCount(final AccessibleContext ac) { + debugString("##### getAccessibleTableRowCount"); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleRowCount(); + } + } + return -1; + } + }, ac); + } + + /* + * returns the column count for an AccessibleTable + */ + private int getAccessibleTableColumnCount(final AccessibleContext ac) { + debugString("##### getAccessibleTableColumnCount"); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleColumnCount(); + } + } + return -1; + } + }, ac); + } + + /* + * returns the AccessibleContext for an AccessibleTable cell + */ + private AccessibleContext getAccessibleTableCellAccessibleContext(final AccessibleTable at, + final int row, final int column) { + debugString("getAccessibleTableCellAccessibleContext: at = "+at.getClass()); + if (at == null) return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (!(at instanceof AccessibleContext)) { + Accessible a = at.getAccessibleAt(row, column); + if (a != null) { + return a.getAccessibleContext(); + } + } else { + // work-around for AccessibleJTable.getCurrentAccessibleContext returning + // wrong renderer component when cell contains more than one component + AccessibleContext ac = (AccessibleContext) at; + Accessible parent = ac.getAccessibleParent(); + if (parent != null) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JTable) { + JTable table = (JTable) child; + + TableCellRenderer renderer = table.getCellRenderer(row, column); + if (renderer == null) { + Class columnClass = table.getColumnClass(column); + renderer = table.getDefaultRenderer(columnClass); + } + Component component = + renderer.getTableCellRendererComponent(table, table.getValueAt(row, column), + false, false, row, column); + if (component instanceof Accessible) { + return component.getAccessibleContext(); + } + } + } + } + return null; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the index of a cell at a given row and column in an AccessibleTable + */ + private int getAccessibleTableCellIndex(final AccessibleTable at, int row, int column) { + debugString("##### getAccessibleTableCellIndex: at="+at); + if (at != null) { + int cellIndex = row * + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)) + + column; + debugString(" ##### getAccessibleTableCellIndex="+cellIndex); + return cellIndex; + } + debugString(" ##### getAccessibleTableCellIndex FAILED"); + return -1; + } + + /* + * returns the row extent of a cell at a given row and column in an AccessibleTable + */ + private int getAccessibleTableCellRowExtent(final AccessibleTable at, final int row, final int column) { + debugString("##### getAccessibleTableCellRowExtent"); + if (at != null) { + int rowExtent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleRowExtentAt(row, column); + } + }, + getContextFromAccessibleTable(at)); + debugString(" ##### getAccessibleTableCellRowExtent="+rowExtent); + return rowExtent; + } + debugString(" ##### getAccessibleTableCellRowExtent FAILED"); + return -1; + } + + /* + * returns the column extent of a cell at a given row and column in an AccessibleTable + */ + private int getAccessibleTableCellColumnExtent(final AccessibleTable at, final int row, final int column) { + debugString("##### getAccessibleTableCellColumnExtent"); + if (at != null) { + int columnExtent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnExtentAt(row, column); + } + }, + getContextFromAccessibleTable(at)); + debugString(" ##### getAccessibleTableCellColumnExtent="+columnExtent); + return columnExtent; + } + debugString(" ##### getAccessibleTableCellColumnExtent FAILED"); + return -1; + } + + /* + * returns whether a cell is selected at a given row and column in an AccessibleTable + */ + private boolean isAccessibleTableCellSelected(final AccessibleTable at, final int row, + final int column) { + debugString("##### isAccessibleTableCellSelected: ["+row+"]["+column+"]"); + if (at == null) + return false; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + boolean isSelected = false; + Accessible a = at.getAccessibleAt(row, column); + if (a != null) { + AccessibleContext ac = a.getAccessibleContext(); + if (ac == null) + return false; + AccessibleStateSet as = ac.getAccessibleStateSet(); + if (as != null) { + isSelected = as.contains(AccessibleState.SELECTED); + } + } + return isSelected; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns an AccessibleTable that represents the row header in an + * AccessibleTable + */ + private AccessibleTable getAccessibleTableRowHeader(final AccessibleContext ac) { + debugString(" ##### getAccessibleTableRowHeader called"); + AccessibleTable at = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleTable call() throws Exception { + if (ac != null) { + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleRowHeader(); + } + } + return null; + } + }, ac); + if (at != null) { + hashtab.put(at, ac); + } + return at; + } + + /* + * returns an AccessibleTable that represents the column header in an + * AccessibleTable + */ + private AccessibleTable getAccessibleTableColumnHeader(final AccessibleContext ac) { + debugString("##### getAccessibleTableColumnHeader"); + if (ac == null) + return null; + AccessibleTable at = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleTable call() throws Exception { + // workaround for getAccessibleColumnHeader NPE + // when the table header is null + Accessible parent = ac.getAccessibleParent(); + if (parent != null) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JTable) { + JTable table = (JTable) child; + if (table.getTableHeader() == null) { + return null; + } + } + } + AccessibleTable at = ac.getAccessibleTable(); + if (at != null) { + return at.getAccessibleColumnHeader(); + } + return null; + } + }, ac); + if (at != null) { + hashtab.put(at, ac); + } + return at; + } + + /* + * returns the number of row headers in an AccessibleTable that represents + * the row header in an AccessibleTable + */ + private int getAccessibleTableRowHeaderRowCount(AccessibleContext ac) { + + debugString(" ##### getAccessibleTableRowHeaderRowCount called"); + if (ac != null) { + final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac); + if (atRowHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atRowHeader != null) { + return atRowHeader.getAccessibleRowCount(); + } + return -1; + } + }, ac); + } + } + return -1; + } + + /* + * returns the number of column headers in an AccessibleTable that represents + * the row header in an AccessibleTable + */ + private int getAccessibleTableRowHeaderColumnCount(AccessibleContext ac) { + debugString(" ##### getAccessibleTableRowHeaderColumnCount called"); + if (ac != null) { + final AccessibleTable atRowHeader = getAccessibleTableRowHeader(ac); + if (atRowHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atRowHeader != null) { + return atRowHeader.getAccessibleColumnCount(); + } + return -1; + } + }, ac); + } + } + debugString(" ##### getAccessibleTableRowHeaderColumnCount FAILED"); + return -1; + } + + /* + * returns the number of row headers in an AccessibleTable that represents + * the column header in an AccessibleTable + */ + private int getAccessibleTableColumnHeaderRowCount(AccessibleContext ac) { + + debugString("##### getAccessibleTableColumnHeaderRowCount"); + if (ac != null) { + final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac); + if (atColumnHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atColumnHeader != null) { + return atColumnHeader.getAccessibleRowCount(); + } + return -1; + } + }, ac); + } + } + debugString(" ##### getAccessibleTableColumnHeaderRowCount FAILED"); + return -1; + } + + /* + * returns the number of column headers in an AccessibleTable that represents + * the column header in an AccessibleTable + */ + private int getAccessibleTableColumnHeaderColumnCount(AccessibleContext ac) { + + debugString("##### getAccessibleTableColumnHeaderColumnCount"); + if (ac != null) { + final AccessibleTable atColumnHeader = getAccessibleTableColumnHeader(ac); + if (atColumnHeader != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (atColumnHeader != null) { + return atColumnHeader.getAccessibleColumnCount(); + } + return -1; + } + }, ac); + } + } + debugString(" ##### getAccessibleTableColumnHeaderColumnCount FAILED"); + return -1; + } + + /* + * returns the description of a row header in an AccessibleTable + */ + private AccessibleContext getAccessibleTableRowDescription(final AccessibleTable table, + final int row) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (table != null) { + Accessible a = table.getAccessibleRowDescription(row); + if (a != null) { + return a.getAccessibleContext(); + } + } + return null; + } + }, getContextFromAccessibleTable(table)); + } + + /* + * returns the description of a column header in an AccessibleTable + */ + private AccessibleContext getAccessibleTableColumnDescription(final AccessibleTable at, + final int column) { + if (at == null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = at.getAccessibleColumnDescription(column); + if (a != null) { + return a.getAccessibleContext(); + } + return null; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the number of rows selected in an AccessibleTable + */ + private int getAccessibleTableRowSelectionCount(final AccessibleTable at) { + if (at != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleRows(); + if (selections != null) + return selections.length; + else + return -1; + } + }, getContextFromAccessibleTable(at)); + } + return -1; + } + + /* + * returns the row number of the i-th selected row in an AccessibleTable + */ + private int getAccessibleTableRowSelections(final AccessibleTable at, final int i) { + if (at != null) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleRows(); + if (selections.length > i) { + return selections[i]; + } + return -1; + } + }, getContextFromAccessibleTable(at)); + } + return -1; + } + + /* + * returns whether a row is selected in an AccessibleTable + */ + private boolean isAccessibleTableRowSelected(final AccessibleTable at, + final int row) { + if (at == null) + return false; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return at.isAccessibleRowSelected(row); + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns whether a column is selected in an AccessibleTable + */ + private boolean isAccessibleTableColumnSelected(final AccessibleTable at, + final int column) { + if (at == null) + return false; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return at.isAccessibleColumnSelected(column); + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the number of columns selected in an AccessibleTable + */ + private int getAccessibleTableColumnSelectionCount(final AccessibleTable at) { + if (at == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleColumns(); + if (selections != null) + return selections.length; + else + return -1; + } + }, getContextFromAccessibleTable(at)); + } + + /* + * returns the row number of the i-th selected row in an AccessibleTable + */ + private int getAccessibleTableColumnSelections(final AccessibleTable at, final int i) { + if (at == null) + return -1; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int[] selections = at.getSelectedAccessibleColumns(); + if (selections != null && selections.length > i) { + return selections[i]; + } + return -1; + } + }, getContextFromAccessibleTable(at)); + } + + /* ===== AccessibleExtendedTable (since 1.4) ===== */ + + /* + * returns the row number for a cell at a given index in an AccessibleTable + */ + private int getAccessibleTableRow(final AccessibleTable at, int index) { + if (at == null) + return -1; + int colCount=InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)); + return index / colCount; + } + + /* + * returns the column number for a cell at a given index in an AccessibleTable + */ + private int getAccessibleTableColumn(final AccessibleTable at, int index) { + if (at == null) + return -1; + int colCount=InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)); + return index % colCount; + } + + /* + * returns the index for a cell at a given row and column in an + * AccessibleTable + */ + private int getAccessibleTableIndex(final AccessibleTable at, int row, int column) { + if (at == null) + return -1; + int colCount = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return at.getAccessibleColumnCount(); + } + }, getContextFromAccessibleTable(at)); + return row * colCount + column; + } + + // ===== AccessibleRelationSet ===== + + /* + * returns the number of relations in the AccessibleContext's + * AccessibleRelationSet + */ + private int getAccessibleRelationCount(final AccessibleContext ac) { + { + if (ac != null) { + AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleRelationSet call() throws Exception { + return ac.getAccessibleRelationSet(); + } + }, ac); + if (ars != null) + return ars.size(); + } + } + return 0; + } + + /* + * returns the ith relation key in the AccessibleContext's + * AccessibleRelationSet + */ + private String getAccessibleRelationKey(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + if (ac != null) { + AccessibleRelationSet ars = ac.getAccessibleRelationSet(); + if (ars != null) { + AccessibleRelation[] relations = ars.toArray(); + if (relations != null && i >= 0 && i < relations.length) { + return relations[i].getKey(); + } + } + } + return null; + } + }, ac); + } + + /* + * returns the number of targets in a relation in the AccessibleContext's + * AccessibleRelationSet + */ + private int getAccessibleRelationTargetCount(final AccessibleContext ac, final int i) { + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + if (ac != null) { + AccessibleRelationSet ars = ac.getAccessibleRelationSet(); + if (ars != null) { + AccessibleRelation[] relations = ars.toArray(); + if (relations != null && i >= 0 && i < relations.length) { + Object[] targets = relations[i].getTarget(); + return targets.length; + } + } + } + return -1; + } + }, ac); + } + + /* + * returns the jth target in the ith relation in the AccessibleContext's + * AccessibleRelationSet + */ + private AccessibleContext getAccessibleRelationTarget(final AccessibleContext ac, + final int i, final int j) { + debugString("***** getAccessibleRelationTarget"); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (ac != null) { + AccessibleRelationSet ars = ac.getAccessibleRelationSet(); + if (ars != null) { + AccessibleRelation[] relations = ars.toArray(); + if (relations != null && i >= 0 && i < relations.length) { + Object[] targets = relations[i].getTarget(); + if (targets != null && j >= 0 & j < targets.length) { + Object o = targets[j]; + if (o instanceof Accessible) { + return ((Accessible) o).getAccessibleContext(); + } + } + } + } + } + return null; + } + }, ac); + } + + // ========= AccessibleHypertext ========= + + private Map hyperTextContextMap = new WeakHashMap<>(); + private Map hyperLinkContextMap = new WeakHashMap<>(); + + /* + * Returns the AccessibleHypertext + */ + private AccessibleHypertext getAccessibleHypertext(final AccessibleContext ac) { + debugString("getAccessibleHyperlink"); + if (ac==null) + return null; + AccessibleHypertext hypertext = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleHypertext call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (!(at instanceof AccessibleHypertext)) { + return null; + } + return ((AccessibleHypertext) at); + } + }, ac); + hyperTextContextMap.put(hypertext, ac); + return hypertext; + } + + /* + * Returns the number of AccessibleHyperlinks + */ + private int getAccessibleHyperlinkCount(AccessibleContext ac) { + debugString("getAccessibleHyperlinkCount"); + if (ac == null) { + return 0; + } + final AccessibleHypertext hypertext = getAccessibleHypertext(ac); + if (hypertext == null) { + return 0; + } + //return hypertext.getLinkCount(); + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return hypertext.getLinkCount(); + } + }, ac); + } + + /* + * Returns the hyperlink at the specified index + */ + private AccessibleHyperlink getAccessibleHyperlink(final AccessibleHypertext hypertext, final int i) { + debugString("getAccessibleHyperlink"); + if (hypertext == null) { + return null; + } + AccessibleContext ac = hyperTextContextMap.get(hypertext); + if ( i < 0 || i >= + InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return hypertext.getLinkCount(); + } + }, ac) ) { + return null; + } + AccessibleHyperlink acLink = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleHyperlink call() throws Exception { + AccessibleHyperlink link = hypertext.getLink(i); + if (link == null || (!link.isValid())) { + return null; + } + return link; + } + }, ac); + hyperLinkContextMap.put(acLink, ac); + return acLink; + } + + /* + * Returns the hyperlink object description + */ + private String getAccessibleHyperlinkText(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkText"); + if (link == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + Object o = link.getAccessibleActionDescription(0); + if (o != null) { + return o.toString(); + } + return null; + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the hyperlink URL + */ + private String getAccessibleHyperlinkURL(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkURL"); + if (link == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + Object o = link.getAccessibleActionObject(0); + if (o != null) { + return o.toString(); + } else { + return null; + } + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the start index of the hyperlink text + */ + private int getAccessibleHyperlinkStartIndex(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkStartIndex"); + if (link == null) { + return -1; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return link.getStartIndex(); + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the end index of the hyperlink text + */ + private int getAccessibleHyperlinkEndIndex(final AccessibleHyperlink link) { + debugString("getAccessibleHyperlinkEndIndex"); + if (link == null) { + return -1; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return link.getEndIndex(); + } + }, hyperLinkContextMap.get(link)); + } + + /* + * Returns the index into an array of hyperlinks that + * is associated with this character index, or -1 if there + * is no hyperlink associated with this index. + */ + private int getAccessibleHypertextLinkIndex(final AccessibleHypertext hypertext, final int charIndex) { + debugString("getAccessibleHypertextLinkIndex: charIndex = "+charIndex); + if (hypertext == null) { + return -1; + } + int linkIndex = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return hypertext.getLinkIndex(charIndex); + } + }, hyperTextContextMap.get(hypertext)); + debugString("getAccessibleHypertextLinkIndex returning "+linkIndex); + return linkIndex; + } + + /* + * Actives the hyperlink + */ + private boolean activateAccessibleHyperlink(final AccessibleContext ac, + final AccessibleHyperlink link) { + //debugString("activateAccessibleHyperlink: link = "+link.getClass()); + if (link == null) { + return false; + } + boolean retval = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return link.doAccessibleAction(0); + } + }, ac); + debugString("activateAccessibleHyperlink: returning = "+retval); + return retval; + } + + + // ============ AccessibleKeyBinding ============= + + /* + * returns the component mnemonic + */ + private KeyStroke getMnemonic(final AccessibleContext ac) { + if (ac == null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public KeyStroke call() throws Exception { + AccessibleComponent comp = ac.getAccessibleComponent(); + if (!(comp instanceof AccessibleExtendedComponent)) { + return null; + } + AccessibleExtendedComponent aec = (AccessibleExtendedComponent) comp; + if (aec != null) { + AccessibleKeyBinding akb = aec.getAccessibleKeyBinding(); + if (akb != null) { + Object o = akb.getAccessibleKeyBinding(0); + if (o instanceof KeyStroke) { + return (KeyStroke) o; + } + } + } + return null; + } + }, ac); + } + + /* + * returns the JMenuItem accelerator + */ + private KeyStroke getAccelerator(final AccessibleContext ac) { + // workaround for getAccessibleKeyBinding not returning the + // JMenuItem accelerator + if (ac == null) + return null; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public KeyStroke call() throws Exception { + Accessible parent = ac.getAccessibleParent(); + if (parent instanceof Accessible) { + int indexInParent = ac.getAccessibleIndexInParent(); + Accessible child = + parent.getAccessibleContext().getAccessibleChild(indexInParent); + if (child instanceof JMenuItem) { + JMenuItem menuItem = (JMenuItem) child; + if (menuItem == null) + return null; + KeyStroke keyStroke = menuItem.getAccelerator(); + return keyStroke; + } + } + return null; + } + }, ac); + } + + /* + * returns 1-24 to indicate which F key is being used for a shortcut or 0 otherwise + */ + private int fKeyNumber(KeyStroke keyStroke) { + if (keyStroke == null) + return 0; + int fKey = 0; + String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); + if (keyText != null && (keyText.length() == 2 || keyText.length() == 3)) { + String prefix = keyText.substring(0, 1); + if (prefix.equals("F")) { + try { + int suffix = Integer.parseInt(keyText.substring(1)); + if (suffix >= 1 && suffix <= 24) { + fKey = suffix; + } + } catch (Exception e) { // ignore NumberFormatException + } + } + } + return fKey; + } + + /* + * returns one of several important control characters or 0 otherwise + */ + private int controlCode(KeyStroke keyStroke) { + if (keyStroke == null) + return 0; + int code = keyStroke.getKeyCode(); + switch (code) { + case KeyEvent.VK_BACK_SPACE: + case KeyEvent.VK_DELETE: + case KeyEvent.VK_DOWN: + case KeyEvent.VK_END: + case KeyEvent.VK_HOME: + case KeyEvent.VK_INSERT: + case KeyEvent.VK_KP_DOWN: + case KeyEvent.VK_KP_LEFT: + case KeyEvent.VK_KP_RIGHT: + case KeyEvent.VK_KP_UP: + case KeyEvent.VK_LEFT: + case KeyEvent.VK_PAGE_DOWN: + case KeyEvent.VK_PAGE_UP: + case KeyEvent.VK_RIGHT: + case KeyEvent.VK_UP: + break; + default: + code = 0; + break; + } + return code; + } + + /* + * returns the KeyStoke character + */ + private char getKeyChar(KeyStroke keyStroke) { + // If the shortcut is an FKey return 1-24 + if (keyStroke == null) + return 0; + int fKey = fKeyNumber(keyStroke); + if (fKey != 0) { + // return 0x00000001 through 0x00000018 + debugString(" Shortcut is: F" + fKey); + return (char)fKey; + } + // If the accelerator is a control character, return it + int keyCode = controlCode(keyStroke); + if (keyCode != 0) { + debugString(" Shortcut is control character: " + Integer.toHexString(keyCode)); + return (char)keyCode; + } + String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); + debugString(" Shortcut is: " + keyText); + if (keyText != null || keyText.length() > 0) { + CharSequence seq = keyText.subSequence(0, 1); + if (seq != null || seq.length() > 0) { + return seq.charAt(0); + } + } + return 0; + } + + /* + * returns the KeyStroke modifiers as an int + */ + private int getModifiers(KeyStroke keyStroke) { + if (keyStroke == null) + return 0; + debugString("In AccessBridge.getModifiers"); + // modifiers is a bit strip where bits 0-7 indicate a traditional modifier + // such as Ctrl/Alt/Shift, bit 8 indicates an F key shortcut, and bit 9 indicates + // a control code shortcut such as the delete key. + + int modifiers = 0; + // Is the shortcut an FKey? + if (fKeyNumber(keyStroke) != 0) { + modifiers |= 1 << 8; + } + // Is the shortcut a control code? + if (controlCode(keyStroke) != 0) { + modifiers |= 1 << 9; + } + // The following is needed in order to handle translated modifiers. + // getKeyModifiersText doesn't work because for example in German Strg is + // returned for Ctrl. + + // There can be more than one modifier, e.g. if the modifier is ctrl + shift + B + // the toString text is "shift ctrl pressed B". Need to parse through that. + StringTokenizer st = new StringTokenizer(keyStroke.toString()); + while (st.hasMoreTokens()) { + String text = st.nextToken(); + // Meta+Ctrl+Alt+Shift + // 0-3 are shift, ctrl, meta, alt + // 4-7 are for Solaris workstations (though not being used) + if (text.startsWith("met")) { + debugString(" found meta"); + modifiers |= ActionEvent.META_MASK; + } + if (text.startsWith("ctr")) { + debugString(" found ctrl"); + modifiers |= ActionEvent.CTRL_MASK; + } + if (text.startsWith("alt")) { + debugString(" found alt"); + modifiers |= ActionEvent.ALT_MASK; + } + if (text.startsWith("shi")) { + debugString(" found shift"); + modifiers |= ActionEvent.SHIFT_MASK; + } + } + debugString(" returning modifiers: 0x" + Integer.toHexString(modifiers)); + return modifiers; + } + + /* + * returns the number of key bindings associated with this context + */ + private int getAccessibleKeyBindingsCount(AccessibleContext ac) { + if (ac == null) + return 0; + int count = 0; + + if (getMnemonic(ac) != null) { + count++; + } + if (getAccelerator(ac) != null) { + count++; + } + return count; + } + + /* + * returns the key binding character at the specified index + */ + private char getAccessibleKeyBindingChar(AccessibleContext ac, int index) { + if (ac == null) + return 0; + if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getKeyChar(keyStroke); + } + } + if (index == 0) { // mnemonic + KeyStroke keyStroke = getMnemonic(ac); + if (keyStroke != null) { + return getKeyChar(keyStroke); + } + } else if (index == 1) { // accelerator + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getKeyChar(keyStroke); + } + } + return 0; + } + + /* + * returns the key binding modifiers at the specified index + */ + private int getAccessibleKeyBindingModifiers(AccessibleContext ac, int index) { + if (ac == null) + return 0; + if((index == 0) && getMnemonic(ac)==null) {// special case when there is no mnemonic + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getModifiers(keyStroke); + } + } + if (index == 0) { // mnemonic + KeyStroke keyStroke = getMnemonic(ac); + if (keyStroke != null) { + return getModifiers(keyStroke); + } + } else if (index == 1) { // accelerator + KeyStroke keyStroke = getAccelerator(ac); + if (keyStroke != null) { + return getModifiers(keyStroke); + } + } + return 0; + } + + // ========== AccessibleIcon ============ + + /* + * return the number of icons associated with this context + */ + private int getAccessibleIconsCount(final AccessibleContext ac) { + debugString("getAccessibleIconsCount"); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null) { + return 0; + } + return ai.length; + } + }, ac); + } + + /* + * return icon description at the specified index + */ + private String getAccessibleIconDescription(final AccessibleContext ac, final int index) { + debugString("getAccessibleIconDescription: index = "+index); + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null || index < 0 || index >= ai.length) { + return null; + } + return ai[index].getAccessibleIconDescription(); + } + }, ac); + } + + /* + * return icon height at the specified index + */ + private int getAccessibleIconHeight(final AccessibleContext ac, final int index) { + debugString("getAccessibleIconHeight: index = "+index); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null || index < 0 || index >= ai.length) { + return 0; + } + return ai[index].getAccessibleIconHeight(); + } + }, ac); + } + + /* + * return icon width at the specified index + */ + private int getAccessibleIconWidth(final AccessibleContext ac, final int index) { + debugString("getAccessibleIconWidth: index = "+index); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleIcon[] ai = ac.getAccessibleIcon(); + if (ai == null || index < 0 || index >= ai.length) { + return 0; + } + return ai[index].getAccessibleIconWidth(); + } + }, ac); + } + + // ========= AccessibleAction =========== + + /* + * return the number of icons associated with this context + */ + private int getAccessibleActionsCount(final AccessibleContext ac) { + debugString("getAccessibleActionsCount"); + if (ac == null) { + return 0; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa == null) + return 0; + return aa.getAccessibleActionCount(); + } + }, ac); + } + + /* + * return icon description at the specified index + */ + private String getAccessibleActionName(final AccessibleContext ac, final int index) { + debugString("getAccessibleActionName: index = "+index); + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa == null) { + return null; + } + return aa.getAccessibleActionDescription(index); + } + }, ac); + } + /* + * return icon description at the specified index + */ + private boolean doAccessibleActions(final AccessibleContext ac, final String name) { + debugString("doAccessibleActions: action name = "+name); + if (ac == null || name == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa == null) { + return false; + } + int index = -1; + int numActions = aa.getAccessibleActionCount(); + for (int i = 0; i < numActions; i++) { + String actionName = aa.getAccessibleActionDescription(i); + if (name.equals(actionName)) { + index = i; + break; + } + } + if (index == -1) { + return false; + } + boolean retval = aa.doAccessibleAction(index); + return retval; + } + }, ac); + } + + /* ===== AT utility methods ===== */ + + /** + * Sets the contents of an AccessibleContext that + * implements AccessibleEditableText with the + * specified text string. + * Returns whether successful. + */ + private boolean setTextContents(final AccessibleContext ac, final String text) { + debugString("setTextContents: ac = "+ac+"; text = "+text); + + if (! (ac instanceof AccessibleEditableText)) { + debugString(" ac not instanceof AccessibleEditableText: "+ac); + return false; + } + if (text == null) { + debugString(" text is null"); + return false; + } + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + // check whether the text field is editable + AccessibleStateSet ass = ac.getAccessibleStateSet(); + if (!ass.contains(AccessibleState.ENABLED)) { + return false; + } + ((AccessibleEditableText) ac).setTextContents(text); + return true; + } + }, ac); + } + + /** + * Returns the Accessible Context of an Internal Frame object that is + * the ancestor of a given object. If the object is an Internal Frame + * object or an Internal Frame ancestor object was found, returns the + * object's AccessibleContext. + * If there is no ancestor object that has an Accessible Role of + * Internal Frame, returns (AccessibleContext)0. + */ + private AccessibleContext getInternalFrame (AccessibleContext ac) { + return getParentWithRole(ac, AccessibleRole.INTERNAL_FRAME.toString()); + } + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + private AccessibleContext getTopLevelObject (final AccessibleContext ac) { + debugString("getTopLevelObject; ac = "+ac); + if (ac == null) { + return null; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + if (ac.getAccessibleRole() == AccessibleRole.DIALOG) { + // return the dialog, not the parent window + return ac; + } + + Accessible parent = ac.getAccessibleParent(); + if (parent == null) { + return ac; + } + Accessible tmp = parent; + while (tmp != null && tmp.getAccessibleContext() != null) { + AccessibleContext ac2 = tmp.getAccessibleContext(); + if (ac2 != null && ac2.getAccessibleRole() == AccessibleRole.DIALOG) { + // return the dialog, not the parent window + return ac2; + } + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + } + return parent.getAccessibleContext(); + } + }, ac); + } + + /** + * Returns the parent AccessibleContext that has the specified AccessibleRole. + * Returns null on error or if the AccessibleContext does not exist. + */ + private AccessibleContext getParentWithRole (final AccessibleContext ac, + final String roleName) { + debugString("getParentWithRole; ac = "+ac); + debugString("role = "+roleName); + if (ac == null || roleName == null) { + return null; + } + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + AccessibleRole role = AccessBridge.this.accessibleRoleMap.get(roleName); + if (role == null) { + return ac; + } + + Accessible parent = ac.getAccessibleParent(); + if (parent == null && ac.getAccessibleRole() == role) { + return ac; + } + + Accessible tmp = parent; + AccessibleContext tmp_ac = null; + + while (tmp != null && (tmp_ac = tmp.getAccessibleContext()) != null) { + AccessibleRole ar = tmp_ac.getAccessibleRole(); + if (ar == role) { + // found + return tmp_ac; + } + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + } + // not found + return null; + } + }, ac); + } + + /** + * Returns the parent AccessibleContext that has the specified AccessibleRole. + * Otherwise, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + private AccessibleContext getParentWithRoleElseRoot (AccessibleContext ac, + String roleName) { + AccessibleContext retval = getParentWithRole(ac, roleName); + if (retval == null) { + retval = getTopLevelObject(ac); + } + return retval; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + private int getObjectDepth(final AccessibleContext ac) { + debugString("getObjectDepth: ac = "+ac); + + if (ac == null) { + return -1; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + int count = 0; + Accessible parent = ac.getAccessibleParent(); + if (parent == null) { + return count; + } + Accessible tmp = parent; + while (tmp != null && tmp.getAccessibleContext() != null) { + parent = tmp; + tmp = parent.getAccessibleContext().getAccessibleParent(); + count++; + } + return count; + } + }, ac); + } + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * Returns (AccessibleContext)0 on error. + */ + private AccessibleContext getActiveDescendent (final AccessibleContext ac) { + debugString("getActiveDescendent: ac = "+ac); + if (ac == null) { + return null; + } + // workaround for JTree bug where the only possible active + // descendent is the JTree root + final Accessible parent = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + return ac.getAccessibleParent(); + } + }, ac); + + if (parent != null) { + Accessible child = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Accessible call() throws Exception { + int indexInParent = ac.getAccessibleIndexInParent(); + return parent.getAccessibleContext().getAccessibleChild(indexInParent); + } + }, ac); + + if (child instanceof JTree) { + // return the selected node + final JTree tree = (JTree)child; + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + return new AccessibleJTreeNode(tree, + tree.getSelectionPath(), + null); + } + }, child); + } + } + + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + AccessibleSelection as = ac.getAccessibleSelection(); + if (as == null) { + return null; + } + // assume single selection + if (as.getAccessibleSelectionCount() != 1) { + return null; + } + Accessible a = as.getAccessibleSelection(0); + if (a == null) { + return null; + } + return a.getAccessibleContext(); + } + }, ac); + } + + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. + * Returns whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + private String getJAWSAccessibleName(final AccessibleContext ac) { + debugString("getJAWSAccessibleName"); + if (ac == null) { + return null; + } + // placeholder + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return ac.getAccessibleName(); + } + }, ac); + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + private boolean requestFocus(final AccessibleContext ac) { + debugString("requestFocus"); + if (ac == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleComponent acomp = ac.getAccessibleComponent(); + if (acomp == null) { + return false; + } + acomp.requestFocus(); + return ac.getAccessibleStateSet().contains(AccessibleState.FOCUSED); + } + }, ac); + } + + /** + * Selects text between two indices. Selection includes the + * text at the start index and the text at the end index. Returns + * whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + private boolean selectTextRange(final AccessibleContext ac, final int startIndex, final int endIndex) { + debugString("selectTextRange: start = "+startIndex+"; end = "+endIndex); + if (ac == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (!(at instanceof AccessibleEditableText)) { + return false; + } + ((AccessibleEditableText) at).selectText(startIndex, endIndex); + + boolean result = at.getSelectionStart() == startIndex && + at.getSelectionEnd() == endIndex; + return result; + } + }, ac); + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + private boolean setCaretPosition(final AccessibleContext ac, final int position) { + debugString("setCaretPosition: position = "+position); + if (ac == null) { + return false; + } + return InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + AccessibleText at = ac.getAccessibleText(); + if (!(at instanceof AccessibleEditableText)) { + return false; + } + ((AccessibleEditableText) at).selectText(position, position); + return at.getCaretPosition() == position; + } + }, ac); + } + + /** + * Gets the number of visible children of an AccessibleContext. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + private int _visibleChildrenCount; + private AccessibleContext _visibleChild; + private int _currentVisibleIndex; + private boolean _foundVisibleChild; + + private int getVisibleChildrenCount(AccessibleContext ac) { + debugString("getVisibleChildrenCount"); + if (ac == null) { + return -1; + } + _visibleChildrenCount = 0; + _getVisibleChildrenCount(ac); + debugString(" _visibleChildrenCount = "+_visibleChildrenCount); + return _visibleChildrenCount; + } + + /* + * Recursively descends AccessibleContext and gets the number + * of visible children + */ + private void _getVisibleChildrenCount(final AccessibleContext ac) { + if (ac == null) + return; + int numChildren = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleChildrenCount(); + } + }, ac); + for (int i = 0; i < numChildren; i++) { + final int idx = i; + final AccessibleContext ac2 = InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleChild(idx); + if (a != null) + return a.getAccessibleContext(); + else + return null; + } + }, ac); + if ( ac2 == null || + (!InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); + } + }, ac)) + ) { + continue; + } + _visibleChildrenCount++; + + if (InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac2.getAccessibleChildrenCount(); + } + }, ac) > 0 ) { + _getVisibleChildrenCount(ac2); + } + } + } + + /** + * Gets the visible child of an AccessibleContext at the + * specified index + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + private AccessibleContext getVisibleChild(AccessibleContext ac, int index) { + debugString("getVisibleChild: index = "+index); + if (ac == null) { + return null; + } + _visibleChild = null; + _currentVisibleIndex = 0; + _foundVisibleChild = false; + _getVisibleChild(ac, index); + + if (_visibleChild != null) { + debugString( " getVisibleChild: found child = " + + InvocationUtils.invokeAndWait(new Callable() { + @Override + public String call() throws Exception { + return AccessBridge.this._visibleChild.getAccessibleName(); + } + }, ac) ); + } + return _visibleChild; + } + + /* + * Recursively searchs AccessibleContext and finds the visible component + * at the specified index + */ + private void _getVisibleChild(final AccessibleContext ac, final int index) { + if (_visibleChild != null) { + return; + } + + int numChildren = InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac.getAccessibleChildrenCount(); + } + }, ac); + for (int i = 0; i < numChildren; i++) { + final int idx=i; + final AccessibleContext ac2=InvocationUtils.invokeAndWait(new Callable() { + @Override + public AccessibleContext call() throws Exception { + Accessible a = ac.getAccessibleChild(idx); + if (a == null) + return null; + else + return a.getAccessibleContext(); + } + }, ac); + if (ac2 == null || + (!InvocationUtils.invokeAndWait(new Callable() { + @Override + public Boolean call() throws Exception { + return ac2.getAccessibleStateSet().contains(AccessibleState.SHOWING); + } + }, ac))) { + continue; + } + if (!_foundVisibleChild && _currentVisibleIndex == index) { + _visibleChild = ac2; + _foundVisibleChild = true; + return; + } + _currentVisibleIndex++; + + if ( InvocationUtils.invokeAndWait(new Callable() { + @Override + public Integer call() throws Exception { + return ac2.getAccessibleChildrenCount(); + } + }, ac) > 0 ) { + _getVisibleChild(ac2, index); + } + } + } + + + /* ===== Java object memory management code ===== */ + + /** + * Class to track object references to ensure the + * Java VM doesn't garbage collect them + */ + private class ObjectReferences { + + private class Reference { + private int value; + + Reference(int i) { + value = i; + } + + public String toString() { + return ("refCount: " + value); + } + } + + /** + * table object references, to keep 'em from being garbage collected + */ + private ConcurrentHashMap refs; + + /** + * Constructor + */ + ObjectReferences() { + refs = new ConcurrentHashMap<>(4); + } + + /** + * Debugging: dump the contents of ObjectReferences' refs Hashtable + */ + String dump() { + return refs.toString(); + } + + /** + * Increment ref count; set to 1 if we have no references for it + */ + void increment(Object o) { + if (o == null){ + debugString("ObjectReferences::increment - Passed in object is null"); + return; + } + + if (refs.containsKey(o)) { + (refs.get(o)).value++; + } else { + refs.put(o, new Reference(1)); + } + } + + /** + * Decrement ref count; remove if count drops to 0 + */ + void decrement(Object o) { + Reference aRef = refs.get(o); + if (aRef != null) { + aRef.value--; + if (aRef.value == 0) { + refs.remove(o); + } else if (aRef.value < 0) { + debugString("ERROR: decrementing reference count below 0"); + } + } else { + debugString("ERROR: object to decrement not in ObjectReferences table"); + } + } + + } + + /* ===== event handling code ===== */ + + /** + * native method for handling property change events + */ + private native void propertyCaretChange(PropertyChangeEvent e, + AccessibleContext src, + int oldValue, int newValue); + private native void propertyDescriptionChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertyNameChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertySelectionChange(PropertyChangeEvent e, + AccessibleContext src); + private native void propertyStateChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertyTextChange(PropertyChangeEvent e, + AccessibleContext src); + private native void propertyValueChange(PropertyChangeEvent e, + AccessibleContext src, + String oldValue, String newValue); + private native void propertyVisibleDataChange(PropertyChangeEvent e, + AccessibleContext src); + private native void propertyChildChange(PropertyChangeEvent e, + AccessibleContext src, + AccessibleContext oldValue, + AccessibleContext newValue); + private native void propertyActiveDescendentChange(PropertyChangeEvent e, + AccessibleContext src, + AccessibleContext oldValue, + AccessibleContext newValue); + + private native void javaShutdown(); + + /** + * native methods for handling focus events + */ + private native void focusGained(FocusEvent e, AccessibleContext src); + private native void focusLost(FocusEvent e, AccessibleContext src); + + /** + * native method for handling caret events + */ + private native void caretUpdate(CaretEvent e, AccessibleContext src); + + /** + * native methods for handling mouse events + */ + private native void mouseClicked(MouseEvent e, AccessibleContext src); + private native void mouseEntered(MouseEvent e, AccessibleContext src); + private native void mouseExited(MouseEvent e, AccessibleContext src); + private native void mousePressed(MouseEvent e, AccessibleContext src); + private native void mouseReleased(MouseEvent e, AccessibleContext src); + + /** + * native methods for handling menu & popupMenu events + */ + private native void menuCanceled(MenuEvent e, AccessibleContext src); + private native void menuDeselected(MenuEvent e, AccessibleContext src); + private native void menuSelected(MenuEvent e, AccessibleContext src); + private native void popupMenuCanceled(PopupMenuEvent e, AccessibleContext src); + private native void popupMenuWillBecomeInvisible(PopupMenuEvent e, + AccessibleContext src); + private native void popupMenuWillBecomeVisible(PopupMenuEvent e, + AccessibleContext src); + + /* ===== event definitions ===== */ + + private static final long PROPERTY_CHANGE_EVENTS = 1; + private static final long FOCUS_GAINED_EVENTS = 2; + private static final long FOCUS_LOST_EVENTS = 4; + private static final long FOCUS_EVENTS = (FOCUS_GAINED_EVENTS | FOCUS_LOST_EVENTS); + + private static final long CARET_UPATE_EVENTS = 8; + private static final long CARET_EVENTS = CARET_UPATE_EVENTS; + + private static final long MOUSE_CLICKED_EVENTS = 16; + private static final long MOUSE_ENTERED_EVENTS = 32; + private static final long MOUSE_EXITED_EVENTS = 64; + private static final long MOUSE_PRESSED_EVENTS = 128; + private static final long MOUSE_RELEASED_EVENTS = 256; + private static final long MOUSE_EVENTS = (MOUSE_CLICKED_EVENTS | MOUSE_ENTERED_EVENTS | + MOUSE_EXITED_EVENTS | MOUSE_PRESSED_EVENTS | + MOUSE_RELEASED_EVENTS); + + private static final long MENU_CANCELED_EVENTS = 512; + private static final long MENU_DESELECTED_EVENTS = 1024; + private static final long MENU_SELECTED_EVENTS = 2048; + private static final long MENU_EVENTS = (MENU_CANCELED_EVENTS | MENU_DESELECTED_EVENTS | + MENU_SELECTED_EVENTS); + + private static final long POPUPMENU_CANCELED_EVENTS = 4096; + private static final long POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS = 8192; + private static final long POPUPMENU_WILL_BECOME_VISIBLE_EVENTS = 16384; + private static final long POPUPMENU_EVENTS = (POPUPMENU_CANCELED_EVENTS | + POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS | + POPUPMENU_WILL_BECOME_VISIBLE_EVENTS); + + /* These use their own numbering scheme, to ensure sufficient expansion room */ + private static final long PROPERTY_NAME_CHANGE_EVENTS = 1; + private static final long PROPERTY_DESCRIPTION_CHANGE_EVENTS = 2; + private static final long PROPERTY_STATE_CHANGE_EVENTS = 4; + private static final long PROPERTY_VALUE_CHANGE_EVENTS = 8; + private static final long PROPERTY_SELECTION_CHANGE_EVENTS = 16; + private static final long PROPERTY_TEXT_CHANGE_EVENTS = 32; + private static final long PROPERTY_CARET_CHANGE_EVENTS = 64; + private static final long PROPERTY_VISIBLEDATA_CHANGE_EVENTS = 128; + private static final long PROPERTY_CHILD_CHANGE_EVENTS = 256; + private static final long PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS = 512; + + + private static final long PROPERTY_EVENTS = (PROPERTY_NAME_CHANGE_EVENTS | + PROPERTY_DESCRIPTION_CHANGE_EVENTS | + PROPERTY_STATE_CHANGE_EVENTS | + PROPERTY_VALUE_CHANGE_EVENTS | + PROPERTY_SELECTION_CHANGE_EVENTS | + PROPERTY_TEXT_CHANGE_EVENTS | + PROPERTY_CARET_CHANGE_EVENTS | + PROPERTY_VISIBLEDATA_CHANGE_EVENTS | + PROPERTY_CHILD_CHANGE_EVENTS | + PROPERTY_ACTIVEDESCENDENT_CHANGE_EVENTS); + + /** + * The EventHandler class listens for Java events and + * forwards them to the AT + */ + private class EventHandler implements PropertyChangeListener, + FocusListener, CaretListener, + MenuListener, PopupMenuListener, + MouseListener, WindowListener, + ChangeListener { + + private AccessBridge accessBridge; + private long javaEventMask = 0; + private long accessibilityEventMask = 0; + + EventHandler(AccessBridge bridge) { + accessBridge = bridge; + + // Register to receive WINDOW_OPENED and WINDOW_CLOSED + // events. Add the event source as a native window + // handler is it implements NativeWindowHandler. + // SwingEventMonitor.addWindowListener(this); + } + + // --------- Event Notification Registration methods + + /** + * Invoked the first time a window is made visible. + */ + public void windowOpened(WindowEvent e) { + // If the window is a NativeWindowHandler, add it. + Object o = null; + if (e != null) + o = e.getSource(); + if (o instanceof NativeWindowHandler) { + addNativeWindowHandler((NativeWindowHandler)o); + } + } + + /** + * Invoked when the user attempts to close the window + * from the window's system menu. If the program does not + * explicitly hide or dispose the window while processing + * this event, the window close operation will be canceled. + */ + public void windowClosing(WindowEvent e) {} + + /** + * Invoked when a window has been closed as the result + * of calling dispose on the window. + */ + public void windowClosed(WindowEvent e) { + // If the window is a NativeWindowHandler, remove it. + Object o = null; + if (e != null) + o = e.getSource(); + if (o instanceof NativeWindowHandler) { + removeNativeWindowHandler((NativeWindowHandler)o); + } + } + + /** + * Invoked when a window is changed from a normal to a + * minimized state. For many platforms, a minimized window + * is displayed as the icon specified in the window's + * iconImage property. + * @see java.awt.Frame#setIconImage + */ + public void windowIconified(WindowEvent e) {} + + /** + * Invoked when a window is changed from a minimized + * to a normal state. + */ + public void windowDeiconified(WindowEvent e) {} + + /** + * Invoked when the Window is set to be the active Window. Only a Frame or + * a Dialog can be the active Window. The native windowing system may + * denote the active Window or its children with special decorations, such + * as a highlighted title bar. The active Window is always either the + * focused Window, or the first Frame or Dialog that is an owner of the + * focused Window. + */ + public void windowActivated(WindowEvent e) {} + + /** + * Invoked when a Window is no longer the active Window. Only a Frame or a + * Dialog can be the active Window. The native windowing system may denote + * the active Window or its children with special decorations, such as a + * highlighted title bar. The active Window is always either the focused + * Window, or the first Frame or Dialog that is an owner of the focused + * Window. + */ + public void windowDeactivated(WindowEvent e) {} + + /** + * Turn on event monitoring for the event type passed in + * If necessary, add the appropriate event listener (if + * no other event of that type is being listened for) + */ + void addJavaEventNotification(long type) { + long newEventMask = javaEventMask | type; + /* + if ( ((javaEventMask & PROPERTY_EVENTS) == 0) && + ((newEventMask & PROPERTY_EVENTS) != 0) ) { + AccessibilityEventMonitor.addPropertyChangeListener(this); + } + */ + if ( ((javaEventMask & FOCUS_EVENTS) == 0) && + ((newEventMask & FOCUS_EVENTS) != 0) ) { + SwingEventMonitor.addFocusListener(this); + } + if ( ((javaEventMask & CARET_EVENTS) == 0) && + ((newEventMask & CARET_EVENTS) != 0) ) { + SwingEventMonitor.addCaretListener(this); + } + if ( ((javaEventMask & MOUSE_EVENTS) == 0) && + ((newEventMask & MOUSE_EVENTS) != 0) ) { + SwingEventMonitor.addMouseListener(this); + } + if ( ((javaEventMask & MENU_EVENTS) == 0) && + ((newEventMask & MENU_EVENTS) != 0) ) { + SwingEventMonitor.addMenuListener(this); + SwingEventMonitor.addPopupMenuListener(this); + } + if ( ((javaEventMask & POPUPMENU_EVENTS) == 0) && + ((newEventMask & POPUPMENU_EVENTS) != 0) ) { + SwingEventMonitor.addPopupMenuListener(this); + } + + javaEventMask = newEventMask; + } + + /** + * Turn off event monitoring for the event type passed in + * If necessary, remove the appropriate event listener (if + * no other event of that type is being listened for) + */ + void removeJavaEventNotification(long type) { + long newEventMask = javaEventMask & (~type); + /* + if ( ((javaEventMask & PROPERTY_EVENTS) != 0) && + ((newEventMask & PROPERTY_EVENTS) == 0) ) { + AccessibilityEventMonitor.removePropertyChangeListener(this); + } + */ + if (((javaEventMask & FOCUS_EVENTS) != 0) && + ((newEventMask & FOCUS_EVENTS) == 0)) { + SwingEventMonitor.removeFocusListener(this); + } + if (((javaEventMask & CARET_EVENTS) != 0) && + ((newEventMask & CARET_EVENTS) == 0)) { + SwingEventMonitor.removeCaretListener(this); + } + if (((javaEventMask & MOUSE_EVENTS) == 0) && + ((newEventMask & MOUSE_EVENTS) != 0)) { + SwingEventMonitor.removeMouseListener(this); + } + if (((javaEventMask & MENU_EVENTS) == 0) && + ((newEventMask & MENU_EVENTS) != 0)) { + SwingEventMonitor.removeMenuListener(this); + } + if (((javaEventMask & POPUPMENU_EVENTS) == 0) && + ((newEventMask & POPUPMENU_EVENTS) != 0)) { + SwingEventMonitor.removePopupMenuListener(this); + } + + javaEventMask = newEventMask; + } + + /** + * Turn on event monitoring for the event type passed in + * If necessary, add the appropriate event listener (if + * no other event of that type is being listened for) + */ + void addAccessibilityEventNotification(long type) { + long newEventMask = accessibilityEventMask | type; + if ( ((accessibilityEventMask & PROPERTY_EVENTS) == 0) && + ((newEventMask & PROPERTY_EVENTS) != 0) ) { + AccessibilityEventMonitor.addPropertyChangeListener(this); + } + accessibilityEventMask = newEventMask; + } + + /** + * Turn off event monitoring for the event type passed in + * If necessary, remove the appropriate event listener (if + * no other event of that type is being listened for) + */ + void removeAccessibilityEventNotification(long type) { + long newEventMask = accessibilityEventMask & (~type); + if ( ((accessibilityEventMask & PROPERTY_EVENTS) != 0) && + ((newEventMask & PROPERTY_EVENTS) == 0) ) { + AccessibilityEventMonitor.removePropertyChangeListener(this); + } + accessibilityEventMask = newEventMask; + } + + /** + * ------- property change event glue + */ + // This is invoked on the EDT , as + public void propertyChange(PropertyChangeEvent e) { + + accessBridge.debugString("propertyChange(" + e.toString() + ") called"); + + if (e != null && (accessibilityEventMask & PROPERTY_EVENTS) != 0) { + Object o = e.getSource(); + AccessibleContext ac; + + if (o instanceof AccessibleContext) { + ac = (AccessibleContext) o; + } else { + Accessible a = Translator.getAccessible(e.getSource()); + if (a == null) + return; + else + ac = a.getAccessibleContext(); + } + if (ac != null) { + InvocationUtils.registerAccessibleContext(ac, AppContext.getAppContext()); + + accessBridge.debugString("AccessibleContext: " + ac); + String propertyName = e.getPropertyName(); + + if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) { + int oldValue = 0; + int newValue = 0; + + if (e.getOldValue() instanceof Integer) { + oldValue = ((Integer) e.getOldValue()).intValue(); + } + if (e.getNewValue() instanceof Integer) { + newValue = ((Integer) e.getNewValue()).intValue(); + } + accessBridge.debugString(" - about to call propertyCaretChange()"); + accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue); + accessBridge.propertyCaretChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY) == 0) { + String oldValue = null; + String newValue = null; + + if (e.getOldValue() != null) { + oldValue = e.getOldValue().toString(); + } + if (e.getNewValue() != null) { + newValue = e.getNewValue().toString(); + } + accessBridge.debugString(" - about to call propertyDescriptionChange()"); + accessBridge.debugString(" old value: " + oldValue + "new value: " + newValue); + accessBridge.propertyDescriptionChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_NAME_PROPERTY) == 0) { + String oldValue = null; + String newValue = null; + + if (e.getOldValue() != null) { + oldValue = e.getOldValue().toString(); + } + if (e.getNewValue() != null) { + newValue = e.getNewValue().toString(); + } + accessBridge.debugString(" - about to call propertyNameChange()"); + accessBridge.debugString(" old value: " + oldValue + " new value: " + newValue); + accessBridge.propertyNameChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY) == 0) { + accessBridge.debugString(" - about to call propertySelectionChange() " + ac + " " + Thread.currentThread() + " " + e.getSource()); + + accessBridge.propertySelectionChange(e, ac); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_STATE_PROPERTY) == 0) { + String oldValue = null; + String newValue = null; + + // Localization fix requested by Oliver for EA-1 + if (e.getOldValue() != null) { + AccessibleState oldState = (AccessibleState) e.getOldValue(); + oldValue = oldState.toDisplayString(Locale.US); + } + if (e.getNewValue() != null) { + AccessibleState newState = (AccessibleState) e.getNewValue(); + newValue = newState.toDisplayString(Locale.US); + } + + accessBridge.debugString(" - about to call propertyStateChange()"); + accessBridge.propertyStateChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0) { + accessBridge.debugString(" - about to call propertyTextChange()"); + accessBridge.propertyTextChange(e, ac); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY) == 0) { // strings 'cause of floating point, etc. + String oldValue = null; + String newValue = null; + + if (e.getOldValue() != null) { + oldValue = e.getOldValue().toString(); + } + if (e.getNewValue() != null) { + newValue = e.getNewValue().toString(); + } + accessBridge.debugString(" - about to call propertyDescriptionChange()"); + accessBridge.propertyValueChange(e, ac, oldValue, newValue); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY) == 0) { + accessBridge.propertyVisibleDataChange(e, ac); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) { + AccessibleContext oldAC = null; + AccessibleContext newAC = null; + Accessible a; + + if (e.getOldValue() instanceof AccessibleContext) { + oldAC = (AccessibleContext) e.getOldValue(); + InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext()); + } + if (e.getNewValue() instanceof AccessibleContext) { + newAC = (AccessibleContext) e.getNewValue(); + InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext()); + } + accessBridge.debugString(" - about to call propertyChildChange()"); + accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC); + accessBridge.propertyChildChange(e, ac, oldAC, newAC); + + } else if (propertyName.compareTo(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0) { + handleActiveDescendentEvent(e, ac); + } + } + } + } + + /* + * Handle an ActiveDescendent PropertyChangeEvent. This + * method works around a JTree bug where ActiveDescendent + * PropertyChangeEvents have the wrong parent. + */ + private AccessibleContext prevAC = null; // previous AccessibleContext + + private void handleActiveDescendentEvent(PropertyChangeEvent e, + AccessibleContext ac) { + if (e == null || ac == null) + return; + AccessibleContext oldAC = null; + AccessibleContext newAC = null; + Accessible a; + + // get the old active descendent + if (e.getOldValue() instanceof Accessible) { + oldAC = ((Accessible) e.getOldValue()).getAccessibleContext(); + } else if (e.getOldValue() instanceof Component) { + a = Translator.getAccessible(e.getOldValue()); + if (a != null) { + oldAC = a.getAccessibleContext(); + } + } + if (oldAC != null) { + Accessible parent = oldAC.getAccessibleParent(); + if (parent instanceof JTree) { + // use the previous AccessibleJTreeNode + oldAC = prevAC; + } + } + + // get the new active descendent + if (e.getNewValue() instanceof Accessible) { + newAC = ((Accessible) e.getNewValue()).getAccessibleContext(); + } else if (e.getNewValue() instanceof Component) { + a = Translator.getAccessible(e.getNewValue()); + if (a != null) { + newAC = a.getAccessibleContext(); + } + } + if (newAC != null) { + Accessible parent = newAC.getAccessibleParent(); + if (parent instanceof JTree) { + // use a new AccessibleJTreeNode with the right parent + JTree tree = (JTree)parent; + newAC = new AccessibleJTreeNode(tree, + tree.getSelectionPath(), + null); + } + } + prevAC = newAC; + + accessBridge.debugString(" - about to call propertyActiveDescendentChange()"); + accessBridge.debugString(" AC: " + ac); + accessBridge.debugString(" old AC: " + oldAC + "new AC: " + newAC); + + InvocationUtils.registerAccessibleContext(oldAC, AppContext.getAppContext()); + InvocationUtils.registerAccessibleContext(newAC, AppContext.getAppContext()); + accessBridge.propertyActiveDescendentChange(e, ac, oldAC, newAC); + } + + /** + * ------- focus event glue + */ + private boolean stateChangeListenerAdded = false; + + public void focusGained(FocusEvent e) { + processFocusGained(); + } + + public void stateChanged(ChangeEvent e) { + processFocusGained(); + } + + private void processFocusGained() { + Component focusOwner = KeyboardFocusManager. + getCurrentKeyboardFocusManager().getFocusOwner(); + if (focusOwner == null) { + return; + } + + // Only menus and popup selections are handled by the JRootPane. + if (focusOwner instanceof JRootPane) { + MenuElement [] path = + MenuSelectionManager.defaultManager().getSelectedPath(); + if (path.length > 1) { + Component penult = path[path.length-2].getComponent(); + Component last = path[path.length-1].getComponent(); + + if (last instanceof JPopupMenu) { + // This is a popup with nothing in the popup + // selected. The menu itself is selected. + FocusEvent e = new FocusEvent(penult, FocusEvent.FOCUS_GAINED); + AccessibleContext context = penult.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, SunToolkit.targetToAppContext(penult)); + accessBridge.focusGained(e, context); + } else if (penult instanceof JPopupMenu) { + // This is a popup with an item selected + FocusEvent e = + new FocusEvent(last, FocusEvent.FOCUS_GAINED); + accessBridge.debugString(" - about to call focusGained()"); + AccessibleContext focusedAC = last.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(last)); + accessBridge.debugString(" AC: " + focusedAC); + accessBridge.focusGained(e, focusedAC); + } + } + } else { + // The focus owner has the selection. + if (focusOwner instanceof Accessible) { + FocusEvent e = new FocusEvent(focusOwner, + FocusEvent.FOCUS_GAINED); + accessBridge.debugString(" - about to call focusGained()"); + AccessibleContext focusedAC = focusOwner.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(focusedAC, SunToolkit.targetToAppContext(focusOwner)); + accessBridge.debugString(" AC: " + focusedAC); + accessBridge.focusGained(e, focusedAC); + } + } + } + + public void focusLost(FocusEvent e) { + if (e != null && (javaEventMask & FOCUS_LOST_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + accessBridge.debugString(" - about to call focusLost()"); + accessBridge.debugString(" AC: " + a.getAccessibleContext()); + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.focusLost(e, context); + } + } + } + + /** + * ------- caret event glue + */ + public void caretUpdate(CaretEvent e) { + if (e != null && (javaEventMask & CARET_UPATE_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.caretUpdate(e, context); + } + } + } + + /** + * ------- mouse event glue + */ + + public void mouseClicked(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_CLICKED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseClicked(e, context); + } + } + } + + public void mouseEntered(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_ENTERED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseEntered(e, context); + } + } + } + + public void mouseExited(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_EXITED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseExited(e, context); + } + } + } + + public void mousePressed(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_PRESSED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mousePressed(e, context); + } + } + } + + public void mouseReleased(MouseEvent e) { + if (e != null && (javaEventMask & MOUSE_RELEASED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.mouseReleased(e, context); + } + } + } + + /** + * ------- menu event glue + */ + public void menuCanceled(MenuEvent e) { + if (e != null && (javaEventMask & MENU_CANCELED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.menuCanceled(e, context); + } + } + } + + public void menuDeselected(MenuEvent e) { + if (e != null && (javaEventMask & MENU_DESELECTED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.menuDeselected(e, context); + } + } + } + + public void menuSelected(MenuEvent e) { + if (e != null && (javaEventMask & MENU_SELECTED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.menuSelected(e, context); + } + } + } + + public void popupMenuCanceled(PopupMenuEvent e) { + if (e != null && (javaEventMask & POPUPMENU_CANCELED_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.popupMenuCanceled(e, context); + } + } + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_INVISIBLE_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.popupMenuWillBecomeInvisible(e, context); + } + } + } + + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + if (e != null && (javaEventMask & POPUPMENU_WILL_BECOME_VISIBLE_EVENTS) != 0) { + Accessible a = Translator.getAccessible(e.getSource()); + if (a != null) { + AccessibleContext context = a.getAccessibleContext(); + InvocationUtils.registerAccessibleContext(context, AppContext.getAppContext()); + accessBridge.popupMenuWillBecomeVisible(e, context); + } + } + } + + } // End of EventHandler Class + + // --------- Event Notification Registration methods + + /** + * Wrapper method around eventHandler.addJavaEventNotification() + */ + private void addJavaEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.addJavaEventNotification(type); + } + }); + } + + /** + * Wrapper method around eventHandler.removeJavaEventNotification() + */ + private void removeJavaEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.removeJavaEventNotification(type); + } + }); + } + + + /** + * Wrapper method around eventHandler.addAccessibilityEventNotification() + */ + private void addAccessibilityEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.addAccessibilityEventNotification(type); + } + }); + } + + /** + * Wrapper method around eventHandler.removeAccessibilityEventNotification() + */ + private void removeAccessibilityEventNotification(final long type) { + EventQueue.invokeLater(new Runnable() { + public void run(){ + eventHandler.removeAccessibilityEventNotification(type); + } + }); + } + + /** + ****************************************************** + * All AccessibleRoles + * + * We shouldn't have to do this since it requires us + * to synchronize the allAccessibleRoles array when + * the AccessibleRoles class interface changes. However, + * there is no Accessibility API method to get all + * AccessibleRoles + ****************************************************** + */ + private AccessibleRole [] allAccessibleRoles = { + /** + * Object is used to alert the user about something. + */ + AccessibleRole.ALERT, + + /** + * The header for a column of data. + */ + AccessibleRole.COLUMN_HEADER, + + /** + * Object that can be drawn into and is used to trap + * events. + * @see #FRAME + * @see #GLASS_PANE + * @see #LAYERED_PANE + */ + AccessibleRole.CANVAS, + + /** + * A list of choices the user can select from. Also optionally + * allows the user to enter a choice of their own. + */ + AccessibleRole.COMBO_BOX, + + /** + * An iconified internal frame in a DESKTOP_PANE. + * @see #DESKTOP_PANE + * @see #INTERNAL_FRAME + */ + AccessibleRole.DESKTOP_ICON, + + /** + * A frame-like object that is clipped by a desktop pane. The + * desktop pane, internal frame, and desktop icon objects are + * often used to create multiple document interfaces within an + * application. + * @see #DESKTOP_ICON + * @see #DESKTOP_PANE + * @see #FRAME + */ + AccessibleRole.INTERNAL_FRAME, + + /** + * A pane that supports internal frames and + * iconified versions of those internal frames. + * @see #DESKTOP_ICON + * @see #INTERNAL_FRAME + */ + AccessibleRole.DESKTOP_PANE, + + /** + * A specialized pane whose primary use is inside a DIALOG + * @see #DIALOG + */ + AccessibleRole.OPTION_PANE, + + /** + * A top level window with no title or border. + * @see #FRAME + * @see #DIALOG + */ + AccessibleRole.WINDOW, + + /** + * A top level window with a title bar, border, menu bar, etc. It is + * often used as the primary window for an application. + * @see #DIALOG + * @see #CANVAS + * @see #WINDOW + */ + AccessibleRole.FRAME, + + /** + * A top level window with title bar and a border. A dialog is similar + * to a frame, but it has fewer properties and is often used as a + * secondary window for an application. + * @see #FRAME + * @see #WINDOW + */ + AccessibleRole.DIALOG, + + /** + * A specialized dialog that lets the user choose a color. + */ + AccessibleRole.COLOR_CHOOSER, + + + /** + * A pane that allows the user to navigate through + * and select the contents of a directory. May be used + * by a file chooser. + * @see #FILE_CHOOSER + */ + AccessibleRole.DIRECTORY_PANE, + + /** + * A specialized dialog that displays the files in the directory + * and lets the user select a file, browse a different directory, + * or specify a filename. May use the directory pane to show the + * contents of a directory. + * @see #DIRECTORY_PANE + */ + AccessibleRole.FILE_CHOOSER, + + /** + * An object that fills up space in a user interface. It is often + * used in interfaces to tweak the spacing between components, + * but serves no other purpose. + */ + AccessibleRole.FILLER, + + /** + * A hypertext anchor + */ + // AccessibleRole.HYPERLINK, + + /** + * A small fixed size picture, typically used to decorate components. + */ + AccessibleRole.ICON, + + /** + * An object used to present an icon or short string in an interface. + */ + AccessibleRole.LABEL, + + /** + * A specialized pane that has a glass pane and a layered pane as its + * children. + * @see #GLASS_PANE + * @see #LAYERED_PANE + */ + AccessibleRole.ROOT_PANE, + + /** + * A pane that is guaranteed to be painted on top + * of all panes beneath it. + * @see #ROOT_PANE + * @see #CANVAS + */ + AccessibleRole.GLASS_PANE, + + /** + * A specialized pane that allows its children to be drawn in layers, + * providing a form of stacking order. This is usually the pane that + * holds the menu bar as well as the pane that contains most of the + * visual components in a window. + * @see #GLASS_PANE + * @see #ROOT_PANE + */ + AccessibleRole.LAYERED_PANE, + + /** + * An object that presents a list of objects to the user and allows the + * user to select one or more of them. A list is usually contained + * within a scroll pane. + * @see #SCROLL_PANE + * @see #LIST_ITEM + */ + AccessibleRole.LIST, + + /** + * An object that presents an element in a list. A list is usually + * contained within a scroll pane. + * @see #SCROLL_PANE + * @see #LIST + */ + AccessibleRole.LIST_ITEM, + + /** + * An object usually drawn at the top of the primary dialog box of + * an application that contains a list of menus the user can choose + * from. For example, a menu bar might contain menus for "File," + * "Edit," and "Help." + * @see #MENU + * @see #POPUP_MENU + * @see #LAYERED_PANE + */ + AccessibleRole.MENU_BAR, + + /** + * A temporary window that is usually used to offer the user a + * list of choices, and then hides when the user selects one of + * those choices. + * @see #MENU + * @see #MENU_ITEM + */ + AccessibleRole.POPUP_MENU, + + /** + * An object usually found inside a menu bar that contains a list + * of actions the user can choose from. A menu can have any object + * as its children, but most often they are menu items, other menus, + * or rudimentary objects such as radio buttons, check boxes, or + * separators. For example, an application may have an "Edit" menu + * that contains menu items for "Cut" and "Paste." + * @see #MENU_BAR + * @see #MENU_ITEM + * @see #SEPARATOR + * @see #RADIO_BUTTON + * @see #CHECK_BOX + * @see #POPUP_MENU + */ + AccessibleRole.MENU, + + /** + * An object usually contained in a menu that presents an action + * the user can choose. For example, the "Cut" menu item in an + * "Edit" menu would be an action the user can select to cut the + * selected area of text in a document. + * @see #MENU_BAR + * @see #SEPARATOR + * @see #POPUP_MENU + */ + AccessibleRole.MENU_ITEM, + + /** + * An object usually contained in a menu to provide a visual + * and logical separation of the contents in a menu. For example, + * the "File" menu of an application might contain menu items for + * "Open," "Close," and "Exit," and will place a separator between + * "Close" and "Exit" menu items. + * @see #MENU + * @see #MENU_ITEM + */ + AccessibleRole.SEPARATOR, + + /** + * An object that presents a series of panels (or page tabs), one at a + * time, through some mechanism provided by the object. The most common + * mechanism is a list of tabs at the top of the panel. The children of + * a page tab list are all page tabs. + * @see #PAGE_TAB + */ + AccessibleRole.PAGE_TAB_LIST, + + /** + * An object that is a child of a page tab list. Its sole child is + * the panel that is to be presented to the user when the user + * selects the page tab from the list of tabs in the page tab list. + * @see #PAGE_TAB_LIST + */ + AccessibleRole.PAGE_TAB, + + /** + * A generic container that is often used to group objects. + */ + AccessibleRole.PANEL, + + /** + * An object used to indicate how much of a task has been completed. + */ + AccessibleRole.PROGRESS_BAR, + + /** + * A text object used for passwords, or other places where the + * text contents is not shown visibly to the user + */ + AccessibleRole.PASSWORD_TEXT, + + /** + * An object the user can manipulate to tell the application to do + * something. + * @see #CHECK_BOX + * @see #TOGGLE_BUTTON + * @see #RADIO_BUTTON + */ + AccessibleRole.PUSH_BUTTON, + + /** + * A specialized push button that can be checked or unchecked, but + * does not provide a separate indicator for the current state. + * @see #PUSH_BUTTON + * @see #CHECK_BOX + * @see #RADIO_BUTTON + */ + AccessibleRole.TOGGLE_BUTTON, + + /** + * A choice that can be checked or unchecked and provides a + * separate indicator for the current state. + * @see #PUSH_BUTTON + * @see #TOGGLE_BUTTON + * @see #RADIO_BUTTON + */ + AccessibleRole.CHECK_BOX, + + /** + * A specialized check box that will cause other radio buttons in the + * same group to become unchecked when this one is checked. + * @see #PUSH_BUTTON + * @see #TOGGLE_BUTTON + * @see #CHECK_BOX + */ + AccessibleRole.RADIO_BUTTON, + + /** + * The header for a row of data. + */ + AccessibleRole.ROW_HEADER, + + /** + * An object that allows a user to incrementally view a large amount + * of information. Its children can include scroll bars and a viewport. + * @see #SCROLL_BAR + * @see #VIEWPORT + */ + AccessibleRole.SCROLL_PANE, + + /** + * An object usually used to allow a user to incrementally view a + * large amount of data. Usually used only by a scroll pane. + * @see #SCROLL_PANE + */ + AccessibleRole.SCROLL_BAR, + + /** + * An object usually used in a scroll pane. It represents the portion + * of the entire data that the user can see. As the user manipulates + * the scroll bars, the contents of the viewport can change. + * @see #SCROLL_PANE + */ + AccessibleRole.VIEWPORT, + + /** + * An object that allows the user to select from a bounded range. For + * example, a slider might be used to select a number between 0 and 100. + */ + AccessibleRole.SLIDER, + + /** + * A specialized panel that presents two other panels at the same time. + * Between the two panels is a divider the user can manipulate to make + * one panel larger and the other panel smaller. + */ + AccessibleRole.SPLIT_PANE, + + /** + * An object used to present information in terms of rows and columns. + * An example might include a spreadsheet application. + */ + AccessibleRole.TABLE, + + /** + * An object that presents text to the user. The text is usually + * editable by the user as opposed to a label. + * @see #LABEL + */ + AccessibleRole.TEXT, + + /** + * An object used to present hierarchical information to the user. + * The individual nodes in the tree can be collapsed and expanded + * to provide selective disclosure of the tree's contents. + */ + AccessibleRole.TREE, + + /** + * A bar or palette usually composed of push buttons or toggle buttons. + * It is often used to provide the most frequently used functions for an + * application. + */ + AccessibleRole.TOOL_BAR, + + /** + * An object that provides information about another object. The + * accessibleDescription property of the tool tip is often displayed + * to the user in a small "help bubble" when the user causes the + * mouse to hover over the object associated with the tool tip. + */ + AccessibleRole.TOOL_TIP, + + /** + * An AWT component, but nothing else is known about it. + * @see #SWING_COMPONENT + * @see #UNKNOWN + */ + AccessibleRole.AWT_COMPONENT, + + /** + * A Swing component, but nothing else is known about it. + * @see #AWT_COMPONENT + * @see #UNKNOWN + */ + AccessibleRole.SWING_COMPONENT, + + /** + * The object contains some Accessible information, but its role is + * not known. + * @see #AWT_COMPONENT + * @see #SWING_COMPONENT + */ + AccessibleRole.UNKNOWN, + + // These roles are only available in JDK 1.4 + + /** + * A STATUS_BAR is an simple component that can contain + * multiple labels of status information to the user. + AccessibleRole.STATUS_BAR, + + /** + * A DATE_EDITOR is a component that allows users to edit + * java.util.Date and java.util.Time objects + AccessibleRole.DATE_EDITOR, + + /** + * A SPIN_BOX is a simple spinner component and its main use + * is for simple numbers. + AccessibleRole.SPIN_BOX, + + /** + * A FONT_CHOOSER is a component that lets the user pick various + * attributes for fonts. + AccessibleRole.FONT_CHOOSER, + + /** + * A GROUP_BOX is a simple container that contains a border + * around it and contains components inside it. + AccessibleRole.GROUP_BOX + + /** + * Since JDK 1.5 + * + * A text header + + AccessibleRole.HEADER, + + /** + * A text footer + + AccessibleRole.FOOTER, + + /** + * A text paragraph + + AccessibleRole.PARAGRAPH, + + /** + * A ruler is an object used to measure distance + + AccessibleRole.RULER, + + /** + * A role indicating the object acts as a formula for + * calculating a value. An example is a formula in + * a spreadsheet cell. + AccessibleRole.EDITBAR + */ + }; + + /** + * This class implements accessibility support for the + * JTree child. It provides an implementation of the + * Java Accessibility API appropriate to tree nodes. + * + * Copied from JTree.java to work around a JTree bug where + * ActiveDescendent PropertyChangeEvents contain the wrong + * parent. + */ + /** + * This class in invoked on the EDT as its part of ActiveDescendant, + * hence the calls do not need to be specifically made on the EDT + */ + private class AccessibleJTreeNode extends AccessibleContext + implements Accessible, AccessibleComponent, AccessibleSelection, + AccessibleAction { + + private JTree tree = null; + private TreeModel treeModel = null; + private Object obj = null; + private TreePath path = null; + private Accessible accessibleParent = null; + private int index = 0; + private boolean isLeaf = false; + + /** + * Constructs an AccessibleJTreeNode + */ + AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) { + tree = t; + path = p; + accessibleParent = ap; + if (t != null) + treeModel = t.getModel(); + if (p != null) { + obj = p.getLastPathComponent(); + if (treeModel != null && obj != null) { + isLeaf = treeModel.isLeaf(obj); + } + } + debugString("AccessibleJTreeNode: name = "+getAccessibleName()+"; TreePath = "+p+"; parent = "+ap); + } + + private TreePath getChildTreePath(int i) { + // Tree nodes can't be so complex that they have + // two sets of children -> we're ignoring that case + if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) { + return null; + } else { + Object childObj = treeModel.getChild(obj, i); + Object[] objPath = path.getPath(); + Object[] objChildPath = new Object[objPath.length+1]; + java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length); + objChildPath[objChildPath.length-1] = childObj; + return new TreePath(objChildPath); + } + } + + /** + * Get the AccessibleContext associated with this tree node. + * In the implementation of the Java Accessibility API for + * this class, return this object, which is its own + * AccessibleContext. + * + * @return this object + */ + public AccessibleContext getAccessibleContext() { + return this; + } + + private AccessibleContext getCurrentAccessibleContext() { + Component c = getCurrentComponent(); + if (c instanceof Accessible) { + return (c.getAccessibleContext()); + } else { + return null; + } + } + + private Component getCurrentComponent() { + debugString("AccessibleJTreeNode: getCurrentComponent"); + // is the object visible? + // if so, get row, selected, focus & leaf state, + // and then get the renderer component and return it + if (tree != null && tree.isVisible(path)) { + TreeCellRenderer r = tree.getCellRenderer(); + if (r == null) { + debugString(" returning null 1"); + return null; + } + TreeUI ui = tree.getUI(); + if (ui != null) { + int row = ui.getRowForPath(tree, path); + boolean selected = tree.isPathSelected(path); + boolean expanded = tree.isExpanded(path); + boolean hasFocus = false; // how to tell?? -PK + Component retval = r.getTreeCellRendererComponent(tree, obj, + selected, expanded, + isLeaf, row, hasFocus); + debugString(" returning = "+retval.getClass()); + return retval; + } + } + debugString(" returning null 2"); + return null; + } + + // AccessibleContext methods + + /** + * Get the accessible name of this object. + * + * @return the localized name of the object; null if this + * object does not have a name + */ + public String getAccessibleName() { + debugString("AccessibleJTreeNode: getAccessibleName"); + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + String name = ac.getAccessibleName(); + if ((name != null) && (!name.isEmpty())) { + String retval = ac.getAccessibleName(); + debugString(" returning "+retval); + return retval; + } else { + return null; + } + } + if ((accessibleName != null) && (accessibleName.isEmpty())) { + return accessibleName; + } else { + return null; + } + } + + /** + * Set the localized accessible name of this object. + * + * @param s the new localized name of the object. + */ + public void setAccessibleName(String s) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.setAccessibleName(s); + } else { + super.setAccessibleName(s); + } + } + + // + // *** should check tooltip text for desc. (needs MouseEvent) + // + /** + * Get the accessible description of this object. + * + * @return the localized description of the object; null if + * this object does not have a description + */ + public String getAccessibleDescription() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return ac.getAccessibleDescription(); + } else { + return super.getAccessibleDescription(); + } + } + + /** + * Set the accessible description of this object. + * + * @param s the new localized description of the object + */ + public void setAccessibleDescription(String s) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.setAccessibleDescription(s); + } else { + super.setAccessibleDescription(s); + } + } + + /** + * Get the role of this object. + * + * @return an instance of AccessibleRole describing the role of the object + * @see AccessibleRole + */ + public AccessibleRole getAccessibleRole() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return ac.getAccessibleRole(); + } else { + return AccessibleRole.UNKNOWN; + } + } + + /** + * Get the state set of this object. + * + * @return an instance of AccessibleStateSet containing the + * current state set of the object + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() { + if (tree == null) + return null; + AccessibleContext ac = getCurrentAccessibleContext(); + AccessibleStateSet states; + int row = tree.getUI().getRowForPath(tree,path); + int lsr = tree.getLeadSelectionRow(); + if (ac != null) { + states = ac.getAccessibleStateSet(); + } else { + states = new AccessibleStateSet(); + } + // need to test here, 'cause the underlying component + // is a cellRenderer, which is never showing... + if (isShowing()) { + states.add(AccessibleState.SHOWING); + } else if (states.contains(AccessibleState.SHOWING)) { + states.remove(AccessibleState.SHOWING); + } + if (isVisible()) { + states.add(AccessibleState.VISIBLE); + } else if (states.contains(AccessibleState.VISIBLE)) { + states.remove(AccessibleState.VISIBLE); + } + if (tree.isPathSelected(path)){ + states.add(AccessibleState.SELECTED); + } + if (lsr == row) { + states.add(AccessibleState.ACTIVE); + } + if (!isLeaf) { + states.add(AccessibleState.EXPANDABLE); + } + if (tree.isExpanded(path)) { + states.add(AccessibleState.EXPANDED); + } else { + states.add(AccessibleState.COLLAPSED); + } + if (tree.isEditable()) { + states.add(AccessibleState.EDITABLE); + } + return states; + } + + /** + * Get the Accessible parent of this object. + * + * @return the Accessible parent of this object; null if this + * object does not have an Accessible parent + */ + public Accessible getAccessibleParent() { + // someone wants to know, so we need to create our parent + // if we don't have one (hey, we're a talented kid!) + if (accessibleParent == null && path != null) { + Object[] objPath = path.getPath(); + if (objPath.length > 1) { + Object objParent = objPath[objPath.length-2]; + if (treeModel != null) { + index = treeModel.getIndexOfChild(objParent, obj); + } + Object[] objParentPath = new Object[objPath.length-1]; + java.lang.System.arraycopy(objPath, 0, objParentPath, + 0, objPath.length-1); + TreePath parentPath = new TreePath(objParentPath); + accessibleParent = new AccessibleJTreeNode(tree, + parentPath, + null); + this.setAccessibleParent(accessibleParent); + } else if (treeModel != null) { + accessibleParent = tree; // we're the top! + index = 0; // we're an only child! + this.setAccessibleParent(accessibleParent); + } + } + return accessibleParent; + } + + /** + * Get the index of this object in its accessible parent. + * + * @return the index of this object in its parent; -1 if this + * object does not have an accessible parent. + * @see #getAccessibleParent + */ + public int getAccessibleIndexInParent() { + // index is invalid 'till we have an accessibleParent... + if (accessibleParent == null) { + getAccessibleParent(); + } + if (path != null) { + Object[] objPath = path.getPath(); + if (objPath.length > 1) { + Object objParent = objPath[objPath.length-2]; + if (treeModel != null) { + index = treeModel.getIndexOfChild(objParent, obj); + } + } + } + return index; + } + + /** + * Returns the number of accessible children in the object. + * + * @return the number of accessible children in the object. + */ + public int getAccessibleChildrenCount() { + // Tree nodes can't be so complex that they have + // two sets of children -> we're ignoring that case + if (obj != null && treeModel != null) { + return treeModel.getChildCount(obj); + } + return 0; + } + + /** + * Return the specified Accessible child of the object. + * + * @param i zero-based index of child + * @return the Accessible child of the object + */ + public Accessible getAccessibleChild(int i) { + // Tree nodes can't be so complex that they have + // two sets of children -> we're ignoring that case + if (i < 0 || i >= getAccessibleChildrenCount() || path == null || treeModel == null) { + return null; + } else { + Object childObj = treeModel.getChild(obj, i); + Object[] objPath = path.getPath(); + Object[] objChildPath = new Object[objPath.length+1]; + java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length); + objChildPath[objChildPath.length-1] = childObj; + TreePath childPath = new TreePath(objChildPath); + return new AccessibleJTreeNode(tree, childPath, this); + } + } + + /** + * Gets the locale of the component. If the component does not have + * a locale, then the locale of its parent is returned. + * + * @return This component's locale. If this component does not have + * a locale, the locale of its parent is returned. + * @exception IllegalComponentStateException + * If the Component does not have its own locale and has not yet + * been added to a containment hierarchy such that the locale can be + * determined from the containing parent. + * @see #setLocale + */ + public Locale getLocale() { + if (tree == null) + return null; + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return ac.getLocale(); + } else { + return tree.getLocale(); + } + } + + /** + * Add a PropertyChangeListener to the listener list. + * The listener is registered for all properties. + * + * @param l The PropertyChangeListener to be added + */ + public void addPropertyChangeListener(PropertyChangeListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.addPropertyChangeListener(l); + } else { + super.addPropertyChangeListener(l); + } + } + + /** + * Remove a PropertyChangeListener from the listener list. + * This removes a PropertyChangeListener that was registered + * for all properties. + * + * @param l The PropertyChangeListener to be removed + */ + public void removePropertyChangeListener(PropertyChangeListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + ac.removePropertyChangeListener(l); + } else { + super.removePropertyChangeListener(l); + } + } + + /** + * Get the AccessibleAction associated with this object. In the + * implementation of the Java Accessibility API for this class, + * return this object, which is responsible for implementing the + * AccessibleAction interface on behalf of itself. + * + * @return this object + */ + public AccessibleAction getAccessibleAction() { + return this; + } + + /** + * Get the AccessibleComponent associated with this object. In the + * implementation of the Java Accessibility API for this class, + * return this object, which is responsible for implementing the + * AccessibleComponent interface on behalf of itself. + * + * @return this object + */ + public AccessibleComponent getAccessibleComponent() { + return this; // to override getBounds() + } + + /** + * Get the AccessibleSelection associated with this object if one + * exists. Otherwise return null. + * + * @return the AccessibleSelection, or null + */ + public AccessibleSelection getAccessibleSelection() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null && isLeaf) { + return getCurrentAccessibleContext().getAccessibleSelection(); + } else { + return this; + } + } + + /** + * Get the AccessibleText associated with this object if one + * exists. Otherwise return null. + * + * @return the AccessibleText, or null + */ + public AccessibleText getAccessibleText() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return getCurrentAccessibleContext().getAccessibleText(); + } else { + return null; + } + } + + /** + * Get the AccessibleValue associated with this object if one + * exists. Otherwise return null. + * + * @return the AccessibleValue, or null + */ + public AccessibleValue getAccessibleValue() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + return getCurrentAccessibleContext().getAccessibleValue(); + } else { + return null; + } + } + + + // AccessibleComponent methods + + /** + * Get the background color of this object. + * + * @return the background color, if supported, of the object; + * otherwise, null + */ + public Color getBackground() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getBackground(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getBackground(); + } else { + return null; + } + } + } + + /** + * Set the background color of this object. + * + * @param c the new Color for the background + */ + public void setBackground(Color c) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setBackground(c); + } else { + Component cp = getCurrentComponent(); + if ( cp != null) { + cp.setBackground(c); + } + } + } + + + /** + * Get the foreground color of this object. + * + * @return the foreground color, if supported, of the object; + * otherwise, null + */ + public Color getForeground() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getForeground(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getForeground(); + } else { + return null; + } + } + } + + public void setForeground(Color c) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setForeground(c); + } else { + Component cp = getCurrentComponent(); + if (cp != null) { + cp.setForeground(c); + } + } + } + + public Cursor getCursor() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getCursor(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getCursor(); + } else { + Accessible ap = getAccessibleParent(); + if (ap instanceof AccessibleComponent) { + return ((AccessibleComponent) ap).getCursor(); + } else { + return null; + } + } + } + } + + public void setCursor(Cursor c) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setCursor(c); + } else { + Component cp = getCurrentComponent(); + if (cp != null) { + cp.setCursor(c); + } + } + } + + public Font getFont() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getFont(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getFont(); + } else { + return null; + } + } + } + + public void setFont(Font f) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setFont(f); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setFont(f); + } + } + } + + public FontMetrics getFontMetrics(Font f) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getFontMetrics(f); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.getFontMetrics(f); + } else { + return null; + } + } + } + + public boolean isEnabled() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).isEnabled(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.isEnabled(); + } else { + return false; + } + } + } + + public void setEnabled(boolean b) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setEnabled(b); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setEnabled(b); + } + } + } + + public boolean isVisible() { + if (tree == null) + return false; + Rectangle pathBounds = tree.getPathBounds(path); + Rectangle parentBounds = tree.getVisibleRect(); + if ( pathBounds != null && parentBounds != null && + parentBounds.intersects(pathBounds) ) { + return true; + } else { + return false; + } + } + + public void setVisible(boolean b) { + } + + public boolean isShowing() { + return (tree.isShowing() && isVisible()); + } + + public boolean contains(Point p) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + Rectangle r = ((AccessibleComponent) ac).getBounds(); + return r.contains(p); + } else { + Component c = getCurrentComponent(); + if (c != null) { + Rectangle r = c.getBounds(); + return r.contains(p); + } else { + return getBounds().contains(p); + } + } + } + + public Point getLocationOnScreen() { + if (tree != null) { + Point treeLocation = tree.getLocationOnScreen(); + Rectangle pathBounds = tree.getPathBounds(path); + if (treeLocation != null && pathBounds != null) { + Point nodeLocation = new Point(pathBounds.x, + pathBounds.y); + nodeLocation.translate(treeLocation.x, treeLocation.y); + return nodeLocation; + } else { + return null; + } + } else { + return null; + } + } + + private Point getLocationInJTree() { + Rectangle r = tree.getPathBounds(path); + if (r != null) { + return r.getLocation(); + } else { + return null; + } + } + + public Point getLocation() { + Rectangle r = getBounds(); + if (r != null) { + return r.getLocation(); + } else { + return null; + } + } + + public void setLocation(Point p) { + } + + public Rectangle getBounds() { + if (tree == null) + return null; + Rectangle r = tree.getPathBounds(path); + Accessible parent = getAccessibleParent(); + if (parent instanceof AccessibleJTreeNode) { + Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree(); + if (parentLoc != null && r != null) { + r.translate(-parentLoc.x, -parentLoc.y); + } else { + return null; // not visible! + } + } + return r; + } + + public void setBounds(Rectangle r) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setBounds(r); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setBounds(r); + } + } + } + + public Dimension getSize() { + return getBounds().getSize(); + } + + public void setSize (Dimension d) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).setSize(d); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.setSize(d); + } + } + } + + /** + * Returns the Accessible child, if one exists, + * contained at the local coordinate Point. + * Otherwise returns null. + * + * @param p point in local coordinates of this + * Accessible + * @return the Accessible, if it exists, + * at the specified location; else null + */ + public Accessible getAccessibleAt(Point p) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).getAccessibleAt(p); + } else { + return null; + } + } + + public boolean isFocusTraversable() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + return ((AccessibleComponent) ac).isFocusTraversable(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + return c.isFocusable(); + } else { + return false; + } + } + } + + public void requestFocus() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).requestFocus(); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.requestFocus(); + } + } + } + + public void addFocusListener(FocusListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).addFocusListener(l); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.addFocusListener(l); + } + } + } + + public void removeFocusListener(FocusListener l) { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac instanceof AccessibleComponent) { + ((AccessibleComponent) ac).removeFocusListener(l); + } else { + Component c = getCurrentComponent(); + if (c != null) { + c.removeFocusListener(l); + } + } + } + + // AccessibleSelection methods + + /** + * Returns the number of items currently selected. + * If no items are selected, the return value will be 0. + * + * @return the number of items currently selected. + */ + public int getAccessibleSelectionCount() { + int count = 0; + int childCount = getAccessibleChildrenCount(); + for (int i = 0; i < childCount; i++) { + TreePath childPath = getChildTreePath(i); + if (tree.isPathSelected(childPath)) { + count++; + } + } + return count; + } + + /** + * Returns an Accessible representing the specified selected item + * in the object. If there isn't a selection, or there are + * fewer items selected than the integer passed in, the return + * value will be null. + * + * @param i the zero-based index of selected items + * @return an Accessible containing the selected item + */ + public Accessible getAccessibleSelection(int i) { + int childCount = getAccessibleChildrenCount(); + if (i < 0 || i >= childCount) { + return null; // out of range + } + int count = 0; + for (int j = 0; j < childCount && i >= count; j++) { + TreePath childPath = getChildTreePath(j); + if (tree.isPathSelected(childPath)) { + if (count == i) { + return new AccessibleJTreeNode(tree, childPath, this); + } else { + count++; + } + } + } + return null; + } + + /** + * Returns true if the current child of this object is selected. + * + * @param i the zero-based index of the child in this Accessible + * object. + * @see AccessibleContext#getAccessibleChild + */ + public boolean isAccessibleChildSelected(int i) { + int childCount = getAccessibleChildrenCount(); + if (i < 0 || i >= childCount) { + return false; // out of range + } else { + TreePath childPath = getChildTreePath(i); + return tree.isPathSelected(childPath); + } + } + + /** + * Adds the specified selected item in the object to the object's + * selection. If the object supports multiple selections, + * the specified item is added to any existing selection, otherwise + * it replaces any existing selection in the object. If the + * specified item is already selected, this method has no effect. + * + * @param i the zero-based index of selectable items + */ + public void addAccessibleSelection(int i) { + if (tree == null) + return; + TreeModel model = tree.getModel(); + if (model != null) { + if (i >= 0 && i < getAccessibleChildrenCount()) { + TreePath path = getChildTreePath(i); + tree.addSelectionPath(path); + } + } + } + + /** + * Removes the specified selected item in the object from the + * object's + * selection. If the specified item isn't currently selected, this + * method has no effect. + * + * @param i the zero-based index of selectable items + */ + public void removeAccessibleSelection(int i) { + if (tree == null) + return; + TreeModel model = tree.getModel(); + if (model != null) { + if (i >= 0 && i < getAccessibleChildrenCount()) { + TreePath path = getChildTreePath(i); + tree.removeSelectionPath(path); + } + } + } + + /** + * Clears the selection in the object, so that nothing in the + * object is selected. + */ + public void clearAccessibleSelection() { + int childCount = getAccessibleChildrenCount(); + for (int i = 0; i < childCount; i++) { + removeAccessibleSelection(i); + } + } + + /** + * Causes every selected item in the object to be selected + * if the object supports multiple selections. + */ + public void selectAllAccessibleSelection() { + if (tree == null) + return; + TreeModel model = tree.getModel(); + if (model != null) { + int childCount = getAccessibleChildrenCount(); + TreePath path; + for (int i = 0; i < childCount; i++) { + path = getChildTreePath(i); + tree.addSelectionPath(path); + } + } + } + + // AccessibleAction methods + + /** + * Returns the number of accessible actions available in this + * tree node. If this node is not a leaf, there is at least + * one action (toggle expand), in addition to any available + * on the object behind the TreeCellRenderer. + * + * @return the number of Actions in this object + */ + public int getAccessibleActionCount() { + AccessibleContext ac = getCurrentAccessibleContext(); + if (ac != null) { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa != null) { + return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1)); + } + } + return isLeaf ? 0 : 1; + } + + /** + * Return a description of the specified action of the tree node. + * If this node is not a leaf, there is at least one action + * description (toggle expand), in addition to any available + * on the object behind the TreeCellRenderer. + * + * @param i zero-based index of the actions + * @return a description of the action + */ + public String getAccessibleActionDescription(int i) { + if (i < 0 || i >= getAccessibleActionCount()) { + return null; + } + AccessibleContext ac = getCurrentAccessibleContext(); + if (i == 0) { + // TIGER - 4766636 + // return AccessibleAction.TOGGLE_EXPAND; + return "toggle expand"; + } else if (ac != null) { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa != null) { + return aa.getAccessibleActionDescription(i - 1); + } + } + return null; + } + + /** + * Perform the specified Action on the tree node. If this node + * is not a leaf, there is at least one action which can be + * done (toggle expand), in addition to any available on the + * object behind the TreeCellRenderer. + * + * @param i zero-based index of actions + * @return true if the the action was performed; else false. + */ + public boolean doAccessibleAction(int i) { + if (i < 0 || i >= getAccessibleActionCount()) { + return false; + } + AccessibleContext ac = getCurrentAccessibleContext(); + if (i == 0) { + if (tree.isExpanded(path)) { + tree.collapsePath(path); + } else { + tree.expandPath(path); + } + return true; + } else if (ac != null) { + AccessibleAction aa = ac.getAccessibleAction(); + if (aa != null) { + return aa.doAccessibleAction(i - 1); + } + } + return false; + } + + } // inner class AccessibleJTreeNode + + /** + * A helper class to perform {@code Callable} objects on the event dispatch thread appropriate + * for the provided {@code AccessibleContext}. + */ + private static class InvocationUtils { + + /** + * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Accessible} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke + * @param accessible the {@code Accessible} which would be used to find the right context + * for the task execution + * @param type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static T invokeAndWait(final Callable callable, + final Accessible accessible) { + if (accessible instanceof Component) { + return invokeAndWait(callable, (Component)accessible); + } + if (accessible instanceof AccessibleContext) { + // This case also covers the Translator + return invokeAndWait(callable, (AccessibleContext)accessible); + } + throw new RuntimeException("Unmapped Accessible used to dispatch event: " + accessible); + } + + /** + * Invokes a {@code Callable} in the {@code AppContext} of the given {@code Component} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke + * @param component the {@code Component} which would be used to find the right context + * for the task execution + * @param type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static T invokeAndWait(final Callable callable, + final Component component) { + return invokeAndWait(callable, SunToolkit.targetToAppContext(component)); + } + + /** + * Invokes a {@code Callable} in the {@code AppContext} mapped to the given {@code AccessibleContext} + * and waits for it to finish blocking the caller thread. + * + * @param callable the {@code Callable} to invoke + * @param accessibleContext the {@code AccessibleContext} which would be used to determine the right + * context for the task execution. + * @param type parameter for the result value + * + * @return the result of the {@code Callable} execution + */ + public static T invokeAndWait(final Callable callable, + final AccessibleContext accessibleContext) { + AppContext targetContext = AWTAccessor.getAccessibleContextAccessor() + .getAppContext(accessibleContext); + if (targetContext != null) { + return invokeAndWait(callable, targetContext); + } else { + // Normally this should not happen, unmapped context provided and + // the target AppContext is unknown. + + // Try to recover in case the context is a translator. + if (accessibleContext instanceof Translator) { + Object source = ((Translator)accessibleContext).getSource(); + if (source instanceof Component) { + return invokeAndWait(callable, (Component)source); + } + } + } + throw new RuntimeException("Unmapped AccessibleContext used to dispatch event: " + accessibleContext); + } + + private static T invokeAndWait(final Callable callable, + final AppContext targetAppContext) { + final CallableWrapper wrapper = new CallableWrapper(callable); + try { + invokeAndWait(wrapper, targetAppContext); + T result = wrapper.getResult(); + updateAppContextMap(result, targetAppContext); + return result; + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + private static void invokeAndWait(final Runnable runnable, + final AppContext appContext) + throws InterruptedException, InvocationTargetException { + + EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext); + Object lock = new Object(); + Toolkit source = Toolkit.getDefaultToolkit(); + InvocationEvent event = + new InvocationEvent(source, runnable, lock, true); + synchronized (lock) { + eq.postEvent(event); + lock.wait(); + } + + Throwable eventThrowable = event.getThrowable(); + if (eventThrowable != null) { + throw new InvocationTargetException(eventThrowable); + } + } + + /** + * Maps the {@code AccessibleContext} to the {@code AppContext} which should be used + * to dispatch events related to the {@code AccessibleContext} + * @param accessibleContext the {@code AccessibleContext} for the mapping + * @param targetContext the {@code AppContext} for the mapping + */ + public static void registerAccessibleContext(final AccessibleContext accessibleContext, + final AppContext targetContext) { + if (accessibleContext != null) { + AWTAccessor.getAccessibleContextAccessor().setAppContext(accessibleContext, targetContext); + } + } + + private static void updateAppContextMap(final T accessibleContext, + final AppContext targetContext) { + if (accessibleContext instanceof AccessibleContext) { + registerAccessibleContext((AccessibleContext)accessibleContext, targetContext); + } + } + + private static class CallableWrapper implements Runnable { + private final Callable callable; + private volatile T object; + private Exception e; + + CallableWrapper(final Callable callable) { + this.callable = callable; + } + + public void run() { + try { + if (callable != null) { + object = callable.call(); + } + } catch (final Exception e) { + this.e = e; + } + } + + T getResult() throws Exception { + if (e != null) + throw e; + return object; + } + } + } +} diff --git a/jdk/src/jdk.accessibility/windows/conf/accessibility.properties b/jdk/src/jdk.accessibility/windows/conf/accessibility.properties new file mode 100644 index 00000000000..7217be09feb --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/conf/accessibility.properties @@ -0,0 +1,6 @@ +# +# Load the Java Access Bridge class into the JVM +# +#assistive_technologies=com.sun.java.accessibility.AccessBridge +#screen_magnifier_present=true + diff --git a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp new file mode 100644 index 00000000000..e7325a84ffd --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage AccessBridge debugging + */ + +#include "AccessBridgeDebug.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * print a GetLastError message + */ +char *printError(char *msg) { + LPVOID lpMsgBuf = NULL; + static char retbuf[256]; + + if (msg != NULL) { + strncpy((char *)retbuf, msg, sizeof(retbuf)); + } + if (!FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL )) + { + PrintDebugString(" %s: FormatMessage failed", msg); + } else { + PrintDebugString(" %s: %s", msg, (char *)lpMsgBuf); + } + if (lpMsgBuf != NULL) { + strncat((char *)retbuf, ": ", sizeof(retbuf) - strlen(retbuf) - 1); + strncat((char *)retbuf, (char *)lpMsgBuf, sizeof(retbuf) - strlen(retbuf) - 1); + } + return (char *)retbuf; +} + + + /** + * Send debugging info to the appropriate place + */ + void PrintDebugString(char *msg, ...) { +#ifdef DEBUGGING_ON + char buf[1024]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + vsprintf(buf, msg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } + + /** + * Send Java debugging info to the appropriate place + */ + void PrintJavaDebugString2(char *msg, ...) { +#ifdef JAVA_DEBUGGING_ON + char buf[1024]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + vsprintf(buf, msg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } + /** + * Wide version of the method to send debugging info to the appropriate place + */ + void wPrintDebugString(wchar_t *msg, ...) { +#ifdef DEBUGGING_ON + char buf[1024]; + char charmsg[256]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + sprintf(charmsg, "%ls", msg); // convert format string to multi-byte + vsprintf(buf, charmsg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } + + /** + * Wide version of the method to send Java debugging info to the appropriate place + */ + void wPrintJavaDebugString(wchar_t *msg, ...) { +#ifdef JAVA_DEBUGGING_ON + char buf[1024]; + char charmsg[256]; + va_list argprt; + + va_start(argprt, msg); // set up argptr + sprintf(charmsg, "%ls", msg); // convert format string to multi-byte + vsprintf(buf, charmsg, argprt); +#ifdef SEND_TO_OUTPUT_DEBUG_STRING + OutputDebugString(buf); +#endif +#ifdef SEND_TO_CONSOLE + printf(buf); + printf("\r\n"); +#endif +#endif + } +#ifdef __cplusplus +} +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.h b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.h new file mode 100644 index 00000000000..1ac7426d6e0 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeDebug.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage AccessBridge debugging + */ + +#ifndef __AccessBridgeDebug_H__ +#define __AccessBridgeDebug_H__ + +#include +#include + +#ifdef DEBUG +#define DEBUGGING_ON +#define SEND_TO_OUTPUT_DEBUG_STRING +//#define JAVA_DEBUGGING_ON +#endif + +#ifdef DEBUGGING_ON +#define DEBUG_CODE(x) x +#else +#define DEBUG_CODE(x) /* */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + char *printError(char *msg); + void PrintDebugString(char *msg, ...); + void PrintJavaDebugString(char *msg, ...); + void wPrintJavaDebugString(wchar_t *msg, ...); + void wPrintDebugString(wchar_t *msg, ...); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeMessages.cpp b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeMessages.cpp new file mode 100644 index 00000000000..e071b9873cb --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeMessages.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Common AccessBridge IPC message definitions + */ + +#include "AccessBridgeMessages.h" + + +// unique broadcast msg. IDs gotten dymanically + +// wParam == sourceHwnc; lParam = *vmID +UINT theFromJavaHelloMsgID; +// wParam == sourceHwnc; lParam unused +UINT theFromWindowsHelloMsgID; + + +BOOL initBroadcastMessageIDs() { + theFromJavaHelloMsgID = RegisterWindowMessage("AccessBridge-FromJava-Hello"); + theFromWindowsHelloMsgID = RegisterWindowMessage("AccessBridge-FromWindows-Hello"); + + if (theFromJavaHelloMsgID == 0 || theFromWindowsHelloMsgID) { + return FALSE; + } + return TRUE; +} diff --git a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeMessages.h b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeMessages.h new file mode 100644 index 00000000000..08c67f6e5c3 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeMessages.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Common AccessBridge IPC message definitions + */ + +#include +#include + +#ifndef __AccessBridgeMessages_H__ +#define __AccessBridgeMessages_H__ + + +// used for messages between AccessBridge dlls to manage IPC +// In the SendMessage call, the third param (WPARAM) is +// the source HWND (ourAccessBridgeWindow in this case), +// and the fourth param (LPARAM) is the size in bytes of +// the package put into shared memory. +#define AB_MEMORY_MAPPED_FILE_SETUP (WM_USER+0x1000) + +// used for messages between AccessBridge dlls to manage IPC +// In the SendMessage call, the third param (WPARAM) is +// the source HWND (ourAccessBridgeWindow in this case), +// and the fourth param (LPARAM) is the size in bytes of +// the package put into shared memory. +#define AB_MESSAGE_WAITING (WM_USER+0x1001) + +// used for messages from JavaDLL to itself (or perhaps later also +// for messages from WindowsDLL to itself). Used with PostMessage, +// it is called for deferred processing of messages to send across +// to another DLL (or DLLs) +#define AB_MESSAGE_QUEUED (WM_USER+0x1002) + +// used to let other AccessBridge DLLs know that one of the DLLs +// they are communicating with is going away (not reversable) +#define AB_DLL_GOING_AWAY (WM_USER+0x1003) + + +// used as part of the Memory-Mapped file IPC setup. The first +// constant is the query, the second the response, that are put +// into the memory mapped file for reading by the opposite DLL +// to verify that communication is working +#define AB_MEMORY_MAPPED_FILE_OK_QUERY "OK?" +#define AB_MEMORY_MAPPED_FILE_OK_ANSWER "OK!" + + +BOOL initBroadcastMessageIDs(); + + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC new file mode 100644 index 00000000000..86f62fe5847 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC @@ -0,0 +1,175 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" +#include "accessBridgeResource.h" + +#define XSTR(x) STR(x) +#define STR(x) #x + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +ACCESSBRIDGESTATUSWINDOW DIALOGEX 160, 78, 209, 163 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CLIENTEDGE +CAPTION "Access Bridge status" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT cVMID,67,23,121,13,ES_READONLY + EDITTEXT cStatusText,40,147,162,13,ES_READONLY + LTEXT "Java VM ID:",IDC_STATIC,23,25,40,8 + LTEXT "Status:",IDC_STATIC,11,149,23,8 + EDITTEXT cWindowsID,67,39,121,13,ES_READONLY + LTEXT "Windows ID:",IDC_STATIC,21,41,42,8 + EDITTEXT cCallInfo,12,65,184,75,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL + GROUPBOX "Call info",IDC_STATIC,4,55,197,90 + EDITTEXT cInvokedByText,67,1,121,13,ES_READONLY + LTEXT "Invoked by:",IDC_STATIC,25,3,38,8 +END + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "ACCESSBRIDGESTATUSWINDOW", DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 202 + BOTTOMMARGIN, 160 + END + + "IDD_DIALOG1", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION JDK_FVER + PRODUCTVERSION JDK_FVER + FILEFLAGSMASK 0x3fL +#ifdef DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE JDK_FTYPE + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Java Access Bridge\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/jdk/src/jdk.accessibility/windows/native/common/accessBridgeResource.h b/jdk/src/jdk.accessibility/windows/native/common/accessBridgeResource.h new file mode 100644 index 00000000000..eeb36751953 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/accessBridgeResource.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#define cVMID 1001 +#define cWindowsID 1002 +#define cStatusText 1003 +#define cCallInfo 1004 +#define cInvokedByText 1005 +#define IDC_STATIC -1 + +#define cInstallAccessBridge 2001 +#define cRemindThereIsNewJVM 2005 +#define cDoNotRemindThereIsNewJVM 2005 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1032 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/common/resource.h b/jdk/src/jdk.accessibility/windows/native/common/resource.h new file mode 100644 index 00000000000..f419f9be09a --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/common/resource.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by AccessBridgeStatusWindow.RC +// +//#define IDB_BITMAP1 102 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1032 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCallbacks.h b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCallbacks.h new file mode 100644 index 00000000000..d7c62cf0828 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCallbacks.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * AccessBridgeCallbacks.h 1.17 05/03/21 + */ + +/* + * Header file defining callback typedefs for Windows routines + * which are called from Java (responding to events, etc.). + */ + +#ifndef __AccessBridgeCallbacks_H__ +#define __AccessBridgeCallbacks_H__ + +#include +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*AccessBridge_PropertyChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldValue, wchar_t *newValue); + +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); +typedef void (*AccessBridge_JavaShutdownFP) (long vmID); + +typedef void (*AccessBridge_FocusGainedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_FocusLostFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_CaretUpdateFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MouseClickedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseEnteredFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseExitedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MousePressedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MouseReleasedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_MenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuDeselectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_MenuSelectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeInvisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PopupMenuWillBecomeVisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source); + +typedef void (*AccessBridge_PropertyNameChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldName, wchar_t *newName); +typedef void (*AccessBridge_PropertyDescriptionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldDescription, wchar_t *newDescription); +typedef void (*AccessBridge_PropertyStateChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldState, wchar_t *newState); +typedef void (*AccessBridge_PropertyValueChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); +typedef void (*AccessBridge_PropertySelectionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyTextChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyCaretChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + int oldPosition, int newPosition); +typedef void (*AccessBridge_PropertyVisibleDataChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source); +typedef void (*AccessBridge_PropertyChildChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldChild, JOBJECT64 newChild); +typedef void (*AccessBridge_PropertyActiveDescendentChangeFP) (long vmID, JOBJECT64 event, + JOBJECT64 source, + JOBJECT64 oldActiveDescendent, + JOBJECT64 newActiveDescendent); + +typedef void (*AccessBridge_PropertyTableModelChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 src, + wchar_t *oldValue, wchar_t *newValue); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCalls.c b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCalls.c new file mode 100644 index 00000000000..dc3d1019b51 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCalls.c @@ -0,0 +1,1131 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @(#)AccessBridgeCalls.c 1.25 05/08/22 + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + + +#include +#include + + +//#define ACCESSBRIDGE_32 +//#define ACCESSBRIDGE_64 + +#include "AccessBridgeCalls.h" +#include "AccessBridgeDebug.h" + +#ifdef __cplusplus +extern "C" { +#endif + + HINSTANCE theAccessBridgeInstance; + AccessBridgeFPs theAccessBridge; + + BOOL theAccessBridgeInitializedFlag = FALSE; + +#define LOAD_FP(result, type, name) \ + PrintDebugString("LOAD_FP loading: %s ...", name); \ + if ((theAccessBridge.result = \ + (type) GetProcAddress(theAccessBridgeInstance, name)) == (type) 0) { \ + PrintDebugString("LOAD_FP failed: %s", name); \ + return FALSE; \ + } + + BOOL initializeAccessBridge() { + +#ifdef ACCESSBRIDGE_ARCH_32 // For 32bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-32"); +#else +#ifdef ACCESSBRIDGE_ARCH_64 // For 64bit AT new bridge + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE-64"); +#else // legacy + theAccessBridgeInstance = LoadLibrary("WINDOWSACCESSBRIDGE"); +#endif +#endif + if (theAccessBridgeInstance != 0) { + LOAD_FP(Windows_run, Windows_runFP, "Windows_run"); + + LOAD_FP(SetJavaShutdown, SetJavaShutdownFP, "setJavaShutdownFP"); + LOAD_FP(SetFocusGained, SetFocusGainedFP, "setFocusGainedFP"); + LOAD_FP(SetFocusLost, SetFocusLostFP, "setFocusLostFP"); + + LOAD_FP(SetCaretUpdate, SetCaretUpdateFP, "setCaretUpdateFP"); + + LOAD_FP(SetMouseClicked, SetMouseClickedFP, "setMouseClickedFP"); + LOAD_FP(SetMouseEntered, SetMouseEnteredFP, "setMouseEnteredFP"); + LOAD_FP(SetMouseExited, SetMouseExitedFP, "setMouseExitedFP"); + LOAD_FP(SetMousePressed, SetMousePressedFP, "setMousePressedFP"); + LOAD_FP(SetMouseReleased, SetMouseReleasedFP, "setMouseReleasedFP"); + + LOAD_FP(SetMenuCanceled, SetMenuCanceledFP, "setMenuCanceledFP"); + LOAD_FP(SetMenuDeselected, SetMenuDeselectedFP, "setMenuDeselectedFP"); + LOAD_FP(SetMenuSelected, SetMenuSelectedFP, "setMenuSelectedFP"); + LOAD_FP(SetPopupMenuCanceled, SetPopupMenuCanceledFP, "setPopupMenuCanceledFP"); + LOAD_FP(SetPopupMenuWillBecomeInvisible, SetPopupMenuWillBecomeInvisibleFP, "setPopupMenuWillBecomeInvisibleFP"); + LOAD_FP(SetPopupMenuWillBecomeVisible, SetPopupMenuWillBecomeVisibleFP, "setPopupMenuWillBecomeVisibleFP"); + + LOAD_FP(SetPropertyNameChange, SetPropertyNameChangeFP, "setPropertyNameChangeFP"); + LOAD_FP(SetPropertyDescriptionChange, SetPropertyDescriptionChangeFP, "setPropertyDescriptionChangeFP"); + LOAD_FP(SetPropertyStateChange, SetPropertyStateChangeFP, "setPropertyStateChangeFP"); + LOAD_FP(SetPropertyValueChange, SetPropertyValueChangeFP, "setPropertyValueChangeFP"); + LOAD_FP(SetPropertySelectionChange, SetPropertySelectionChangeFP, "setPropertySelectionChangeFP"); + LOAD_FP(SetPropertyTextChange, SetPropertyTextChangeFP, "setPropertyTextChangeFP"); + LOAD_FP(SetPropertyCaretChange, SetPropertyCaretChangeFP, "setPropertyCaretChangeFP"); + LOAD_FP(SetPropertyVisibleDataChange, SetPropertyVisibleDataChangeFP, "setPropertyVisibleDataChangeFP"); + LOAD_FP(SetPropertyChildChange, SetPropertyChildChangeFP, "setPropertyChildChangeFP"); + LOAD_FP(SetPropertyActiveDescendentChange, SetPropertyActiveDescendentChangeFP, "setPropertyActiveDescendentChangeFP"); + + LOAD_FP(SetPropertyTableModelChange, SetPropertyTableModelChangeFP, "setPropertyTableModelChangeFP"); + + LOAD_FP(ReleaseJavaObject, ReleaseJavaObjectFP, "releaseJavaObject"); + LOAD_FP(GetVersionInfo, GetVersionInfoFP, "getVersionInfo"); + + LOAD_FP(IsJavaWindow, IsJavaWindowFP, "isJavaWindow"); + LOAD_FP(IsSameObject, IsSameObjectFP, "isSameObject"); + LOAD_FP(GetAccessibleContextFromHWND, GetAccessibleContextFromHWNDFP, "getAccessibleContextFromHWND"); + LOAD_FP(getHWNDFromAccessibleContext, getHWNDFromAccessibleContextFP, "getHWNDFromAccessibleContext"); + + LOAD_FP(GetAccessibleContextAt, GetAccessibleContextAtFP, "getAccessibleContextAt"); + LOAD_FP(GetAccessibleContextWithFocus, GetAccessibleContextWithFocusFP, "getAccessibleContextWithFocus"); + LOAD_FP(GetAccessibleContextInfo, GetAccessibleContextInfoFP, "getAccessibleContextInfo"); + LOAD_FP(GetAccessibleChildFromContext, GetAccessibleChildFromContextFP, "getAccessibleChildFromContext"); + LOAD_FP(GetAccessibleParentFromContext, GetAccessibleParentFromContextFP, "getAccessibleParentFromContext"); + + /* begin AccessibleTable */ + LOAD_FP(getAccessibleTableInfo, getAccessibleTableInfoFP, "getAccessibleTableInfo"); + LOAD_FP(getAccessibleTableCellInfo, getAccessibleTableCellInfoFP, "getAccessibleTableCellInfo"); + + LOAD_FP(getAccessibleTableRowHeader, getAccessibleTableRowHeaderFP, "getAccessibleTableRowHeader"); + LOAD_FP(getAccessibleTableColumnHeader, getAccessibleTableColumnHeaderFP, "getAccessibleTableColumnHeader"); + + LOAD_FP(getAccessibleTableRowDescription, getAccessibleTableRowDescriptionFP, "getAccessibleTableRowDescription"); + LOAD_FP(getAccessibleTableColumnDescription, getAccessibleTableColumnDescriptionFP, "getAccessibleTableColumnDescription"); + + LOAD_FP(getAccessibleTableRowSelectionCount, getAccessibleTableRowSelectionCountFP, + "getAccessibleTableRowSelectionCount"); + LOAD_FP(isAccessibleTableRowSelected, isAccessibleTableRowSelectedFP, + "isAccessibleTableRowSelected"); + LOAD_FP(getAccessibleTableRowSelections, getAccessibleTableRowSelectionsFP, + "getAccessibleTableRowSelections"); + + LOAD_FP(getAccessibleTableColumnSelectionCount, getAccessibleTableColumnSelectionCountFP, + "getAccessibleTableColumnSelectionCount"); + LOAD_FP(isAccessibleTableColumnSelected, isAccessibleTableColumnSelectedFP, + "isAccessibleTableColumnSelected"); + LOAD_FP(getAccessibleTableColumnSelections, getAccessibleTableColumnSelectionsFP, + "getAccessibleTableColumnSelections"); + + LOAD_FP(getAccessibleTableRow, getAccessibleTableRowFP, + "getAccessibleTableRow"); + LOAD_FP(getAccessibleTableColumn, getAccessibleTableColumnFP, + "getAccessibleTableColumn"); + LOAD_FP(getAccessibleTableIndex, getAccessibleTableIndexFP, + "getAccessibleTableIndex"); + + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + LOAD_FP(getAccessibleRelationSet, getAccessibleRelationSetFP, "getAccessibleRelationSet"); + + /* AccessibleHypertext */ + LOAD_FP(getAccessibleHypertext, getAccessibleHypertextFP, "getAccessibleHypertext"); + LOAD_FP(activateAccessibleHyperlink, activateAccessibleHyperlinkFP, "activateAccessibleHyperlink"); + LOAD_FP(getAccessibleHyperlinkCount, getAccessibleHyperlinkCountFP, "getAccessibleHyperlinkCount"); + LOAD_FP(getAccessibleHypertextExt, getAccessibleHypertextExtFP, "getAccessibleHypertextExt"); + LOAD_FP(getAccessibleHypertextLinkIndex, getAccessibleHypertextLinkIndexFP, "getAccessibleHypertextLinkIndex"); + LOAD_FP(getAccessibleHyperlink, getAccessibleHyperlinkFP, "getAccessibleHyperlink"); + + /* Accessible KeyBinding, Icon and Action */ + LOAD_FP(getAccessibleKeyBindings, getAccessibleKeyBindingsFP, "getAccessibleKeyBindings"); + LOAD_FP(getAccessibleIcons, getAccessibleIconsFP, "getAccessibleIcons"); + LOAD_FP(getAccessibleActions, getAccessibleActionsFP, "getAccessibleActions"); + LOAD_FP(doAccessibleActions, doAccessibleActionsFP, "doAccessibleActions"); + + /* AccessibleText */ + LOAD_FP(GetAccessibleTextInfo, GetAccessibleTextInfoFP, "getAccessibleTextInfo"); + LOAD_FP(GetAccessibleTextItems, GetAccessibleTextItemsFP, "getAccessibleTextItems"); + LOAD_FP(GetAccessibleTextSelectionInfo, GetAccessibleTextSelectionInfoFP, "getAccessibleTextSelectionInfo"); + LOAD_FP(GetAccessibleTextAttributes, GetAccessibleTextAttributesFP, "getAccessibleTextAttributes"); + LOAD_FP(GetAccessibleTextRect, GetAccessibleTextRectFP, "getAccessibleTextRect"); + LOAD_FP(GetAccessibleTextLineBounds, GetAccessibleTextLineBoundsFP, "getAccessibleTextLineBounds"); + LOAD_FP(GetAccessibleTextRange, GetAccessibleTextRangeFP, "getAccessibleTextRange"); + + LOAD_FP(GetCurrentAccessibleValueFromContext, GetCurrentAccessibleValueFromContextFP, "getCurrentAccessibleValueFromContext"); + LOAD_FP(GetMaximumAccessibleValueFromContext, GetMaximumAccessibleValueFromContextFP, "getMaximumAccessibleValueFromContext"); + LOAD_FP(GetMinimumAccessibleValueFromContext, GetMinimumAccessibleValueFromContextFP, "getMinimumAccessibleValueFromContext"); + + LOAD_FP(AddAccessibleSelectionFromContext, AddAccessibleSelectionFromContextFP, "addAccessibleSelectionFromContext"); + LOAD_FP(ClearAccessibleSelectionFromContext, ClearAccessibleSelectionFromContextFP, "clearAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionFromContext, GetAccessibleSelectionFromContextFP, "getAccessibleSelectionFromContext"); + LOAD_FP(GetAccessibleSelectionCountFromContext, GetAccessibleSelectionCountFromContextFP, "getAccessibleSelectionCountFromContext"); + LOAD_FP(IsAccessibleChildSelectedFromContext, IsAccessibleChildSelectedFromContextFP, "isAccessibleChildSelectedFromContext"); + LOAD_FP(RemoveAccessibleSelectionFromContext, RemoveAccessibleSelectionFromContextFP, "removeAccessibleSelectionFromContext"); + LOAD_FP(SelectAllAccessibleSelectionFromContext, SelectAllAccessibleSelectionFromContextFP, "selectAllAccessibleSelectionFromContext"); + + LOAD_FP(setTextContents, setTextContentsFP, "setTextContents"); + LOAD_FP(getParentWithRole, getParentWithRoleFP, "getParentWithRole"); + LOAD_FP(getTopLevelObject, getTopLevelObjectFP, "getTopLevelObject"); + LOAD_FP(getParentWithRoleElseRoot, getParentWithRoleElseRootFP, "getParentWithRoleElseRoot"); + LOAD_FP(getObjectDepth, getObjectDepthFP, "getObjectDepth"); + LOAD_FP(getActiveDescendent, getActiveDescendentFP, "getActiveDescendent"); + + // additional methods for Teton + LOAD_FP(getVirtualAccessibleName, getVirtualAccessibleNameFP, "getVirtualAccessibleName"); + LOAD_FP(requestFocus, requestFocusFP, "requestFocus"); + LOAD_FP(selectTextRange, selectTextRangeFP, "selectTextRange"); + LOAD_FP(getTextAttributesInRange, getTextAttributesInRangeFP, "getTextAttributesInRange"); + LOAD_FP(getVisibleChildrenCount, getVisibleChildrenCountFP, "getVisibleChildrenCount"); + LOAD_FP(getVisibleChildren, getVisibleChildrenFP, "getVisibleChildren"); + LOAD_FP(setCaretPosition, setCaretPositionFP, "setCaretPosition"); + LOAD_FP(getCaretLocation, getCaretLocationFP, "getCaretLocation"); + + LOAD_FP(getEventsWaiting, getEventsWaitingFP, "getEventsWaiting"); + + theAccessBridge.Windows_run(); + + theAccessBridgeInitializedFlag = TRUE; + PrintDebugString("theAccessBridgeInitializedFlag = TRUE"); + return TRUE; + } else { + return FALSE; + } + } + + + BOOL shutdownAccessBridge() { + BOOL result; + DWORD error; + theAccessBridgeInitializedFlag = FALSE; + if (theAccessBridgeInstance != (HANDLE) 0) { + result = FreeLibrary(theAccessBridgeInstance); + if (result != TRUE) { + error = GetLastError(); + } + return TRUE; + } + return FALSE; + } + + + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetJavaShutdown(fp); + } + } + + void SetFocusGained(AccessBridge_FocusGainedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusGained(fp); + } + } + + void SetFocusLost(AccessBridge_FocusLostFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetFocusLost(fp); + } + } + + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetCaretUpdate(fp); + } + } + + + void SetMouseClicked(AccessBridge_MouseClickedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseClicked(fp); + } + } + + void SetMouseEntered(AccessBridge_MouseEnteredFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseEntered(fp); + } + } + + void SetMouseExited(AccessBridge_MouseExitedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseExited(fp); + } + } + + void SetMousePressed(AccessBridge_MousePressedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMousePressed(fp); + } + } + + void SetMouseReleased(AccessBridge_MouseReleasedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMouseReleased(fp); + } + } + + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuCanceled(fp); + } + } + + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuDeselected(fp); + } + } + + void SetMenuSelected(AccessBridge_MenuSelectedFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetMenuSelected(fp); + } + } + + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuCanceled(fp); + } + } + + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeInvisible(fp); + } + } + + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPopupMenuWillBecomeVisible(fp); + } + } + + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyNameChange(fp); + } + } + + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyDescriptionChange(fp); + } + } + + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyStateChange(fp); + } + } + + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyValueChange(fp); + } + } + + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertySelectionChange(fp); + } + } + + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTextChange(fp); + } + } + + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyCaretChange(fp); + } + } + + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyVisibleDataChange(fp); + } + } + + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyChildChange(fp); + } + } + + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyActiveDescendentChange(fp); + } + } + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SetPropertyTableModelChange(fp); + } + } + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ReleaseJavaObject(vmID, object); + } + } + + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetVersionInfo(vmID, info); + } + return FALSE; + } + + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window) { + if (theAccessBridgeInitializedFlag == TRUE) { + BOOL ret ; + ret = theAccessBridge.IsJavaWindow(window); + return ret ; + + } + return FALSE; + } + + + /** + * Returns the virtual machine ID and AccessibleContext for a top-level window + */ + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextFromHWND(target, vmID, ac); + } + return FALSE; + } + + /** + * Returns the HWND from the AccessibleContext of a top-level window. Returns 0 + * on error or if the AccessibleContext does not refer to a top-level window. + */ + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getHWNDFromAccessibleContext(vmID, accesibleContext); + } + return (HWND)0; + } + + /** + * returns whether two objects are the same + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsSameObject(vmID, obj1, obj2); + } + return FALSE; + } + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setTextContents(vmID, accessibleContext, text); + } + return FALSE; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRole(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getParentWithRoleElseRoot(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTopLevelObject(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getObjectDepth(vmID, accessibleContext); + } + return -1; + } + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getActiveDescendent(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextAt(vmID, acParent, x, y, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextWithFocus(window, vmID, ac); + } + return FALSE; + } + + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleContextInfo(vmID, ac, info); + } + return FALSE; + } + + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleChildFromContext(vmID, ac, index); + } + return (AccessibleContext) 0; + } + + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleParentFromContext(vmID, ac); + } + return (AccessibleContext) 0; + } + + /* begin AccessibleTable routines */ + + /* + * get information about an AccessibleTable + */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableInfo(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable cell + */ + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableCellInfo(vmID, accessibleTable, row, column, tableCellInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable row header + */ + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * get information about an AccessibleTable column header + */ + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnHeader(vmID, acParent, tableInfo); + } + return FALSE; + } + + /* + * return a description of an AccessibleTable row header + */ + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowDescription(vmID, acParent, row); + } + return (AccessibleContext)0; + } + + /* + * return a description of an AccessibleTable column header + */ + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnDescription(vmID, acParent, column); + } + return (AccessibleContext)0; + } + + /* + * return the number of rows selected in an AccessibleTable + */ + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a row is selected in an AccessibleTable + */ + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableRowSelected(vmID, table, row); + } + return FALSE; + } + + /* + * get an array of selected rows in an AccessibleTable + */ + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRowSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the number of columns selected in an AccessibleTable + */ + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelectionCount(vmID, table); + } + return -1; + } + + /* + * return whether a column is selected in an AccessibleTable + */ + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.isAccessibleTableColumnSelected(vmID, table, column); + } + return FALSE; + } + + /* + * get an array of columns selected in an AccessibleTable + */ + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumnSelections(vmID, table, count, selections); + } + return FALSE; + } + + /* + * return the row number for a cell at a given index + */ + jint + getAccessibleTableRow(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableRow(vmID, table, index); + } + return -1; + } + + /* + * return the column number for a cell at a given index + */ + jint + getAccessibleTableColumn(long vmID, AccessibleTable table, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableColumn(vmID, table, index); + } + return -1; + } + + /* + * return the index of a cell at a given row and column + */ + jint + getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleTableIndex(vmID, table, row, column); + } + return -1; + } + + /* end AccessibleTable routines */ + + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextInfo(vmID, at, textInfo, x, y); + } + return FALSE; + } + + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextItems(vmID, at, textItems, index); + } + return FALSE; + } + + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextSelectionInfo(vmID, at, textSelection); + } + return FALSE; + } + + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextAttributes(vmID, at, index, attributes); + } + return FALSE; + } + + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRect(vmID, at, rectInfo, index); + } + return FALSE; + } + + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextLineBounds(vmID, at, index, startIndex, endIndex); + } + return FALSE; + } + + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleTextRange(vmID, at, start, end, text, len); + } + return FALSE; + } + + /** + * AccessibleRelationSet routines + */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleRelationSet(vmID, accessibleContext, relationSetInfo); + } + return FALSE; + } + + /** + * AccessibleHypertext routines + */ + + // Gets AccessibleHypertext for an AccessibleContext + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertext(vmID, accessibleContext, hypertextInfo); + } + return FALSE; + } + + // Activates an AccessibleHyperlink for an AccessibleContext + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.activateAccessibleHyperlink(vmID, accessibleContext, accessibleHyperlink); + } + return FALSE; + } + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlinkCount(vmID, accessibleContext); + } + return -1; + } + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextExt(vmID, + accessibleContext, + nStartIndex, + hypertextInfo); + } + return FALSE; + } + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; + * Maps to AccessibleHypertext.getLinkIndex. + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHypertextLinkIndex(vmID, + hypertext, + nIndex); + } + return -1; + } + + /* + * Returns the nth hyperlink in a document. + * Maps to AccessibleHypertext.getLink. + * Returns -1 on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleHyperlink(vmID, + hypertext, + nIndex, + hyperlinkInfo); + } + return FALSE; + } + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleKeyBindings(vmID, accessibleContext, keyBindings); + } + return FALSE; + } + + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleIcons(vmID, accessibleContext, icons); + } + return FALSE; + } + + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getAccessibleActions(vmID, accessibleContext, actions); + } + return FALSE; + } + + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.doAccessibleActions(vmID, accessibleContext, actionsToDo, failure); + } + return FALSE; + } + + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetCurrentAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMaximumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetMinimumAccessibleValueFromContext(vmID, av, value, len); + } + return FALSE; + } + + + /** + * Accessible Selection routines + */ + void addAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.AddAccessibleSelectionFromContext(vmID, as, i); + } + } + + void clearAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.ClearAccessibleSelectionFromContext(vmID, as); + } + } + + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionFromContext(vmID, as, i); + } + return (JOBJECT64) 0; + } + + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.GetAccessibleSelectionCountFromContext(vmID, as); + } + return -1; + } + + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.IsAccessibleChildSelectedFromContext(vmID, as, i); + } + return FALSE; + } + + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.RemoveAccessibleSelectionFromContext(vmID, as, i); + } + } + + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as) { + if (theAccessBridgeInitializedFlag == TRUE) { + theAccessBridge.SelectAllAccessibleSelectionFromContext(vmID, as); + } + } + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVirtualAccessibleName(vmID, accessibleContext, name, len); + } + return FALSE; + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.requestFocus(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.selectTextRange(vmID, accessibleContext, startIndex, endIndex); + } + return FALSE; + } + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getTextAttributesInRange(vmID, accessibleContext, startIndex, + endIndex, attributes, len); + } + return FALSE; + } + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildrenCount(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *visibleChildrenInfo) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getVisibleChildren(vmID, accessibleContext, startIndex, + visibleChildrenInfo); + } + return FALSE; + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.setCaretPosition(vmID, accessibleContext, position); + } + return FALSE; + } + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index) { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getCaretLocation(vmID, ac, rectInfo, index); + } + return FALSE; + } + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting() { + if (theAccessBridgeInitializedFlag == TRUE) { + return theAccessBridge.getEventsWaiting(); + } + return FALSE; + } + +#ifdef __cplusplus +} +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCalls.h b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCalls.h new file mode 100644 index 00000000000..51fa08c794a --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgeCalls.h @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Wrapper functions around calls to the AccessBridge DLL + */ + +#include +#include +#include "AccessBridgeCallbacks.h" +#include "AccessBridgePackages.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define null NULL + + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + + typedef void (*Windows_runFP) (); + + typedef void (*SetPropertyChangeFP) (AccessBridge_PropertyChangeFP fp); + + typedef void (*SetJavaShutdownFP) (AccessBridge_JavaShutdownFP fp); + typedef void (*SetFocusGainedFP) (AccessBridge_FocusGainedFP fp); + typedef void (*SetFocusLostFP) (AccessBridge_FocusLostFP fp); + + typedef void (*SetCaretUpdateFP) (AccessBridge_CaretUpdateFP fp); + + typedef void (*SetMouseClickedFP) (AccessBridge_MouseClickedFP fp); + typedef void (*SetMouseEnteredFP) (AccessBridge_MouseEnteredFP fp); + typedef void (*SetMouseExitedFP) (AccessBridge_MouseExitedFP fp); + typedef void (*SetMousePressedFP) (AccessBridge_MousePressedFP fp); + typedef void (*SetMouseReleasedFP) (AccessBridge_MouseReleasedFP fp); + + typedef void (*SetMenuCanceledFP) (AccessBridge_MenuCanceledFP fp); + typedef void (*SetMenuDeselectedFP) (AccessBridge_MenuDeselectedFP fp); + typedef void (*SetMenuSelectedFP) (AccessBridge_MenuSelectedFP fp); + typedef void (*SetPopupMenuCanceledFP) (AccessBridge_PopupMenuCanceledFP fp); + typedef void (*SetPopupMenuWillBecomeInvisibleFP) (AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + typedef void (*SetPopupMenuWillBecomeVisibleFP) (AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + typedef void (*SetPropertyNameChangeFP) (AccessBridge_PropertyNameChangeFP fp); + typedef void (*SetPropertyDescriptionChangeFP) (AccessBridge_PropertyDescriptionChangeFP fp); + typedef void (*SetPropertyStateChangeFP) (AccessBridge_PropertyStateChangeFP fp); + typedef void (*SetPropertyValueChangeFP) (AccessBridge_PropertyValueChangeFP fp); + typedef void (*SetPropertySelectionChangeFP) (AccessBridge_PropertySelectionChangeFP fp); + typedef void (*SetPropertyTextChangeFP) (AccessBridge_PropertyTextChangeFP fp); + typedef void (*SetPropertyCaretChangeFP) (AccessBridge_PropertyCaretChangeFP fp); + typedef void (*SetPropertyVisibleDataChangeFP) (AccessBridge_PropertyVisibleDataChangeFP fp); + typedef void (*SetPropertyChildChangeFP) (AccessBridge_PropertyChildChangeFP fp); + typedef void (*SetPropertyActiveDescendentChangeFP) (AccessBridge_PropertyActiveDescendentChangeFP fp); + + typedef void (*SetPropertyTableModelChangeFP) (AccessBridge_PropertyTableModelChangeFP fp); + + typedef void (*ReleaseJavaObjectFP) (long vmID, Java_Object object); + + typedef BOOL (*GetVersionInfoFP) (long vmID, AccessBridgeVersionInfo *info); + + typedef BOOL (*IsJavaWindowFP) (HWND window); + typedef BOOL (*IsSameObjectFP) (long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + typedef BOOL (*GetAccessibleContextFromHWNDFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef HWND (*getHWNDFromAccessibleContextFP) (long vmID, AccessibleContext ac); + + typedef BOOL (*GetAccessibleContextAtFP) (long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextWithFocusFP) (HWND window, long *vmID, AccessibleContext *ac); + typedef BOOL (*GetAccessibleContextInfoFP) (long vmID, AccessibleContext ac, AccessibleContextInfo *info); + typedef AccessibleContext (*GetAccessibleChildFromContextFP) (long vmID, AccessibleContext ac, jint i); + typedef AccessibleContext (*GetAccessibleParentFromContextFP) (long vmID, AccessibleContext ac); + + /* begin AccessibleTable */ + typedef BOOL (*getAccessibleTableInfoFP) (long vmID, AccessibleContext ac, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableCellInfoFP) (long vmID, AccessibleTable accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo); + + typedef BOOL (*getAccessibleTableRowHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + typedef BOOL (*getAccessibleTableColumnHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + typedef AccessibleContext (*getAccessibleTableRowDescriptionFP) (long vmID, AccessibleContext acParent, jint row); + typedef AccessibleContext (*getAccessibleTableColumnDescriptionFP) (long vmID, AccessibleContext acParent, jint column); + + typedef jint (*getAccessibleTableRowSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableRowSelectedFP) (long vmID, AccessibleTable table, jint row); + typedef BOOL (*getAccessibleTableRowSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableColumnSelectionCountFP) (long vmID, AccessibleTable table); + typedef BOOL (*isAccessibleTableColumnSelectedFP) (long vmID, AccessibleTable table, jint column); + typedef BOOL (*getAccessibleTableColumnSelectionsFP) (long vmID, AccessibleTable table, jint count, + jint *selections); + + typedef jint (*getAccessibleTableRowFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableColumnFP) (long vmID, AccessibleTable table, jint index); + typedef jint (*getAccessibleTableIndexFP) (long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* AccessibleRelationSet */ + typedef BOOL (*getAccessibleRelationSetFP) (long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* AccessibleHypertext */ + typedef BOOL (*getAccessibleHypertextFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + typedef BOOL (*activateAccessibleHyperlinkFP)(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + typedef jint (*getAccessibleHyperlinkCountFP)(const long vmID, + const AccessibleContext accessibleContext); + + typedef BOOL (*getAccessibleHypertextExtFP) (const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + AccessibleHypertextInfo *hypertextInfo); + + typedef jint (*getAccessibleHypertextLinkIndexFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + typedef BOOL (*getAccessibleHyperlinkFP)(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + typedef BOOL (*getAccessibleKeyBindingsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + typedef BOOL (*getAccessibleIconsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + typedef BOOL (*getAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + typedef BOOL (*doAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + /* AccessibleText */ + + typedef BOOL (*GetAccessibleTextInfoFP) (long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + typedef BOOL (*GetAccessibleTextItemsFP) (long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + typedef BOOL (*GetAccessibleTextSelectionInfoFP) (long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + typedef BOOL (*GetAccessibleTextAttributesFP) (long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + typedef BOOL (*GetAccessibleTextRectFP) (long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + typedef BOOL (*GetAccessibleTextLineBoundsFP) (long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + typedef BOOL (*GetAccessibleTextRangeFP) (long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + typedef BOOL (*GetCurrentAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMaximumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + typedef BOOL (*GetMinimumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len); + + typedef void (*AddAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*ClearAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + typedef JOBJECT64 (*GetAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef int (*GetAccessibleSelectionCountFromContextFP) (long vmID, AccessibleSelection as); + typedef BOOL (*IsAccessibleChildSelectedFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*RemoveAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i); + typedef void (*SelectAllAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as); + + /* Utility methods */ + + typedef BOOL (*setTextContentsFP) (const long vmID, const AccessibleContext ac, const wchar_t *text); + typedef AccessibleContext (*getParentWithRoleFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getParentWithRoleElseRootFP) (const long vmID, const AccessibleContext ac, const wchar_t *role); + typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac); + typedef int (*getObjectDepthFP) (const long vmID, const AccessibleContext ac); + typedef AccessibleContext (*getActiveDescendentFP) (const long vmID, const AccessibleContext ac); + + + typedef BOOL (*getVirtualAccessibleNameFP) (const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + typedef BOOL (*requestFocusFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*selectTextRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex); + + typedef BOOL (*getTextAttributesInRangeFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + typedef int (*getVisibleChildrenCountFP) (const long vmID, const AccessibleContext accessibleContext); + + typedef BOOL (*getVisibleChildrenFP) (const long vmID, const AccessibleContext accessibleContext, + const int startIndex, VisibleChildrenInfo *children); + + typedef BOOL (*setCaretPositionFP) (const long vmID, const AccessibleContext accessibleContext, const int position); + + typedef BOOL (*getCaretLocationFP) (long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index); + + typedef int (*getEventsWaitingFP) (); + + typedef struct AccessBridgeFPsTag { + Windows_runFP Windows_run; + + SetPropertyChangeFP SetPropertyChange; + + SetJavaShutdownFP SetJavaShutdown; + SetFocusGainedFP SetFocusGained; + SetFocusLostFP SetFocusLost; + + SetCaretUpdateFP SetCaretUpdate; + + SetMouseClickedFP SetMouseClicked; + SetMouseEnteredFP SetMouseEntered; + SetMouseExitedFP SetMouseExited; + SetMousePressedFP SetMousePressed; + SetMouseReleasedFP SetMouseReleased; + + SetMenuCanceledFP SetMenuCanceled; + SetMenuDeselectedFP SetMenuDeselected; + SetMenuSelectedFP SetMenuSelected; + SetPopupMenuCanceledFP SetPopupMenuCanceled; + SetPopupMenuWillBecomeInvisibleFP SetPopupMenuWillBecomeInvisible; + SetPopupMenuWillBecomeVisibleFP SetPopupMenuWillBecomeVisible; + + SetPropertyNameChangeFP SetPropertyNameChange; + SetPropertyDescriptionChangeFP SetPropertyDescriptionChange; + SetPropertyStateChangeFP SetPropertyStateChange; + SetPropertyValueChangeFP SetPropertyValueChange; + SetPropertySelectionChangeFP SetPropertySelectionChange; + SetPropertyTextChangeFP SetPropertyTextChange; + SetPropertyCaretChangeFP SetPropertyCaretChange; + SetPropertyVisibleDataChangeFP SetPropertyVisibleDataChange; + SetPropertyChildChangeFP SetPropertyChildChange; + SetPropertyActiveDescendentChangeFP SetPropertyActiveDescendentChange; + + SetPropertyTableModelChangeFP SetPropertyTableModelChange; + + ReleaseJavaObjectFP ReleaseJavaObject; + GetVersionInfoFP GetVersionInfo; + + IsJavaWindowFP IsJavaWindow; + IsSameObjectFP IsSameObject; + GetAccessibleContextFromHWNDFP GetAccessibleContextFromHWND; + getHWNDFromAccessibleContextFP getHWNDFromAccessibleContext; + + GetAccessibleContextAtFP GetAccessibleContextAt; + GetAccessibleContextWithFocusFP GetAccessibleContextWithFocus; + GetAccessibleContextInfoFP GetAccessibleContextInfo; + GetAccessibleChildFromContextFP GetAccessibleChildFromContext; + GetAccessibleParentFromContextFP GetAccessibleParentFromContext; + + getAccessibleTableInfoFP getAccessibleTableInfo; + getAccessibleTableCellInfoFP getAccessibleTableCellInfo; + + getAccessibleTableRowHeaderFP getAccessibleTableRowHeader; + getAccessibleTableColumnHeaderFP getAccessibleTableColumnHeader; + + getAccessibleTableRowDescriptionFP getAccessibleTableRowDescription; + getAccessibleTableColumnDescriptionFP getAccessibleTableColumnDescription; + + getAccessibleTableRowSelectionCountFP getAccessibleTableRowSelectionCount; + isAccessibleTableRowSelectedFP isAccessibleTableRowSelected; + getAccessibleTableRowSelectionsFP getAccessibleTableRowSelections; + + getAccessibleTableColumnSelectionCountFP getAccessibleTableColumnSelectionCount; + isAccessibleTableColumnSelectedFP isAccessibleTableColumnSelected; + getAccessibleTableColumnSelectionsFP getAccessibleTableColumnSelections; + + getAccessibleTableRowFP getAccessibleTableRow; + getAccessibleTableColumnFP getAccessibleTableColumn; + getAccessibleTableIndexFP getAccessibleTableIndex; + + getAccessibleRelationSetFP getAccessibleRelationSet; + + getAccessibleHypertextFP getAccessibleHypertext; + activateAccessibleHyperlinkFP activateAccessibleHyperlink; + getAccessibleHyperlinkCountFP getAccessibleHyperlinkCount; + getAccessibleHypertextExtFP getAccessibleHypertextExt; + getAccessibleHypertextLinkIndexFP getAccessibleHypertextLinkIndex; + getAccessibleHyperlinkFP getAccessibleHyperlink; + + getAccessibleKeyBindingsFP getAccessibleKeyBindings; + getAccessibleIconsFP getAccessibleIcons; + getAccessibleActionsFP getAccessibleActions; + doAccessibleActionsFP doAccessibleActions; + + GetAccessibleTextInfoFP GetAccessibleTextInfo; + GetAccessibleTextItemsFP GetAccessibleTextItems; + GetAccessibleTextSelectionInfoFP GetAccessibleTextSelectionInfo; + GetAccessibleTextAttributesFP GetAccessibleTextAttributes; + GetAccessibleTextRectFP GetAccessibleTextRect; + GetAccessibleTextLineBoundsFP GetAccessibleTextLineBounds; + GetAccessibleTextRangeFP GetAccessibleTextRange; + + GetCurrentAccessibleValueFromContextFP GetCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextFP GetMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextFP GetMinimumAccessibleValueFromContext; + + AddAccessibleSelectionFromContextFP AddAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextFP ClearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextFP GetAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextFP GetAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextFP IsAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextFP RemoveAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextFP SelectAllAccessibleSelectionFromContext; + + setTextContentsFP setTextContents; + getParentWithRoleFP getParentWithRole; + getTopLevelObjectFP getTopLevelObject; + getParentWithRoleElseRootFP getParentWithRoleElseRoot; + getObjectDepthFP getObjectDepth; + getActiveDescendentFP getActiveDescendent; + + getVirtualAccessibleNameFP getVirtualAccessibleName; + requestFocusFP requestFocus; + selectTextRangeFP selectTextRange; + getTextAttributesInRangeFP getTextAttributesInRange; + getVisibleChildrenCountFP getVisibleChildrenCount; + getVisibleChildrenFP getVisibleChildren; + setCaretPositionFP setCaretPosition; + getCaretLocationFP getCaretLocation; + + getEventsWaitingFP getEventsWaiting; + + } AccessBridgeFPs; + + + /** + * Initialize the world + */ + BOOL initializeAccessBridge(); + BOOL shutdownAccessBridge(); + + /** + * Window routines + */ + BOOL IsJavaWindow(HWND window); + + // Returns the virtual machine ID and AccessibleContext for a top-level window + BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac); + + // Returns the HWND from the AccessibleContext of a top-level window + HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac); + + + /** + * Event handling routines + */ + void SetJavaShutdown(AccessBridge_JavaShutdownFP fp); + void SetFocusGained(AccessBridge_FocusGainedFP fp); + void SetFocusLost(AccessBridge_FocusLostFP fp); + + void SetCaretUpdate(AccessBridge_CaretUpdateFP fp); + + void SetMouseClicked(AccessBridge_MouseClickedFP fp); + void SetMouseEntered(AccessBridge_MouseEnteredFP fp); + void SetMouseExited(AccessBridge_MouseExitedFP fp); + void SetMousePressed(AccessBridge_MousePressedFP fp); + void SetMouseReleased(AccessBridge_MouseReleasedFP fp); + + void SetMenuCanceled(AccessBridge_MenuCanceledFP fp); + void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp); + void SetMenuSelected(AccessBridge_MenuSelectedFP fp); + void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp); + void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp); + void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp); + void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp); + void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp); + void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp); + void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp); + void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp); + void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp); + void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp); + void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp); + + + /** + * General routines + */ + void ReleaseJavaObject(long vmID, Java_Object object); + BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info); + HWND GetHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext); + + /** + * Accessible Context routines + */ + BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, + jint x, jint y, AccessibleContext *ac); + BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac); + BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info); + AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index); + AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac); + + /** + * Accessible Text routines + */ + BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index); + BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection); + BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes); + BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index); + BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex); + BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len); + + /* begin AccessibleTable routines */ + BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo); + + AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row); + AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row); + BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table); + BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections); + + jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index); + jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column); + /* end AccessibleTable */ + + /* ----- AccessibleRelationSet routines */ + BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + /* ----- AccessibleHypertext routines */ + + /* + * Returns hypertext information associated with a component. + */ + BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext, + AccessibleHypertextInfo *hypertextInfo); + + /* + * Requests that a hyperlink be activated. + */ + BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext, + AccessibleHyperlink accessibleHyperlink); + + /* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleHypertext hypertext); + + /* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * Returns FALSE on error. + */ + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + /* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; maps to AccessibleHypertext.getLinkIndex + * Returns -1 on error. + */ + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + /* + * Returns the nth hyperlink in a document + * Maps to AccessibleHypertext.getLink. + * Returns FALSE on error + */ + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + /* Accessible KeyBindings, Icons and Actions */ + + /* + * Returns a list of key bindings associated with a component. + */ + BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext, + AccessibleKeyBindings *keyBindings); + + /* + * Returns a list of icons associate with a component. + */ + BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext, + AccessibleIcons *icons); + + /* + * Returns a list of actions that a component can perform. + */ + BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActions *actions); + + /* + * Request that a list of AccessibleActions be performed by a component. + * Returns TRUE if all actions are performed. Returns FALSE + * when the first requested action fails in which case "failure" + * contains the index of the action that failed. + */ + BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + + /* Additional utility methods */ + + /* + * Returns whether two object references refer to the same object. + */ + BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + /** + * Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and + * be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1. + * Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h + * If there is no ancestor object that has the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context with the specified role that is the + * ancestor of a given object. The role is one of the role strings + * defined in AccessBridgePackages.h. If an object with the specified + * role does not exist, returns the top level object for the Java Window. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + /** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * This method assumes the ActiveDescendent is the component that is currently + * selected in a container object. + * Returns (AccessibleContext)0 on error or if there is no selection. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + /** + /** + * Accessible Value routines + */ + BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len); + + /** + * Accessible Selection routines + */ + void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as); + BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i); + void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i); + void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext, + wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful. + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful. + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, const int startIndex, + const int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, const int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext, + const int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful. + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position); + + /** + * Gets the text caret location + */ + BOOL getCaretLocation(long vmID, AccessibleContext ac, + AccessibleTextRectInfo *rectInfo, jint index); + + /** + * Gets the number of events waiting to fire + */ + int getEventsWaiting(); + +#ifdef __cplusplus +} +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h new file mode 100644 index 00000000000..27c31be09a8 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h @@ -0,0 +1,2215 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Header file for packages of paramaters passed between Java Accessibility + * and native Assistive Technologies + */ + +#ifndef __AccessBridgePackages_H__ +#define __AccessBridgePackages_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ACCESSBRIDGE_ARCH_LEGACY +typedef jobject JOBJECT64; +typedef HWND ABHWND64; +#define ABHandleToLong +#define ABLongToHandle +#else +typedef jlong JOBJECT64; +typedef long ABHWND64; +#define ABHandleToLong HandleToLong +#define ABLongToHandle LongToHandle +#endif + +#define MAX_BUFFER_SIZE 10240 +#define MAX_STRING_SIZE 1024 +#define SHORT_STRING_SIZE 256 + + // object types + typedef JOBJECT64 AccessibleContext; + typedef JOBJECT64 AccessibleText; + typedef JOBJECT64 AccessibleValue; + typedef JOBJECT64 AccessibleSelection; + typedef JOBJECT64 Java_Object; + typedef JOBJECT64 PropertyChangeEvent; + typedef JOBJECT64 FocusEvent; + typedef JOBJECT64 CaretEvent; + typedef JOBJECT64 MouseEvent; + typedef JOBJECT64 MenuEvent; + typedef JOBJECT64 AccessibleTable; + typedef JOBJECT64 AccessibleHyperlink; + typedef JOBJECT64 AccessibleHypertext; + + /** + ****************************************************** + * Java event types + ****************************************************** + */ + +#define cPropertyChangeEvent (jlong) 1 // 1 +#define cFocusGainedEvent (jlong) 2 // 2 +#define cFocusLostEvent (jlong) 4 // 4 +#define cCaretUpdateEvent (jlong) 8 // 8 +#define cMouseClickedEvent (jlong) 16 // 10 +#define cMouseEnteredEvent (jlong) 32 // 20 +#define cMouseExitedEvent (jlong) 64 // 40 +#define cMousePressedEvent (jlong) 128 // 80 +#define cMouseReleasedEvent (jlong) 256 // 100 +#define cMenuCanceledEvent (jlong) 512 // 200 +#define cMenuDeselectedEvent (jlong) 1024 // 400 +#define cMenuSelectedEvent (jlong) 2048 // 800 +#define cPopupMenuCanceledEvent (jlong) 4096 // 1000 +#define cPopupMenuWillBecomeInvisibleEvent (jlong) 8192 // 2000 +#define cPopupMenuWillBecomeVisibleEvent (jlong) 16384 // 4000 +#define cJavaShutdownEvent (jlong) 32768 // 8000 + + /** + ****************************************************** + * Accessible Roles + * Defines all AccessibleRoles in Local.US + ****************************************************** + */ + + /** + * Object is used to alert the user about something. + */ +#define ACCESSIBLE_ALERT L"alert" + + /** + * The header for a column of data. + */ +#define ACCESSIBLE_COLUMN_HEADER L"column header" + + /** + * Object that can be drawn into and is used to trap + * events. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_CANVAS L"canvas" + + /** + * A list of choices the user can select from. Also optionally + * allows the user to enter a choice of their own. + */ +#define ACCESSIBLE_COMBO_BOX L"combo box" + + /** + * An iconified internal frame in a DESKTOP_PANE. + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_ICON L"desktop icon" + + /** + * A frame-like object that is clipped by a desktop pane. The + * desktop pane, internal frame, and desktop icon objects are + * often used to create multiple document interfaces within an + * application. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_DESKTOP_PANE + * see ACCESSIBLE_FRAME + */ +#define ACCESSIBLE_INTERNAL_FRAME L"internal frame" + + /** + * A pane that supports internal frames and + * iconified versions of those internal frames. + * see ACCESSIBLE_DESKTOP_ICON + * see ACCESSIBLE_INTERNAL_FRAME + */ +#define ACCESSIBLE_DESKTOP_PANE L"desktop pane" + + /** + * A specialized pane whose primary use is inside a DIALOG + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_OPTION_PANE L"option pane" + + /** + * A top level window with no title or border. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_DIALOG + */ +#define ACCESSIBLE_WINDOW L"window" + + /** + * A top level window with a title bar, border, menu bar, etc. It is + * often used as the primary window for an application. + * see ACCESSIBLE_DIALOG + * see ACCESSIBLE_CANVAS + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_FRAME L"frame" + + /** + * A top level window with title bar and a border. A dialog is similar + * to a frame, but it has fewer properties and is often used as a + * secondary window for an application. + * see ACCESSIBLE_FRAME + * see ACCESSIBLE_WINDOW + */ +#define ACCESSIBLE_DIALOG L"dialog" + + /** + * A specialized dialog that lets the user choose a color. + */ +#define ACCESSIBLE_COLOR_CHOOSER L"color chooser" + + + /** + * A pane that allows the user to navigate through + * and select the contents of a directory. May be used + * by a file chooser. + * see ACCESSIBLE_FILE_CHOOSER + */ +#define ACCESSIBLE_DIRECTORY_PANE L"directory pane" + + /** + * A specialized dialog that displays the files in the directory + * and lets the user select a file, browse a different directory, + * or specify a filename. May use the directory pane to show the + * contents of a directory. + * see ACCESSIBLE_DIRECTORY_PANE + */ +#define ACCESSIBLE_FILE_CHOOSER L"file chooser" + + /** + * An object that fills up space in a user interface. It is often + * used in interfaces to tweak the spacing between components, + * but serves no other purpose. + */ +#define ACCESSIBLE_FILLER L"filler" + + /** + * A hypertext anchor + */ +#define ACCESSIBLE_HYPERLINK L"hyperlink" + + /** + * A small fixed size picture, typically used to decorate components. + */ +#define ACCESSIBLE_ICON L"icon" + + /** + * An object used to present an icon or short string in an interface. + */ +#define ACCESSIBLE_LABEL L"label" + + /** + * A specialized pane that has a glass pane and a layered pane as its + * children. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_ROOT_PANE L"root pane" + + /** + * A pane that is guaranteed to be painted on top + * of all panes beneath it. + * see ACCESSIBLE_ROOT_PANE + * see ACCESSIBLE_CANVAS + */ +#define ACCESSIBLE_GLASS_PANE L"glass pane" + + /** + * A specialized pane that allows its children to be drawn in layers, + * providing a form of stacking order. This is usually the pane that + * holds the menu bar as well as the pane that contains most of the + * visual components in a window. + * see ACCESSIBLE_GLASS_PANE + * see ACCESSIBLE_ROOT_PANE + */ +#define ACCESSIBLE_LAYERED_PANE L"layered pane" + + /** + * An object that presents a list of objects to the user and allows the + * user to select one or more of them. A list is usually contained + * within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST_ITEM + */ +#define ACCESSIBLE_LIST L"list" + + /** + * An object that presents an element in a list. A list is usually + * contained within a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + * see ACCESSIBLE_LIST + */ +#define ACCESSIBLE_LIST_ITEM L"list item" + + /** + * An object usually drawn at the top of the primary dialog box of + * an application that contains a list of menus the user can choose + * from. For example, a menu bar might contain menus for "File," + * "Edit," and "Help." + * see ACCESSIBLE_MENU + * see ACCESSIBLE_POPUP_MENU + * see ACCESSIBLE_LAYERED_PANE + */ +#define ACCESSIBLE_MENU_BAR L"menu bar" + + /** + * A temporary window that is usually used to offer the user a + * list of choices, and then hides when the user selects one of + * those choices. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_POPUP_MENU L"popup menu" + + /** + * An object usually found inside a menu bar that contains a list + * of actions the user can choose from. A menu can have any object + * as its children, but most often they are menu items, other menus, + * or rudimentary objects such as radio buttons, check boxes, or + * separators. For example, an application may have an "Edit" menu + * that contains menu items for "Cut" and "Paste." + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_MENU_ITEM + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_RADIO_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU L"menu" + + /** + * An object usually contained in a menu that presents an action + * the user can choose. For example, the "Cut" menu item in an + * "Edit" menu would be an action the user can select to cut the + * selected area of text in a document. + * see ACCESSIBLE_MENU_BAR + * see ACCESSIBLE_SEPARATOR + * see ACCESSIBLE_POPUP_MENU + */ +#define ACCESSIBLE_MENU_ITEM L"menu item" + + /** + * An object usually contained in a menu to provide a visual + * and logical separation of the contents in a menu. For example, + * the "File" menu of an application might contain menu items for + * "Open," "Close," and "Exit," and will place a separator between + * "Close" and "Exit" menu items. + * see ACCESSIBLE_MENU + * see ACCESSIBLE_MENU_ITEM + */ +#define ACCESSIBLE_SEPARATOR L"separator" + + /** + * An object that presents a series of panels (or page tabs), one at a + * time, through some mechanism provided by the object. The most common + * mechanism is a list of tabs at the top of the panel. The children of + * a page tab list are all page tabs. + * see ACCESSIBLE_PAGE_TAB + */ +#define ACCESSIBLE_PAGE_TAB_LIST L"page tab list" + + /** + * An object that is a child of a page tab list. Its sole child is + * the panel that is to be presented to the user when the user + * selects the page tab from the list of tabs in the page tab list. + * see ACCESSIBLE_PAGE_TAB_LIST + */ +#define ACCESSIBLE_PAGE_TAB L"page tab" + + /** + * A generic container that is often used to group objects. + */ +#define ACCESSIBLE_PANEL L"panel" + + /** + * An object used to indicate how much of a task has been completed. + */ +#define ACCESSIBLE_PROGRESS_BAR L"progress bar" + + /** + * A text object used for passwords, or other places where the + * text contents is not shown visibly to the user + */ +#define ACCESSIBLE_PASSWORD_TEXT L"password text" + + /** + * An object the user can manipulate to tell the application to do + * something. + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_PUSH_BUTTON L"push button" + + /** + * A specialized push button that can be checked or unchecked, but + * does not provide a separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_CHECK_BOX + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_TOGGLE_BUTTON L"toggle button" + + /** + * A choice that can be checked or unchecked and provides a + * separate indicator for the current state. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_RADIO_BUTTON + */ +#define ACCESSIBLE_CHECK_BOX L"check box" + + /** + * A specialized check box that will cause other radio buttons in the + * same group to become unchecked when this one is checked. + * see ACCESSIBLE_PUSH_BUTTON + * see ACCESSIBLE_TOGGLE_BUTTON + * see ACCESSIBLE_CHECK_BOX + */ +#define ACCESSIBLE_RADIO_BUTTON L"radio button" + + /** + * The header for a row of data. + */ +#define ACCESSIBLE_ROW_HEADER L"row header" + + /** + * An object that allows a user to incrementally view a large amount + * of information. Its children can include scroll bars and a viewport. + * see ACCESSIBLE_SCROLL_BAR + * see ACCESSIBLE_VIEWPORT + */ +#define ACCESSIBLE_SCROLL_PANE L"scroll pane" + + /** + * An object usually used to allow a user to incrementally view a + * large amount of data. Usually used only by a scroll pane. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_SCROLL_BAR L"scroll bar" + + /** + * An object usually used in a scroll pane. It represents the portion + * of the entire data that the user can see. As the user manipulates + * the scroll bars, the contents of the viewport can change. + * see ACCESSIBLE_SCROLL_PANE + */ +#define ACCESSIBLE_VIEWPORT L"viewport" + + /** + * An object that allows the user to select from a bounded range. For + * example, a slider might be used to select a number between 0 and 100. + */ +#define ACCESSIBLE_SLIDER L"slider" + + /** + * A specialized panel that presents two other panels at the same time. + * Between the two panels is a divider the user can manipulate to make + * one panel larger and the other panel smaller. + */ +#define ACCESSIBLE_SPLIT_PANE L"split pane" + + /** + * An object used to present information in terms of rows and columns. + * An example might include a spreadsheet application. + */ +#define ACCESSIBLE_TABLE L"table" + + /** + * An object that presents text to the user. The text is usually + * editable by the user as opposed to a label. + * see ACCESSIBLE_LABEL + */ +#define ACCESSIBLE_TEXT L"text" + + /** + * An object used to present hierarchical information to the user. + * The individual nodes in the tree can be collapsed and expanded + * to provide selective disclosure of the tree's contents. + */ +#define ACCESSIBLE_TREE L"tree" + + /** + * A bar or palette usually composed of push buttons or toggle buttons. + * It is often used to provide the most frequently used functions for an + * application. + */ +#define ACCESSIBLE_TOOL_BAR L"tool bar" + + /** + * An object that provides information about another object. The + * accessibleDescription property of the tool tip is often displayed + * to the user in a small L"help bubble" when the user causes the + * mouse to hover over the object associated with the tool tip. + */ +#define ACCESSIBLE_TOOL_TIP L"tool tip" + + /** + * An AWT component, but nothing else is known about it. + * see ACCESSIBLE_SWING_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_AWT_COMPONENT L"awt component" + + /** + * A Swing component, but nothing else is known about it. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_UNKNOWN + */ +#define ACCESSIBLE_SWING_COMPONENT L"swing component" + + /** + * The object contains some Accessible information, but its role is + * not known. + * see ACCESSIBLE_AWT_COMPONENT + * see ACCESSIBLE_SWING_COMPONENT + */ +#define ACCESSIBLE_UNKNOWN L"unknown" + + /** + * A STATUS_BAR is an simple component that can contain + * multiple labels of status information to the user. + */ +#define ACCESSIBLE_STATUS_BAR L"status bar" + + /** + * A DATE_EDITOR is a component that allows users to edit + * java.util.Date and java.util.Time objects + */ +#define ACCESSIBLE_DATE_EDITOR L"date editor" + + /** + * A SPIN_BOX is a simple spinner component and its main use + * is for simple numbers. + */ +#define ACCESSIBLE_SPIN_BOX L"spin box" + + /** + * A FONT_CHOOSER is a component that lets the user pick various + * attributes for fonts. + */ +#define ACCESSIBLE_FONT_CHOOSER L"font chooser" + + /** + * A GROUP_BOX is a simple container that contains a border + * around it and contains components inside it. + */ +#define ACCESSIBLE_GROUP_BOX L"group box" + + /** + * A text header + */ +#define ACCESSIBLE_HEADER L"header" + + /** + * A text footer + */ +#define ACCESSIBLE_FOOTER L"footer" + + /** + * A text paragraph + */ +#define ACCESSIBLE_PARAGRAPH L"paragraph" + + /** + * A ruler is an object used to measure distance + */ +#define ACCESSIBLE_RULER L"ruler" + + /** + * A role indicating the object acts as a formula for + * calculating a value. An example is a formula in + * a spreadsheet cell. + */ +#define ACCESSIBLE_EDITBAR L"editbar" + + /** + * A role indicating the object monitors the progress + * of some operation. + */ +#define PROGRESS_MONITOR L"progress monitor" + + + /** + ****************************************************** + * Accessibility event types + ****************************************************** + */ + +#define cPropertyNameChangeEvent (jlong) 1 // 1 +#define cPropertyDescriptionChangeEvent (jlong) 2 // 2 +#define cPropertyStateChangeEvent (jlong) 4 // 4 +#define cPropertyValueChangeEvent (jlong) 8 // 8 +#define cPropertySelectionChangeEvent (jlong) 16 // 10 +#define cPropertyTextChangeEvent (jlong) 32 // 20 +#define cPropertyCaretChangeEvent (jlong) 64 // 40 +#define cPropertyVisibleDataChangeEvent (jlong) 128 // 80 +#define cPropertyChildChangeEvent (jlong) 256 // 100 +#define cPropertyActiveDescendentChangeEvent (jlong) 512 // 200 +#define cPropertyTableModelChangeEvent (jlong) 1024 // 400 + + /** + ****************************************************** + * optional AccessibleContext interfaces + * + * This version of the bridge reuses the accessibleValue + * field in the AccessibleContextInfo struct to represent + * additional optional interfaces that are supported by + * the Java AccessibleContext. This is backwardly compatable + * because the old accessibleValue was set to the BOOL + * value TRUE (i.e., 1) if the AccessibleValue interface is + * supported. + ****************************************************** + */ + +#define cAccessibleValueInterface (jlong) 1 // 1 << 1 (TRUE) +#define cAccessibleActionInterface (jlong) 2 // 1 << 2 +#define cAccessibleComponentInterface (jlong) 4 // 1 << 3 +#define cAccessibleSelectionInterface (jlong) 8 // 1 << 4 +#define cAccessibleTableInterface (jlong) 16 // 1 << 5 +#define cAccessibleTextInterface (jlong) 32 // 1 << 6 +#define cAccessibleHypertextInterface (jlong) 64 // 1 << 7 + + + /** + ****************************************************** + * Accessibility information bundles + ****************************************************** + */ + + typedef struct AccessBridgeVersionInfoTag { + wchar_t VMversion[SHORT_STRING_SIZE]; // output of "java -version" + wchar_t bridgeJavaClassVersion[SHORT_STRING_SIZE]; // version of the AccessBridge.class + wchar_t bridgeJavaDLLVersion[SHORT_STRING_SIZE]; // version of JavaAccessBridge.dll + wchar_t bridgeWinDLLVersion[SHORT_STRING_SIZE]; // version of WindowsAccessBridge.dll + } AccessBridgeVersionInfo; + + + typedef struct AccessibleContextInfoTag { + wchar_t name[MAX_STRING_SIZE]; // the AccessibleName of the object + wchar_t description[MAX_STRING_SIZE]; // the AccessibleDescription of the object + + wchar_t role[SHORT_STRING_SIZE]; // localized AccesibleRole string + wchar_t role_en_US[SHORT_STRING_SIZE]; // AccesibleRole string in the en_US locale + wchar_t states[SHORT_STRING_SIZE]; // localized AccesibleStateSet string (comma separated) + wchar_t states_en_US[SHORT_STRING_SIZE]; // AccesibleStateSet string in the en_US locale (comma separated) + + jint indexInParent; // index of object in parent + jint childrenCount; // # of children, if any + + jint x; // screen coords in pixels + jint y; // " + jint width; // pixel width of object + jint height; // pixel height of object + + BOOL accessibleComponent; // flags for various additional + BOOL accessibleAction; // Java Accessibility interfaces + BOOL accessibleSelection; // FALSE if this object doesn't + BOOL accessibleText; // implement the additional interface + // in question + + // BOOL accessibleValue; // old BOOL indicating whether AccessibleValue is supported + BOOL accessibleInterfaces; // new bitfield containing additional interface flags + + } AccessibleContextInfo; + + + + // AccessibleText packages + typedef struct AccessibleTextInfoTag { + jint charCount; // # of characters in this text object + jint caretIndex; // index of caret + jint indexAtPoint; // index at the passsed in point + } AccessibleTextInfo; + + typedef struct AccessibleTextItemsInfoTag { + wchar_t letter; + wchar_t word[SHORT_STRING_SIZE]; + wchar_t sentence[MAX_STRING_SIZE]; + } AccessibleTextItemsInfo; + + typedef struct AccessibleTextSelectionInfoTag { + jint selectionStartIndex; + jint selectionEndIndex; + wchar_t selectedText[MAX_STRING_SIZE]; + } AccessibleTextSelectionInfo; + + typedef struct AccessibleTextRectInfoTag { + jint x; // bounding rect of char at index + jint y; // " + jint width; // " + jint height; // " + } AccessibleTextRectInfo; + + // standard attributes for text; note: tabstops are not supported + typedef struct AccessibleTextAttributesInfoTag { + BOOL bold; + BOOL italic; + BOOL underline; + BOOL strikethrough; + BOOL superscript; + BOOL subscript; + + wchar_t backgroundColor[SHORT_STRING_SIZE]; + wchar_t foregroundColor[SHORT_STRING_SIZE]; + wchar_t fontFamily[SHORT_STRING_SIZE]; + jint fontSize; + + jint alignment; + jint bidiLevel; + + jfloat firstLineIndent; + jfloat leftIndent; + jfloat rightIndent; + jfloat lineSpacing; + jfloat spaceAbove; + jfloat spaceBelow; + + wchar_t fullAttributesString[MAX_STRING_SIZE]; + } AccessibleTextAttributesInfo; + + /** + ****************************************************** + * IPC management typedefs + ****************************************************** + */ + +#define cMemoryMappedNameSize 255 + + /** + * sent by the WindowsDLL -> the memory-mapped file is setup + * + */ + typedef struct MemoryMappedFileCreatedPackageTag { +// HWND bridgeWindow; // redundant, but easier to get to here... + ABHWND64 bridgeWindow; // redundant, but easier to get to here... + char filename[cMemoryMappedNameSize]; + } MemoryMappedFileCreatedPackage; + + + + + /** + * sent when a new JavaVM attaches to the Bridge + * + */ + typedef struct JavaVMCreatedPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMCreatedPackage; + + /** + * sent when a JavaVM detatches from the Bridge + * + */ + typedef struct JavaVMDestroyedPackageTag { + ABHWND64 bridgeWindow; + } JavaVMDestroyedPackage; + + /** + * sent when a new AT attaches to the Bridge + * + */ + typedef struct WindowsATCreatedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATCreatedPackage; + + /** + * sent when an AT detatches from the Bridge + * + */ + typedef struct WindowsATDestroyedPackageTag { + ABHWND64 bridgeWindow; + } WindowsATDestroyedPackage; + + + /** + * sent by JVM Bridges in response to a WindowsATCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct JavaVMPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + long vmID; + } JavaVMPresentNotificationPackage; + + /** + * sent by AT Bridges in response to a JavaVMCreate + * message; saying "howdy, welcome to the neighborhood" + * + */ + typedef struct WindowsATPresentNotificationPackageTag { + ABHWND64 bridgeWindow; + } WindowsATPresentNotificationPackage; + + + /** + ****************************************************** + * Core packages + ****************************************************** + */ + + typedef struct ReleaseJavaObjectPackageTag { + long vmID; + JOBJECT64 object; + } ReleaseJavaObjectPackage; + + typedef struct GetAccessBridgeVersionPackageTag { + long vmID; // can't get VM info w/out a VM! + AccessBridgeVersionInfo rVersionInfo; + } GetAccessBridgeVersionPackage; + + typedef struct IsSameObjectPackageTag { + long vmID; + JOBJECT64 obj1; + JOBJECT64 obj2; + jboolean rResult; + } IsSameObjectPackage; + + /** + ****************************************************** + * Windows packages + ****************************************************** + */ + + typedef struct IsJavaWindowPackageTag { + jint window; + jboolean rResult; + } IsJavaWindowPackage; + + typedef struct GetAccessibleContextFromHWNDPackageTag { + jint window; + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextFromHWNDPackage; + + typedef struct GetHWNDFromAccessibleContextPackageTag { + JOBJECT64 accessibleContext; + ABHWND64 rHWND; + } GetHWNDFromAccessibleContextPackage; + + /** +****************************************************** +* AccessibleContext packages +****************************************************** +*/ + + typedef struct GetAccessibleContextAtPackageTag { + jint x; + jint y; + long vmID; + JOBJECT64 AccessibleContext; // look within this AC + JOBJECT64 rAccessibleContext; + } GetAccessibleContextAtPackage; + + typedef struct GetAccessibleContextWithFocusPackageTag { + long rVMID; + JOBJECT64 rAccessibleContext; + } GetAccessibleContextWithFocusPackage; + + typedef struct GetAccessibleContextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleContextInfo rAccessibleContextInfo; + } GetAccessibleContextInfoPackage; + + typedef struct GetAccessibleChildFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint childIndex; + JOBJECT64 rAccessibleContext; + } GetAccessibleChildFromContextPackage; + + typedef struct GetAccessibleParentFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + JOBJECT64 rAccessibleContext; + } GetAccessibleParentFromContextPackage; + + /** +****************************************************** +* AccessibleTable packages +****************************************************** +*/ + +#define MAX_TABLE_SELECTIONS 64 + + // table information + typedef struct AccessibleTableInfoTag { + JOBJECT64 caption; // AccesibleContext + JOBJECT64 summary; // AccessibleContext + jint rowCount; + jint columnCount; + JOBJECT64 accessibleContext; + JOBJECT64 accessibleTable; + } AccessibleTableInfo; + + typedef struct GetAccessibleTableInfoPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableInfoPackage; + + // table cell information + typedef struct AccessibleTableCellInfoTag { + JOBJECT64 accessibleContext; + jint index; + jint row; + jint column; + jint rowExtent; + jint columnExtent; + jboolean isSelected; + } AccessibleTableCellInfo; + + typedef struct GetAccessibleTableCellInfoPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + AccessibleTableCellInfo rTableCellInfo; + } GetAccessibleTableCellInfoPackage; + + typedef struct GetAccessibleTableRowHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableRowHeaderPackage; + + typedef struct GetAccessibleTableColumnHeaderPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleTableInfo rTableInfo; + } GetAccessibleTableColumnHeaderPackage; + + typedef struct GetAccessibleTableRowDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint row; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableRowDescriptionPackage; + + typedef struct GetAccessibleTableColumnDescriptionPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint column; + JOBJECT64 rAccessibleContext; + } GetAccessibleTableColumnDescriptionPackage; + + typedef struct GetAccessibleTableRowSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableRowSelectionCountPackage; + + typedef struct IsAccessibleTableRowSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jboolean rResult; + } IsAccessibleTableRowSelectedPackage; + + typedef struct GetAccessibleTableRowSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableRowSelectionsPackage; + + typedef struct GetAccessibleTableColumnSelectionCountPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint rCount; + } GetAccessibleTableColumnSelectionCountPackage; + + typedef struct IsAccessibleTableColumnSelectedPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint column; + jboolean rResult; + } IsAccessibleTableColumnSelectedPackage; + + typedef struct GetAccessibleTableColumnSelectionsPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint count; + jint rSelections[MAX_TABLE_SELECTIONS]; + } GetAccessibleTableColumnSelectionsPackage; + + + typedef struct GetAccessibleTableRowPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rRow; + } GetAccessibleTableRowPackage; + + typedef struct GetAccessibleTableColumnPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint index; + jint rColumn; + } GetAccessibleTableColumnPackage; + + typedef struct GetAccessibleTableIndexPackageTag { + long vmID; + JOBJECT64 accessibleTable; + jint row; + jint column; + jint rIndex; + } GetAccessibleTableIndexPackage; + + + /** + ****************************************************** + * AccessibleRelationSet packages + ****************************************************** + */ + +#define MAX_RELATION_TARGETS 25 +#define MAX_RELATIONS 5 + + typedef struct AccessibleRelationInfoTag { + wchar_t key[SHORT_STRING_SIZE]; + jint targetCount; + JOBJECT64 targets[MAX_RELATION_TARGETS]; // AccessibleContexts + } AccessibleRelationInfo; + + typedef struct AccessibleRelationSetInfoTag { + jint relationCount; + AccessibleRelationInfo relations[MAX_RELATIONS]; + } AccessibleRelationSetInfo; + + typedef struct GetAccessibleRelationSetPackageTag { + long vmID; + JOBJECT64 accessibleContext; + AccessibleRelationSetInfo rAccessibleRelationSetInfo; + } GetAccessibleRelationSetPackage; + + /** + ****************************************************** + * AccessibleHypertext packagess + ****************************************************** + */ + +#define MAX_HYPERLINKS 64 // maximum number of hyperlinks returned + + // hyperlink information + typedef struct AccessibleHyperlinkInfoTag { + wchar_t text[SHORT_STRING_SIZE]; // the hyperlink text + jint startIndex; //index in the hypertext document where the link begins + jint endIndex; //index in the hypertext document where the link ends + JOBJECT64 accessibleHyperlink; // AccessibleHyperlink object + } AccessibleHyperlinkInfo; + + // hypertext information + typedef struct AccessibleHypertextInfoTag { + jint linkCount; // number of hyperlinks + AccessibleHyperlinkInfo links[MAX_HYPERLINKS]; // the hyperlinks + JOBJECT64 accessibleHypertext; // AccessibleHypertext object + } AccessibleHypertextInfo; + + // struct for sending a message to get the hypertext for an AccessibleContext + typedef struct GetAccessibleHypertextPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + } GetAccessibleHypertextPackage; + + // struct for sending an message to activate a hyperlink + typedef struct ActivateAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing the link + JOBJECT64 accessibleHyperlink; // the link to activate + BOOL rResult; // hyperlink activation return value + } ActivateAccessibleHyperlinkPackage; + + // struct for sending a message to get the number of hyperlinks in a component + typedef struct GetAccessibleHyperlinkCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext containing AccessibleHypertext + jint rLinkCount; // link count return value + } GetAccessibleHyperlinkCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetAccessibleHypertextExtPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext with hypertext + jint startIndex; // start index in document + AccessibleHypertextInfo rAccessibleHypertextInfo; // returned hypertext + BOOL rSuccess; // whether call succeeded + } GetAccessibleHypertextExtPackage; + + // struct for sending a message to get the nth hyperlink in a document; + // maps to AccessibleHypertext.getLink + typedef struct GetAccessibleHyperlinkPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint linkIndex; // hyperlink index + AccessibleHyperlinkInfo rAccessibleHyperlinkInfo; // returned hyperlink + } GetAccessibleHyperlinkPackage; + + // struct for sending a message to get the index into an array + // of hyperlinks that is associated with a character index in a + // document; maps to AccessibleHypertext.getLinkIndex + typedef struct GetAccessibleHypertextLinkIndexPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 hypertext; // AccessibleHypertext + jint charIndex; // character index in document + jint rLinkIndex; // returned hyperlink index + } GetAccessibleHypertextLinkIndexPackage; + + /** + ****************************************************** + * Accessible Key Bindings packages + ****************************************************** + */ + +#define MAX_KEY_BINDINGS 10 + + // keyboard character modifiers +#define ACCESSIBLE_SHIFT_KEYSTROKE 1 +#define ACCESSIBLE_CONTROL_KEYSTROKE 2 +#define ACCESSIBLE_META_KEYSTROKE 4 +#define ACCESSIBLE_ALT_KEYSTROKE 8 +#define ACCESSIBLE_ALT_GRAPH_KEYSTROKE 16 +#define ACCESSIBLE_BUTTON1_KEYSTROKE 32 +#define ACCESSIBLE_BUTTON2_KEYSTROKE 64 +#define ACCESSIBLE_BUTTON3_KEYSTROKE 128 +#define ACCESSIBLE_FKEY_KEYSTROKE 256 // F key pressed, character contains 1-24 +#define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. + +// The supported control code keys are: +#define ACCESSIBLE_VK_BACK_SPACE 8 +#define ACCESSIBLE_VK_DELETE 127 +#define ACCESSIBLE_VK_DOWN 40 +#define ACCESSIBLE_VK_END 35 +#define ACCESSIBLE_VK_HOME 36 +#define ACCESSIBLE_VK_INSERT 155 +#define ACCESSIBLE_VK_KP_DOWN 225 +#define ACCESSIBLE_VK_KP_LEFT 226 +#define ACCESSIBLE_VK_KP_RIGHT 227 +#define ACCESSIBLE_VK_KP_UP 224 +#define ACCESSIBLE_VK_LEFT 37 +#define ACCESSIBLE_VK_PAGE_DOWN 34 +#define ACCESSIBLE_VK_PAGE_UP 33 +#define ACCESSIBLE_VK_RIGHT 39 +#define ACCESSIBLE_VK_UP 38 + + // a key binding associates with a component + typedef struct AccessibleKeyBindingInfoTag { + jchar character; // the key character + jint modifiers; // the key modifiers + } AccessibleKeyBindingInfo; + + // all of the key bindings associated with a component + typedef struct AccessibleKeyBindingsTag { + int keyBindingsCount; // number of key bindings + AccessibleKeyBindingInfo keyBindingInfo[MAX_KEY_BINDINGS]; + } AccessibleKeyBindings; + + // struct to get the key bindings associated with a component + typedef struct GetAccessibleKeyBindingsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleKeyBindings rAccessibleKeyBindings; // the key bindings + } GetAccessibleKeyBindingsPackage; + + /** +****************************************************** +* AccessibleIcon packages +****************************************************** +*/ +#define MAX_ICON_INFO 8 + + // an icon assocated with a component + typedef struct AccessibleIconInfoTag { + wchar_t description[SHORT_STRING_SIZE]; // icon description + jint height; // icon height + jint width; // icon width + } AccessibleIconInfo; + + // all of the icons associated with a component + typedef struct AccessibleIconsTag { + jint iconsCount; // number of icons + AccessibleIconInfo iconInfo[MAX_ICON_INFO]; // the icons + } AccessibleIcons; + + // struct to get the icons associated with a component + typedef struct GetAccessibleIconsPackageTag { + long vmID; // the virtual machine id + JOBJECT64 accessibleContext; // the component + AccessibleIcons rAccessibleIcons; // the icons + } GetAccessibleIconsPackage; + + + /** +****************************************************** +* AccessibleAction packages +****************************************************** +*/ +#define MAX_ACTION_INFO 256 +#define MAX_ACTIONS_TO_DO 32 + + // an action assocated with a component + typedef struct AccessibleActionInfoTag { + wchar_t name[SHORT_STRING_SIZE]; // action name + } AccessibleActionInfo; + + // all of the actions associated with a component + typedef struct AccessibleActionsTag { + jint actionsCount; // number of actions + AccessibleActionInfo actionInfo[MAX_ACTION_INFO]; // the action information + } AccessibleActions; + + // struct for requesting the actions associated with a component + typedef struct GetAccessibleActionsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the component + AccessibleActions rAccessibleActions; // the actions + } GetAccessibleActionsPackage; + + // list of AccessibleActions to do + typedef struct AccessibleActionsToDoTag { + jint actionsCount; // number of actions to do + AccessibleActionInfo actions[MAX_ACTIONS_TO_DO];// the accessible actions to do + } AccessibleActionsToDo; + + // struct for sending an message to do one or more actions + typedef struct DoAccessibleActionsPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // component to do the action + AccessibleActionsToDo actionsToDo; // the accessible actions to do + BOOL rResult; // action return value + jint failure; // index of action that failed if rResult is FALSE + } DoAccessibleActionsPackage; + + /** +****************************************************** +* AccessibleText packages +****************************************************** +*/ + + typedef struct GetAccessibleTextInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint x; + jint y; + AccessibleTextInfo rTextInfo; + } GetAccessibleTextInfoPackage; + + typedef struct GetAccessibleTextItemsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextItemsInfo rTextItemsInfo; + } GetAccessibleTextItemsPackage; + + typedef struct GetAccessibleTextSelectionInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + AccessibleTextSelectionInfo rTextSelectionItemsInfo; + } GetAccessibleTextSelectionInfoPackage; + + typedef struct GetAccessibleTextAttributeInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextAttributesInfo rAttributeInfo; + } GetAccessibleTextAttributeInfoPackage; + + typedef struct GetAccessibleTextRectInfoPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetAccessibleTextRectInfoPackage; + + typedef struct GetCaretLocationPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + AccessibleTextRectInfo rTextRectInfo; + } GetCaretLocationPackage; + + typedef struct GetAccessibleTextLineBoundsPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jint rLineStart; + jint rLineEnd; + } GetAccessibleTextLineBoundsPackage; + + typedef struct GetAccessibleTextRangePackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint start; + jint end; + wchar_t rText[MAX_BUFFER_SIZE]; + } GetAccessibleTextRangePackage; + + /** +****************************************************** +* +* Utility method packages +****************************************************** +*/ + + typedef struct SetTextContentsPackageTag { + long vmID; + JOBJECT64 accessibleContext; // the text field + wchar_t text[MAX_STRING_SIZE]; // the text + BOOL rResult; + } SetTextContentsPackage; + + typedef struct GetParentWithRolePackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRolePackage; + + typedef struct GetTopLevelObjectPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetTopLevelObjectPackage; + + typedef struct GetParentWithRoleElseRootPackageTag { + long vmID; + JOBJECT64 accessibleContext; + wchar_t role[SHORT_STRING_SIZE]; // one of Accessible Roles above + JOBJECT64 rAccessibleContext; + } GetParentWithRoleElseRootPackage; + + typedef struct GetObjectDepthPackageTag { + long vmID; + JOBJECT64 accessibleContext; + jint rResult; + } GetObjectDepthPackage; + + typedef struct GetActiveDescendentPackageTag { + long vmID; + JOBJECT64 accessibleContext; + JOBJECT64 rAccessibleContext; + } GetActiveDescendentPackage; + + /** +****************************************************** +* AccessibleValue packages +****************************************************** +*/ + + typedef struct GetCurrentAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetCurrentAccessibleValueFromContextPackage; + + typedef struct GetMaximumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMaximumAccessibleValueFromContextPackage; + + typedef struct GetMinimumAccessibleValueFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + wchar_t rValue[SHORT_STRING_SIZE]; + } GetMinimumAccessibleValueFromContextPackage; + + + /** +****************************************************** +* AccessibleSelection packages +****************************************************** +*/ + + typedef struct AddAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } AddAccessibleSelectionFromContextPackage; + + typedef struct ClearAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } ClearAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + JOBJECT64 rAccessibleContext; + } GetAccessibleSelectionFromContextPackage; + + typedef struct GetAccessibleSelectionCountFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint rCount; + } GetAccessibleSelectionCountFromContextPackage; + + typedef struct IsAccessibleChildSelectedFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + jboolean rResult; + } IsAccessibleChildSelectedFromContextPackage; + + typedef struct RemoveAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + jint index; + } RemoveAccessibleSelectionFromContextPackage; + + typedef struct SelectAllAccessibleSelectionFromContextPackageTag { + long vmID; + JOBJECT64 AccessibleContext; + } SelectAllAccessibleSelectionFromContextPackage; + + + /** +****************************************************** +* Java Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddJavaEventNotificationPackage; + + typedef struct RemoveJavaEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveJavaEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Event Notification Registration packages +****************************************************** +*/ + + typedef struct AddAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } AddAccessibilityEventNotificationPackage; + + typedef struct RemoveAccessibilityEventNotificationPackageTag { + jlong type; + //HWND DLLwindow; + ABHWND64 DLLwindow; + } RemoveAccessibilityEventNotificationPackage; + + + /** +****************************************************** +* Accessibility Property Change Event packages +****************************************************** +*/ + + typedef struct PropertyCaretChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + jint oldPosition; + jint newPosition; + } PropertyCaretChangePackage; + + typedef struct PropertyDescriptionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldDescription[SHORT_STRING_SIZE]; + wchar_t newDescription[SHORT_STRING_SIZE]; + } PropertyDescriptionChangePackage; + + typedef struct PropertyNameChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldName[SHORT_STRING_SIZE]; + wchar_t newName[SHORT_STRING_SIZE]; + } PropertyNameChangePackage; + + typedef struct PropertySelectionChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertySelectionChangePackage; + + typedef struct PropertyStateChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldState[SHORT_STRING_SIZE]; + wchar_t newState[SHORT_STRING_SIZE]; + } PropertyStateChangePackage; + + typedef struct PropertyTextChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyTextChangePackage; + + typedef struct PropertyValueChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyValueChangePackage; + + typedef struct PropertyVisibleDataChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PropertyVisibleDataChangePackage; + + typedef struct PropertyChildChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldChildAccessibleContext; + JOBJECT64 newChildAccessibleContext; + } PropertyChildChangePackage; + + typedef struct PropertyActiveDescendentChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + JOBJECT64 oldActiveDescendentAccessibleContext; + JOBJECT64 newActiveDescendentAccessibleContext; + } PropertyActiveDescendentChangePackage; + + + // String format for newValue is: + // "type" one of "INSERT", "UPDATE" or "DELETE" + // "firstRow" + // "lastRow" + // "firstColumn" + // "lastColumn" + // + // oldValue is currently unused + // + typedef struct PropertyTableModelChangePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + wchar_t oldValue[SHORT_STRING_SIZE]; + wchar_t newValue[SHORT_STRING_SIZE]; + } PropertyTableModelChangePackage; + + + /** +****************************************************** +* Property Change Event packages +****************************************************** +*/ + + /* + typedef struct PropertyChangePackageTag { + long vmID; + jobject Event; + jobject AccessibleContextSource; + char propertyName[SHORT_STRING_SIZE]; + char oldValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getOldValue().toString() + char newValue[SHORT_STRING_SIZE]; // PropertyChangeEvent().getNewValue().toString() + } PropertyChangePackage; + */ + + /* + * Java shutdown event package + */ + typedef struct JavaShutdownPackageTag { + long vmID; + } JavaShutdownPackage; + + + /** +****************************************************** +* Focus Event packages +****************************************************** +*/ + + typedef struct FocusGainedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusGainedPackage; + + typedef struct FocusLostPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } FocusLostPackage; + + + /** +****************************************************** +* Caret Event packages +****************************************************** +*/ + + typedef struct CaretUpdatePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } CaretUpdatePackage; + + + /** +****************************************************** +* Mouse Event packages +****************************************************** +*/ + + typedef struct MouseClickedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseClickedPackage; + + typedef struct MouseEnteredPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseEnteredPackage; + + typedef struct MouseExitedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseExitedPackage; + + typedef struct MousePressedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MousePressedPackage; + + typedef struct MouseReleasedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MouseReleasedPackage; + + + /** +****************************************************** +* Menu/PopupMenu Event packages +****************************************************** +*/ + + typedef struct MenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuCanceledPackage; + + typedef struct MenuDeselectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuDeselectedPackage; + + typedef struct MenuSelectedPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } MenuSelectedPackage; + + + typedef struct PopupMenuCanceledPackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuCanceledPackage; + + typedef struct PopupMenuWillBecomeInvisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeInvisiblePackage; + + typedef struct PopupMenuWillBecomeVisiblePackageTag { + long vmID; + JOBJECT64 Event; + JOBJECT64 AccessibleContextSource; + } PopupMenuWillBecomeVisiblePackage; + + /** +****************************************************** +* Additional methods for Teton +****************************************************** +*/ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + typedef struct GetVirtualAccessibleNamePackageTag { + long vmID; + AccessibleContext accessibleContext; + wchar_t rName[MAX_STRING_SIZE]; + int len; + } GetVirtualAccessibleNamePackage; + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + typedef struct RequestFocusPackageTag { + long vmID; + AccessibleContext accessibleContext; + } RequestFocusPackage; + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + typedef struct SelectTextRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; + jint endIndex; + } SelectTextRangePackage; + + /** + * Gets the number of contiguous characters with the same attributes. + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + typedef struct GetTextAttributesInRangePackageTag { + long vmID; + AccessibleContext accessibleContext; + jint startIndex; // start index (inclusive) + jint endIndex; // end index (inclusive) + AccessibleTextAttributesInfo attributes; // character attributes to match + short rLength; // number of contiguous characters with matching attributes + } GetTextAttributesInRangePackage; + +#define MAX_VISIBLE_CHILDREN 256 + + // visible children information + typedef struct VisibleChildenInfoTag { + int returnedChildrenCount; // number of children returned + AccessibleContext children[MAX_VISIBLE_CHILDREN]; // the visible children + } VisibleChildrenInfo; + + // struct for sending a message to get the number of visible children + typedef struct GetVisibleChildrenCountPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint rChildrenCount; // visible children count return value + } GetVisibleChildrenCountPackage; + + // struct for sending a message to get the hypertext for an AccessibleContext + // starting at a specified index in the document + typedef struct GetVisibleChildrenPackageTag { + long vmID; // the virtual machine ID + JOBJECT64 accessibleContext; // AccessibleContext of parent component + jint startIndex; // start index for retrieving children + VisibleChildrenInfo rVisibleChildrenInfo; // returned info + BOOL rSuccess; // whether call succeeded + } GetVisibleChildrenPackage; + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + typedef struct SetCaretPositionPackageTag { + long vmID; + AccessibleContext accessibleContext; + jint position; + } SetCaretPositionPackage; + + + /** + ****************************************************** + * Wrapping up all of the packages + ****************************************************** + */ + + /** + * What is the type of this package + */ + typedef enum PackageType { + + cMemoryMappedFileCreatedPackage = 0x11000, + + // many of these will go away... + cJavaVMCreatedPackage = 0x10000, + cJavaVMDestroyedPackage, + cWindowsATCreatedPackage, + cWindowsATDestroyedPackage, + cJavaVMPresentNotificationPackage, + cWindowsATPresentNotificationPackage, + + cReleaseJavaObjectPackage = 1, + cGetAccessBridgeVersionPackage = 2, + + cGetAccessibleContextFromHWNDPackage = 0x10, + cIsJavaWindowPackage, + cGetHWNDFromAccessibleContextPackage, + + cGetAccessibleContextAtPackage = 0x100, + cGetAccessibleContextWithFocusPackage, + cGetAccessibleContextInfoPackage, + cGetAccessibleChildFromContextPackage, + cGetAccessibleParentFromContextPackage, + cIsSameObjectPackage, + + cGetAccessibleTextInfoPackage = 0x200, + cGetAccessibleTextItemsPackage, + cGetAccessibleTextSelectionInfoPackage, + cGetAccessibleTextAttributeInfoPackage, + cGetAccessibleTextRectInfoPackage, + cGetAccessibleTextLineBoundsPackage, + cGetAccessibleTextRangePackage, + + cGetCurrentAccessibleValueFromContextPackage = 0x300, + cGetMaximumAccessibleValueFromContextPackage, + cGetMinimumAccessibleValueFromContextPackage, + + cAddAccessibleSelectionFromContextPackage = 0x400, + cClearAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionFromContextPackage, + cGetAccessibleSelectionCountFromContextPackage, + cIsAccessibleChildSelectedFromContextPackage, + cRemoveAccessibleSelectionFromContextPackage, + cSelectAllAccessibleSelectionFromContextPackage, + + cAddJavaEventNotificationPackage = 0x900, + cRemoveJavaEventNotificationPackage, + cAddAccessibilityEventNotificationPackage, + cRemoveAccessibilityEventNotificationPackage, + + cPropertyChangePackage = 0x1000, + + cJavaShutdownPackage = 0x1010, + cFocusGainedPackage, + cFocusLostPackage, + + cCaretUpdatePackage = 0x1020, + + cMouseClickedPackage = 0x1030, + cMouseEnteredPackage, + cMouseExitedPackage, + cMousePressedPackage, + cMouseReleasedPackage, + + cMenuCanceledPackage = 0x1040, + cMenuDeselectedPackage, + cMenuSelectedPackage, + cPopupMenuCanceledPackage, + cPopupMenuWillBecomeInvisiblePackage, + cPopupMenuWillBecomeVisiblePackage, + + cPropertyCaretChangePackage = 0x1100, + cPropertyDescriptionChangePackage, + cPropertyNameChangePackage, + cPropertySelectionChangePackage, + cPropertyStateChangePackage, + cPropertyTextChangePackage, + cPropertyValueChangePackage, + cPropertyVisibleDataChangePackage, + cPropertyChildChangePackage, + cPropertyActiveDescendentChangePackage, + + + // AccessibleTable + cGetAccessibleTableInfoPackage = 0x1200, + cGetAccessibleTableCellInfoPackage, + + cGetAccessibleTableRowHeaderPackage, + cGetAccessibleTableColumnHeaderPackage, + + cGetAccessibleTableRowDescriptionPackage, + cGetAccessibleTableColumnDescriptionPackage, + + cGetAccessibleTableRowSelectionCountPackage, + cIsAccessibleTableRowSelectedPackage, + cGetAccessibleTableRowSelectionsPackage, + + cGetAccessibleTableColumnSelectionCountPackage, + cIsAccessibleTableColumnSelectedPackage, + cGetAccessibleTableColumnSelectionsPackage, + + cGetAccessibleTableRowPackage, + cGetAccessibleTableColumnPackage, + cGetAccessibleTableIndexPackage, + + cPropertyTableModelChangePackage, + + + // AccessibleRelationSet + cGetAccessibleRelationSetPackage = 0x1300, + + // AccessibleHypertext + cGetAccessibleHypertextPackage = 0x1400, + cActivateAccessibleHyperlinkPackage, + cGetAccessibleHyperlinkCountPackage, + cGetAccessibleHypertextExtPackage, + cGetAccessibleHypertextLinkIndexPackage, + cGetAccessibleHyperlinkPackage, + + // Accessible KeyBinding, Icon and Action + cGetAccessibleKeyBindingsPackage = 0x1500, + cGetAccessibleIconsPackage, + cGetAccessibleActionsPackage, + cDoAccessibleActionsPackage, + + // Utility methods + cSetTextContentsPackage = 0x1600, + cGetParentWithRolePackage, + cGetTopLevelObjectPackage, + cGetParentWithRoleElseRootPackage, + cGetObjectDepthPackage, + cGetActiveDescendentPackage, + + // Additional methods for Teton + cGetVirtualAccessibleNamePackage = 0x1700, + cRequestFocusPackage, + cSelectTextRangePackage, + cGetTextAttributesInRangePackage, + cGetSameTextAttributesInRangePackage, + cGetVisibleChildrenCountPackage, + cGetVisibleChildrenPackage, + cSetCaretPositionPackage, + cGetCaretLocationPackage + + + } PackageType; + + + /** + * Union of all package contents + */ + typedef union AllPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // Event contents packages + // PropertyChangePackage propertyChange; + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage getAccessibleRelationSet; + + // AccessibleHypertext + GetAccessibleHypertextPackage _getAccessibleHypertext; + ActivateAccessibleHyperlinkPackage _activateAccessibleHyperlink; + GetAccessibleHyperlinkCountPackage _getAccessibleHyperlinkCount; + GetAccessibleHypertextExtPackage _getAccessibleHypertextExt; + GetAccessibleHypertextLinkIndexPackage _getAccessibleHypertextLinkIndex; + GetAccessibleHyperlinkPackage _getAccessibleHyperlink; + + // Accessible KeyBinding, Icon and Action + GetAccessibleKeyBindingsPackage getAccessibleKeyBindings; + GetAccessibleIconsPackage getAccessibleIcons; + GetAccessibleActionsPackage getAccessibleActions; + DoAccessibleActionsPackage doAccessibleActions; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + } AllPackages; + + + /** + * Union of all Java-initiated package contents + */ + typedef union JavaInitiatedPackagesTag { + + // Initial Rendezvous packages + JavaVMCreatedPackage javaVMCreatedPackage; + JavaVMDestroyedPackage javaVMDestroyedPackage; + JavaVMPresentNotificationPackage javaVMPresentNotificationPackage; + + // Event contents packages + PropertyCaretChangePackage propertyCaretChangePackage; + PropertyDescriptionChangePackage propertyDescriptionChangePackage; + PropertyNameChangePackage propertyNameChangePackage; + PropertySelectionChangePackage propertySelectionChangePackage; + PropertyStateChangePackage propertyStateChangePackage; + PropertyTextChangePackage propertyTextChangePackage; + PropertyValueChangePackage propertyValueChangePackage; + PropertyVisibleDataChangePackage propertyVisibleDataChangePackage; + PropertyChildChangePackage propertyChildChangePackage; + PropertyActiveDescendentChangePackage propertyActiveDescendentChangePackage; + + PropertyTableModelChangePackage propertyTableModelChangePackage; + + JavaShutdownPackage JavaShutdown; + FocusGainedPackage focusGained; + FocusLostPackage focusLost; + + CaretUpdatePackage caretUpdate; + + MouseClickedPackage mouseClicked; + MouseEnteredPackage mouseEntered; + MouseExitedPackage mouseExited; + MousePressedPackage mousePressed; + MouseReleasedPackage mouseReleased; + + MenuCanceledPackage menuCanceled; + MenuDeselectedPackage menuDeselected; + MenuSelectedPackage menuSelected; + PopupMenuCanceledPackage popupMenuCanceled; + PopupMenuWillBecomeInvisiblePackage popupMenuWillBecomeInvisible; + PopupMenuWillBecomeVisiblePackage popupMenuWillBecomeVisible; + + } JavaInitiatedPackages; + + + /** + * Union of all Windows-initiated package contents + */ + typedef union WindowsInitiatedPackagesTag { + + // Initial Rendezvous packages + MemoryMappedFileCreatedPackage memoryMappedFileCreatedPackage; + + WindowsATCreatedPackage windowsATCreatedPackage; + WindowsATDestroyedPackage windowsATDestroyedPackage; + WindowsATPresentNotificationPackage windowsATPresentNotificationPackage; + + // Core packages + ReleaseJavaObjectPackage releaseJavaObject; + GetAccessBridgeVersionPackage getAccessBridgeVersion; + + // Window packages + GetAccessibleContextFromHWNDPackage getAccessibleContextFromHWND; + GetHWNDFromAccessibleContextPackage getHWNDFromAccessibleContext; + + // AccessibleContext packages + GetAccessibleContextAtPackage getAccessibleContextAt; + GetAccessibleContextWithFocusPackage getAccessibleContextWithFocus; + GetAccessibleContextInfoPackage getAccessibleContextInfo; + GetAccessibleChildFromContextPackage getAccessibleChildFromContext; + GetAccessibleParentFromContextPackage getAccessibleParentFromContext; + + // AccessibleText packages + GetAccessibleTextInfoPackage getAccessibleTextInfo; + GetAccessibleTextItemsPackage getAccessibleTextItems; + GetAccessibleTextSelectionInfoPackage getAccessibleTextSelectionInfo; + GetAccessibleTextAttributeInfoPackage getAccessibleTextAttributeInfo; + GetAccessibleTextRectInfoPackage getAccessibleTextRectInfo; + GetAccessibleTextLineBoundsPackage getAccessibleTextLineBounds; + GetAccessibleTextRangePackage getAccessibleTextRange; + + // AccessibleValue packages + GetCurrentAccessibleValueFromContextPackage getCurrentAccessibleValueFromContext; + GetMaximumAccessibleValueFromContextPackage getMaximumAccessibleValueFromContext; + GetMinimumAccessibleValueFromContextPackage getMinimumAccessibleValueFromContext; + + // AccessibleSelection packages + AddAccessibleSelectionFromContextPackage addAccessibleSelectionFromContext; + ClearAccessibleSelectionFromContextPackage clearAccessibleSelectionFromContext; + GetAccessibleSelectionFromContextPackage getAccessibleSelectionFromContext; + GetAccessibleSelectionCountFromContextPackage getAccessibleSelectionCountFromContext; + IsAccessibleChildSelectedFromContextPackage isAccessibleChildSelectedFromContext; + RemoveAccessibleSelectionFromContextPackage removeAccessibleSelectionFromContext; + SelectAllAccessibleSelectionFromContextPackage selectAllAccessibleSelectionFromContext; + + // Event Notification Registration packages + AddJavaEventNotificationPackage addJavaEventNotification; + RemoveJavaEventNotificationPackage removeJavaEventNotification; + AddAccessibilityEventNotificationPackage addAccessibilityEventNotification; + RemoveAccessibilityEventNotificationPackage removeAccessibilityEventNotification; + + // AccessibleTable + GetAccessibleTableInfoPackage _getAccessibleTableInfo; + GetAccessibleTableCellInfoPackage _getAccessibleTableCellInfo; + + GetAccessibleTableRowHeaderPackage _getAccessibleTableRowHeader; + GetAccessibleTableColumnHeaderPackage _getAccessibleTableColumnHeader; + + GetAccessibleTableRowDescriptionPackage _getAccessibleTableRowDescription; + GetAccessibleTableColumnDescriptionPackage _getAccessibleTableColumnDescription; + + GetAccessibleTableRowSelectionCountPackage _getAccessibleTableRowSelectionCount; + IsAccessibleTableRowSelectedPackage _isAccessibleTableRowSelected; + GetAccessibleTableRowSelectionsPackage _getAccessibleTableRowSelections; + + GetAccessibleTableColumnSelectionCountPackage _getAccessibleTableColumnSelectionCount; + IsAccessibleTableColumnSelectedPackage _isAccessibleTableColumnSelected; + GetAccessibleTableColumnSelectionsPackage _getAccessibleTableColumnSelections; + + GetAccessibleTableRowPackage _getAccessibleTableRow; + GetAccessibleTableColumnPackage _getAccessibleTableColumn; + GetAccessibleTableIndexPackage _getAccessibleTableIndex; + + // AccessibleRelationSet + GetAccessibleRelationSetPackage _getAccessibleRelationSet; + + // Accessible KeyBindings, Icons and Actions + GetAccessibleKeyBindingsPackage _getAccessibleKeyBindings; + GetAccessibleIconsPackage _getAccessibleIcons; + GetAccessibleActionsPackage _getAccessibleActions; + DoAccessibleActionsPackage _doAccessibleActions; + + + IsSameObjectPackage _isSameObject; + + // utility methods + SetTextContentsPackage _setTextContents; + GetParentWithRolePackage _getParentWithRole; + GetTopLevelObjectPackage _getTopLevelObject; + GetParentWithRoleElseRootPackage _getParentWithRoleElseRoot; + GetObjectDepthPackage _getObjectDepth; + GetActiveDescendentPackage _getActiveDescendent; + + // Additional methods for Teton + GetVirtualAccessibleNamePackage _getVirtualAccessibleName; + RequestFocusPackage _requestFocus; + SelectTextRangePackage _selectTextRange; + GetTextAttributesInRangePackage _getTextAttributesInRange; + GetVisibleChildrenCountPackage _getVisibleChildrenCount; + GetVisibleChildrenPackage _getVisibleChildren; + SetCaretPositionPackage _setCaretPosition; + + + } WindowsInitiatedPackages; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/jabswitch/jabswitch.cpp b/jdk/src/jdk.accessibility/windows/native/jabswitch/jabswitch.cpp new file mode 100644 index 00000000000..e3257d7df6a --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/jabswitch/jabswitch.cpp @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include +#include +#include +#include + +// This is the default buffer size used for RegQueryValue values. +#define DEFAULT_ALLOC MAX_PATH +// only allocate a buffer as big as MAX_ALLOC for RegQueryValue values. +#define MAX_ALLOC 262144 + +static LPCTSTR ACCESSIBILITY_USER_KEY = + _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility"); +static LPCTSTR ACCESSIBILITY_SYSTEM_KEY = + _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility\\Session"); +static LPCTSTR ACCESSIBILITY_CONFIG = + _T("Configuration"); +static LPCTSTR STR_ACCESSBRIDGE = + _T("oracle_javaaccessbridge"); + +// Note: There are senarios where more than one extension can be specified on the +// asssistive_technologies= +// line but this code only deals with the case of +// assistive_technologies=com.sun.java.accessibility.AccessBridge +// assuming that if additional extensions are desired the user knows how edit the file. + +FILE* origFile; +FILE* tempFile; + +bool isXP() +{ + static bool isXPFlag = false; + OSVERSIONINFO osvi; + + // Initialize the OSVERSIONINFO structure. + ZeroMemory( &osvi, sizeof( osvi ) ); + osvi.dwOSVersionInfoSize = sizeof( osvi ); + + GetVersionEx( &osvi ); + + if ( osvi.dwMajorVersion == 5 ) // For Windows XP and Windows 2000 + isXPFlag = true; + + return isXPFlag ; +} + +void enableJAB() { + // Copy lines from orig to temp modifying the line containing + // assistive_technologies= + // There are various scenarios: + // 1) If the line exists exactly as + // #assistive_technologies=com.sun.java.accessibility.AccessBridge + // replace it with + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // 2) else if the line exists exactly as + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // use it as is + // 3) else if a line containing "assistive_technologies" exits + // a) if it's already commented out, us it as is (jab will be enabled in step 4) + // b) else if it's not commented out, comment it out and add a new line with + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // 4) If the line doesn't exist (or case 3a), add + // assistive_technologies=com.sun.java.accessibility.AccessBridge + // Do the same for screen_magnifier_present= + char line[512]; + char commentLine[512] = "#"; + char jabLine[] = "assistive_technologies=com.sun.java.accessibility.AccessBridge\n"; + char magLine[] = "screen_magnifier_present=true\n"; + bool foundJabLine = false; + bool foundMagLine = false; + while (!feof(origFile)) { + if (fgets(line, 512, origFile) != NULL) { + if (_stricmp(line, "#assistive_technologies=com.sun.java.accessibility.AccessBridge\n") == 0) { + fputs(jabLine, tempFile); + foundJabLine = true; + } else if (_stricmp(line, jabLine) == 0) { + fputs(line, tempFile); + foundJabLine = true; + } else if (strstr(line, "assistive_technologies") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar == '#') { + fputs(line, tempFile); + } else { + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + fputs(jabLine, tempFile); + foundJabLine = true; + } + } else if (_stricmp(line, "#screen_magnifier_present=true\n") == 0) { + fputs(magLine, tempFile); + foundMagLine = true; + } else if (_stricmp(line, magLine) == 0) { + fputs(line, tempFile); + foundMagLine = true; + } else if (strstr(line, "screen_magnifier_present") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar == '#') { + fputs(line, tempFile); + } else { + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + fputs(magLine, tempFile); + foundMagLine = true; + } + } else { + fputs(line, tempFile); + } + } + } + if (!foundJabLine) { + fputs(jabLine, tempFile); + } + if (!foundMagLine) { + fputs(magLine, tempFile); + } +} + +void disableJAB() { + // Copy lines from orig to temp modifying the line containing + // assistive_technologies= + // There are various scenarios: + // 1) If the uncommented line exists, comment it out + // 2) If the line exists but is preceeded by a #, nothing to do + // 3) If the line doesn't exist, nothing to do + // Do the same for screen_magnifier_present= + char line[512]; + char commentLine[512]; + while (!feof(origFile)) { + if (fgets(line, 512, origFile) != NULL) { + if (strstr(line, "assistive_technologies") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar != '#') { + strcpy_s(commentLine, "#"); + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + } else { + fputs(line, tempFile); + } + } else if (strstr(line, "screen_magnifier_present") != NULL) { + char* context; + char* firstNonSpaceChar = strtok_s(line, " ", &context); + if (*firstNonSpaceChar != '#') { + strcpy_s(commentLine, "#"); + strcat_s(commentLine, line); + fputs(commentLine, tempFile); + } else { + fputs(line, tempFile); + } + } else { + fputs(line, tempFile); + } + } + } +} + +int modify(bool enable) { + errno_t error = 0; + char path[512]; + char tempPath[512]; + // Get the path for %USERPROFILE% + char *profilePath; + size_t len; + error = _dupenv_s(&profilePath, &len, "USERPROFILE" ); + if (error) { + printf("Error fetching USERPROFILE.\n"); + perror("Error"); + return error; + } + strcpy_s(path, profilePath); + strcat_s(path, "\\.accessibility.properties"); + strcpy_s(tempPath, profilePath); + strcat_s(tempPath, "\\.acce$$ibility.properties"); + free(profilePath); + // Open the original file. If it doesn't exist and this is an enable request then create it. + error = fopen_s(&origFile, path, "r"); + if (error) { + if (enable) { + error = fopen_s(&origFile, path, "w"); + if (error) { + printf("Couldn't create file: %s\n", path); + perror("Error"); + } else { + char str[100] = "assistive_technologies=com.sun.java.accessibility.AccessBridge\n"; + strcat_s(str, "screen_magnifier_present=true\n"); + fprintf(origFile, str); + fclose(origFile); + } + } else { + // It's OK if the file isn't there for a -disable + error = 0; + } + } else { + // open a temp file + error = fopen_s(&tempFile, tempPath, "w"); + if (error) { + printf("Couldn't open temp file: %s\n", tempPath); + perror("Error"); + return error; + } + if (enable) { + enableJAB(); + } else { + disableJAB(); + } + fclose(origFile); + fclose(tempFile); + // delete the orig file and rename the temp file + if (remove(path) != 0) { + printf("Couldn't remove file: %s\n", path); + perror("Error"); + return errno; + } + if (rename(tempPath, path) != 0) { + printf("Couldn't rename %s to %s.\n", tempPath, path); + perror("Error"); + return errno; + } + } + return error; +} + +void printUsage() { + printf("\njabswitch [/enable | /disable | /version | /?]\n\n"); + printf("Description:\n"); + printf(" jabswitch enables or disables the Java Access Bridge.\n\n"); + printf("Parameters:\n"); + printf(" /enable Enable the Java Accessibility Bridge.\n"); + printf(" /disable Disable the Java Accessibility Bridge.\n"); + printf(" /version Display the version.\n"); + printf(" /? Display this usage information.\n"); + printf("\nNote:\n"); + printf(" The Java Access Bridge can also be enabled with the\n"); + printf(" Windows Ease of Access control panel (which can be\n"); + printf(" activated by pressing Windows + U). The Ease of Access\n"); + printf(" control panel has a Java Access Bridge checkbox. Please\n"); + printf(" be aware that unchecking the checkbox has no effect and\n"); + printf(" in order to disable the Java Access Bridge you must run\n"); + printf(" jabswitch.exe from the command line.\n"); +} + +void printVersion() { + TCHAR executableFileName[_MAX_PATH]; + if (!GetModuleFileName(0, executableFileName, _MAX_PATH)) { + printf("Unable to get executable file name.\n"); + return; + } + DWORD nParam; + DWORD nVersionSize = GetFileVersionInfoSize(executableFileName, &nParam); + if (!nVersionSize) { + printf("Unable to get version info size.\n"); + return; + } + char* pVersionData = new char[nVersionSize]; + if (!GetFileVersionInfo(executableFileName, 0, nVersionSize, pVersionData)) { + printf("Unable to get version info.\n"); + return; + } + LPVOID pVersionInfo; + UINT nSize; + if (!VerQueryValue(pVersionData, _T("\\"), &pVersionInfo, &nSize)) { + printf("Unable to query version value.\n"); + return; + } + VS_FIXEDFILEINFO *pVSInfo = (VS_FIXEDFILEINFO *)pVersionInfo; + char versionString[100]; + sprintf_s( versionString, "version %i.%i.%i.%i", + pVSInfo->dwProductVersionMS >> 16, + pVSInfo->dwProductVersionMS & 0xFFFF, + pVSInfo->dwProductVersionLS >> 16, + pVSInfo->dwProductVersionLS & 0xFFFF ); + char outputString[100]; + strcpy_s(outputString, "jabswitch "); + strcat_s(outputString, versionString); + strcat_s(outputString, "\njabswitch enables or disables the Java Access Bridge.\n"); + printf(outputString); +} + +int regEnable() { + HKEY hKey; + DWORD retval = -1; + LSTATUS err; + err = RegOpenKeyEx(HKEY_CURRENT_USER, ACCESSIBILITY_USER_KEY, NULL, KEY_READ|KEY_WRITE, &hKey); + if (err == ERROR_SUCCESS) { + DWORD dataType = REG_SZ; + DWORD dataLength = DEFAULT_ALLOC; + TCHAR dataBuffer[DEFAULT_ALLOC]; + TCHAR *data = dataBuffer; + bool freeData = false; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + if (err == ERROR_MORE_DATA) { + if (dataLength > 0 && dataLength < MAX_ALLOC) { + data = new TCHAR[dataLength]; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + } + } + if (err == ERROR_SUCCESS) { + err = _tcslwr_s(dataBuffer, DEFAULT_ALLOC); + if (err) { + return -1; + } + if (_tcsstr(dataBuffer, STR_ACCESSBRIDGE) != NULL) { + return 0; // This is OK, e.g. ran enable twice and the value is there. + } else { + // add oracle_javaaccessbridge to Config key for HKCU + dataLength = dataLength + (_tcslen(STR_ACCESSBRIDGE) + 1) * sizeof(TCHAR); + TCHAR *newStr = new TCHAR[dataLength]; + if (newStr != NULL) { + wsprintf(newStr, L"%s,%s", dataBuffer, STR_ACCESSBRIDGE); + RegSetValueEx(hKey, ACCESSIBILITY_CONFIG, 0, REG_SZ, (BYTE *)newStr, dataLength); + } + } + } + RegCloseKey(hKey); + } + return err; +} + +int regDeleteValue(HKEY hFamilyKey, LPCWSTR lpSubKey) +{ + HKEY hKey; + DWORD retval = -1; + LSTATUS err; + err = RegOpenKeyEx(hFamilyKey, lpSubKey, NULL, KEY_READ|KEY_WRITE|KEY_WOW64_64KEY, &hKey); + if (err != ERROR_SUCCESS) + err = RegOpenKeyEx(hFamilyKey, lpSubKey, NULL, KEY_READ|KEY_WRITE, &hKey); + + if (err == ERROR_SUCCESS) { + DWORD dataType = REG_SZ; + DWORD dataLength = DEFAULT_ALLOC; + TCHAR dataBuffer[DEFAULT_ALLOC]; + TCHAR searchBuffer[DEFAULT_ALLOC]; + TCHAR *data = dataBuffer; + bool freeData = false; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + if (err == ERROR_MORE_DATA) { + if (dataLength > 0 && dataLength < MAX_ALLOC) { + data = new TCHAR[dataLength]; + err = RegQueryValueEx(hKey, ACCESSIBILITY_CONFIG, 0, &dataType, (BYTE *)data, &dataLength); + } + } + if (err == ERROR_SUCCESS) { + err = _tcslwr_s(dataBuffer, DEFAULT_ALLOC); + if (err) { + return -1; + } + if (_tcsstr(dataBuffer, STR_ACCESSBRIDGE) == NULL) { + return 0; // This is OK, e.g. ran disable twice and the value is not there. + } else { + // remove oracle_javaaccessbridge from Config key + TCHAR *newStr = new TCHAR[dataLength]; + TCHAR *nextToken; + LPTSTR tok, beg1 = dataBuffer; + bool first = true; + _tcscpy_s(newStr, dataLength, L""); + tok = _tcstok_s(beg1, L",", &nextToken); + while (tok != NULL) { + _tcscpy_s(searchBuffer, DEFAULT_ALLOC, tok); + err = _tcslwr_s(searchBuffer, DEFAULT_ALLOC); + if (err) { + return -1; + } + if (_tcsstr(searchBuffer, STR_ACCESSBRIDGE) == NULL) { + if (!first) { + _tcscat_s(newStr, dataLength, L","); + } + first = false; + _tcscat_s(newStr, dataLength, tok); + } + tok = _tcstok_s(NULL, L",", &nextToken); + } + dataLength = (_tcslen(newStr) + 1) * sizeof(TCHAR); + RegSetValueEx(hKey, ACCESSIBILITY_CONFIG, 0, REG_SZ, (BYTE *)newStr, dataLength); + } + } + RegCloseKey(hKey); + } + return err; +} + +int regDisable() +{ + LSTATUS err; + // Update value for HKCU + err=regDeleteValue(HKEY_CURRENT_USER, ACCESSIBILITY_USER_KEY); + // Update value for HKLM for Session + TCHAR dataBuffer[DEFAULT_ALLOC]; + DWORD dwSessionId ; + ProcessIdToSessionId(GetCurrentProcessId(),&dwSessionId ) ; + if( dwSessionId >= 0 ) + { + wsprintf(dataBuffer, L"%s%d", ACCESSIBILITY_SYSTEM_KEY, dwSessionId); + err=regDeleteValue(HKEY_LOCAL_MACHINE, dataBuffer); + } + return err; +} + +void main(int argc, char* argv[]) { + bool enableWasRequested = false; + bool disableWasRequested = false; + bool badParams = true; + int error = 0; + if (argc == 2) { + if (_stricmp(argv[1], "-?") == 0 || _stricmp(argv[1], "/?") == 0) { + printUsage(); + badParams = false; + } else if (_stricmp(argv[1], "-version") == 0 || _stricmp(argv[1], "/version") == 0) { + printVersion(); + badParams = false; + } else { + if (_stricmp(argv[1], "-enable") == 0 || _stricmp(argv[1], "/enable") == 0) { + badParams = false; + enableWasRequested = true; + error = modify(true); + if (error == 0) { + if( !isXP() ) + regEnable(); + } + } else if (_stricmp(argv[1], "-disable") == 0 || _stricmp(argv[1], "/disable") == 0) { + badParams = false; + disableWasRequested = true; + error = modify(false); + if (error == 0) { + if( !isXP() ) + regDisable(); + } + } + } + } + if (badParams) { + printUsage(); + } else if (enableWasRequested || disableWasRequested) { + if (error != 0) { + printf("There was an error.\n\n"); + } + printf("The Java Access Bridge has "); + if (error != 0) { + printf("not "); + } + printf("been "); + if (enableWasRequested) { + printf("enabled.\n"); + } else { + printf("disabled.\n"); + } + } +} diff --git a/jdk/src/jdk.accessibility/windows/native/jabswitch/jabswitch.manifest b/jdk/src/jdk.accessibility/windows/native/jabswitch/jabswitch.manifest new file mode 100644 index 00000000000..a43d11b21a0 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/jabswitch/jabswitch.manifest @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/jdk/src/jdk.accessibility/windows/native/libjabsysinfo/AccessBridgeSysInfo.cpp b/jdk/src/jdk.accessibility/windows/native/libjabsysinfo/AccessBridgeSysInfo.cpp new file mode 100644 index 00000000000..14e5ba47cc2 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjabsysinfo/AccessBridgeSysInfo.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include +#include +#include + +extern "C" { + +BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { + return TRUE; +} + +// Determine bitness of Win OS +JNIEXPORT jboolean JNICALL +Java_com_sun_java_accessibility_AccessBridge_isSysWow(JNIEnv *env, jobject callingObj) { + BOOL bIsWow64 = FALSE; + typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + + LPFN_ISWOW64PROCESS fnIsWow64Process = + (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + + if (fnIsWow64Process != NULL) { + if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) { + throw std::runtime_error("fnIsWow64Process() failed"); + } + } + + return bIsWow64 ? JNI_TRUE : JNI_FALSE; +} + +} diff --git a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeATInstance.cpp b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeATInstance.cpp new file mode 100644 index 00000000000..092c4a0b352 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeATInstance.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key AT instance info from the JavaAccessBridge + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeATInstance.h" +#include "AccessBridgeMessages.h" + +#include +#include + + +/** + * AccessBridgeATInstance constructor + */ +AccessBridgeATInstance::AccessBridgeATInstance(HWND ourABWindow, HWND winABWindow, + char *memoryFilename, + AccessBridgeATInstance *next) { + ourAccessBridgeWindow = ourABWindow; + winAccessBridgeWindow = winABWindow; + nextATInstance = next; + javaEventMask = 0; + accessibilityEventMask = 0; + strncpy(memoryMappedFileName, memoryFilename, cMemoryMappedNameSize); +} + +/** + * AccessBridgeATInstance descructor + */ +AccessBridgeATInstance::~AccessBridgeATInstance() { + PrintDebugString("\r\nin AccessBridgeATInstance::~AccessBridgeATInstance"); + + // if IPC memory mapped file view is valid, unmap it + if (memoryMappedView != (char *) 0) { + PrintDebugString(" unmapping memoryMappedView; view = %p", memoryMappedView); + UnmapViewOfFile(memoryMappedView); + memoryMappedView = (char *) 0; + } + // if IPC memory mapped file handle map is open, close it + if (memoryMappedFileMapHandle != (HANDLE) 0) { + PrintDebugString(" closing memoryMappedFileMapHandle; handle = %p", memoryMappedFileMapHandle); + CloseHandle(memoryMappedFileMapHandle); + memoryMappedFileMapHandle = (HANDLE) 0; + } +} + +/** + * Sets up the memory-mapped file to do IPC messaging + * 1 files is created: to handle requests for information + * initiated from Windows AT. The package is placed into + * the memory-mapped file (char *memoryMappedView), + * and then a special SendMessage() is sent. When the + * JavaDLL returns from SendMessage() processing, the + * data will be in memoryMappedView. The SendMessage() + * return value tells us if all is right with the world. + * + * The set-up proces involves creating the memory-mapped + * file, and writing a special string to it so that the + * WindowsDLL so it knows about it as well. + */ +LRESULT +AccessBridgeATInstance::initiateIPC() { + DWORD errorCode; + + PrintDebugString("\r\nin AccessBridgeATInstance::initiateIPC()"); + + // open Windows-initiated IPC filemap & map it to a ptr + + memoryMappedFileMapHandle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, + FALSE, memoryMappedFileName); + if (memoryMappedFileMapHandle == NULL) { + errorCode = GetLastError(); + PrintDebugString(" Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode); + return errorCode; + } else { + PrintDebugString(" CreateFileMapping worked - filename: %s", memoryMappedFileName); + } + + memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle, + FILE_MAP_READ | FILE_MAP_WRITE, + 0, 0, 0); + if (memoryMappedView == NULL) { + errorCode = GetLastError(); + PrintDebugString(" Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode); + return errorCode; + } else { + PrintDebugString(" MapViewOfFile worked - view: %p", memoryMappedView); + } + + + // look for the JavaDLL's answer to see if it could read the file + if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY) != 0) { + PrintDebugString(" JavaVM failed to write to memory mapped file %s", + memoryMappedFileName); + return -1; + } else { + PrintDebugString(" JavaVM successfully wrote to file!"); + } + + + // write some data to the memory mapped file for WindowsDLL to verify + strcpy(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_ANSWER); + + + return 0; +} + + +typedef struct EVENT_STRUCT +{ + char *buffer; + int bufsize; + ABHWND64 winAccessBridgeWindow; + ABHWND64 ourAccessBridgeWindow; +}EVENT_STRUCT; + + +#include +#define THREAD_PROC unsigned int __stdcall +typedef unsigned int (__stdcall *THREAD_ROUTINE)(LPVOID lpThreadParameter); + +static HANDLE BeginThread(THREAD_ROUTINE thread_func,DWORD *id,DWORD param) +{ + HANDLE ret; + ret = (HANDLE) _beginthreadex(NULL,0,thread_func,(void *)param,0,(unsigned int *)id); + if(ret == INVALID_HANDLE_VALUE) + ret = NULL; + return(ret); +} + +DWORD JavaBridgeThreadId = 0; + +static THREAD_PROC JavaBridgeThread(LPVOID param1) +{ + MSG msg; + DWORD rc = 0; + while (GetMessage(&msg, // message structure + NULL, // handle of window receiving the message + 0, // lowest message to examine + 0)) // highest message to examine + { + if(msg.message == WM_USER) + { + EVENT_STRUCT *event_struct = (EVENT_STRUCT *)msg.wParam; + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = event_struct->bufsize; + toCopy.lpData = event_struct->buffer; + + LRESULT ret = SendMessage((HWND)ABLongToHandle(event_struct->winAccessBridgeWindow), WM_COPYDATA, + (WPARAM)event_struct->ourAccessBridgeWindow, (LPARAM) &toCopy); + delete event_struct->buffer; + delete event_struct; + } + if(msg.message == (WM_USER+1)) + PostQuitMessage(0); + } + JavaBridgeThreadId = 0; + return(0); +} + +/* + * Handles one event + */ +static void do_event(char *buffer, int bufsize,HWND ourAccessBridgeWindow,HWND winAccessBridgeWindow) +{ + EVENT_STRUCT *event_struct = new EVENT_STRUCT; + event_struct->bufsize = bufsize; + event_struct->buffer = new char[bufsize]; + memcpy(event_struct->buffer,buffer,bufsize); + event_struct->ourAccessBridgeWindow = ABHandleToLong(ourAccessBridgeWindow); + event_struct->winAccessBridgeWindow = ABHandleToLong(winAccessBridgeWindow); + if(!JavaBridgeThreadId) + { + HANDLE JavaBridgeThreadHandle = BeginThread(JavaBridgeThread,&JavaBridgeThreadId,(DWORD)event_struct); + CloseHandle(JavaBridgeThreadHandle); + } + PostThreadMessage(JavaBridgeThreadId,WM_USER,(WPARAM)event_struct,0); +} + + +/** + * sendJavaEventPackage - uses SendMessage(WM_COPYDATA) to do + * IPC messaging with the Java AccessBridge DLL + * to propogate events to those ATs that want 'em + * + */ +LRESULT +AccessBridgeATInstance::sendJavaEventPackage(char *buffer, int bufsize, long eventID) { + + PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() eventID = %X", eventID); + PrintDebugString("AccessBridgeATInstance::sendJavaEventPackage() (using PostMessage) eventID = %X", eventID); + + if (eventID & javaEventMask) { + do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow); + return(0); + } else { + return -1; + } +} + + +/** + * uses SendMessage(WM_COPYDATA) to do + * IPC messaging with the Java AccessBridge DLL + * to propogate events to those ATs that want 'em + * + */ +LRESULT +AccessBridgeATInstance::sendAccessibilityEventPackage(char *buffer, int bufsize, long eventID) { + + PrintDebugString("AccessBridgeATInstance::sendAccessibilityEventPackage() eventID = %X", eventID); + + if (eventID & accessibilityEventMask) { + do_event(buffer,bufsize,ourAccessBridgeWindow,winAccessBridgeWindow); + return(0); + } else { + return -1; + } +} + + +/** + * findABATInstanceFromATHWND - walk through linked list from + * where we are. Return the + * AccessBridgeATInstance + * of the ABATInstance that + * matches the passed in vmID; + * no match: return 0 + */ +AccessBridgeATInstance * +AccessBridgeATInstance::findABATInstanceFromATHWND(HWND window) { + // no need to recurse really + if (winAccessBridgeWindow == window) { + return this; + } else { + AccessBridgeATInstance *current = nextATInstance; + while (current != (AccessBridgeATInstance *) 0) { + if (current->winAccessBridgeWindow == window) { + return current; + } + current = current->nextATInstance; + } + } + return (AccessBridgeATInstance *) 0; +} diff --git a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeATInstance.h b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeATInstance.h new file mode 100644 index 00000000000..0bd5930eb1a --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeATInstance.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key AT instance info from the JavaAccessBridge + */ + +#include +#include "AccessBridgePackages.h" + +#ifndef __AccessBridgeATInstance_H__ +#define __AccessBridgeATInstance_H__ + + +/** + * The AccessBridgeATInstance class. + */ +class AccessBridgeATInstance { + friend class JavaAccessBridge; + + AccessBridgeATInstance *nextATInstance; + HWND ourAccessBridgeWindow; + HWND winAccessBridgeWindow; + long javaEventMask; + long accessibilityEventMask; + + // IPC variables + HANDLE memoryMappedFileMapHandle; // handle to file map + char *memoryMappedView; // ptr to shared memory + char memoryMappedFileName[cMemoryMappedNameSize]; + +public: + AccessBridgeATInstance(HWND ourABWindow, HWND winABWindow, + char *memoryFilename, + AccessBridgeATInstance *next); + ~AccessBridgeATInstance(); + LRESULT initiateIPC(); + LRESULT sendJavaEventPackage(char *buffer, int bufsize, long eventID); + LRESULT sendAccessibilityEventPackage(char *buffer, int bufsize, long eventID); + AccessBridgeATInstance *findABATInstanceFromATHWND(HWND window); +}; + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp new file mode 100644 index 00000000000..952df4f8c55 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp @@ -0,0 +1,4787 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage JNI calls into AccessBridge.java + */ + +#include "AccessBridgeJavaEntryPoints.h" +#include "AccessBridgeDebug.h" + + + +/** + * Initialize the AccessBridgeJavaEntryPoints class + * + */ +AccessBridgeJavaEntryPoints::AccessBridgeJavaEntryPoints(JNIEnv *jniEnvironment, + jobject bridgeObject) { + jniEnv = jniEnvironment; + accessBridgeObject = (jobject)bridgeObject; + PrintDebugString("AccessBridgeJavaEntryPoints(%X, %X) called", jniEnv, accessBridgeObject); +} + + +/** + * Destructor + * + */ +AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() { +} + +// ----------------------------------- + +#define FIND_CLASS(classRef, className) \ + localClassRef = jniEnv->FindClass(className); \ + if (localClassRef == (jclass) 0) { \ + PrintDebugString(" Error! FindClass(%s) failed!", className); \ + PrintDebugString(" -> jniEnv = %p", jniEnv); \ + return FALSE; \ + } \ + classRef = (jclass) jniEnv->NewGlobalRef(localClassRef); \ + jniEnv->DeleteLocalRef(localClassRef); \ + if (classRef == (jclass) 0) { \ + PrintDebugString(" Error! FindClass(%s) failed!", className); \ + PrintDebugString(" -> (ran out of RAM)"); \ + return FALSE; \ + } + + +#define FIND_METHOD(methodID, classRef, methodString, methodSignature); \ + methodID = jniEnv->GetMethodID(classRef, methodString, methodSignature); \ + if (methodID == (jmethodID) 0) { \ + PrintDebugString(" Error! GetMethodID(%s) failed!", methodString); \ + PrintDebugString(" -> jniEnv = %p; classRef = %p", jniEnv, classRef); \ + return FALSE; \ + } + +#define EXCEPTION_CHECK(situationDescription, returnVal) \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("\r\n *** Exception occured while doing: %s; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return (returnVal); \ + } + +#define EXCEPTION_CHECK_VOID(situationDescription) \ + if (exception = jniEnv->ExceptionOccurred()) { \ + PrintDebugString("\r\n *** Exception occured while doing: %s", situationDescription); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return; \ + } + +/** + * Make all of the getClass() & getMethod() calls + * + */ +BOOL +AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() { + jclass localClassRef; + + PrintDebugString("Calling BuildJavaEntryPoints():"); + + FIND_CLASS(bridgeClass, "com/sun/java/accessibility/AccessBridge"); + + // ------- general methods + + // GetMethodID(decrementReference) + FIND_METHOD(decrementReferenceMethod, bridgeClass, + "decrementReference", + "(Ljava/lang/Object;)V"); + + // GetMethodID(getJavaVersionPropertyMethod) + FIND_METHOD(getJavaVersionPropertyMethod, bridgeClass, + "getJavaVersionProperty", + "()Ljava/lang/String;"); + + // ------- Window methods + + // GetMethodID(isJavaWindow) + FIND_METHOD(isJavaWindowMethod, bridgeClass, + "isJavaWindow", + "(I)Z"); + + // GetMethodID(getAccessibleContextFromHWND) + FIND_METHOD(getAccessibleContextFromHWNDMethod, bridgeClass, + "getContextFromNativeWindowHandle", + "(I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getHWNDFromAccessibleContext) + FIND_METHOD(getHWNDFromAccessibleContextMethod, bridgeClass, + "getNativeWindowHandleFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleParentFromContext) + FIND_METHOD(getAccessibleParentFromContextMethod, bridgeClass, + "getAccessibleParentFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // ===== utility methods ===== */ + + // GetMethodID(setTextContents) + FIND_METHOD(setTextContentsMethod, bridgeClass, + "setTextContents", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Z"); + + // GetMethodID(getParentWithRole) + FIND_METHOD(getParentWithRoleMethod, bridgeClass, + "getParentWithRole", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getTopLevelObject) + FIND_METHOD(getTopLevelObjectMethod, bridgeClass, + "getTopLevelObject", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getParentWithRoleElseRoot) + FIND_METHOD(getParentWithRoleElseRootMethod, bridgeClass, + "getParentWithRoleElseRoot", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getObjectDepth) + FIND_METHOD(getObjectDepthMethod, bridgeClass, + "getObjectDepth", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getActiveDescendent) + FIND_METHOD(getActiveDescendentMethod, bridgeClass, + "getActiveDescendent", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // ------- AccessibleContext methods + + // GetMethodID(getAccessibleContextAt) + FIND_METHOD(getAccessibleContextAtMethod, bridgeClass, + "getAccessibleContextAt", + "(IILjavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleContextWithFocus) + FIND_METHOD(getAccessibleContextWithFocusMethod, bridgeClass, + "getAccessibleContextWithFocus", + "()Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleNameFromContext) + FIND_METHOD(getAccessibleNameFromContextMethod, bridgeClass, + "getAccessibleNameFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleDescriptionFromContext) + FIND_METHOD(getAccessibleDescriptionFromContextMethod, bridgeClass, + "getAccessibleDescriptionFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleRoleStringFromContext) + FIND_METHOD(getAccessibleRoleStringFromContextMethod, bridgeClass, + "getAccessibleRoleStringFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleRoleStringFromContext_en_US) + FIND_METHOD(getAccessibleRoleStringFromContext_en_USMethod, bridgeClass, + "getAccessibleRoleStringFromContext_en_US", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleStatesStringFromContext) + FIND_METHOD(getAccessibleStatesStringFromContextMethod, bridgeClass, + "getAccessibleStatesStringFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleStatesStringFromContext_en_US) + FIND_METHOD(getAccessibleStatesStringFromContext_en_USMethod, bridgeClass, + "getAccessibleStatesStringFromContext_en_US", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleParentFromContext) + FIND_METHOD(getAccessibleParentFromContextMethod, bridgeClass, + "getAccessibleParentFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleIndexInParentFromContext) + FIND_METHOD(getAccessibleIndexInParentFromContextMethod, bridgeClass, + "getAccessibleIndexInParentFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleChildrenCountFromContext) + FIND_METHOD(getAccessibleChildrenCountFromContextMethod, bridgeClass, + "getAccessibleChildrenCountFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleChildFromContext) + FIND_METHOD(getAccessibleChildFromContextMethod, bridgeClass, + "getAccessibleChildFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleBoundsOnScreenFromContext) + FIND_METHOD(getAccessibleBoundsOnScreenFromContextMethod, bridgeClass, + "getAccessibleBoundsOnScreenFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/awt/Rectangle;"); + + // GetMethodID(getAccessibleXcoordFromContext) + FIND_METHOD(getAccessibleXcoordFromContextMethod, bridgeClass, + "getAccessibleXcoordFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleYcoordFromContext) + FIND_METHOD(getAccessibleYcoordFromContextMethod, bridgeClass, + "getAccessibleYcoordFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleHeightFromContext) + FIND_METHOD(getAccessibleHeightFromContextMethod, bridgeClass, + "getAccessibleHeightFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleWidthFromContext) + FIND_METHOD(getAccessibleWidthFromContextMethod, bridgeClass, + "getAccessibleWidthFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleComponentFromContext) + FIND_METHOD(getAccessibleComponentFromContextMethod, bridgeClass, + "getAccessibleComponentFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleComponent;"); + + // GetMethodID(getAccessibleActionFromContext) + FIND_METHOD(getAccessibleActionFromContextMethod, bridgeClass, + "getAccessibleActionFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleAction;"); + + // GetMethodID(getAccessibleSelectionFromContext) + FIND_METHOD(getAccessibleSelectionFromContextMethod, bridgeClass, + "getAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleSelection;"); + + // GetMethodID(getAccessibleTextFromContext) + FIND_METHOD(getAccessibleTextFromContextMethod, bridgeClass, + "getAccessibleTextFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleText;"); + + // GetMethodID(getAccessibleValueFromContext) + FIND_METHOD(getAccessibleValueFromContextMethod, bridgeClass, + "getAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleValue;"); + + + // ------- begin AccessibleTable methods + + // GetMethodID(getAccessibleTableFromContext) + FIND_METHOD(getAccessibleTableFromContextMethod, bridgeClass, + "getAccessibleTableFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;"); + + // GetMethodID(getContextFromAccessibleTable) + FIND_METHOD(getContextFromAccessibleTableMethod, bridgeClass, + "getContextFromAccessibleTable", + "(Ljavax/accessibility/AccessibleTable;)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableRowHeader) + FIND_METHOD(getAccessibleTableRowHeaderMethod, bridgeClass, + "getAccessibleTableRowHeader", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;"); + + + // GetMethodID(getAccessibleTableColumnHeader) + FIND_METHOD(getAccessibleTableColumnHeaderMethod, bridgeClass, + "getAccessibleTableColumnHeader", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleTable;"); + + + // GetMethodID(getAccessibleTableRowCount) + FIND_METHOD(getAccessibleTableRowCountMethod, bridgeClass, + "getAccessibleTableRowCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableColumnCount) + FIND_METHOD(getAccessibleTableColumnCountMethod, bridgeClass, + "getAccessibleTableColumnCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableCellAccessibleContext) + FIND_METHOD(getAccessibleTableCellAccessibleContextMethod, bridgeClass, + "getAccessibleTableCellAccessibleContext", + "(Ljavax/accessibility/AccessibleTable;II)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableCellIndex) + FIND_METHOD(getAccessibleTableCellIndexMethod, bridgeClass, + "getAccessibleTableCellIndex", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + // GetMethodID(getAccessibleTableCellRowExtent) + FIND_METHOD(getAccessibleTableCellRowExtentMethod, bridgeClass, + "getAccessibleTableCellRowExtent", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + // GetMethodID(getAccessibleTableCellColumnExtent) + FIND_METHOD(getAccessibleTableCellColumnExtentMethod, bridgeClass, + "getAccessibleTableCellColumnExtent", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + // GetMethodID(isAccessibleTableCellSelected) + FIND_METHOD(isAccessibleTableCellSelectedMethod, bridgeClass, + "isAccessibleTableCellSelected", + "(Ljavax/accessibility/AccessibleTable;II)Z"); + + // GetMethodID(getAccessibleTableRowHeaderRowCount) + FIND_METHOD(getAccessibleTableRowHeaderRowCountMethod, bridgeClass, + "getAccessibleTableRowHeaderRowCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableColumnHeaderRowCount) + FIND_METHOD(getAccessibleTableColumnHeaderRowCountMethod, bridgeClass, + "getAccessibleTableColumnHeaderRowCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableRowHeaderColumnCount) + FIND_METHOD(getAccessibleTableRowHeaderColumnCountMethod, bridgeClass, + "getAccessibleTableRowHeaderColumnCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableColumnHeaderColumnCount) + FIND_METHOD(getAccessibleTableColumnHeaderColumnCountMethod, bridgeClass, + "getAccessibleTableColumnHeaderColumnCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTableRowDescription) + FIND_METHOD(getAccessibleTableRowDescriptionMethod, bridgeClass, + "getAccessibleTableRowDescription", + "(Ljavax/accessibility/AccessibleTable;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableColumnDescription) + FIND_METHOD(getAccessibleTableColumnDescriptionMethod, bridgeClass, + "getAccessibleTableColumnDescription", + "(Ljavax/accessibility/AccessibleTable;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleTableRowSelectionCount) + FIND_METHOD(getAccessibleTableRowSelectionCountMethod, bridgeClass, + "getAccessibleTableRowSelectionCount", + "(Ljavax/accessibility/AccessibleTable;)I"); + + // GetMethodID(isAccessibleTableRowSelected) + FIND_METHOD(isAccessibleTableRowSelectedMethod, bridgeClass, + "isAccessibleTableRowSelected", + "(Ljavax/accessibility/AccessibleTable;I)Z"); + + // GetMethodID(getAccessibleTableRowSelections) + FIND_METHOD(getAccessibleTableRowSelectionsMethod, bridgeClass, + "getAccessibleTableRowSelections", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableColumnSelectionCount) + FIND_METHOD(getAccessibleTableColumnSelectionCountMethod, bridgeClass, + "getAccessibleTableColumnSelectionCount", + "(Ljavax/accessibility/AccessibleTable;)I"); + + // GetMethodID(isAccessibleTableColumnSelected) + FIND_METHOD(isAccessibleTableColumnSelectedMethod, bridgeClass, + "isAccessibleTableColumnSelected", + "(Ljavax/accessibility/AccessibleTable;I)Z"); + + // GetMethodID(getAccessibleTableColumnSelections) + FIND_METHOD(getAccessibleTableColumnSelectionsMethod, bridgeClass, + "getAccessibleTableColumnSelections", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableRow) + FIND_METHOD(getAccessibleTableRowMethod, bridgeClass, + "getAccessibleTableRow", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableColumn) + FIND_METHOD(getAccessibleTableColumnMethod, bridgeClass, + "getAccessibleTableColumn", + "(Ljavax/accessibility/AccessibleTable;I)I"); + + // GetMethodID(getAccessibleTableIndex) + FIND_METHOD(getAccessibleTableIndexMethod, bridgeClass, + "getAccessibleTableIndex", + "(Ljavax/accessibility/AccessibleTable;II)I"); + + /* ------- end AccessibleTable methods */ + + /* start AccessibleRelationSet methods ----- */ + + // GetMethodID(getAccessibleRelationCount) + FIND_METHOD(getAccessibleRelationCountMethod, bridgeClass, + "getAccessibleRelationCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleRelationKey) + FIND_METHOD(getAccessibleRelationKeyMethod, bridgeClass, + "getAccessibleRelationKey", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleRelationTargetCount) + FIND_METHOD(getAccessibleRelationTargetCountMethod, bridgeClass, + "getAccessibleRelationTargetCount", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleRelationTarget) + FIND_METHOD(getAccessibleRelationTargetMethod, bridgeClass, + "getAccessibleRelationTarget", + "(Ljavax/accessibility/AccessibleContext;II)Ljavax/accessibility/AccessibleContext;"); + + + // ------- AccessibleHypertext methods + + // GetMethodID(getAccessibleHypertext) + FIND_METHOD(getAccessibleHypertextMethod, bridgeClass, + "getAccessibleHypertext", + "(Ljavax/accessibility/AccessibleContext;)Ljavax/accessibility/AccessibleHypertext;"); + + // GetMethodID(activateAccessibleHyperlink) + FIND_METHOD(activateAccessibleHyperlinkMethod, bridgeClass, + "activateAccessibleHyperlink", + "(Ljavax/accessibility/AccessibleContext;Ljavax/accessibility/AccessibleHyperlink;)Z"); + + // GetMethodID(getAccessibleHyperlinkCount) + FIND_METHOD(getAccessibleHyperlinkCountMethod, bridgeClass, + "getAccessibleHyperlinkCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleHyperlink) + FIND_METHOD(getAccessibleHyperlinkMethod, bridgeClass, + "getAccessibleHyperlink", + "(Ljavax/accessibility/AccessibleHypertext;I)Ljavax/accessibility/AccessibleHyperlink;"); + + // GetMethodID(getAccessibleHyperlinkText) + FIND_METHOD(getAccessibleHyperlinkTextMethod, bridgeClass, + "getAccessibleHyperlinkText", + "(Ljavax/accessibility/AccessibleHyperlink;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleHyperlinkURL) + FIND_METHOD(getAccessibleHyperlinkURLMethod, bridgeClass, + "getAccessibleHyperlinkURL", + "(Ljavax/accessibility/AccessibleHyperlink;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleHyperlinkStartIndex) + FIND_METHOD(getAccessibleHyperlinkStartIndexMethod, bridgeClass, + "getAccessibleHyperlinkStartIndex", + "(Ljavax/accessibility/AccessibleHyperlink;)I"); + + // GetMethodID(getAccessibleHyperlinkEndIndex) + FIND_METHOD(getAccessibleHyperlinkEndIndexMethod, bridgeClass, + "getAccessibleHyperlinkEndIndex", + "(Ljavax/accessibility/AccessibleHyperlink;)I"); + + // GetMethodID(getAccessibleHypertextLinkIndex) + FIND_METHOD(getAccessibleHypertextLinkIndexMethod, bridgeClass, + "getAccessibleHypertextLinkIndex", + "(Ljavax/accessibility/AccessibleHypertext;I)I"); + + // Accessible KeyBinding, Icon and Action ==================== + + // GetMethodID(getAccessibleKeyBindingsCount) + FIND_METHOD(getAccessibleKeyBindingsCountMethod, bridgeClass, + "getAccessibleKeyBindingsCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleKeyBindingChar) + FIND_METHOD(getAccessibleKeyBindingCharMethod, bridgeClass, + "getAccessibleKeyBindingChar", + "(Ljavax/accessibility/AccessibleContext;I)C"); + + // GetMethodID(getAccessibleKeyBindingModifiers) + FIND_METHOD(getAccessibleKeyBindingModifiersMethod, bridgeClass, + "getAccessibleKeyBindingModifiers", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleIconsCount) + FIND_METHOD(getAccessibleIconsCountMethod, bridgeClass, + "getAccessibleIconsCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleIconDescription) + FIND_METHOD(getAccessibleIconDescriptionMethod, bridgeClass, + "getAccessibleIconDescription", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleIconHeight) + FIND_METHOD(getAccessibleIconHeightMethod, bridgeClass, + "getAccessibleIconHeight", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleIconWidth) + FIND_METHOD(getAccessibleIconWidthMethod, bridgeClass, + "getAccessibleIconWidth", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleActionsCount) + FIND_METHOD(getAccessibleActionsCountMethod, bridgeClass, + "getAccessibleActionsCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleActionName) + FIND_METHOD(getAccessibleActionNameMethod, bridgeClass, + "getAccessibleActionName", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(doAccessibleActions) + FIND_METHOD(doAccessibleActionsMethod, bridgeClass, + "doAccessibleActions", + "(Ljavax/accessibility/AccessibleContext;Ljava/lang/String;)Z"); + + // ------- AccessibleText methods + + // GetMethodID(getAccessibleCharCountFromContext) + FIND_METHOD(getAccessibleCharCountFromContextMethod, bridgeClass, + "getAccessibleCharCountFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleCaretPositionFromContext) + FIND_METHOD(getAccessibleCaretPositionFromContextMethod, bridgeClass, + "getAccessibleCaretPositionFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleIndexAtPointFromContext) + FIND_METHOD(getAccessibleIndexAtPointFromContextMethod, bridgeClass, + "getAccessibleIndexAtPointFromContext", + "(Ljavax/accessibility/AccessibleContext;II)I"); + + // GetMethodID(getAccessibleLetterAtIndexFromContext) + FIND_METHOD(getAccessibleLetterAtIndexFromContextMethod, bridgeClass, + "getAccessibleLetterAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleWordAtIndexFromContext) + FIND_METHOD(getAccessibleWordAtIndexFromContextMethod, bridgeClass, + "getAccessibleWordAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleSentenceAtIndexFromContext) + FIND_METHOD(getAccessibleSentenceAtIndexFromContextMethod, bridgeClass, + "getAccessibleSentenceAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleTextSelectionStartFromContext) + FIND_METHOD(getAccessibleTextSelectionStartFromContextMethod, bridgeClass, + "getAccessibleTextSelectionStartFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTextSelectionEndFromContext) + FIND_METHOD(getAccessibleTextSelectionEndFromContextMethod, bridgeClass, + "getAccessibleTextSelectionEndFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getAccessibleTextSelectedTextFromContext) + FIND_METHOD(getAccessibleTextSelectedTextFromContextMethod, bridgeClass, + "getAccessibleTextSelectedTextFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getAccessibleAttributesAtIndexFromContext) + FIND_METHOD(getAccessibleAttributesAtIndexFromContextMethod, bridgeClass, + "getAccessibleAttributesAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/lang/String;"); + + // GetMethodID(getAccessibleAttributeSetAtIndexFromContext) + FIND_METHOD(getAccessibleAttributeSetAtIndexFromContextMethod, bridgeClass, + "getAccessibleAttributeSetAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/swing/text/AttributeSet;"); + + // GetMethodID(getAccessibleTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljava/awt/Rectangle;"); + + // GetMethodID(getAccessibleXcoordTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleXcoordTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleXcoordTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleYcoordTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleYcoordTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleYcoordTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleHeightTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleHeightTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleHeightTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleWidthTextRectAtIndexFromContext) + FIND_METHOD(getAccessibleWidthTextRectAtIndexFromContextMethod, bridgeClass, + "getAccessibleWidthTextRectAtIndexFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getCaretLocationX) + FIND_METHOD(getCaretLocationXMethod, bridgeClass, + "getCaretLocationX", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getCaretLocationY) + FIND_METHOD(getCaretLocationYMethod, bridgeClass, + "getCaretLocationY", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getCaretLocationHeight) + FIND_METHOD(getCaretLocationHeightMethod, bridgeClass, + "getCaretLocationHeight", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getCaretLocationWidth) + FIND_METHOD(getCaretLocationWidthMethod, bridgeClass, + "getCaretLocationWidth", + "(Ljavax/accessibility/AccessibleContext;)I"); + + + // GetMethodID(getAccessibleTextLineLeftBoundsFromContextMethod) + FIND_METHOD(getAccessibleTextLineLeftBoundsFromContextMethod, bridgeClass, + "getAccessibleTextLineLeftBoundsFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleTextLineRightBoundsFromContextMethod) + FIND_METHOD(getAccessibleTextLineRightBoundsFromContextMethod, bridgeClass, + "getAccessibleTextLineRightBoundsFromContext", + "(Ljavax/accessibility/AccessibleContext;I)I"); + + // GetMethodID(getAccessibleTextRangeFromContextMethod) + FIND_METHOD(getAccessibleTextRangeFromContextMethod, bridgeClass, + "getAccessibleTextRangeFromContext", + "(Ljavax/accessibility/AccessibleContext;II)Ljava/lang/String;"); + + + // ------- AccessibleValue methods + + // GetMethodID(getCurrentAccessibleValueFromContext) + FIND_METHOD(getCurrentAccessibleValueFromContextMethod, bridgeClass, + "getCurrentAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getMaximumAccessibleValueFromContext) + FIND_METHOD(getMaximumAccessibleValueFromContextMethod, bridgeClass, + "getMaximumAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + // GetMethodID(getMinimumAccessibleValueFromContext) + FIND_METHOD(getMinimumAccessibleValueFromContextMethod, bridgeClass, + "getMinimumAccessibleValueFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + + // ------- AccessibleSelection methods + + // GetMethodID(addAccessibleSelectionFromContext) + FIND_METHOD(addAccessibleSelectionFromContextMethod, bridgeClass, + "addAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;I)V"); + + // GetMethodID(clearAccessibleSelectionFromContext) + FIND_METHOD(clearAccessibleSelectionFromContextMethod, bridgeClass, + "clearAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;)V"); + + // GetMethodID(getAccessibleSelectionFromContext) + FIND_METHOD(getAccessibleSelectionContextFromContextMethod, bridgeClass, + "getAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(getAccessibleSelectionCountFromContext) + FIND_METHOD(getAccessibleSelectionCountFromContextMethod, bridgeClass, + "getAccessibleSelectionCountFromContext", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(isAccessibleChildSelectedFromContext) + FIND_METHOD(isAccessibleChildSelectedFromContextMethod, bridgeClass, + "isAccessibleChildSelectedFromContext", + "(Ljavax/accessibility/AccessibleContext;I)Z"); + + // GetMethodID(removeAccessibleSelectionFromContext) + FIND_METHOD(removeAccessibleSelectionFromContextMethod, bridgeClass, + "removeAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;I)V"); + + // GetMethodID(selectAllAccessibleSelectionFromContext) + FIND_METHOD(selectAllAccessibleSelectionFromContextMethod, bridgeClass, + "selectAllAccessibleSelectionFromContext", + "(Ljavax/accessibility/AccessibleContext;)V"); + + + // ------- Event Notification methods + + // GetMethodID(addJavaEventNotification) + FIND_METHOD(addJavaEventNotificationMethod, bridgeClass, + "addJavaEventNotification", "(J)V"); + + // GetMethodID(removeJavaEventNotification) + FIND_METHOD(removeJavaEventNotificationMethod, bridgeClass, + "removeJavaEventNotification", "(J)V"); + + // GetMethodID(addAccessibilityEventNotification) + FIND_METHOD(addAccessibilityEventNotificationMethod, bridgeClass, + "addAccessibilityEventNotification", "(J)V"); + + // GetMethodID(removeAccessibilityEventNotification) + FIND_METHOD(removeAccessibilityEventNotificationMethod, bridgeClass, + "removeAccessibilityEventNotification", "(J)V"); + + + // ------- AttributeSet methods + + // GetMethodID(getBoldFromAttributeSet) + FIND_METHOD(getBoldFromAttributeSetMethod, bridgeClass, + "getBoldFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getItalicFromAttributeSet) + FIND_METHOD(getItalicFromAttributeSetMethod, bridgeClass, + "getItalicFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getUnderlineFromAttributeSet) + FIND_METHOD(getUnderlineFromAttributeSetMethod, bridgeClass, + "getUnderlineFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getStrikethroughFromAttributeSet) + FIND_METHOD(getStrikethroughFromAttributeSetMethod, bridgeClass, + "getStrikethroughFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getSuperscriptFromAttributeSet) + FIND_METHOD(getSuperscriptFromAttributeSetMethod, bridgeClass, + "getSuperscriptFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getSubscriptFromAttributeSet) + FIND_METHOD(getSubscriptFromAttributeSetMethod, bridgeClass, + "getSubscriptFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Z"); + + // GetMethodID(getBackgroundColorFromAttributeSet) + FIND_METHOD(getBackgroundColorFromAttributeSetMethod, bridgeClass, + "getBackgroundColorFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;"); + + // GetMethodID(getForegroundColorFromAttributeSet) + FIND_METHOD(getForegroundColorFromAttributeSetMethod, bridgeClass, + "getForegroundColorFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;"); + + // GetMethodID(getFontFamilyFromAttributeSet) + FIND_METHOD(getFontFamilyFromAttributeSetMethod, bridgeClass, + "getFontFamilyFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)Ljava/lang/String;"); + + // GetMethodID(getFontSizeFromAttributeSet) + FIND_METHOD(getFontSizeFromAttributeSetMethod, bridgeClass, + "getFontSizeFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I"); + + // GetMethodID(getAlignmentFromAttributeSet) + FIND_METHOD(getAlignmentFromAttributeSetMethod, bridgeClass, + "getAlignmentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I"); + + // GetMethodID(getBidiLevelFromAttributeSet) + FIND_METHOD(getBidiLevelFromAttributeSetMethod, bridgeClass, + "getBidiLevelFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)I"); + + // GetMethodID(getFirstLineIndentFromAttributeSet) + FIND_METHOD(getFirstLineIndentFromAttributeSetMethod, bridgeClass, + "getFirstLineIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getLeftIndentFromAttributeSet) + FIND_METHOD(getLeftIndentFromAttributeSetMethod, bridgeClass, + "getLeftIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getRightIndentFromAttributeSet) + FIND_METHOD(getRightIndentFromAttributeSetMethod, bridgeClass, + "getRightIndentFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getLineSpacingFromAttributeSet) + FIND_METHOD(getLineSpacingFromAttributeSetMethod, bridgeClass, + "getLineSpacingFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getSpaceAboveFromAttributeSet) + FIND_METHOD(getSpaceAboveFromAttributeSetMethod, bridgeClass, + "getSpaceAboveFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + // GetMethodID(getSpaceBelowFromAttributeSet) + FIND_METHOD(getSpaceBelowFromAttributeSetMethod, bridgeClass, + "getSpaceBelowFromAttributeSet", "(Ljavax/swing/text/AttributeSet;)F"); + + + /** + * Additional methods for Teton + */ + + // GetMethodID(requestFocus) + FIND_METHOD(requestFocusMethod, bridgeClass, + "requestFocus", + "(Ljavax/accessibility/AccessibleContext;)Z"); + + // GetMethodID(selectTextRange) + FIND_METHOD(selectTextRangeMethod, bridgeClass, + "selectTextRange", + "(Ljavax/accessibility/AccessibleContext;II)Z"); + + // GetMethodID(getVisibleChildrenCount) + FIND_METHOD(getVisibleChildrenCountMethod, bridgeClass, + "getVisibleChildrenCount", + "(Ljavax/accessibility/AccessibleContext;)I"); + + // GetMethodID(getVisibleChild) + FIND_METHOD(getVisibleChildMethod, bridgeClass, + "getVisibleChild", + "(Ljavax/accessibility/AccessibleContext;I)Ljavax/accessibility/AccessibleContext;"); + + // GetMethodID(setCaretPosition) + FIND_METHOD(setCaretPositionMethod, bridgeClass, + "setCaretPosition", + "(Ljavax/accessibility/AccessibleContext;I)Z"); + + // GetMethodID(getVirtualAccessibleNameFromContextMethod) Ben Key + FIND_METHOD(getVirtualAccessibleNameFromContextMethod, bridgeClass, + "getVirtualAccessibleNameFromContext", + "(Ljavax/accessibility/AccessibleContext;)Ljava/lang/String;"); + + return TRUE; +} + +// Note for the following code which makes JNI upcalls... +// +// Problem, bug DB 16818166, JBS DB JDK-8015400 +// AccessibleContext is a JOBJECT64 which is a jobject (32 bit pointer) +// for a Legacy (XP) build and a jlong (64 bits) for a -32 or -64 build. +// For the -32 build the lower 32 bits needs to be extracted into a jobject. +// Otherwise, if AccessibleContext is used directly what happens is that +// the JNI code consumes the lower 32 of its 64 bits and that is not a +// problem, but then when the JNI code consumes the next 32 bits for the +// reference to the role String it gets the higher 0x00000000 bits from +// the 64 bit JOBJECT64 AccessibleContext variable and thus a null reference +// is passed as the String reference. +// +// Solution: +// Cast the JOBJECT64 to a jobject. For a 64 bit compile this is basically +// a noop, i.e. JOBJECT64 is a 64 bit jlong and a jobject is a 64 bit reference. +// For a 32 bit compile the cast drops the high order 32 bits, i.e. JOBJECT64 +// is a 64 bit jlong and jobject is a 32 bit reference. For a Legacy build +// JOBJECT64 is a jobject so this is also basically a noop. The casts are +// done in the methods in JavaAccessBridge::processPackage. + +// ----------------------------------- + +/** + * isJavaWindow - returns whether the HWND is a Java window or not + * + */ +BOOL +AccessBridgeJavaEntryPoints::isJavaWindow(jint window) { + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window); + + if (isJavaWindowMethod != (jmethodID) 0) { + returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, isJavaWindowMethod, window); + EXCEPTION_CHECK("Getting isJavaWindow - call to CallBooleanMethod()", FALSE); + return returnVal; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or isJavaWindowMethod == 0"); + return FALSE; + } +} + +// ----------------------------------- + +/** + * isSameObject - returns whether two object reference refer to the same object + * + */ +BOOL +AccessBridgeJavaEntryPoints::isSameObject(jobject obj1, jobject obj2) { + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2); + + returnVal = (BOOL) jniEnv->IsSameObject((jobject)obj1, (jobject)obj2); + EXCEPTION_CHECK("Calling IsSameObject", FALSE); + + PrintDebugString("\r\n isSameObject returning %d", returnVal); + return returnVal; +} + +// ----------------------------------- + +/** + * getAccessibleContextFromHWND - returns the AccessibleContext, if any, for an HWND + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window); + + if (getAccessibleContextFromHWNDMethod != (jmethodID) 0) { + returnedAccessibleContext = + (jobject)jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleContextFromHWNDMethod, + window); + EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0); + globalRef = (jobject)jniEnv->NewGlobalRef((jobject)returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextFromHWND - call to CallObjectMethod()", (jobject) 0); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getAccessibleContextFromHWNDMethod == 0"); + return (jobject) 0; + } +} + +// ----------------------------------- + +/** + * getHWNDFromAccessibleContext - returns the HWND for an AccessibleContext, if any + * returns (HWND)0 on error. + */ +HWND +AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleContext) { + jthrowable exception; + HWND rHWND; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):", + accessibleContext); + + if (getHWNDFromAccessibleContextMethod != (jmethodID) 0) { + rHWND = (HWND)jniEnv->CallIntMethod(accessBridgeObject, getHWNDFromAccessibleContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting HWNDFromAccessibleContext - call to CallIntMethod()", (HWND)0); + PrintDebugString("\r\n rHWND = %X", rHWND); + return rHWND; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getHWNDFromAccessibleContextMethod == 0"); + return (HWND)0; + } +} + + +/* ====== Utility methods ===== */ + +/** + * Sets a text field to the specified string. Returns whether successful; + */ +BOOL +AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, const wchar_t *text) { + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):", + accessibleContext, text); + + if (setTextContentsMethod != (jmethodID) 0) { + + // create a Java String for the text + jstring textString = jniEnv->NewString(text, (jsize)wcslen(text)); + if (textString == 0) { + PrintDebugString("\r NewString failed"); + return FALSE; + } + + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + setTextContentsMethod, + accessibleContext, textString); + EXCEPTION_CHECK("setTextContents - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or setTextContentsMethod == 0"); + return result; + } +} + +/** + * Returns the Accessible Context of a Page Tab object that is the + * ancestor of a given object. If the object is a Page Tab object + * or a Page Tab ancestor object was found, returns the object + * AccessibleContext. + * If there is no ancestor object that has an Accessible Role of Page Tab, + * returns (AccessibleContext)0. + */ +jobject +AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, const wchar_t *role) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("In AccessBridgeJavaEntryPoints::getParentWithRole(%p):", + accessibleContext); + + if (getParentWithRoleMethod != (jmethodID) 0) { + // create a Java String for the role + jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role)); + if (roleName == 0) { + PrintDebugString(" NewString failed"); + return FALSE; + } + + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getParentWithRoleMethod, + accessibleContext, roleName); + EXCEPTION_CHECK("Getting ParentWithRole - call to CallObjectMethod()", (AccessibleContext)0); + PrintDebugString(" rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting ParentWithRole - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getParentWithRoleMethod == 0"); + return 0; + } +} + +/** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ +jobject +AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTopLevelObject(%p):", + accessibleContext); + + if (getTopLevelObjectMethod != (jmethodID) 0) { + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getTopLevelObjectMethod, + accessibleContext); + EXCEPTION_CHECK("Getting TopLevelObject - call to CallObjectMethod()", FALSE); + PrintDebugString("\r\n rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting TopLevelObject - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getTopLevelObjectMethod == 0"); + return 0; + } +} + +/** + * If there is an Ancestor object that has an Accessible Role of + * Internal Frame, returns the Accessible Context of the Internal + * Frame object. Otherwise, returns the top level object for that + * Java Window. Returns (AccessibleContext)0 on error. + */ +jobject +AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleContext, const wchar_t *role) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):", + accessibleContext); + + if (getParentWithRoleElseRootMethod != (jmethodID) 0) { + + // create a Java String for the role + jstring roleName = jniEnv->NewString(role, (jsize)wcslen(role)); + if (roleName == 0) { + PrintDebugString("\r NewString failed"); + return FALSE; + } + + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getParentWithRoleElseRootMethod, + accessibleContext, roleName); + EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to CallObjectMethod()", (AccessibleContext)0); + PrintDebugString(" rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting ParentWithRoleElseRoot - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getParentWithRoleElseRootMethod == 0"); + return 0; + } +} + +/** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ +jint +AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) { + jthrowable exception; + jint rResult; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getObjectDepth(%p):", + accessibleContext); + + if (getObjectDepthMethod != (jmethodID) 0) { + rResult = jniEnv->CallIntMethod(accessBridgeObject, + getObjectDepthMethod, + accessibleContext); + EXCEPTION_CHECK("Getting ObjectDepth - call to CallIntMethod()", -1); + PrintDebugString("\r\n rResult = %d", rResult); + return rResult; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getObjectDepthMethod == 0"); + return -1; + } +} + + + +/** + * Returns the Accessible Context of the current ActiveDescendent of an object. + * Returns 0 on error. + */ +jobject +AccessBridgeJavaEntryPoints::getActiveDescendent(const jobject accessibleContext) { + jthrowable exception; + jobject rAccessibleContext; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getActiveDescendent(%p):", + accessibleContext); + + if (getActiveDescendentMethod != (jmethodID) 0) { + rAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getActiveDescendentMethod, + accessibleContext); + EXCEPTION_CHECK("Getting ActiveDescendent - call to CallObjectMethod()", (AccessibleContext)0); + PrintDebugString("\r\n rAccessibleContext = %p", rAccessibleContext); + jobject globalRef = jniEnv->NewGlobalRef(rAccessibleContext); + EXCEPTION_CHECK("Getting ActiveDescendant - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + rAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or getActiveDescendentMethod == 0"); + return (AccessibleContext)0; + } +} + +/** + * Additional methods for Teton + */ + +/** + * Returns an AccessibleName for a component using an algorithm optimized + * for the JAWS screen reader by Ben Key (Freedom Scientific). This method + * is only intended for JAWS. All other uses are entirely optional. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ +BOOL +AccessBridgeJavaEntryPoints::getVirtualAccessibleName ( + IN const jobject object, + OUT wchar_t * name, + IN const int nameSize) +{ + /* + + + Parameter validation + + + */ + if ((name == 0) || (nameSize == 0)) + { + return FALSE; + } + ::memset (name, 0, nameSize * sizeof (wchar_t)); + if (0 == object) + { + return FALSE; + } + + jstring js = NULL; + const wchar_t * stringBytes = NULL; + jthrowable exception = NULL; + jsize length = 0; + PrintDebugString("\r\n getVirtualAccessibleName called."); + if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0) + { + js = (jstring) jniEnv->CallObjectMethod ( + accessBridgeObject, + getVirtualAccessibleNameFromContextMethod, + object); + EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) + { + stringBytes = (const wchar_t *) jniEnv->GetStringChars (js, 0); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); + wcsncpy(name, stringBytes, nameSize - 1); + length = jniEnv->GetStringLength(js); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod ( + accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Name = %ls", name); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); + } + else + { + PrintDebugString(" Accessible Name is null."); + } + } + else + { + PrintDebugString("\r\n Error! either jniEnv == 0 or getVirtualAccessibleNameFromContextMethod == 0"); + return FALSE; + } + if ( 0 != name [0] ) + { + return TRUE; + } + return FALSE; +} + + +/** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ +BOOL +AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) { + + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::requestFocus(%p):", + accessibleContext); + + if (requestFocusMethod != (jmethodID) 0) { + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + requestFocusMethod, + accessibleContext); + EXCEPTION_CHECK("requestFocus - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or requestFocusMethod == 0"); + return result; + } +} + +/** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ +BOOL +AccessBridgeJavaEntryPoints::selectTextRange(const jobject accessibleContext, int startIndex, int endIndex) { + + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):", + accessibleContext, startIndex, endIndex); + + if (selectTextRangeMethod != (jmethodID) 0) { + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + selectTextRangeMethod, + accessibleContext, + startIndex, endIndex); + EXCEPTION_CHECK("selectTextRange - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or selectTextRangeMethod == 0"); + return result; + } +} + +/* + * Returns whether two text attributes are the same. + */ +static BOOL CompareAccessibleTextAttributesInfo(AccessibleTextAttributesInfo *one, + AccessibleTextAttributesInfo *two) { + return(one->bold == two->bold + && one->italic == two->italic + && one->underline == two->underline + && one->strikethrough == two->strikethrough + && one->superscript == two->superscript + && one->subscript == two->subscript + && one->fontSize == two->fontSize + && one->alignment == two->alignment + && one->bidiLevel == two->bidiLevel + && one->firstLineIndent == two->firstLineIndent + && one->leftIndent == two->leftIndent + && one->rightIndent == two->rightIndent + && one->lineSpacing == two->lineSpacing + && one->spaceAbove == two->spaceAbove + && one->spaceBelow == two->spaceBelow + && !wcscmp(one->backgroundColor,two->backgroundColor) + && !wcscmp(one->foregroundColor,two->foregroundColor) + && !wcscmp(one->fullAttributesString,two->fullAttributesString)); +} + +/** + * Get text attributes between two indices. + * + * Only one AccessibleTextAttributesInfo structure is passed - which + * contains the attributes for the first character, the function then goes + * through the following characters in the range specified and stops when the + * attributes are different from the first, it then returns in the passed + * parameter len the number of characters with the attributes returned. In most + * situations this will be all the characters, and if not the calling program + * can easily get the attributes for the next characters with different + * attributes + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + +/* NEW FASTER CODE!!*/ +BOOL +AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleContext, + int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::getTextAttributesInRange(%p start = %d end = %d):", + accessibleContext, startIndex, endIndex); + + *len = 0; + result = getAccessibleTextAttributes((jobject)accessibleContext, startIndex, attributes); + if (result != TRUE) { + return FALSE; + } + (*len)++; + + for (jint i = startIndex+1; i <= endIndex; i++) { + + AccessibleTextAttributesInfo test_attributes = *attributes; + // Get the full test_attributes string at i + if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) { + PrintDebugString(" Getting full test_attributes string from Context..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleAttributesAtIndexFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE); + wcsncpy(test_attributes.fullAttributesString, stringBytes, (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + test_attributes.fullAttributesString[length < (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t)) ? + length : (sizeof(test_attributes.fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text attributes = %ls", test_attributes.fullAttributesString); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text attributes is null."); + test_attributes.fullAttributesString[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); + return FALSE; + } + + if(wcscmp(attributes->fullAttributesString,test_attributes.fullAttributesString)) + break; + if (result != TRUE) { + return FALSE; + } + (*len)++; + } + return TRUE; +} + +/* + * Returns the number of visible children of a component + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +int +AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) { + + jthrowable exception; + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)", + accessibleContext); + + // get the visible children count + int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### visible children count = %d", numChildren); + + return numChildren; +} + + +/* + * This method is used to iterate through the visible children of a component. It + * returns visible children information for a component starting at nStartIndex. + * No more than MAX_VISIBLE_CHILDREN VisibleChildrenInfo objects will + * be returned for each call to this method. Returns FALSE on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleContext, + const int nStartIndex, + /* OUT */ VisibleChildrenInfo *visibleChildrenInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)", + accessibleContext, nStartIndex); + + // get the visible children count + int numChildren = jniEnv->CallIntMethod(accessBridgeObject, getVisibleChildrenCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting visible children count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### visible children count = %d", numChildren); + + if (nStartIndex >= numChildren) { + return FALSE; + } + + // get the visible children + int bufIndex = 0; + for (int i = nStartIndex; (i < numChildren) && (i < nStartIndex + MAX_VISIBLE_CHILDREN); i++) { + PrintDebugString(" getting visible child %d ...", i); + + // get the visible child at index i + jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, getVisibleChildMethod, + accessibleContext, i); + EXCEPTION_CHECK("##### getVisibleChildMethod - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ac); + EXCEPTION_CHECK("##### getVisibleChildMethod - call to NewGlobalRef()", FALSE); + visibleChildrenInfo->children[bufIndex] = (JOBJECT64)globalRef; + PrintDebugString(" ##### visible child = %p", globalRef); + + bufIndex++; + } + visibleChildrenInfo->returnedChildrenCount = bufIndex; + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getVisibleChildren succeeded"); + return TRUE; +} + +/** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ +BOOL +AccessBridgeJavaEntryPoints::setCaretPosition(const jobject accessibleContext, int position) { + + jthrowable exception; + BOOL result = FALSE; + + PrintDebugString("\r\nIn AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):", + accessibleContext, position); + + if (setCaretPositionMethod != (jmethodID) 0) { + result = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, + setCaretPositionMethod, + accessibleContext, position); + EXCEPTION_CHECK("setCaretPostion - call to CallBooleanMethod()", FALSE); + PrintDebugString("\r\n result = %d", result); + return result; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or setCaretPositionMethod == 0"); + return result; + } +} + + +// ----------------------------------- + +/** + * getVersionInfo - returns the version string of the java.version property + * and the AccessBridge.java version + * + */ +BOOL +AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getVersionInfo():"); + + if (getJavaVersionPropertyMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getJavaVersionPropertyMethod); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + length = jniEnv->GetStringLength(js); + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + if (stringBytes == NULL) { + if (!jniEnv->ExceptionCheck()) { + PrintDebugString("\r\n *** Exception when getting JavaVersionProperty - call to GetStringChars"); + jniEnv->ExceptionDescribe(); + jniEnv->ExceptionClear(); + } + return FALSE; + } + wcsncpy(info->bridgeJavaDLLVersion, + stringBytes, + sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)); + info->bridgeJavaDLLVersion[length < (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t)) ? + length : (sizeof(info->bridgeJavaDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0; + wcsncpy(info->VMversion, + stringBytes, + sizeof(info->VMversion) / sizeof(wchar_t)); + info->VMversion[length < (sizeof(info->VMversion) / sizeof(wchar_t)) ? + length : (sizeof(info->VMversion) / sizeof(wchar_t))-2] = (wchar_t) 0; + wcsncpy(info->bridgeJavaClassVersion, + stringBytes, + sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)); + info->bridgeJavaClassVersion[length < (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t)) ? + length : (sizeof(info->bridgeJavaClassVersion) / sizeof(wchar_t))-2] = (wchar_t) 0; + wcsncpy(info->bridgeWinDLLVersion, + stringBytes, + sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)); + info->bridgeWinDLLVersion[length < (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t)) ? + length : (sizeof(info->bridgeWinDLLVersion) / sizeof(wchar_t))-2] = (wchar_t) 0; + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Java version = %ls", info->VMversion); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting JavaVersionProperty - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Java version is null."); + info->VMversion[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getJavaVersionPropertyMethod == 0"); + return FALSE; + } + + return TRUE; +} + + +/* + * Verifies the Java VM still exists and obj is an + * instance of AccessibleText + */ +BOOL AccessBridgeJavaEntryPoints::verifyAccessibleText(jobject obj) { + JavaVM *vm; + BOOL retval; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::verifyAccessibleText"); + + if (jniEnv->GetJavaVM(&vm) != 0) { + PrintDebugString(" Error! No Java VM"); + return FALSE; + } + + if (obj == (jobject)0) { + PrintDebugString(" Error! Null jobject"); + return FALSE; + } + + // Copied from getAccessibleContextInfo + if (getAccessibleTextFromContextMethod != (jmethodID) 0) { + jobject returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextFromContextMethod, + (jobject)obj); + EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleText = %p", returnedJobject); + retval = returnedJobject != (jobject) 0; + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextFromContextMethod == 0"); + return FALSE; + } + if (retval == FALSE) { + PrintDebugString(" Error! jobject is not an AccessibleText"); + } + return retval; +} + + +/********** AccessibleContext routines ***********************************/ + +/** + * getAccessibleContextAt - performs the Java method call: + * Accessible AccessBridge.getAccessibleContextAt(x, y) + * + * Note: this call explicitly goes through the AccessBridge, + * so that it can keep a reference the returned jobject for the JavaVM. + * You must explicity call INTreleaseJavaObject() when you are through using + * the Accessible returned, to let the AccessBridge know it can release the + * object, so that the can then garbage collect it. + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleContextAt(jint x, jint y, jobject accessibleContext) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):", + x, y, accessibleContext); + + if (getAccessibleContextAtMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleContextAtMethod, + x, y, accessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextAt - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextAt - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleContextAtMethod == 0"); + return (jobject) 0; + } +} + +/** + * getAccessibleWithFocus - performs the Java method calls: + * Accessible Translator.getAccessible(SwingEventMonitor.getComponentWithFocus(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus() { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()"); + + if (getAccessibleContextWithFocusMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleContextWithFocusMethod); + EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleContextWithFocus - call to NewGlobalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either jniEnv == 0 or getAccessibleContextWithFocusMethod == 0"); + return (jobject) 0; + } +} + +/** + * getAccessibleContextInfo - fills a struct with a bunch of information + * contained in the Java Accessibility API + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + * + * Note: this call explicitly goes through the AccessBridge, + * so that it can keep a reference the returned jobject for the JavaVM. + * You must explicity call releaseJavaObject() when you are through using + * the AccessibleContext returned, to let the AccessBridge know it can release the + * object, so that the JavaVM can then garbage collect it. + */ +BOOL +AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, AccessibleContextInfo *info) { + jstring js; + const wchar_t *stringBytes; + jobject returnedJobject; + jthrowable exception; + jsize length; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext); + + ZeroMemory(info, sizeof(AccessibleContextInfo)); + + if (accessibleContext == (jobject) 0) { + PrintDebugString(" passed in AccessibleContext == null! (oops)"); + return (FALSE); + } + + // Get the Accessible Name + if (getAccessibleNameFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleNameFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleName - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); + wcsncpy(info->name, stringBytes, (sizeof(info->name) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->name[length < (sizeof(info->name) / sizeof(wchar_t)) ? + length : (sizeof(info->name) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Name = %ls", info->name); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Name is null."); + info->name[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleNameFromContextMethod == 0"); + return FALSE; + } + + + // Get the Accessible Description + if (getAccessibleDescriptionFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleDescriptionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleDescription - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringChars()", FALSE); + wcsncpy(info->description, stringBytes, (sizeof(info->description) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->description[length < (sizeof(info->description) / sizeof(wchar_t)) ? + length : (sizeof(info->description) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleName - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleName - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleName - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Description = %ls", info->description); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleName - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Description is null."); + info->description[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleDescriptionFromContextMethod == 0"); + return FALSE; + } + + + // Get the Accessible Role String + if (getAccessibleRoleStringFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleRoleStringFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleRole - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringChars()", FALSE); + wcsncpy(info->role, stringBytes, (sizeof(info->role) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->role[length < (sizeof(info->role) / sizeof(wchar_t)) ? + length : (sizeof(info->role) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleRole - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleRole - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleRole - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Role = %ls", info->role); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleRole - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Role is null."); + info->role[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleRoleStringFromContextMethod == 0"); + return FALSE; + } + + + // Get the Accessible Role String in the en_US locale + if (getAccessibleRoleStringFromContext_en_USMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleRoleStringFromContext_en_USMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringChars()", FALSE); + wcsncpy(info->role_en_US, stringBytes, (sizeof(info->role_en_US) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->role_en_US[length < (sizeof(info->role_en_US) / sizeof(wchar_t)) ? + length : (sizeof(info->role_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Role en_US = %ls", info->role_en_US); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleRole_en_US - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Role en_US is null."); + info->role[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleRoleStringFromContext_en_USMethod == 0"); + return FALSE; + } + + // Get the Accessible States String + if (getAccessibleStatesStringFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleStatesStringFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleState - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleState - call to GetStringChars()", FALSE); + wcsncpy(info->states, stringBytes, (sizeof(info->states) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->states[length < (sizeof(info->states) / sizeof(wchar_t)) ? + length : (sizeof(info->states) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleState - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleState - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleState - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible States = %ls", info->states); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleState - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible States is null."); + info->states[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleStatesStringFromContextMethod == 0"); + return FALSE; + } + + // Get the Accessible States String in the en_US locale + if (getAccessibleStatesStringFromContext_en_USMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleStatesStringFromContext_en_USMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringChars()", FALSE); + wcsncpy(info->states_en_US, stringBytes, (sizeof(info->states_en_US) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + info->states_en_US[length < (sizeof(info->states_en_US) / sizeof(wchar_t)) ? + length : (sizeof(info->states_en_US) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible States en_US = %ls", info->states_en_US); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleState_en_US - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible States en_US is null."); + info->states[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleStatesStringFromContext_en_USMethod == 0"); + return FALSE; + } + + + // Get the index in Parent + if (getAccessibleIndexInParentFromContextMethod != (jmethodID) 0) { + info->indexInParent = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIndexInParentFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleIndexInParent - call to CallIntMethod()", FALSE); + PrintDebugString(" Index in Parent = %d", info->indexInParent); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleIndexInParentFromContextMethod == 0"); + return FALSE; + } + + + PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %p ***", + jniEnv, accessBridgeObject, accessibleContext); + + // Get the children count + if (getAccessibleChildrenCountFromContextMethod != (jmethodID) 0) { + info->childrenCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleChildrenCountFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleChildrenCount - call to CallIntMethod()", FALSE); + PrintDebugString(" Children count = %d", info->childrenCount); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleChildrenCountFromContextMethod == 0"); + return FALSE; + } + + PrintDebugString("*** jniEnv: %p; accessBridgeObject: %p; AccessibleContext: %X ***", + jniEnv, accessBridgeObject, accessibleContext); + + + // Get the x coord + if (getAccessibleXcoordFromContextMethod != (jmethodID) 0) { + info->x = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleXcoordFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleXcoord - call to CallIntMethod()", FALSE); + PrintDebugString(" X coord = %d", info->x); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleXcoordFromContextMethod == 0"); + return FALSE; + } + + PrintDebugString("*** jniEnv: %X; accessBridgeObject: %X; AccessibleContext: %p ***", + jniEnv, accessBridgeObject, accessibleContext); + + + // Get the y coord + if (getAccessibleYcoordFromContextMethod != (jmethodID) 0) { + info->y = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleYcoordFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleYcoord - call to CallIntMethod()", FALSE); + PrintDebugString(" Y coord = %d", info->y); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleYcoordFromContextMethod == 0"); + return FALSE; + } + + // Get the width + if (getAccessibleWidthFromContextMethod != (jmethodID) 0) { + info->width = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleWidthFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleWidth - call to CallIntMethod()", FALSE); + PrintDebugString(" Width = %d", info->width); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleWidthFromContextMethod == 0"); + return FALSE; + } + + // Get the height + if (getAccessibleHeightFromContextMethod != (jmethodID) 0) { + info->height = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHeightFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleHeight - call to CallIntMethod()", FALSE); + PrintDebugString(" Height = %d", info->height); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleHeightFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleComponent + if (getAccessibleComponentFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleComponentFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleComponent - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleComponent = %p", returnedJobject); + info->accessibleComponent = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleComponent - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleComponentFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleAction + if (getAccessibleActionFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleActionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleAction - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleAction = %p", returnedJobject); + info->accessibleAction = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleAction - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleActionFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleSelection + if (getAccessibleSelectionFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleSelectionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelection - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleSelection = %p", returnedJobject); + info->accessibleSelection = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleSelection - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSelectionFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleTable + if (getAccessibleTableFromContextMethod != (jmethodID) 0) { + PrintDebugString("##### Calling getAccessibleTableFromContextMethod ..."); + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableFromContextMethod, + accessibleContext); + PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + PrintDebugString(" ##### AccessibleTable = %p", returnedJobject); + if (returnedJobject != (jobject) 0) { + info->accessibleInterfaces |= cAccessibleTableInterface; + } + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to DeleteLocalRef()", FALSE); + + /* + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableFromContextMethod, + AccessibleContext); + PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + PrintDebugString(" ##### AccessibleTable = %X", returnedJobject); + info->accessibleTable = returnedJobject; + */ + + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleText + if (getAccessibleTextFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleText - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleText = %p", returnedJobject); + info->accessibleText = (returnedJobject != (jobject) 0 ? TRUE : FALSE); + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleText - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextFromContextMethod == 0"); + return FALSE; + } + + // Get the AccessibleValue + if (getAccessibleValueFromContextMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleValue = %p", returnedJobject); + if (returnedJobject != (jobject) 0) { + info->accessibleInterfaces |= cAccessibleValueInterface; + } + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleValueFromContextMethod == 0"); + return FALSE; + } + + // FIX + // get the AccessibleHypertext + if (getAccessibleHypertextMethod != (jmethodID) 0 && + getAccessibleHyperlinkCountMethod != (jmethodID) 0 && + getAccessibleHyperlinkMethod != (jmethodID) 0 && + getAccessibleHyperlinkTextMethod != (jmethodID) 0 && + getAccessibleHyperlinkStartIndexMethod != (jmethodID) 0 && + getAccessibleHyperlinkEndIndexMethod != (jmethodID) 0) { + returnedJobject = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHypertextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); + PrintDebugString(" AccessibleHypertext = %p", + returnedJobject); + if (returnedJobject != (jobject) 0) { + info->accessibleInterfaces |= cAccessibleHypertextInterface; + } + jniEnv->DeleteLocalRef(returnedJobject); + EXCEPTION_CHECK("Getting AccessibleHypertext - call to DeleteLocalRef()", FALSE); + } + + // set new accessibleInterfaces flags from old BOOL values + if(info->accessibleComponent) + info->accessibleInterfaces |= cAccessibleComponentInterface; + if(info->accessibleAction) + info->accessibleInterfaces |= cAccessibleActionInterface; + if(info->accessibleSelection) + info->accessibleInterfaces |= cAccessibleSelectionInterface; + if(info->accessibleText) + info->accessibleInterfaces |= cAccessibleTextInterface; + // FIX END + + return TRUE; +} + +/** + * getAccessibleChildFromContext - performs the Java method call: + * AccessibleContext AccessBridge.getAccessibleChildContext(AccessibleContext) + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + * + * Note: this call explicitly goes through the AccessBridge, + * so that it can keep a reference the returned jobject for the JavaVM. + * You must explicity call releaseJavaObject() when you are through using + * the AccessibleContext returned, to let the AccessBridge know it can release the + * object, so that the JavaVM can then garbage collect it. + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleChildFromContext(jobject accessibleContext, jint childIndex) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):", + accessibleContext, childIndex); + + if (getAccessibleChildFromContextMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleChildFromContextMethod, + accessibleContext, childIndex); + EXCEPTION_CHECK("Getting AccessibleChild - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleChild - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleChild - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleChildContextMethod == 0"); + return (jobject) 0; + } +} + +/** + * getAccessibleParentFromContext - returns the AccessibleContext parent + * + */ +jobject +AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(jobject accessibleContext) +{ + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext); + + if (getAccessibleParentFromContextMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleParentFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleParent - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleParent - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleParent - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleParentFromContextMethod == 0"); + return (jobject) 0; + } +} + + +/********** AccessibleTable routines **********************************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableInfo(jobject accessibleContext, + AccessibleTableInfo *tableInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):", + accessibleContext); + + // get the table row count + if (getAccessibleTableRowCountMethod != (jmethodID) 0) { + tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleTableRowCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowCountMethod == 0"); + return FALSE; + } + + // get the table column count + if (getAccessibleTableColumnCountMethod != (jmethodID) 0) { + tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnCountMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableColumnCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnCountMethod == 0"); + return FALSE; + } + + // get the AccessibleTable + if (getAccessibleTableFromContextMethod != (jmethodID) 0) { + PrintDebugString("##### Calling getAccessibleTableFromContextMethod ..."); + jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableFromContextMethod, + accessibleContext); + PrintDebugString("##### ... Returned from getAccessibleTableFromContextMethod"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(accTable); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE); + tableInfo->accessibleTable = (JOBJECT64)globalRef; + PrintDebugString(" ##### accessibleTable = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableFromContextMethod == 0"); + return FALSE; + } + + // cache the AccessibleContext + if (getContextFromAccessibleTableMethod != (jmethodID) 0) { + PrintDebugString("##### Calling getContextFromAccessibleTable Method ..."); + jobject ac = jniEnv->CallObjectMethod(accessBridgeObject, + getContextFromAccessibleTableMethod, + accessibleContext); + PrintDebugString("##### ... Returned from getContextFromAccessibleTable Method"); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ac); + EXCEPTION_CHECK("##### Getting AccessibleTable - call to NewGlobalRef()", FALSE); + tableInfo->accessibleContext = (JOBJECT64)globalRef; + PrintDebugString(" ##### accessibleContext = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getContextFromAccessibleTable Method == 0"); + return FALSE; + } + + // FIX - set unused elements + tableInfo->caption = NULL; + tableInfo->summary = NULL; + + PrintDebugString("##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo succeeded"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d", + accessibleTable, row, column); + + // FIX + ZeroMemory(tableCellInfo, sizeof(AccessibleTableCellInfo)); + tableCellInfo->row = row; + tableCellInfo->column = column; + // FIX END + + // get the table cell index + if (getAccessibleTableCellIndexMethod != (jmethodID) 0) { + tableCellInfo->index = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableCellIndexMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table cell index = %d", tableCellInfo->index); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellIndexMethod == 0"); + return FALSE; + } + + // get the table cell row extent + if (getAccessibleTableCellRowExtentMethod != (jmethodID) 0) { + tableCellInfo->rowExtent = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableCellRowExtentMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellRowExtentCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table cell row extent = %d", tableCellInfo->rowExtent); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellRowExtentMethod == 0"); + return FALSE; + } + + // get the table cell column extent + if (getAccessibleTableCellColumnExtentMethod != (jmethodID) 0) { + tableCellInfo->columnExtent = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableCellColumnExtentMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellColumnExtentCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table cell column extent = %d", tableCellInfo->columnExtent); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellColumnExtentMethod == 0"); + return FALSE; + } + + // get whether the table cell is selected + if (isAccessibleTableCellSelectedMethod != (jmethodID) 0) { + tableCellInfo->isSelected = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleTableCellSelectedMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting isAccessibleTableCellSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" ##### table cell isSelected = %d", tableCellInfo->isSelected); + } else { + PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableCellSelectedMethod == 0"); + return FALSE; + } + + // get the table cell AccessibleContext + if (getAccessibleTableCellAccessibleContextMethod != (jmethodID) 0) { + jobject tableCellAC = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableCellAccessibleContextMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(tableCellAC); + EXCEPTION_CHECK("##### Getting AccessibleTableCellAccessibleContext - call to NewGlobalRef()", FALSE); + tableCellInfo->accessibleContext = (JOBJECT64)globalRef; + PrintDebugString(" ##### table cell AccessibleContext = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableCellAccessibleContextMethod == 0"); + return FALSE; + } + + PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo succeeded"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo) { + + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):", + acParent); + + // get the header row count + if (getAccessibleTableRowHeaderRowCountMethod != (jmethodID) 0) { + tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowHeaderRowCountMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableRowHeaderRowCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowHeaderRowCountMethod == 0"); + return FALSE; + } + + // get the header column count + if (getAccessibleTableRowHeaderColumnCountMethod != (jmethodID) 0) { + tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowHeaderColumnCountMethod, + acParent); + EXCEPTION_CHECK("Getting AccessibleTableRowHeaderColumnCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowHeaderColumnCountMethod == 0"); + return FALSE; + } + + // get the header AccessibleTable + if (getAccessibleTableRowHeaderMethod != (jmethodID) 0) { + jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableRowHeaderMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(accTable); + EXCEPTION_CHECK("##### Getting AccessibleTableRowHeader - call to NewGlobalRef()", FALSE); + tableInfo->accessibleTable = (JOBJECT64)globalRef; + PrintDebugString(" ##### row header AccessibleTable = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowHeaderMethod == 0"); + return FALSE; + } + + // FIX - set unused elements + tableInfo->caption = NULL; + tableInfo->summary = NULL; + tableInfo->accessibleContext = NULL; + + PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader succeeded"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) { + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):", + acParent); + + // get the header row count + if (getAccessibleTableColumnHeaderRowCountMethod != (jmethodID) 0) { + tableInfo->rowCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnHeaderRowCountMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeaderRowCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row count = %d", tableInfo->rowCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleColumnHeaderRowCountMethod == 0"); + return FALSE; + } + + // get the header column count + if (getAccessibleTableColumnHeaderColumnCountMethod != (jmethodID) 0) { + tableInfo->columnCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnHeaderColumnCountMethod, + acParent); + EXCEPTION_CHECK("Getting AccessibleTableColumnHeaderColumnCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column count = %d", tableInfo->columnCount); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnHeaderColumnCountMethod == 0"); + return FALSE; + } + // get the header AccessibleTable + if (getAccessibleTableColumnHeaderMethod != (jmethodID) 0) { + jobject accTable = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableColumnHeaderMethod, + acParent); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(accTable); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnHeader - call to NewGlobalRef()", FALSE); + tableInfo->accessibleTable = (JOBJECT64)globalRef; + PrintDebugString(" ##### column header AccessibleTable = %p", globalRef); + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnHeaderMethod == 0"); + return FALSE; + } + + // FIX - set unused elements + tableInfo->caption = NULL; + tableInfo->summary = NULL; + tableInfo->accessibleContext = NULL; + + PrintDebugString(" ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader succeeded"); + return TRUE; +} + +jobject +AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(jobject acParent, jint row) { + + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):", + acParent); + + if (getAccessibleTableRowDescriptionMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTableRowDescriptionMethod, + acParent, row); + EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableRowDescription - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTableRowDescriptionMethod == 0"); + return (jobject) 0; + } +} + +jobject +AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParent, jint column) { + + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\n##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):", + acParent); + + if (getAccessibleTableColumnDescriptionMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod( + accessBridgeObject, + getAccessibleTableColumnDescriptionMethod, + acParent, column); + EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to CallObjectMethod()", FALSE); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to NewGlobalRef()", FALSE); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleTableColumnDescription - call to DeleteLocalRef()", FALSE); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTableColumnDescriptionMethod == 0"); + return (jobject) 0; + } +} + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessibleTable) { + + jthrowable exception; + jint count; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)", + accessibleTable); + + // Get the table row selection count + if (getAccessibleTableRowSelectionCountMethod != (jmethodID) 0) { + count = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowSelectionCountMethod, + accessibleTable); + EXCEPTION_CHECK("##### Getting AccessibleTableRowSelectionCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row selection count = %d", count); + return count; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowSelectionCountMethod == 0"); + return 0; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount failed"); + return 0; +} + +BOOL +AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(jobject accessibleTable, jint row) { + jthrowable exception; + BOOL result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)", + accessibleTable, row); + + if (isAccessibleTableRowSelectedMethod != (jmethodID) 0) { + result = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleTableRowSelectedMethod, + accessibleTable, row); + EXCEPTION_CHECK("##### Getting isAccessibleTableRowSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" ##### table row isSelected = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableRowSelectedMethod == 0"); + return FALSE; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected failed"); + return FALSE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleTable, jint count, + jint *selections) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)", + accessibleTable, count, selections); + + if (getAccessibleTableRowSelectionsMethod == (jmethodID) 0) { + return FALSE; + } + // Get the table row selections + for (int i = 0; i < count; i++) { + + selections[i] = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowSelectionsMethod, + accessibleTable, + i); + EXCEPTION_CHECK("##### Getting AccessibleTableRowSelections - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row selection[%d] = %d", i, selections[i]); + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections succeeded"); + return TRUE; +} + + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject accessibleTable) { + + jthrowable exception; + jint count; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)", + accessibleTable); + + // Get the table column selection count + if (getAccessibleTableColumnSelectionCountMethod != (jmethodID) 0) { + count = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnSelectionCountMethod, + accessibleTable); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelectionCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column selection count = %d", count); + return count; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleRowCountMethod == 0"); + return 0; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount failed"); + return 0; +} + +BOOL +AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleTable, jint column) { + jthrowable exception; + BOOL result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)", + accessibleTable, column); + + if (isAccessibleTableColumnSelectedMethod != (jmethodID) 0) { + result = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleTableColumnSelectedMethod, + accessibleTable, column); + EXCEPTION_CHECK("##### Getting isAccessibleTableColumnSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" ##### table column isSelected = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or isAccessibleTableColumnSelectedMethod == 0"); + return FALSE; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected failed"); + return FALSE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessibleTable, jint count, + jint *selections) { + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)", + accessibleTable, count, selections); + + if (getAccessibleTableColumnSelectionsMethod == (jmethodID) 0) { + return FALSE; + } + // Get the table column selections + for (int i = 0; i < count; i++) { + + selections[i] = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnSelectionsMethod, + accessibleTable, + i); + EXCEPTION_CHECK("##### Getting AccessibleTableColumnSelections - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table Column selection[%d] = %d", i, selections[i]); + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections succeeded"); + return TRUE; +} + + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint index) { + jthrowable exception; + jint result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)", + accessibleTable, index); + + if (getAccessibleTableRowMethod != (jmethodID) 0) { + result = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableRowMethod, + accessibleTable, index); + EXCEPTION_CHECK("##### Getting AccessibleTableRow - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table row = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableRowMethod == 0"); + return -1; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow failed"); + return -1; +} + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, jint index) { + jthrowable exception; + jint result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)", + accessibleTable, index); + + if (getAccessibleTableColumnMethod != (jmethodID) 0) { + result = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableColumnMethod, + accessibleTable, index); + EXCEPTION_CHECK("##### Getting AccessibleTableColumn - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table column = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableColumnMethod == 0"); + return -1; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn failed"); + return -1; +} + +jint +AccessBridgeJavaEntryPoints::getAccessibleTableIndex(jobject accessibleTable, jint row, jint column) { + jthrowable exception; + jint result; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)", + accessibleTable, row, column); + + if (getAccessibleTableIndexMethod != (jmethodID) 0) { + result = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTableIndexMethod, + accessibleTable, row, column); + EXCEPTION_CHECK("##### Getting getAccessibleTableIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### table index = %d", result); + return result; + } else { + PrintDebugString(" ##### Error! either env == 0 or getAccessibleTableIndexMethod == 0"); + return -1; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex failed"); + return -1; +} + +/********** end AccessibleTable routines ******************************/ + + +/********** begin AccessibleRelationSet routines **********************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext, + AccessibleRelationSetInfo *relationSet) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet(%p, %p)", + accessibleContext, relationSet); + + if (getAccessibleRelationCountMethod == (jmethodID) 0 || + getAccessibleRelationKeyMethod == (jmethodID) 0 || + getAccessibleRelationTargetCountMethod == (jmethodID) 0 || + getAccessibleRelationTargetMethod == (jmethodID) 0) { + return FALSE; + } + + // Get the relations set count + relationSet->relationCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleRelationCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleRelationCount - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### AccessibleRelation count = %d", relationSet->relationCount); + + + // Get the relation set + for (int i = 0; i < relationSet->relationCount && i < MAX_RELATIONS; i++) { + + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleRelationKeyMethod, + accessibleContext, + i); + + EXCEPTION_CHECK("Getting AccessibleRelationKey - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringChars()", FALSE); + wcsncpy(relationSet->relations[i].key, stringBytes, (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + relationSet->relations[i].key [length < (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t)) ? + length : (sizeof(relationSet->relations[i].key ) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleRelation key - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleRelation key - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleRelation key - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleRelation key = %ls", relationSet->relations[i].key ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleRelation key - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleRelation key is null."); + relationSet->relations[i].key [0] = (wchar_t) 0; + } + + relationSet->relations[i].targetCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleRelationTargetCountMethod, + accessibleContext, + i); + + for (int j = 0; j < relationSet->relations[i].targetCount && j < MAX_RELATION_TARGETS; j++) { + jobject target = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleRelationTargetMethod, + accessibleContext, i, j); + EXCEPTION_CHECK("Getting AccessibleRelationSet - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(target); + EXCEPTION_CHECK("Getting AccessibleRelationSet - call to NewGlobalRef()", FALSE); + relationSet->relations[i].targets[j] = (JOBJECT64)globalRef; + PrintDebugString(" relation set item: %p", globalRef); + } + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleRelationSet succeeded"); + return TRUE; +} + + +/********** end AccessibleRelationSet routines ************************/ + + +/********** begin AccessibleHypertext routines **********************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext, + AccessibleHypertextInfo *hypertext) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertext(%p, %p)", + accessibleContext, hypertext); + + // get the AccessibleHypertext + jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHypertextMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ht); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE); + hypertext->accessibleHypertext = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHypertext = %p", globalRef); + + if (hypertext->accessibleHypertext == 0) { + PrintDebugString(" ##### null AccessibleHypertext; returning FALSE"); + return false; + } + + // get the hyperlink count + hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkCountMethod,accessibleContext); + + EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink count = %d", hypertext->linkCount); + + + // get the hypertext links + for (int i = 0; i < hypertext->linkCount && i < MAX_HYPERLINKS; i++) { + + // get the hyperlink + jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(hl); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); + hypertext->links[i].accessibleHyperlink = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + + // get the hyperlink text + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkTextMethod, + hypertext->links[i].accessibleHyperlink, + i); + + EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE); + wcsncpy(hypertext->links[i].text, stringBytes, (sizeof(hypertext->links[i].text) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(hypertext->links[i].text) / sizeof(wchar_t))) { + length = (sizeof(hypertext->links[i].text) / sizeof(wchar_t)) - 2; + } + hypertext->links[i].text[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[i].text ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleHyperlink text is null."); + hypertext->links[i].text[0] = (wchar_t) 0; + } + + hypertext->links[i].startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkStartIndexMethod, + hypertext->links[i].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink start index = %d", hypertext->links[i].startIndex); + + + hypertext->links[i].endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkEndIndexMethod, + hypertext->links[i].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink end index = %d", hypertext->links[i].endIndex); + + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleHypertext succeeded"); + return TRUE; +} + +/* + * Activates an AccessibleHyperlink + */ +BOOL +AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(jobject accessibleContext, + jobject accessibleHyperlink) { + + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):", + accessibleContext, accessibleHyperlink); + + if (activateAccessibleHyperlinkMethod != (jmethodID) 0) { + returnVal = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, activateAccessibleHyperlinkMethod, + accessibleContext, accessibleHyperlink); + EXCEPTION_CHECK("activateAccessibleHyperlink - call to CallBooleanMethod()", FALSE); + return returnVal; + } else { + PrintDebugString("\r\n Error! either jniEnv == 0 or activateAccessibleHyperlinkMethod == 0"); + return FALSE; + } +} + + +/* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ +BOOL +AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertext) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)", + accessibleContext, hypertext, nStartIndex); + + // get the AccessibleHypertext + jobject ht = jniEnv->CallObjectMethod(accessBridgeObject, getAccessibleHypertextMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(ht); + EXCEPTION_CHECK("##### Getting AccessibleHypertext - call to NewGlobalRef()", FALSE); + hypertext->accessibleHypertext = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHypertext = %p", globalRef); + if (hypertext->accessibleHypertext == 0) { + PrintDebugString(" ##### null AccessibleHypertext; returning FALSE"); + return FALSE; + } + + // get the hyperlink count + hypertext->linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink count = %d", hypertext->linkCount); + + if (nStartIndex >= hypertext->linkCount) { + return FALSE; + } + + // get the hypertext links + // NOTE: To avoid a crash when there are more than MAX_HYPERLINKS (64) links + // in the document, test for i < MAX_HYPERLINKS in addition to + // i < hypertext->linkCount + int bufIndex = 0; + for (int i = nStartIndex; (i < hypertext->linkCount) && (i < nStartIndex + MAX_HYPERLINKS); i++) { + PrintDebugString(" getting hyperlink %d ...", i); + + // get the hyperlink + jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkMethod, + hypertext->accessibleHypertext, + i); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(hl); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); + hypertext->links[bufIndex].accessibleHyperlink = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + + // get the hyperlink text + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkTextMethod, + hypertext->links[bufIndex].accessibleHyperlink, + i); + + EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE); + wcsncpy(hypertext->links[bufIndex].text, stringBytes, + (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t))) { + length = (sizeof(hypertext->links[bufIndex].text) / sizeof(wchar_t)) - 2; + } + hypertext->links[bufIndex].text[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleHyperlink text = %ls", hypertext->links[bufIndex].text ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); + + } else { + PrintDebugString(" AccessibleHyperlink text is null."); + hypertext->links[bufIndex].text[0] = (wchar_t) 0; + } + + hypertext->links[bufIndex].startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkStartIndexMethod, + hypertext->links[bufIndex].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink start index = %d", hypertext->links[bufIndex].startIndex); + + hypertext->links[bufIndex].endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkEndIndexMethod, + hypertext->links[bufIndex].accessibleHyperlink, + i); + EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink end index = %d", hypertext->links[bufIndex].endIndex); + + bufIndex++; + } + + PrintDebugString(" ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt succeeded"); + return TRUE; +} + +jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject accessibleContext) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)", + accessibleContext); + + if (getAccessibleHyperlinkCountMethod == (jmethodID)0) { + return -1; + } + + // get the hyperlink count + jint linkCount = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHyperlinkCountMethod, + accessibleContext); + EXCEPTION_CHECK("##### Getting hyperlink count - call to CallIntMethod()", -1); + PrintDebugString(" ##### hyperlink count = %d", linkCount); + + return linkCount; +} + + +jint AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(const jobject hypertext, + const jint nIndex) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)", + hypertext, nIndex); + + if (getAccessibleHypertextLinkIndexMethod == (jmethodID)0) { + return -1; + } + + // get the hyperlink index + jint index = jniEnv->CallIntMethod(accessBridgeObject, getAccessibleHypertextLinkIndexMethod, + hypertext, nIndex); + + EXCEPTION_CHECK("##### Getting hyperlink index - call to CallIntMethod()", -1); + PrintDebugString(" ##### hyperlink index = %d", index); + + return index; +} + +BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext, + const jint index, + /* OUT */ AccessibleHyperlinkInfo *info) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleHyperlink(%p, index = %d)", + hypertext, index); + + + // get the hyperlink + jobject hl = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkMethod, + hypertext, + index); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to CallObjectMethod()", FALSE); + jobject globalRef = jniEnv->NewGlobalRef(hl); + EXCEPTION_CHECK("##### Getting AccessibleHyperlink - call to NewGlobalRef()", FALSE); + info->accessibleHyperlink = (JOBJECT64)globalRef; + PrintDebugString(" ##### AccessibleHyperlink = %p", globalRef); + + // get the hyperlink text + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleHyperlinkTextMethod, + info->accessibleHyperlink, + index); + + EXCEPTION_CHECK("Getting hyperlink text - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringChars()", FALSE); + wcsncpy(info->text, stringBytes, + (sizeof(info->text) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(info->text) / sizeof(wchar_t))) { + length = (sizeof(info->text) / sizeof(wchar_t)) - 2; + } + info->text[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleHyperlink text = %ls", info->text ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleHyperlink text - call to DeleteLocalRef()", FALSE); + + } else { + PrintDebugString(" AccessibleHyperlink text is null."); + info->text[0] = (wchar_t) 0; + } + + info->startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkStartIndexMethod, + info->accessibleHyperlink, + index); + EXCEPTION_CHECK("##### Getting hyperlink start index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink start index = %d", info->startIndex); + + info->endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHyperlinkEndIndexMethod, + info->accessibleHyperlink, + index); + EXCEPTION_CHECK("##### Getting hyperlink end index - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### hyperlink end index = %d", info->endIndex); + + return TRUE; +} + + +/********** end AccessibleHypertext routines ************************/ + +// Accessible Keybinding methods +BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleContext, + AccessibleKeyBindings *keyBindings) { + + jthrowable exception; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)", + accessibleContext, keyBindings); + + if (getAccessibleKeyBindingsCountMethod == (jmethodID) 0 || + getAccessibleKeyBindingCharMethod == (jmethodID) 0 || + getAccessibleKeyBindingModifiersMethod == (jmethodID) 0) { + return FALSE; + } + + // get the key binding count + keyBindings->keyBindingsCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleKeyBindingsCountMethod, accessibleContext); + + EXCEPTION_CHECK("##### Getting key bindings count - call to CallIntMethod()", FALSE); + + PrintDebugString(" ##### key bindings count = %d", keyBindings->keyBindingsCount); + + // get the key bindings + for (int i = 0; i < keyBindings->keyBindingsCount && i < MAX_KEY_BINDINGS; i++) { + + // get the key binding character + keyBindings->keyBindingInfo[i].character = jniEnv->CallCharMethod(accessBridgeObject, + getAccessibleKeyBindingCharMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting key binding character - call to CallCharMethod()", FALSE); + PrintDebugString(" ##### key binding character = %c", keyBindings->keyBindingInfo[i].character); + PrintDebugString(" ##### key binding character in hex = %hx", keyBindings->keyBindingInfo[i].character); + + // get the key binding modifiers + keyBindings->keyBindingInfo[i].modifiers = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleKeyBindingModifiersMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting key binding modifiers - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### key binding modifiers = %x", keyBindings->keyBindingInfo[i].modifiers); + } + return FALSE; +} + +// AccessibleIcon methods +BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext, + AccessibleIcons *icons) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", + accessibleContext, icons); + + if (getAccessibleIconsCountMethod == (jmethodID) 0 || + getAccessibleIconDescriptionMethod == (jmethodID) 0 || + getAccessibleIconHeightMethod == (jmethodID) 0 || + getAccessibleIconWidthMethod == (jmethodID) 0) { + PrintDebugString(" ##### missing method(s) !!!"); + return FALSE; + } + + + // get the icons count + icons->iconsCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIconsCountMethod, accessibleContext); + + EXCEPTION_CHECK("##### Getting icons count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### icons count = %d", icons->iconsCount); + + + // get the icons + for (int i = 0; i < icons->iconsCount && i < MAX_ICON_INFO; i++) { + + // get the icon description + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleIconDescriptionMethod, + accessibleContext, + i); + + EXCEPTION_CHECK("Getting icon description - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringChars()", FALSE); + wcsncpy(icons->iconInfo[i].description, stringBytes, (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t))) { + length = (sizeof(icons->iconInfo[i].description) / sizeof(wchar_t)) - 2; + } + icons->iconInfo[i].description[length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleIcon description - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleIcon description - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleIcon description - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleIcon description = %ls", icons->iconInfo[i].description ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleIcon description - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleIcon description is null."); + icons->iconInfo[i].description[0] = (wchar_t) 0; + } + + + // get the icon height + icons->iconInfo[i].height = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIconHeightMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting icon height - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### icon height = %d", icons->iconInfo[i].height); + + // get the icon width + icons->iconInfo[i].width = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIconWidthMethod, + accessibleContext, + i); + EXCEPTION_CHECK("##### Getting icon width - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### icon width = %d", icons->iconInfo[i].width); + } + return FALSE; +} + +// AccessibleActionMethods +BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext, + AccessibleActions *actions) { + + jthrowable exception; + const wchar_t *stringBytes; + jsize length; + + PrintDebugString("\r\n##### AccessBridgeJavaEntryPoints::getAccessibleIcons(%p, %p)", + accessibleContext, actions); + + if (getAccessibleActionsCountMethod == (jmethodID) 0 || + getAccessibleActionNameMethod == (jmethodID) 0) { + PrintDebugString(" ##### missing method(s) !!!"); + return FALSE; + } + + + // get the icons count + actions->actionsCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleActionsCountMethod,accessibleContext); + + EXCEPTION_CHECK("##### Getting actions count - call to CallIntMethod()", FALSE); + PrintDebugString(" ##### key actions count = %d", actions->actionsCount); + + + // get the actions + for (int i = 0; i < actions->actionsCount && i < MAX_ACTION_INFO; i++) { + + // get the action name + jstring js = (jstring)jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleActionNameMethod, + accessibleContext, + i); + + EXCEPTION_CHECK("Getting Action Name - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleAction Name - call to GetStringChars()", FALSE); + wcsncpy(actions->actionInfo[i].name , stringBytes, (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + if (length >= (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t))) { + length = (sizeof(actions->actionInfo[i].name ) / sizeof(wchar_t)) - 2; + } + actions->actionInfo[i].name [length] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleAction name - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleAction name - call to ReleaseStringChars()", FALSE); + // jniEnv->CallVoidMethod(accessBridgeObject, + // decrementReferenceMethod, js); + //EXCEPTION_CHECK("Getting AccessibleAction name - call to CallVoidMethod()", FALSE); + PrintDebugString("##### AccessibleAction name = %ls", actions->actionInfo[i].name ); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleAction name - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AccessibleAction name is null."); + actions->actionInfo[i].name [0] = (wchar_t) 0; + } + } + return FALSE; +} + +BOOL AccessBridgeJavaEntryPoints::doAccessibleActions(jobject accessibleContext, + AccessibleActionsToDo *actionsToDo, + jint *failure) { + + jthrowable exception; + BOOL returnVal; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):", + accessibleContext, + actionsToDo->actionsCount, + actionsToDo->actions[0].name); + + if (doAccessibleActionsMethod == (jmethodID) 0) { + *failure = 0; + return FALSE; + } + + PrintDebugString("\r\n doing %d actions ...", actionsToDo->actionsCount); + for (int i = 0; i < actionsToDo->actionsCount && i < MAX_ACTIONS_TO_DO; i++) { + PrintDebugString("\r doing action %d: %s ...", i, actionsToDo->actions[i].name); + + // create a Java String for the action name + wchar_t *actionName = (wchar_t *)actionsToDo->actions[i].name; + jstring javaName = jniEnv->NewString(actionName, (jsize)wcslen(actionName)); + if (javaName == 0) { + PrintDebugString("\r NewString failed"); + *failure = i; + return FALSE; + } + + returnVal = (BOOL)jniEnv->CallBooleanMethod(accessBridgeObject, doAccessibleActionsMethod, + accessibleContext, javaName); + jniEnv->DeleteLocalRef(javaName); + EXCEPTION_CHECK("doAccessibleActions - call to CallBooleanMethod()", FALSE); + + if (returnVal != TRUE) { + PrintDebugString("\r Action %d failed", i); + *failure = i; + return FALSE; + } + } + *failure = -1; + return TRUE; +} + + +/********** AccessibleText routines ***********************************/ + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextInfo(jobject accessibleContext, + AccessibleTextInfo *textInfo, + jint x, jint y) { + jthrowable exception; + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextInfo(%p, %d, %d):", + accessibleContext, x, y); + + // Get the character count + if (getAccessibleCharCountFromContextMethod != (jmethodID) 0) { + textInfo->charCount = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleCharCountFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleCharCount - call to CallIntMethod()", FALSE); + PrintDebugString(" Char count = %d", textInfo->charCount); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleCharCountFromContextMethod == 0"); + return FALSE; + } + + // Get the index of the caret + if (getAccessibleCaretPositionFromContextMethod != (jmethodID) 0) { + textInfo->caretIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleCaretPositionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleCaretPosition - call to CallIntMethod()", FALSE); + PrintDebugString(" Index at caret = %d", textInfo->caretIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleCaretPositionFromContextMethod == 0"); + return FALSE; + } + + // Get the index at the given point + if (getAccessibleIndexAtPointFromContextMethod != (jmethodID) 0) { + textInfo->indexAtPoint = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleIndexAtPointFromContextMethod, + accessibleContext, x, y); + EXCEPTION_CHECK("Getting AccessibleIndexAtPoint - call to CallIntMethod()", FALSE); + PrintDebugString(" Index at point = %d", textInfo->indexAtPoint); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleIndexAtPointFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, + AccessibleTextItemsInfo *textItems, jint index) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the letter at index + if (getAccessibleLetterAtIndexFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleLetterAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to GetStringChars()", FALSE); + textItems->letter = stringBytes[0]; + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to CallVoidMethod()", FALSE); + PrintDebugString(" Accessible Text letter = %c", textItems->letter); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleLetterAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text letter is null."); + textItems->letter = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleLetterAtIndexFromContextMethod == 0"); + return FALSE; + } + + + // Get the word at index + if (getAccessibleWordAtIndexFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleWordAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallIntMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringChars()", FALSE); + wcsncpy(textItems->word, stringBytes, (sizeof(textItems->word) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + textItems->word[length < (sizeof(textItems->word) / sizeof(wchar_t)) ? + length : (sizeof(textItems->word) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text word = %ls", textItems->word); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleWordAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text word is null."); + textItems->word[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleWordAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the sentence at index + if (getAccessibleSentenceAtIndexFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleSentenceAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringChars()", FALSE); + wcsncpy(textItems->sentence, stringBytes, (sizeof(textItems->sentence) / sizeof(wchar_t))-2); + length = jniEnv->GetStringLength(js); + + if (length < sizeof(textItems->sentence) / sizeof(wchar_t)) { + textItems->sentence[length] = (wchar_t) 0; + } else { + textItems->sentence[(sizeof(textItems->sentence) / sizeof(wchar_t))-2] = (wchar_t) 0; + } + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text sentence = %ls", textItems->sentence); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleSentenceAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text sentence is null."); + textItems->sentence[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSentenceAtIndexFromContextMethod == 0"); + return FALSE; + } + + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleContext, + AccessibleTextSelectionInfo *selectionInfo) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):", + accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the selection start index + if (getAccessibleTextSelectionStartFromContextMethod != (jmethodID) 0) { + selectionInfo->selectionStartIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextSelectionStartFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTextSelectionStart - call to CallIntMethod()", FALSE); + PrintDebugString(" Selection start = %d", selectionInfo->selectionStartIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectionStartFromContextMethod == 0"); + return FALSE; + } + + // Get the selection end index + if (getAccessibleTextSelectionEndFromContextMethod != (jmethodID) 0) { + selectionInfo->selectionEndIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextSelectionEndFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTextSelectionEnd - call to CallIntMethod()", FALSE); + PrintDebugString(" Selection end = %d", selectionInfo->selectionEndIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectionEndFromContextMethod == 0"); + return FALSE; + } + + // Get the selected text + if (getAccessibleTextSelectedTextFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextSelectedTextFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringChars()", FALSE); + wcsncpy(selectionInfo->selectedText, stringBytes, (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + selectionInfo->selectedText[length < (sizeof(selectionInfo->selectedText) / sizeof(wchar_t)) ? + length : (sizeof(selectionInfo->selectedText) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to CallVoidMethod()", FALSE); + PrintDebugString(" Accessible's selected text = %s", selectionInfo->selectedText); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleTextSelectedText - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible's selected text is null."); + selectionInfo->selectedText[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextSelectedTextFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleContext, jint index, AccessibleTextAttributesInfo *attributes) { + jstring js; + const wchar_t *stringBytes; + jobject AttributeSet; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + if (accessibleContext == (jobject) 0) { + PrintDebugString(" passed in AccessibleContext == null! (oops)"); + + attributes->bold = FALSE; + attributes->italic = FALSE; + attributes->underline = FALSE; + attributes->strikethrough = FALSE; + attributes->superscript = FALSE; + attributes->subscript = FALSE; + attributes->backgroundColor[0] = (wchar_t) 0; + attributes->foregroundColor[0] = (wchar_t) 0; + attributes->fontFamily[0] = (wchar_t) 0; + attributes->fontSize = -1; + attributes->alignment = -1; + attributes->bidiLevel = -1; + attributes->firstLineIndent = -1; + attributes->leftIndent = -1; + attributes->rightIndent = -1; + attributes->lineSpacing = -1; + attributes->spaceAbove = -1; + attributes->spaceBelow = -1; + attributes->fullAttributesString[0] = (wchar_t) 0; + + return (FALSE); + } + + // Get the AttributeSet + if (getAccessibleAttributeSetAtIndexFromContextMethod != (jmethodID) 0) { + PrintDebugString(" Getting AttributeSet at index..."); + AttributeSet = jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleAttributeSetAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to CallObjectMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleAttributeSetAtIndexFromContextMethod == 0"); + return FALSE; + } + + // It is legal for the AttributeSet object to be null, in which case we return false! + if (AttributeSet == (jobject) 0) { + PrintDebugString(" AttributeSet returned at index is null (this is legal! - see AWT in J2SE 1.3"); + + attributes->bold = FALSE; + attributes->italic = FALSE; + attributes->underline = FALSE; + attributes->strikethrough = FALSE; + attributes->superscript = FALSE; + attributes->subscript = FALSE; + attributes->backgroundColor[0] = (wchar_t) 0; + attributes->foregroundColor[0] = (wchar_t) 0; + attributes->fontFamily[0] = (wchar_t) 0; + attributes->fontSize = -1; + attributes->alignment = -1; + attributes->bidiLevel = -1; + attributes->firstLineIndent = -1; + attributes->leftIndent = -1; + attributes->rightIndent = -1; + attributes->lineSpacing = -1; + attributes->spaceAbove = -1; + attributes->spaceBelow = -1; + attributes->fullAttributesString[0] = (wchar_t) 0; + + return (FALSE); + } + + // Get the bold setting + if (getBoldFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting bold from AttributeSet..."); + attributes->bold = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getBoldFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getBoldFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting BoldFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the italic setting + if (getItalicFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting italic from AttributeSet..."); + attributes->italic = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getItalicFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getItalicdFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting ItalicFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the underline setting + if (getUnderlineFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting underline from AttributeSet..."); + attributes->underline = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getUnderlineFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getUnderlineFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting UnderlineFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the strikethrough setting + if (getStrikethroughFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting strikethrough from AttributeSet..."); + attributes->strikethrough = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getStrikethroughFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getStrikethroughFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting StrikethroughFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the superscript setting + if (getSuperscriptFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting superscript from AttributeSet..."); + attributes->superscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getSuperscriptFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSuperscripteFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SuperscriptFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the subscript setting + if (getSubscriptFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting subscript from AttributeSet..."); + attributes->subscript = (BOOL) jniEnv->CallBooleanMethod(accessBridgeObject, + getSubscriptFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallBooleanMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSubscriptFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SubscriptFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the backgroundColor setting + if (getBackgroundColorFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting backgroundColor from AttributeSet..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getBackgroundColorFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringChars()", FALSE); + wcsncpy(attributes->backgroundColor, stringBytes, (sizeof(attributes->backgroundColor) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->backgroundColor[length < (sizeof(attributes->backgroundColor) / sizeof(wchar_t)) ? + length : (sizeof(attributes->backgroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" AttributeSet's background color = %ls", attributes->backgroundColor); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AttributeSet's background color is null."); + attributes->backgroundColor[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getBackgroundColorFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting BackgroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the foregroundColor setting + if (getForegroundColorFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting foregroundColor from AttributeSet..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getForegroundColorFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringChars()", FALSE); + wcsncpy(attributes->foregroundColor, stringBytes, (sizeof(attributes->foregroundColor) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->foregroundColor[length < (sizeof(attributes->foregroundColor) / sizeof(wchar_t)) ? + length : (sizeof(attributes->foregroundColor) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" AttributeSet's foreground color = %ls", attributes->foregroundColor); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AttributeSet's foreground color is null."); + attributes->foregroundColor[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getForegroundColorFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting ForegroundColorFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the fontFamily setting + if (getFontFamilyFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting fontFamily from AttributeSet..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getFontFamilyFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallObjectMethod()", FALSE); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringChars()", FALSE); + wcsncpy(attributes->fontFamily, stringBytes, (sizeof(attributes->fontFamily) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->fontFamily[length < (sizeof(attributes->fontFamily) / sizeof(wchar_t)) ? + length : (sizeof(attributes->fontFamily) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" AttributeSet's fontFamily = %ls", attributes->fontFamily); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" AttributeSet's fontFamily is null."); + attributes->backgroundColor[0] = (wchar_t) 0; + } + } else { + PrintDebugString(" Error! either env == 0 or getFontFamilyFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting FontFamilyFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the font size + if (getFontSizeFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting font size from AttributeSet..."); + attributes->fontSize = jniEnv->CallIntMethod(accessBridgeObject, + getFontSizeFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallIntMethod()", FALSE); + PrintDebugString(" AttributeSet's font size = %d", attributes->fontSize); + } else { + PrintDebugString(" Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting FontSizeFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + + // Get the alignment setting + if (getAlignmentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting alignment from AttributeSet..."); + attributes->alignment = jniEnv->CallIntMethod(accessBridgeObject, + getAlignmentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getAlignmentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting AlignmentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the bidiLevel setting + if (getBidiLevelFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting bidiLevel from AttributeSet..."); + attributes->bidiLevel = jniEnv->CallIntMethod(accessBridgeObject, + getBidiLevelFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getBidiLevelFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting BidiLevelFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the firstLineIndent setting + if (getFirstLineIndentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting firstLineIndent from AttributeSet..."); + attributes->firstLineIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getFirstLineIndentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getFirstLineIndentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting FirstLineIndentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the leftIndent setting + if (getLeftIndentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting leftIndent from AttributeSet..."); + attributes->leftIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getLeftIndentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getLeftIndentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting LeftIndentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the rightIndent setting + if (getRightIndentFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting rightIndent from AttributeSet..."); + attributes->rightIndent = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getRightIndentFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getRightIndentFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting RightIndentFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the lineSpacing setting + if (getLineSpacingFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting lineSpacing from AttributeSet..."); + attributes->lineSpacing = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getLineSpacingFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getLineSpacingFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting LineSpacingFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the spaceAbove setting + if (getSpaceAboveFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting spaceAbove from AttributeSet..."); + attributes->spaceAbove = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getSpaceAboveFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSpaceAboveFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SpaceAboveFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the spaceBelow setting + if (getSpaceBelowFromAttributeSetMethod != (jmethodID) 0) { + PrintDebugString(" Getting spaceBelow from AttributeSet..."); + attributes->spaceBelow = (jfloat) jniEnv->CallFloatMethod(accessBridgeObject, + getSpaceBelowFromAttributeSetMethod, + AttributeSet); + EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallIntMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or getSpaceBelowFromAttributeSetMethod == 0"); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to CallVoidMethod()", FALSE); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting SpaceBelowFromAttributeSet - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Release the AttributeSet object + if (decrementReferenceMethod != (jmethodID) 0) { + PrintDebugString(" Decrementing reference to AttributeSet..."); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, AttributeSet); + EXCEPTION_CHECK("Releasing AttributeSet object - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or accessBridgeObject == 0"); + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Releasing AttributeSet object - call to DeleteLocalRef()", FALSE); + return FALSE; + } + + // Get the full attributes string at index + if (getAccessibleAttributesAtIndexFromContextMethod != (jmethodID) 0) { + PrintDebugString(" Getting full attributes string from Context..."); + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleAttributesAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringChars()", FALSE); + wcsncpy(attributes->fullAttributesString, stringBytes, (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))); + length = jniEnv->GetStringLength(js); + attributes->fullAttributesString[length < (sizeof(attributes->fullAttributesString) / sizeof(wchar_t)) ? + length : (sizeof(attributes->fullAttributesString) / sizeof(wchar_t))-2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text attributes = %ls", attributes->fullAttributesString); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" Accessible Text attributes is null."); + attributes->fullAttributesString[0] = (wchar_t) 0; + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting AccessibleAttributesAtIndex - call to DeleteLocalRef()", FALSE); + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleAttributesAtIndexFromContextMethod == 0"); + jniEnv->DeleteLocalRef(AttributeSet); + return FALSE; + } + + jniEnv->DeleteLocalRef(AttributeSet); + EXCEPTION_CHECK("Getting AccessibleAttributeSetAtIndex - call to DeleteLocalRef()", FALSE); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) { + + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d", + accessibleContext, index); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the x coord + if (getAccessibleXcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleXcoordTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleXcoordTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" X coord = %d", rectInfo->x); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleXcoordTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the y coord + if (getAccessibleYcoordTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleYcoordTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleYcoordTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" Y coord = %d", rectInfo->y); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleYcoordTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the width + if (getAccessibleWidthTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleWidthTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleWidthTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" Width = %d", rectInfo->width); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleWidthTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + // Get the height + if (getAccessibleHeightTextRectAtIndexFromContextMethod != (jmethodID) 0) { + rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleHeightTextRectAtIndexFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleHeightTextRect - call to CallIntMethod()", FALSE); + PrintDebugString(" Height = %d", rectInfo->height); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleHeightTextRectAtIndexFromContextMethod == 0"); + return FALSE; + } + + return TRUE; +} + +// ===== + +/** + * gets the bounding rectangle for the text caret + */ +BOOL +AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) { + + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d", + accessibleContext, index); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the x coord + if (getCaretLocationXMethod != (jmethodID) 0) { + rectInfo->x = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationXMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret X coordinate - call to CallIntMethod()", FALSE); + PrintDebugString(" X coord = %d", rectInfo->x); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationXMethod == 0"); + return FALSE; + } + + // Get the y coord + if (getCaretLocationYMethod != (jmethodID) 0) { + rectInfo->y = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationYMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret Y coordinate - call to CallIntMethod()", FALSE); + PrintDebugString(" Y coord = %d", rectInfo->y); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationYMethod == 0"); + return FALSE; + } + + // Get the width + if (getCaretLocationWidthMethod != (jmethodID) 0) { + rectInfo->width = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationWidthMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret width - call to CallIntMethod()", FALSE); + PrintDebugString(" Width = %d", rectInfo->width); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationWidthMethod == 0"); + return FALSE; + } + + // Get the height + if (getCaretLocationHeightMethod != (jmethodID) 0) { + rectInfo->height = jniEnv->CallIntMethod(accessBridgeObject, + getCaretLocationHeightMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting caret height - call to CallIntMethod()", FALSE); + PrintDebugString(" Height = %d", rectInfo->height); + } else { + PrintDebugString(" Error! either env == 0 or getCaretLocationHeightMethod == 0"); + return FALSE; + } + + return TRUE; +} + +// ===== + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(jobject accessibleContext, jint index, jint *startIndex, jint *endIndex) { + + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // Get the index of the left boundary of the line containing 'index' + if (getAccessibleTextLineLeftBoundsFromContextMethod != (jmethodID) 0) { + *startIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextLineLeftBoundsFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleTextLineLeftBounds - call to CallIntMethod()", FALSE); + PrintDebugString(" startIndex = %d", *startIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextLineLeftBoundsFromContextMethod == 0"); + return FALSE; + } + + // Get the index of the right boundary of the line containing 'index' + if (getAccessibleTextLineRightBoundsFromContextMethod != (jmethodID) 0) { + *endIndex = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleTextLineRightBoundsFromContextMethod, + accessibleContext, index); + EXCEPTION_CHECK("Getting AccessibleTextLineRightBounds - call to CallIntMethod()", FALSE); + PrintDebugString(" endIndex = %d", *endIndex); + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextLineRightBoundsFromContextMethod == 0"); + return FALSE; + } + + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext, + jint start, jint end, wchar_t *text, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len); + + // Verify the Java VM still exists and AccessibleContext is + // an instance of AccessibleText + if (verifyAccessibleText(accessibleContext) == FALSE) { + return FALSE; + } + + // range is inclusive + if (end < start) { + PrintDebugString(" Error! end < start!"); + text[0] = (wchar_t) 0; + return FALSE; + } + + // Get the text range within [start, end] inclusive + if (getAccessibleTextRangeFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getAccessibleTextRangeFromContextMethod, + accessibleContext, start, end); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringChars()", FALSE); + wPrintDebugString(L" Accessible Text stringBytes returned from Java = %ls", stringBytes); + wcsncpy(text, stringBytes, len); + length = jniEnv->GetStringLength(js); + PrintDebugString(" Accessible Text stringBytes length = %d", length); + text[length < len ? length : len - 2] = (wchar_t) 0; + wPrintDebugString(L" Accessible Text 'text' after null termination = %ls", text); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to CallVoidMethod()", FALSE); + wPrintDebugString(L" Accessible Text range = %ls", text); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting AccessibleTextRange - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" current Accessible Text range is null."); + text[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleTextRangeFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +/********** AccessibleValue routines ***************/ + +BOOL +AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext); + + // Get the current Accessible Value + if (getCurrentAccessibleValueFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getCurrentAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringChars()", FALSE); + wcsncpy(value, stringBytes, len); + length = jniEnv->GetStringLength(js); + value[length < len ? length : len - 2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to CallVoidMethod()", FALSE); + PrintDebugString(" current Accessible Value = %s", value); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting CurrentAccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" current Accessible Value is null."); + value[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getCurrentAccessibleValueFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext); + + // Get the maximum Accessible Value + if (getMaximumAccessibleValueFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getMaximumAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringChars()", FALSE); + wcsncpy(value, stringBytes, len); + length = jniEnv->GetStringLength(js); + value[length < len ? length : len - 2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to CallVoidMethod()", FALSE); + PrintDebugString(" maximum Accessible Value = %s", value); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting MaximumAccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" maximum Accessible Value is null."); + value[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getMaximumAccessibleValueFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { + jstring js; + const wchar_t *stringBytes; + jthrowable exception; + jsize length; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext); + + // Get the mimimum Accessible Value + if (getMinimumAccessibleValueFromContextMethod != (jmethodID) 0) { + js = (jstring) jniEnv->CallObjectMethod(accessBridgeObject, + getMinimumAccessibleValueFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallObjectMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod(), js = %p", js); + if (js != (jstring) 0) { + stringBytes = (const wchar_t *) jniEnv->GetStringChars(js, 0); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringChars()", FALSE); + wcsncpy(value, stringBytes, len); + length = jniEnv->GetStringLength(js); + value[length < len ? length : len - 2] = (wchar_t) 0; + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to GetStringLength()", FALSE); + jniEnv->ReleaseStringChars(js, stringBytes); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to ReleaseStringChars()", FALSE); + jniEnv->CallVoidMethod(accessBridgeObject, + decrementReferenceMethod, js); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to CallVoidMethod()", FALSE); + PrintDebugString(" mimimum Accessible Value = %s", value); + jniEnv->DeleteLocalRef(js); + EXCEPTION_CHECK("Getting MinimumAccessibleValue - call to DeleteLocalRef()", FALSE); + } else { + PrintDebugString(" mimimum Accessible Value is null."); + value[0] = (wchar_t) 0; + return FALSE; + } + } else { + PrintDebugString(" Error! either env == 0 or getMinimumAccessibleValueFromContextMethod == 0"); + return FALSE; + } + return TRUE; +} + + +/********** AccessibleSelection routines ***************/ + +void +AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext); + + // Add the child to the AccessibleSelection + if (addAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + addAccessibleSelectionFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK_VOID("Doing addAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or addAccessibleSelectionFromContextMethod == 0"); + } +} + +void +AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext); + + // Clearing the Selection of the AccessibleSelection + if (clearAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + clearAccessibleSelectionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK_VOID("Doing clearAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or clearAccessibleSelectionFromContextMethod == 0"); + } +} + +jobject +AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibleContext, int i) { + jobject returnedAccessibleContext; + jobject globalRef; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext); + + if (getAccessibleSelectionContextFromContextMethod != (jmethodID) 0) { + returnedAccessibleContext = jniEnv->CallObjectMethod( + accessBridgeObject, + getAccessibleSelectionContextFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to CallObjectMethod()", (jobject) 0); + globalRef = jniEnv->NewGlobalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to NewGlobalRef()", (jobject) 0); + jniEnv->DeleteLocalRef(returnedAccessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelectionContext - call to DeleteLocalRef()", (jobject) 0); + PrintDebugString(" Returning - returnedAccessibleContext = %p; globalRef = %p", + returnedAccessibleContext, globalRef); + return globalRef; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSelectionContextFromContextMethod == 0"); + return (jobject) 0; + } +} + +int +AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject accessibleContext) { + int count; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext); + + // Get (& return) the # of items selected in the AccessibleSelection + if (getAccessibleSelectionCountFromContextMethod != (jmethodID) 0) { + count = jniEnv->CallIntMethod(accessBridgeObject, + getAccessibleSelectionCountFromContextMethod, + accessibleContext); + EXCEPTION_CHECK("Getting AccessibleSelectionCount - call to CallIntMethod()", -1); + PrintDebugString(" returned from CallObjectMethod()"); + return count; + } else { + PrintDebugString(" Error! either env == 0 or getAccessibleSelectionCountFromContextMethod == 0"); + return -1; + } +} + +BOOL +AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject accessibleContext, int i) { + jboolean result; + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext); + + // Get (& return) the # of items selected in the AccessibleSelection + if (isAccessibleChildSelectedFromContextMethod != (jmethodID) 0) { + result = jniEnv->CallBooleanMethod(accessBridgeObject, + isAccessibleChildSelectedFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK("Doing isAccessibleChildSelected - call to CallBooleanMethod()", FALSE); + PrintDebugString(" returned from CallObjectMethod()"); + if (result != 0) { + return TRUE; + } + } else { + PrintDebugString(" Error! either env == 0 or isAccessibleChildSelectedFromContextMethod == 0"); + } + return FALSE; +} + + +void +AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext); + + // Remove the i-th child from the AccessibleSelection + if (removeAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + removeAccessibleSelectionFromContextMethod, + accessibleContext, i); + EXCEPTION_CHECK_VOID("Doing removeAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or removeAccessibleSelectionFromContextMethod == 0"); + } +} + +void +AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) { + jthrowable exception; + + PrintDebugString("\r\nCalling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext); + + // Select all children (if possible) of the AccessibleSelection + if (selectAllAccessibleSelectionFromContextMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + selectAllAccessibleSelectionFromContextMethod, + accessibleContext); + EXCEPTION_CHECK_VOID("Doing selectAllAccessibleSelection - call to CallVoidMethod()"); + PrintDebugString(" returned from CallObjectMethod()"); + } else { + PrintDebugString(" Error! either env == 0 or selectAllAccessibleSelectionFromContextMethod == 0"); + } +} + + +/********** Event Notification Registration routines ***************/ + +BOOL +AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type); + + // Let AccessBridge know we want to add an event type + if (addJavaEventNotificationMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + addJavaEventNotificationMethod, type); + EXCEPTION_CHECK("Doing addJavaEventNotification - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or addJavaEventNotificationMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type); + + // Let AccessBridge know we want to remove an event type + if (removeJavaEventNotificationMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + removeJavaEventNotificationMethod, type); + EXCEPTION_CHECK("Doing removeJavaEventNotification - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or removeJavaEventNotificationMethod == 0"); + return FALSE; + } + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type); + + // Let AccessBridge know we want to add an event type + if (addAccessibilityEventNotificationMethod != (jmethodID) 0) { + PrintDebugString("\r\n addAccessibilityEventNotification: calling void method: accessBridgeObject = %p", accessBridgeObject); + jniEnv->CallVoidMethod(accessBridgeObject, + addAccessibilityEventNotificationMethod, type); + EXCEPTION_CHECK("Doing addAccessibilityEvent - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or addAccessibilityEventNotificationMethod == 0"); + return FALSE; + } + PrintDebugString("\r\n addAccessibilityEventNotification: just returning true"); + return TRUE; +} + +BOOL +AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) { + jthrowable exception; + + PrintDebugString("\r\n in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type); + + // Let AccessBridge know we want to remove an event type + if (removeAccessibilityEventNotificationMethod != (jmethodID) 0) { + jniEnv->CallVoidMethod(accessBridgeObject, + removeAccessibilityEventNotificationMethod, type); + EXCEPTION_CHECK("Doing removeAccessibilityEvent - call to CallVoidMethod()", FALSE); + } else { + PrintDebugString(" Error! either env == 0 or removeAccessibilityEventNotificationMethod == 0"); + return FALSE; + } + return TRUE; +} diff --git a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.h b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.h new file mode 100644 index 00000000000..4233798564f --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.h @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage JNI calls into AccessBridge.java + */ + +#include "AccessBridgePackages.h" + +#include +#include + +#ifndef __AccessBridgeJavaEntryPoints_H__ +#define __AccessBridgeJavaEntryPoints_H__ + +class AccessBridgeJavaEntryPoints { + JNIEnv *jniEnv; + + jobject accessBridgeObject; + + jclass bridgeClass; + jclass eventHandlerClass; + + jmethodID decrementReferenceMethod; + jmethodID getJavaVersionPropertyMethod; + + jmethodID isJavaWindowMethod; + jmethodID isSameObjectMethod; + jmethodID getAccessibleContextFromHWNDMethod; + jmethodID getHWNDFromAccessibleContextMethod; + + jmethodID getAccessibleContextAtMethod; + jmethodID getAccessibleContextWithFocusMethod; + + jmethodID getAccessibleNameFromContextMethod; + jmethodID getAccessibleDescriptionFromContextMethod; + jmethodID getAccessibleRoleStringFromContextMethod; + jmethodID getAccessibleRoleStringFromContext_en_USMethod; + jmethodID getAccessibleStatesStringFromContextMethod; + jmethodID getAccessibleStatesStringFromContext_en_USMethod; + jmethodID getAccessibleParentFromContextMethod; + jmethodID getAccessibleIndexInParentFromContextMethod; + jmethodID getAccessibleChildrenCountFromContextMethod; + jmethodID getAccessibleChildFromContextMethod; + jmethodID getAccessibleBoundsOnScreenFromContextMethod; + jmethodID getAccessibleXcoordFromContextMethod; + jmethodID getAccessibleYcoordFromContextMethod; + jmethodID getAccessibleHeightFromContextMethod; + jmethodID getAccessibleWidthFromContextMethod; + + jmethodID getAccessibleComponentFromContextMethod; + jmethodID getAccessibleActionFromContextMethod; + jmethodID getAccessibleSelectionFromContextMethod; + jmethodID getAccessibleTextFromContextMethod; + jmethodID getAccessibleValueFromContextMethod; + + /* begin AccessibleTable */ + jmethodID getAccessibleTableFromContextMethod; + jmethodID getAccessibleTableRowHeaderMethod; + jmethodID getAccessibleTableColumnHeaderMethod; + jmethodID getAccessibleTableRowCountMethod; + jmethodID getAccessibleTableColumnCountMethod; + jmethodID getAccessibleTableCaptionMethod; + jmethodID getAccessibleTableSummaryMethod; + + jmethodID getContextFromAccessibleTableMethod; + jmethodID getAccessibleTableCellAccessibleContextMethod; + jmethodID getAccessibleTableCellIndexMethod; + jmethodID getAccessibleTableCellRowExtentMethod; + jmethodID getAccessibleTableCellColumnExtentMethod; + jmethodID isAccessibleTableCellSelectedMethod; + + jmethodID getAccessibleTableRowHeaderRowCountMethod; + jmethodID getAccessibleTableColumnHeaderRowCountMethod; + + jmethodID getAccessibleTableRowHeaderColumnCountMethod; + jmethodID getAccessibleTableColumnHeaderColumnCountMethod; + + jmethodID getAccessibleTableRowDescriptionMethod; + jmethodID getAccessibleTableColumnDescriptionMethod; + + jmethodID getAccessibleTableRowSelectionCountMethod; + jmethodID isAccessibleTableRowSelectedMethod; + jmethodID getAccessibleTableRowSelectionsMethod; + + jmethodID getAccessibleTableColumnSelectionCountMethod; + jmethodID isAccessibleTableColumnSelectedMethod; + jmethodID getAccessibleTableColumnSelectionsMethod; + + jmethodID getAccessibleTableRowMethod; + jmethodID getAccessibleTableColumnMethod; + jmethodID getAccessibleTableIndexMethod; + + /* end AccessibleTable */ + + /* begin AccessibleRelationSet */ + + jmethodID getAccessibleRelationSetMethod; + jmethodID getAccessibleRelationCountMethod; + jmethodID getAccessibleRelationKeyMethod; + jmethodID getAccessibleRelationTargetCountMethod; + jmethodID getAccessibleRelationTargetMethod; + + /* end AccessibleRelationSet */ + + // AccessibleHypertext methods + jmethodID getAccessibleHypertextMethod; + jmethodID getAccessibleHyperlinkCountMethod; + jmethodID getAccessibleHyperlinkTextMethod; + jmethodID getAccessibleHyperlinkURLMethod; + jmethodID getAccessibleHyperlinkStartIndexMethod; + jmethodID getAccessibleHyperlinkEndIndexMethod; + jmethodID getAccessibleHypertextLinkIndexMethod; + jmethodID getAccessibleHyperlinkMethod; + jmethodID activateAccessibleHyperlinkMethod; + + // AccessibleKeyBinding + jmethodID getAccessibleKeyBindingsCountMethod; + jmethodID getAccessibleKeyBindingCharMethod; + jmethodID getAccessibleKeyBindingModifiersMethod; + + // AccessibleIcon + jmethodID getAccessibleIconsCountMethod; + jmethodID getAccessibleIconDescriptionMethod; + jmethodID getAccessibleIconHeightMethod; + jmethodID getAccessibleIconWidthMethod; + + // AccessibleAction + jmethodID getAccessibleActionsCountMethod; + jmethodID getAccessibleActionNameMethod; + jmethodID doAccessibleActionsMethod; + + // AccessibleText + jmethodID getAccessibleCharCountFromContextMethod; + jmethodID getAccessibleCaretPositionFromContextMethod; + jmethodID getAccessibleIndexAtPointFromContextMethod; + + jmethodID getAccessibleLetterAtIndexFromContextMethod; + jmethodID getAccessibleWordAtIndexFromContextMethod; + jmethodID getAccessibleSentenceAtIndexFromContextMethod; + + jmethodID getAccessibleTextSelectionStartFromContextMethod; + jmethodID getAccessibleTextSelectionEndFromContextMethod; + jmethodID getAccessibleTextSelectedTextFromContextMethod; + jmethodID getAccessibleAttributesAtIndexFromContextMethod; + jmethodID getAccessibleAttributeSetAtIndexFromContextMethod; + jmethodID getAccessibleTextRectAtIndexFromContextMethod; + jmethodID getAccessibleXcoordTextRectAtIndexFromContextMethod; + jmethodID getAccessibleYcoordTextRectAtIndexFromContextMethod; + jmethodID getAccessibleHeightTextRectAtIndexFromContextMethod; + jmethodID getAccessibleWidthTextRectAtIndexFromContextMethod; + jmethodID getAccessibleTextLineLeftBoundsFromContextMethod; + jmethodID getAccessibleTextLineRightBoundsFromContextMethod; + jmethodID getAccessibleTextRangeFromContextMethod; + + jmethodID getCurrentAccessibleValueFromContextMethod; + jmethodID getMaximumAccessibleValueFromContextMethod; + jmethodID getMinimumAccessibleValueFromContextMethod; + + jmethodID addAccessibleSelectionFromContextMethod; + jmethodID clearAccessibleSelectionFromContextMethod; + jmethodID getAccessibleSelectionContextFromContextMethod; + jmethodID getAccessibleSelectionCountFromContextMethod; + jmethodID isAccessibleChildSelectedFromContextMethod; + jmethodID removeAccessibleSelectionFromContextMethod; + jmethodID selectAllAccessibleSelectionFromContextMethod; + + jmethodID addJavaEventNotificationMethod; + jmethodID removeJavaEventNotificationMethod; + jmethodID addAccessibilityEventNotificationMethod; + jmethodID removeAccessibilityEventNotificationMethod; + + jmethodID getBoldFromAttributeSetMethod; + jmethodID getItalicFromAttributeSetMethod; + jmethodID getUnderlineFromAttributeSetMethod; + jmethodID getStrikethroughFromAttributeSetMethod; + jmethodID getSuperscriptFromAttributeSetMethod; + jmethodID getSubscriptFromAttributeSetMethod; + jmethodID getBackgroundColorFromAttributeSetMethod; + jmethodID getForegroundColorFromAttributeSetMethod; + jmethodID getFontFamilyFromAttributeSetMethod; + jmethodID getFontSizeFromAttributeSetMethod; + jmethodID getAlignmentFromAttributeSetMethod; + jmethodID getBidiLevelFromAttributeSetMethod; + jmethodID getFirstLineIndentFromAttributeSetMethod; + jmethodID getLeftIndentFromAttributeSetMethod; + jmethodID getRightIndentFromAttributeSetMethod; + jmethodID getLineSpacingFromAttributeSetMethod; + jmethodID getSpaceAboveFromAttributeSetMethod; + jmethodID getSpaceBelowFromAttributeSetMethod; + + jmethodID setTextContentsMethod; + jmethodID getParentWithRoleMethod; + jmethodID getTopLevelObjectMethod; + jmethodID getParentWithRoleElseRootMethod; + jmethodID getObjectDepthMethod; + jmethodID getActiveDescendentMethod; + + /** + * Additional methods for Teton + */ + jmethodID getVirtualAccessibleNameFromContextMethod; // Ben Key + jmethodID requestFocusMethod; + jmethodID selectTextRangeMethod; + jmethodID getTextAttributesInRangeMethod; + jmethodID getVisibleChildrenCountMethod; + jmethodID getVisibleChildMethod; + jmethodID setCaretPositionMethod; + + jmethodID getCaretLocationMethod; + jmethodID getCaretLocationXMethod; + jmethodID getCaretLocationYMethod; + jmethodID getCaretLocationHeightMethod; + jmethodID getCaretLocationWidthMethod; + +public: + AccessBridgeJavaEntryPoints(JNIEnv *jniEnvironment, jobject bridgeObject); + ~AccessBridgeJavaEntryPoints(); + BOOL BuildJavaEntryPoints(); + + // HWND management methods + BOOL isJavaWindow(jint window); + jobject getAccessibleContextFromHWND(jint window); + HWND getHWNDFromAccessibleContext(jobject accessibleContext); + + // version methods + BOOL getVersionInfo(AccessBridgeVersionInfo *info); + + // verification methods + BOOL verifyAccessibleText(jobject obj); + + /* ===== utility methods ===== */ + BOOL isSameObject(jobject obj1, jobject obj2); + BOOL setTextContents(const jobject accessibleContext, const wchar_t *text); + jobject getParentWithRole (const jobject accessibleContext, const wchar_t *role); + jobject getTopLevelObject (const jobject accessibleContext); + jobject getParentWithRoleElseRoot (const jobject accessibleContext, const wchar_t *role); + jint getObjectDepth (const jobject accessibleContext); + jobject getActiveDescendent (const jobject accessibleContext); + + // Accessible Context methods + jobject getAccessibleContextAt(jint x, jint y, jobject AccessibleContext); + jobject getAccessibleContextWithFocus(); + BOOL getAccessibleContextInfo(jobject AccessibleContext, AccessibleContextInfo *info); + jobject getAccessibleChildFromContext(jobject AccessibleContext, jint childIndex); + jobject getAccessibleParentFromContext(jobject AccessibleContext); + + /* begin AccessibleTable methods */ + + BOOL getAccessibleTableInfo(jobject acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableCellInfo(jobject accessibleTable,jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo); + + jobject getAccessibleTableRowDescription(jobject acParent, jint row); + jobject getAccessibleTableColumnDescription(jobject acParent, jint column); + + jint getAccessibleTableRowSelectionCount(jobject accessibleTable); + BOOL isAccessibleTableRowSelected(jobject accessibleTable, jint row); + BOOL getAccessibleTableRowSelections(jobject accessibleTable, jint count, jint *selections); + + jint getAccessibleTableColumnSelectionCount(jobject accessibleTable); + BOOL isAccessibleTableColumnSelected(jobject accessibleTable, jint column); + BOOL getAccessibleTableColumnSelections(jobject accessibleTable, jint count, jint *selections); + + jint getAccessibleTableRow(jobject accessibleTable, jint index); + jint getAccessibleTableColumn(jobject accessibleTable, jint index); + jint getAccessibleTableIndex(jobject accessibleTable, jint row, jint column); + + /* end AccessibleTable methods */ + + BOOL getAccessibleRelationSet(jobject accessibleContext, AccessibleRelationSetInfo *relationSetInfo); + + // AccessibleHypertext methods + BOOL getAccessibleHypertext(jobject accessibleContext, AccessibleHypertextInfo *hyperlink); + + BOOL activateAccessibleHyperlink(jobject accessibleContext, jobject accessibleHyperlink); + + BOOL getAccessibleHypertextExt(const jobject accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertext); + jint getAccessibleHyperlinkCount(const jobject accessibleContext); + jint getAccessibleHypertextLinkIndex(const jobject accessibleContext, + const jint nIndex); + BOOL getAccessibleHyperlink(const jobject accessibleContext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + // Accessible Keybinding methods + BOOL getAccessibleKeyBindings(jobject accessibleContext, AccessibleKeyBindings *keyBindings); + + // AccessibleIcon methods + BOOL getAccessibleIcons(jobject accessibleContext, AccessibleIcons *icons); + + // AccessibleActionMethods + BOOL getAccessibleActions(jobject accessibleContext, AccessibleActions *actions); + BOOL doAccessibleActions(jobject accessibleContext, AccessibleActionsToDo *actionsToDo, jint *failure); + + // Accessible Text methods + BOOL getAccessibleTextInfo(jobject AccessibleContext, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL getAccessibleTextItems(jobject AccessibleContext, AccessibleTextItemsInfo *textItems, jint index); + BOOL getAccessibleTextSelectionInfo(jobject AccessibleContext, AccessibleTextSelectionInfo *selectionInfo); + BOOL getAccessibleTextAttributes(jobject AccessibleContext, jint index, AccessibleTextAttributesInfo *attributes); + BOOL getAccessibleTextRect(jobject AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleCaretRect(jobject AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleTextLineBounds(jobject AccessibleContext, jint index, jint *startIndex, jint *endIndex); + BOOL getAccessibleTextRange(jobject AccessibleContext, jint start, jint end, wchar_t *text, short len); + + // Accessible Value methods + BOOL getCurrentAccessibleValueFromContext(jobject AccessibleContext, wchar_t *value, short len); + BOOL getMaximumAccessibleValueFromContext(jobject AccessibleContext, wchar_t *value, short len); + BOOL getMinimumAccessibleValueFromContext(jobject AccessibleContext, wchar_t *value, short len); + + // Accessible Selection methods + void addAccessibleSelectionFromContext(jobject AccessibleContext, int i); + void clearAccessibleSelectionFromContext(jobject AccessibleContext); + jobject getAccessibleSelectionFromContext(jobject AccessibleContext, int i); + int getAccessibleSelectionCountFromContext(jobject AccessibleContext); + BOOL isAccessibleChildSelectedFromContext(jobject AccessibleContext, int i); + void removeAccessibleSelectionFromContext(jobject AccessibleContext, int i); + void selectAllAccessibleSelectionFromContext(jobject AccessibleContext); + + // Event handling methods + BOOL addJavaEventNotification(jlong type); + BOOL removeJavaEventNotification(jlong type); + BOOL addAccessibilityEventNotification(jlong type); + BOOL removeAccessibilityEventNotification(jlong type); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(const jobject accessibleContext, wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(const jobject accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(const jobject accessibleContext, int startIndex, int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(const jobject accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Gets the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(const jobject accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(const jobject accessibleContext, const int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const jobject accessibleContext, int position); + + /** + * Gets the bounding rectangle for the text caret + */ + BOOL getCaretLocation(jobject AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + +}; + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp new file mode 100644 index 00000000000..52316876bca --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.cpp @@ -0,0 +1,2799 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Java applications to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include "AccessBridgeDebug.h" +#include "JavaAccessBridge.h" +#include "com_sun_java_accessibility_AccessBridge.h" // programatically generated by JNI +#include "accessBridgeResource.h" +#include "accessBridgeCallbacks.h" +#include "AccessBridgeMessages.h" + + +#include +#include + +#include +#include + +JavaAccessBridge *theJavaAccessBridge; +HWND theDialogWindow; + +// re-entrance lock for receiving memory messages +CRITICAL_SECTION receiveMemoryIPCLock; + + +// unique broadcast msg. IDs gotten dymanically +extern UINT theFromJavaHelloMsgID; +extern UINT theFromWindowsHelloMsgID; + + +// --------------------------------------------------------------------------- + +extern "C" { + /** + * DllMain - where Windows executables will load/unload us + * + */ + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + InitializeCriticalSection(&receiveMemoryIPCLock); + theJavaAccessBridge = new JavaAccessBridge(hinstDll); + break; + + case DLL_PROCESS_DETACH: // A Windows executable unloaded us + if (theJavaAccessBridge != (JavaAccessBridge *) 0) { + delete theJavaAccessBridge; + DeleteCriticalSection(&receiveMemoryIPCLock); + } + break; + } + return TRUE; + } + + /** + * Open a native window (and init the wrappers we'll be using) + * + */ + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_runDLL(JNIEnv *env, jobject obj) { + PrintDebugString("\r\nJavaAccessBridge.DLL runDLL() called"); + theJavaAccessBridge->javaRun(env, obj); + } + +#if 0 // SetDlgItemText has caused problems with JAWS + /** + * Append debug info to dialog + * + */ + void AppendToCallInfo(char *s) { + char buffer[4096]; + + PrintDebugString(s); + + GetDlgItemText(theDialogWindow, cCallInfo, buffer, sizeof(buffer)); + if (strlen(buffer) < (sizeof(buffer) - strlen(s))) { + strncat(buffer, s, sizeof(buffer)); + SetDlgItemText(theDialogWindow, cCallInfo, buffer); + } else { + SetDlgItemText(theDialogWindow, cCallInfo, s); + } + } +#endif + + + /** + * Our window proc + * + */ + BOOL APIENTRY AccessBridgeDialogProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) { + int command; + COPYDATASTRUCT *sentToUs; + char *package; + //DEBUG_CODE(char buffer[256]); + + switch (message) { + case WM_INITDIALOG: + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Initializing")); + break; + + case WM_COMMAND: + command = LOWORD (wParam); + break; + + // call from Java with data for us to deliver + case WM_COPYDATA: + if (theDialogWindow == (HWND) wParam) { + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got WM_COPYDATA from ourselves")); + } else { + //DEBUG_CODE(sprintf(buffer, "Got WM_COPYDATA from HWND %p", wParam)); + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer)); + sentToUs = (COPYDATASTRUCT *) lParam; + package = (char *) sentToUs->lpData; + theJavaAccessBridge->processPackage(package, sentToUs->cbData); + } + break; + + // call from Java with data for us retrieve from memory mapped file and deliver + case AB_MESSAGE_WAITING: + // wParam == sourceHwnd + // lParam == buffer size in shared memory + if (theDialogWindow == (HWND) wParam) { + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_MESSAGE_WAITING from ourselves")); + } else { + //DEBUG_CODE(sprintf(buffer, "Got AB_MESSAGE_WAITING from HWND %p", wParam)); + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, buffer)); + LRESULT returnVal = theJavaAccessBridge->receiveMemoryPackage((HWND) wParam, lParam); + } + break; + + // a JavaAccessBridge DLL is going away + case AB_DLL_GOING_AWAY: + // wParam == sourceHwnd + //DEBUG_CODE(SetDlgItemText(theDialogWindow, cStatusText, "Got AB_DLL_GOING_AWAY message")); + theJavaAccessBridge->WindowsATDestroyed((HWND) wParam); + break; + + default: + // the Windows AT is saying "hi"! + // wParam == sourceHwnc; lParam unused + if (message == theFromWindowsHelloMsgID) { + // A new Windows AT just said "hi"; + // say "hi" back so it can mate up with us + // otherwise don't do anything (e.g. don't set up data structures yet) + theJavaAccessBridge->postHelloToWindowsDLLMsg((HWND) wParam); + } + } + return FALSE; + } + +} + + +// ----------------------------- + + +/** + * Initialize the JavaAccessBridge + * + */ +JavaAccessBridge::JavaAccessBridge(HINSTANCE hInstance) { + windowsInstance = hInstance; + ATs = (AccessBridgeATInstance *) 0; + initBroadcastMessageIDs(); // get the unique to us broadcast msg. IDs +} + +extern DWORD JavaBridgeThreadId; + +/** + * Destroy the JavaAccessBridge + * + */ +JavaAccessBridge::~JavaAccessBridge() { + // inform all other AccessBridges that we're going away + + PrintDebugString("\r\nin JavaAccessBridge::~JavaAccessBridge()"); + + // Send a shutdown message for those applications like StarOffice that do + // send a shutdown message themselves. + javaShutdown(NULL, 0); + + AccessBridgeATInstance *current = ATs; + while (current != (AccessBridgeATInstance *) 0) { + PrintDebugString(" telling %p we're going away", current->winAccessBridgeWindow); + SendMessage(current->winAccessBridgeWindow, + AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0); + current = current->nextATInstance; + } + + PrintDebugString(" finished telling ATs about our demise"); + + if(JavaBridgeThreadId) + { + PostThreadMessage(JavaBridgeThreadId,WM_USER+1,0,0); + Sleep(100); + } + + delete ATs; + + PrintDebugString(" finished deleting ATs"); + PrintDebugString("GOODBYE CRUEL WORLD..."); +} + + +void +JavaAccessBridge::javaRun(JNIEnv *env, jobject obj) { + MSG msg; + + PrintDebugString("JavaAccessBridge::javaRun(%p, %p) called", env, obj); + + if (env->GetJavaVM(&javaVM) != 0) { + return; // huh!?!?! + } + PrintDebugString(" -> javaVM = %p", javaVM); + + if (javaVM->AttachCurrentThread((void **) &windowsThreadJNIEnv, NULL) != 0) { + return; // huh!?!?! + } + PrintDebugString(" -> windowsThreadJNIEnv = %p", windowsThreadJNIEnv); + + javaThreadABObject = env->NewGlobalRef(obj); + windowsThreadABObject = windowsThreadJNIEnv->NewGlobalRef(obj); + + // initialize the Java thread AccessBridge entry points + javaThreadEntryPoints = new AccessBridgeJavaEntryPoints(env, javaThreadABObject); + if (javaThreadEntryPoints->BuildJavaEntryPoints() == FALSE) { + return; // couldn't build our entry points; let's get out of here! + } + PrintDebugString(" all Java thread entry points successfully found."); + + // initialize the Windows thread AccessBridge entry points + windowsThreadEntryPoints = new AccessBridgeJavaEntryPoints(windowsThreadJNIEnv, + windowsThreadABObject); + if (windowsThreadEntryPoints->BuildJavaEntryPoints() == FALSE) { + return; // couldn't build our entry points; let's get out of here! + } + PrintDebugString(" all Windows thread entry points successfully found."); + + + // open our window + if (initWindow() == TRUE) { + PrintDebugString(" Window created. HWND = %p", dialogWindow); + + // post a broadcast msg.; let other AccessBridge DLLs know we exist + postHelloToWindowsDLLMsg(HWND_BROADCAST); + + // do that message loop thing + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } else { + PrintDebugString(" FAILED TO CREATE WINDOW!!!"); + } + + javaVM->DetachCurrentThread(); +} + +/** + * Bring up our window; make a connection to the rest of the world + * + */ +BOOL +JavaAccessBridge::initWindow() { + theDialogWindow = CreateDialog(windowsInstance, + "ACCESSBRIDGESTATUSWINDOW", NULL, + (DLGPROC) AccessBridgeDialogProc); + + // If window could not be created, return "failure". + if (!theDialogWindow) + return FALSE; + + dialogWindow = theDialogWindow; + + // Make the window visible, update its client area, & return "success". + // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL)); + // DEBUG_CODE(UpdateWindow (theDialogWindow)); + + return TRUE; +} + + + +// ----------------------- + + +/** + * postHelloToWindowsDLLMsg + * - PostMessage(theFromJavaHelloMsgID) to let one or + * all WindowDLLs we're here and have a vmID + * + * destHwnd is either a single hwnd or HWND_BROADCAST + * (former if a reply, latter if we're just born) + * wParam is our HWND + * lParam is our vmID + * + */ +void +JavaAccessBridge::postHelloToWindowsDLLMsg(HWND destHwnd) { + PrintDebugString("\r\nin JavaAccessBridge::postHelloToWindowsDLLMsg"); + PrintDebugString(" calling PostMessage(%p, %X, %p, %p)", + destHwnd, theFromJavaHelloMsgID, dialogWindow, javaVM); + PostMessage(destHwnd, theFromJavaHelloMsgID, (WPARAM) dialogWindow, (LPARAM) dialogWindow); +} + + +// ----------------------- + +/** + * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging + * with the Java AccessBridge DLL + * + */ +void +JavaAccessBridge::sendPackage(char *buffer, int bufsize, HWND destHwnd) { + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = bufsize; + toCopy.lpData = buffer; + + SendMessage(destHwnd, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy); +} + + +/** + * sendJavaEventPackage - walk through ATs, sending event messages to 'em + * + */ +void +JavaAccessBridge::sendJavaEventPackage(char *buffer, int bufsize, long type) { + + PrintDebugString("JavaAccessBridge::sendJavaEventPackage(), type = %X", type); + + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + } + + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + ati->sendJavaEventPackage(buffer, bufsize, type); + ati = ati->nextATInstance; + } +} + +/** + * sendAccessibilityEventPackage - walk through ATs, sending event messages to 'em + * + */ +void +JavaAccessBridge::sendAccessibilityEventPackage(char *buffer, int bufsize, long type) { + + PrintDebugString("JavaAccessBridge::sendAccessibilityEventPackage(), type = %X", type); + + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + } + + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + ati->sendAccessibilityEventPackage(buffer, bufsize, type); + ati = ati->nextATInstance; + } +} + + + + +/** + * receiveMemoryPackage - uses Memory-Mapped files to do IPC messaging + * with the Java AccessBridge DLL, receiving the + * message from Java AccessBridge DLL by reading the + * contents of the shared memory mapped file that + * is used for Java-initiated messages + * + */ +BOOL +JavaAccessBridge::receiveMemoryPackage(HWND srcWindow, long bufsize) { + char *IPCview; + + PrintDebugString("\r\nJavaAccessBridge::receiveMemoryPackage(%p, %d)", srcWindow, bufsize); + + // look-up the appropriate IPCview based on the srcHWND of the Windows AccessBridge DLL + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR! - ATs == 0 (shouldn't happen in receiveMemoryPackage()!"); + return FALSE; + } + AccessBridgeATInstance *ati = ATs->findABATInstanceFromATHWND(srcWindow); + if (ati != (AccessBridgeATInstance *) 0) { + IPCview = (char *) ati->memoryMappedView; + + // wait for the lock if someone else has it (re-entrancy) + EnterCriticalSection(&receiveMemoryIPCLock); + { + // set byte at end of buffer to indicate to caller that we have reached this point + IPCview[bufsize] = 1; + + // process the package + processPackage(IPCview, bufsize); + } + // release re-entrance lock + LeaveCriticalSection(&receiveMemoryIPCLock); + + return TRUE; + + } else { + //DEBUG_CODE(AppendToCallInfo("ERROR receiving memory package: couldn't find srcWindow")); + PrintDebugString("ERROR receiving memory package: couldn't find srcWindow"); + return FALSE; + } +} + +/** + * processPackage - processes the output of SendMessage(WM_COPYDATA) + * to do IPC messaging with the Windows AccessBridge DLL + * + */ +LRESULT +JavaAccessBridge::processPackage(char *buffer, int bufsize) { + PrintDebugString("\r\nProcessing package sent from Windows, bufsize = %d:", bufsize); + + PackageType *type = (PackageType *) buffer; + LRESULT returnVal = 0; + PrintDebugString(" PackageType = %X:", *type); + jobject rAC; + + switch (*type) { + + + case cMemoryMappedFileCreatedPackage: + // Windows is telling us it created a memory mapped file for us to use + // in repsonding to various information querying packages (see below) + PrintDebugString(" type == cMemoryMappedFileCreatedPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage))) { + MemoryMappedFileCreatedPackage *pkg = + (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType)); + returnVal = MemoryMappedFileCreated((HWND)ABLongToHandle(pkg->bridgeWindow), pkg->filename); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage)); + } + break; + + // ------------ information querying packages ------------------ + + case cReleaseJavaObjectPackage: + PrintDebugString(" type == cReleaseJavaObjectPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage))) { + ReleaseJavaObjectPackage *pkg = + (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType)); + releaseJavaObject((jobject)pkg->object); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)); + } + break; + + case cGetAccessBridgeVersionPackage: + PrintDebugString(" type == cGetAccessBridgeVersionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage))) { + GetAccessBridgeVersionPackage *pkg = + (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getVersionInfo(&(pkg->rVersionInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)); + } + break; + + case cIsJavaWindowPackage: + PrintDebugString(" type == cIsJavaWindowPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsJavaWindowPackage))) { + IsJavaWindowPackage *pkg = + (IsJavaWindowPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->isJavaWindow(pkg->window); + PrintDebugString(" -> returning result = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsJavaWindowPackage)); + } + break; + + case cIsSameObjectPackage: + PrintDebugString(" type == cIsSameObjectPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsSameObjectPackage))) { + IsSameObjectPackage *pkg = + (IsSameObjectPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->isSameObject((jobject)pkg->obj1, (jobject)pkg->obj2); + PrintDebugString(" -> returning result = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsSameObjectPackage)); + } + break; + + + case cGetAccessibleContextFromHWNDPackage: + PrintDebugString(" type == cGetAccessibleContextFromHWNDPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage))) { + GetAccessibleContextFromHWNDPackage *pkg = + (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getAccessibleContextFromHWND(pkg->window); + pkg->rAccessibleContext = (JOBJECT64)rAC; + pkg->rVMID = HandleToLong(dialogWindow); + PrintDebugString(" -> returning AC = %p, vmID = %X", rAC, pkg->rVMID); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)); + } + break; + + + case cGetHWNDFromAccessibleContextPackage: + PrintDebugString(" type == cGetHWNDFromAccessibleContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage))) { + GetHWNDFromAccessibleContextPackage *pkg = + (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType)); + pkg->rHWND = + ABHandleToLong( windowsThreadEntryPoints->getHWNDFromAccessibleContext((jobject)pkg->accessibleContext) ); + PrintDebugString(" -> returning HWND = %p", pkg->rHWND); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)); + } + break; + + + /* ===== utility methods ===== */ + + case cSetTextContentsPackage: + PrintDebugString(" type == cSetTextContentsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SetTextContentsPackage))) { + SetTextContentsPackage *pkg = + (SetTextContentsPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->setTextContents((jobject)pkg->accessibleContext, pkg->text); + PrintDebugString(" -> returning result = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SetTextContentsPackage)); + } + break; + + case cGetParentWithRolePackage: + if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRolePackage))) { + GetParentWithRolePackage *pkg = + (GetParentWithRolePackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getParentWithRole((jobject)pkg->accessibleContext, pkg->role); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" type == cGetParentWithRolePackage"); + PrintDebugString(" pkg->vmID: %X", pkg->vmID); + PrintDebugString(" pkg->accessibleContext: %p", (jobject)pkg->accessibleContext); + PrintDebugString(" pkg->role: %ls", pkg->role); + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetParentWithRolePackage)); + } + break; + + case cGetTopLevelObjectPackage: + PrintDebugString(" type == cGetTopLevelObjectPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetTopLevelObjectPackage))) { + GetTopLevelObjectPackage *pkg = + (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getTopLevelObject((jobject)pkg->accessibleContext); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)); + } + break; + + case cGetParentWithRoleElseRootPackage: + PrintDebugString(" type == cGetParentWithRoleElseRootPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage))) { + GetParentWithRoleElseRootPackage *pkg = + (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getParentWithRoleElseRoot((jobject)pkg->accessibleContext, pkg->role); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)); + } + break; + + case cGetObjectDepthPackage: + PrintDebugString(" type == cGetObjectDepthPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetObjectDepthPackage))) { + GetObjectDepthPackage *pkg = + (GetObjectDepthPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->getObjectDepth((jobject)pkg->accessibleContext); + PrintDebugString(" -> returning rResult = %d", pkg->rResult); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetObjectDepthPackage)); + } + break; + + case cGetActiveDescendentPackage: + PrintDebugString(" type == cGetActiveDescendentPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetActiveDescendentPackage))) { + GetActiveDescendentPackage *pkg = + (GetActiveDescendentPackage *) (buffer + sizeof(PackageType)); + rAC = windowsThreadEntryPoints->getActiveDescendent((jobject)pkg->accessibleContext); + pkg->rAccessibleContext = (JOBJECT64)rAC; + PrintDebugString(" -> returning rAccessibleContext = %p", rAC); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetActiveDescendentPackage)); + } + break; + + case cGetAccessibleContextAtPackage: + PrintDebugString(" type == cGetAccessibleContextAtPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage))) { + GetAccessibleContextAtPackage *pkg = + (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64) + windowsThreadEntryPoints->getAccessibleContextAt(pkg->x, pkg->y, + (jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)); + } + break; + + case cGetAccessibleContextWithFocusPackage: + PrintDebugString(" type == cGetAccessibleContextWithFocusPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage))) { + GetAccessibleContextWithFocusPackage *pkg = + (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64) + windowsThreadEntryPoints->getAccessibleContextWithFocus(); + pkg->rVMID = HandleToLong(dialogWindow); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)); + } + break; + + case cGetAccessibleContextInfoPackage: + PrintDebugString(" type == cGetAccessibleContextInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage))) { + GetAccessibleContextInfoPackage *pkg = + (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleContextInfo( + (jobject)pkg->AccessibleContext, &(pkg->rAccessibleContextInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)); + } + break; + + case cGetAccessibleChildFromContextPackage: + PrintDebugString(" type == cGetAccessibleChildFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage))) { + GetAccessibleChildFromContextPackage *pkg = + (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleChildFromContext( + (jobject)pkg->AccessibleContext, pkg->childIndex); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)); + } + break; + + case cGetAccessibleParentFromContextPackage: + PrintDebugString(" type == cGetAccessibleParentFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage))) { + GetAccessibleParentFromContextPackage *pkg = + (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleParentFromContext( + (jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)); + } + break; + + // ------------ begin AccessibleTable packages ------------------ + + case cGetAccessibleTableInfoPackage: + PrintDebugString(" ##### type == cGetAccessibleTableInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage))) { + GetAccessibleTableInfoPackage *pkg = + (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableInfo((jobject)pkg->accessibleContext, + &(pkg->rTableInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)); + } + break; + + case cGetAccessibleTableCellInfoPackage: + PrintDebugString(" ##### type == cGetAccessibleTableCellInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage))) { + GetAccessibleTableCellInfoPackage *pkg = + (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableCellInfo((jobject)pkg->accessibleTable, pkg->row, + pkg->column, &(pkg->rTableCellInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)); + } + break; + + case cGetAccessibleTableRowHeaderPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowHeaderPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage))) { + GetAccessibleTableRowHeaderPackage *pkg = + (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableRowHeader((jobject)pkg->accessibleContext, + &(pkg->rTableInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)); + } + break; + + case cGetAccessibleTableColumnHeaderPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnHeaderPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage))) { + GetAccessibleTableColumnHeaderPackage *pkg = + (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableColumnHeader((jobject)pkg->accessibleContext, + &(pkg->rTableInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)); + } + break; + + + case cGetAccessibleTableRowDescriptionPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowDescriptionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage))) { + GetAccessibleTableRowDescriptionPackage *pkg = + (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableRowDescription( + (jobject)pkg->accessibleContext, pkg->row); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)); + } + break; + + case cGetAccessibleTableColumnDescriptionPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnDescriptionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage))) { + GetAccessibleTableColumnDescriptionPackage *pkg = + (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleTableColumnDescription( + (jobject)pkg->accessibleContext, pkg->column); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)); + } + break; + + case cGetAccessibleTableColumnSelectionCountPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnSelectionCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage))) { + GetAccessibleTableColumnSelectionCountPackage *pkg = + (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType)); + pkg->rCount = windowsThreadEntryPoints->getAccessibleTableColumnSelectionCount( + (jobject)pkg->accessibleTable); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)); + } + break; + + case cGetAccessibleTableRowSelectionCountPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowSelectionCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage))) { + GetAccessibleTableRowSelectionCountPackage *pkg = + (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType)); + + pkg->rCount = windowsThreadEntryPoints->getAccessibleTableRowSelectionCount( + (jobject)pkg->accessibleTable); + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)); + } + break; + + case cIsAccessibleTableRowSelectedPackage: + PrintDebugString(" ##### type == cIsAccessibleTableRowSelectedPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage))) { + IsAccessibleTableRowSelectedPackage *pkg = + (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->isAccessibleTableRowSelected( + (jobject)pkg->accessibleTable, pkg->row); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)); + } + break; + + case cIsAccessibleTableColumnSelectedPackage: + PrintDebugString(" ##### type == cIsAccessibleTableColumnSelectedPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage))) { + IsAccessibleTableColumnSelectedPackage *pkg = + (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->isAccessibleTableColumnSelected( + (jobject)pkg->accessibleTable, pkg->column); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)); + } + break; + + case cGetAccessibleTableColumnSelectionsPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnSelectionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage))) { + GetAccessibleTableColumnSelectionsPackage *pkg = + (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType)); + PrintDebugString(" ##### cGetAccessibleTableColumnSelectionsPackage count=%d", pkg->count); + windowsThreadEntryPoints->getAccessibleTableColumnSelections( + (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections); + + for (int i = 0; i < pkg->count; i++) { + PrintDebugString(" ##### cGetAccessibleTableColumnSelectionsPackage(%d)=%d", i, pkg->rSelections[i]); + } + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)); + } + break; + + + case cGetAccessibleTableRowSelectionsPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowSelectionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage))) { + GetAccessibleTableRowSelectionsPackage *pkg = + (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTableRowSelections( + (jobject)pkg->accessibleTable, pkg->count, pkg->rSelections); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)); + } + break; + + case cGetAccessibleTableRowPackage: + PrintDebugString(" ##### type == cGetAccessibleTableRowPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage))) { + GetAccessibleTableRowPackage *pkg = + (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType)); + pkg->rRow = windowsThreadEntryPoints->getAccessibleTableRow( + (jobject)pkg->accessibleTable, pkg->index); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)); + } + break; + + case cGetAccessibleTableColumnPackage: + PrintDebugString(" ##### type == cGetAccessibleTableColumnPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage))) { + GetAccessibleTableColumnPackage *pkg = + (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType)); + pkg->rColumn = windowsThreadEntryPoints->getAccessibleTableColumn( + (jobject)pkg->accessibleTable, pkg->index); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)); + } + break; + + case cGetAccessibleTableIndexPackage: + PrintDebugString(" ##### type == cGetAccessibleTableIndexPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage))) { + GetAccessibleTableIndexPackage *pkg = + (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType)); + pkg->rIndex = windowsThreadEntryPoints->getAccessibleTableIndex( + (jobject)pkg->accessibleTable, pkg->row, pkg->column); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)); + } + break; + + // ------------ end AccessibleTable packages ------------------ + + + // ------------ begin AccessibleRelationSet packages ------------------ + + case cGetAccessibleRelationSetPackage: + PrintDebugString(" ##### type == cGetAccessibleRelationSetPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage))) { + GetAccessibleRelationSetPackage *pkg = + (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleRelationSet( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleRelationSetInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)); + } + break; + + // ------------ end AccessibleRelationSet packages ------------------ + + // ------------ begin AccessibleHypertext packages ------------------ + + case cGetAccessibleHypertextPackage: + PrintDebugString(" ##### type == cGetAccessibleHypertextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage))) { + GetAccessibleHypertextPackage *pkg = + (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleHypertext( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleHypertextInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)); + } + break; + + case cActivateAccessibleHyperlinkPackage: + PrintDebugString(" ##### type == cActivateAccessibleHyperlinkPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage))) { + ActivateAccessibleHyperlinkPackage *pkg = + (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->activateAccessibleHyperlink( + (jobject)pkg->accessibleContext, (jobject)pkg->accessibleHyperlink); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)); + } + break; + + case cGetAccessibleHyperlinkCountPackage: + PrintDebugString(" ##### type == cGetAccessibleHyperlinkCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage))) { + GetAccessibleHyperlinkCountPackage *pkg = + (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType)); + pkg->rLinkCount = windowsThreadEntryPoints->getAccessibleHyperlinkCount( + (jobject)pkg->accessibleContext); + PrintDebugString(" ##### processing succeeded: pkg->rLinkCount = %d", pkg->rLinkCount); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)); + } + break; + + case cGetAccessibleHypertextExtPackage: + PrintDebugString(" ##### type == cGetAccessibleHypertextExtPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage))) { + GetAccessibleHypertextExtPackage *pkg = + (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType)); + pkg->rSuccess = windowsThreadEntryPoints->getAccessibleHypertextExt( + (jobject)pkg->accessibleContext, pkg->startIndex, &(pkg->rAccessibleHypertextInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)); + } + break; + + case cGetAccessibleHypertextLinkIndexPackage: + PrintDebugString(" ##### type == cGetAccessibleHypertextLinkIndexPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage))) { + GetAccessibleHypertextLinkIndexPackage *pkg = + (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType)); + pkg->rLinkIndex = windowsThreadEntryPoints->getAccessibleHypertextLinkIndex( + (jobject)pkg->hypertext, pkg->charIndex); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)); + } + break; + + case cGetAccessibleHyperlinkPackage: + PrintDebugString(" ##### type == cGetAccessibleHyperlinkPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage))) { + GetAccessibleHyperlinkPackage *pkg = + (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleHyperlink((jobject)pkg->hypertext, pkg->linkIndex, + &(pkg->rAccessibleHyperlinkInfo)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)); + } + break; + + // ------------ end AccessibleHypertext packages + + // ------------ begin Accessible KeyBindings, Icons and Actions + + case cGetAccessibleKeyBindingsPackage: + PrintDebugString(" ##### type == cGetAccessibleKeyBindingsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage))) { + GetAccessibleKeyBindingsPackage *pkg = + (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleKeyBindings ( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleKeyBindings)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)); + } + break; + + case cGetAccessibleIconsPackage: + PrintDebugString(" ##### type == cGetAccessibleIconsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleIconsPackage))) { + GetAccessibleIconsPackage *pkg = + (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleIcons ( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleIcons)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)); + } + break; + + + case cGetAccessibleActionsPackage: + PrintDebugString(" ##### type == cGetAccessibleActionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleActionsPackage))) { + GetAccessibleActionsPackage *pkg = + (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleActions ( + (jobject)pkg->accessibleContext, &(pkg->rAccessibleActions)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)); + } + break; + + case cDoAccessibleActionsPackage: + PrintDebugString(" ##### type == cDoAccessibleActionsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(DoAccessibleActionsPackage))) { + DoAccessibleActionsPackage *pkg = + (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = + windowsThreadEntryPoints->doAccessibleActions((jobject)pkg->accessibleContext, &(pkg->actionsToDo), + &(pkg->failure)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)); + } + break; + + // ------------ begin addtional methods for Teton + + case cGetVirtualAccessibleNamePackage: + PrintDebugString(" ##### type == GetVirtualAccessibleNamePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage))) { + GetVirtualAccessibleNamePackage *pkg = + (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getVirtualAccessibleName ((const jobject)pkg->accessibleContext, + pkg->rName, + pkg->len); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)); + } + break; + + case cRequestFocusPackage: + PrintDebugString(" ##### type == RequestFocusPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RequestFocusPackage))) { + RequestFocusPackage *pkg = + (RequestFocusPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->requestFocus ( + (jobject)pkg->accessibleContext); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RequestFocusPackage)); + } + break; + + case cSelectTextRangePackage: + PrintDebugString(" ##### type == SelectTextRangePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SelectTextRangePackage))) { + SelectTextRangePackage *pkg = + (SelectTextRangePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->selectTextRange ( + (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SelectTextRangePackage)); + } + break; + + case cGetTextAttributesInRangePackage: + PrintDebugString(" ##### type == GetTextAttributesInRangePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage))) { + GetTextAttributesInRangePackage *pkg = + (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getTextAttributesInRange ( + (jobject)pkg->accessibleContext, pkg->startIndex, pkg->endIndex, + (AccessibleTextAttributesInfo *)&(pkg->attributes), + &(pkg->rLength)); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)); + } + break; + + + case cGetVisibleChildrenCountPackage: + PrintDebugString(" ##### type == GetVisibleChildrenCountPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage))) { + GetVisibleChildrenCountPackage *pkg = + (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType)); + pkg->rChildrenCount = windowsThreadEntryPoints->getVisibleChildrenCount ((jobject)pkg->accessibleContext); + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)); + } + break; + + case cGetVisibleChildrenPackage: + PrintDebugString(" ##### type == GetVisibleChildrenPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetVisibleChildrenPackage))) { + GetVisibleChildrenPackage *pkg = + (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType)); + pkg->rSuccess = windowsThreadEntryPoints->getVisibleChildren ((jobject)pkg->accessibleContext, + pkg->startIndex, + &(pkg->rVisibleChildrenInfo)); + + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)); + } + break; + + case cSetCaretPositionPackage: + PrintDebugString(" ##### type == SetCaretPositionPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SetCaretPositionPackage))) { + SetCaretPositionPackage *pkg = + (SetCaretPositionPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->setCaretPosition ( + (jobject)pkg->accessibleContext, pkg->position); + PrintDebugString(" ##### processing succeeded"); + } else { + PrintDebugString(" ##### processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SetCaretPositionPackage)); + } + break; + + // ------------ end additional methods for Teton + + // ------------ end Accessible KeyBindings, Icons and Actions + + // ------------ Accessible Text packages ------------------ + + case cGetAccessibleTextInfoPackage: + PrintDebugString(" type == cGetAccessibleTextInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage))) { + GetAccessibleTextInfoPackage *pkg = + (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextInfo((jobject)pkg->AccessibleContext, + &(pkg->rTextInfo), pkg->x, pkg->y); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)); + } + break; + + case cGetAccessibleTextItemsPackage: + PrintDebugString(" type == cGetAccessibleTextItemsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage))) { + GetAccessibleTextItemsPackage *pkg = + (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextItems((jobject)pkg->AccessibleContext, + &(pkg->rTextItemsInfo), pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)); + } + break; + + case cGetAccessibleTextSelectionInfoPackage: + PrintDebugString(" type == cGetAccessibleTextSelectionInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage))) { + GetAccessibleTextSelectionInfoPackage *pkg = + (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextSelectionInfo( + (jobject)pkg->AccessibleContext, &(pkg->rTextSelectionItemsInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)); + } + break; + + case cGetAccessibleTextAttributeInfoPackage: + PrintDebugString(" type == cGetAccessibleTextAttributeInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage))) { + GetAccessibleTextAttributeInfoPackage *pkg = + (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextAttributes( + (jobject)pkg->AccessibleContext, pkg->index, (AccessibleTextAttributesInfo *) &(pkg->rAttributeInfo)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)); + } + break; + + case cGetAccessibleTextRectInfoPackage: + PrintDebugString(" type == cGetAccessibleTextRectInfoPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage))) { + GetAccessibleTextRectInfoPackage *pkg = + (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextRect((jobject)pkg->AccessibleContext, + &(pkg->rTextRectInfo), pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)); + } + break; + + case cGetCaretLocationPackage: + PrintDebugString(" type == cGetCaretLocationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetCaretLocationPackage))) { + GetCaretLocationPackage *pkg = + (GetCaretLocationPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getCaretLocation((jobject)pkg->AccessibleContext, + &(pkg->rTextRectInfo), pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetCaretLocationPackage)); + } + break; + + case cGetAccessibleTextLineBoundsPackage: + PrintDebugString(" type == cGetAccessibleTextLineBoundsPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage))) { + GetAccessibleTextLineBoundsPackage *pkg = + (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextLineBounds((jobject)pkg->AccessibleContext, + pkg->index, &(pkg->rLineStart), &(pkg->rLineEnd)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)); + } + break; + + case cGetAccessibleTextRangePackage: + PrintDebugString(" type == cGetAccessibleTextRangePackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage))) { + GetAccessibleTextRangePackage *pkg = + (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getAccessibleTextRange((jobject)pkg->AccessibleContext, + pkg->start, pkg->end, (wchar_t *) &(pkg->rText), (sizeof(pkg->rText) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)); + } + break; + + + // ------------ Accessible Value packages ------------------ + + case cGetCurrentAccessibleValueFromContextPackage: + PrintDebugString(" type == cGetCurrentAccessibleValueFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage))) { + GetCurrentAccessibleValueFromContextPackage *pkg = + (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getCurrentAccessibleValueFromContext((jobject)pkg->AccessibleContext, + (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage)); + } + break; + + case cGetMaximumAccessibleValueFromContextPackage: + PrintDebugString(" type == cGetMaximumAccessibleValueFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage))) { + GetMaximumAccessibleValueFromContextPackage *pkg = + (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getMaximumAccessibleValueFromContext((jobject)pkg->AccessibleContext, + (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage)); + } + break; + + case cGetMinimumAccessibleValueFromContextPackage: + PrintDebugString(" type == cGetMinimumAccessibleValueFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage))) { + GetMinimumAccessibleValueFromContextPackage *pkg = + (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->getMinimumAccessibleValueFromContext((jobject)pkg->AccessibleContext, + (wchar_t *) &(pkg->rValue), (sizeof(pkg->rValue) / sizeof(wchar_t))); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage)); + } + break; + + // ------------ Accessible Selection packages ------------------ + + case cAddAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cAddAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage))) { + AddAccessibleSelectionFromContextPackage *pkg = + (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->addAccessibleSelectionFromContext((jobject)pkg->AccessibleContext, + pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage)); + } + break; + + case cClearAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cClearAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage))) { + ClearAccessibleSelectionFromContextPackage *pkg = + (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->clearAccessibleSelectionFromContext((jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage)); + } + break; + + case cGetAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cGetAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage))) { + GetAccessibleSelectionFromContextPackage *pkg = + (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rAccessibleContext = (JOBJECT64)windowsThreadEntryPoints->getAccessibleSelectionFromContext( + (jobject)pkg->AccessibleContext, pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage)); + } + break; + + case cGetAccessibleSelectionCountFromContextPackage: + PrintDebugString(" type == cGetAccessibleSelectionCountFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage))) { + GetAccessibleSelectionCountFromContextPackage *pkg = + (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rCount = windowsThreadEntryPoints->getAccessibleSelectionCountFromContext( + (jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage)); + } + break; + + case cIsAccessibleChildSelectedFromContextPackage: + PrintDebugString(" type == cIsAccessibleChildSelectedFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage))) { + IsAccessibleChildSelectedFromContextPackage *pkg = + (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType)); + pkg->rResult = windowsThreadEntryPoints->isAccessibleChildSelectedFromContext( + (jobject)pkg->AccessibleContext, pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage)); + } + break; + + case cRemoveAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cRemoveAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage))) { + RemoveAccessibleSelectionFromContextPackage *pkg = + (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->removeAccessibleSelectionFromContext((jobject)pkg->AccessibleContext, + pkg->index); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage)); + } + break; + + case cSelectAllAccessibleSelectionFromContextPackage: + PrintDebugString(" type == cSelectAllAccessibleSelectionFromContextPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage))) { + SelectAllAccessibleSelectionFromContextPackage *pkg = + (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + windowsThreadEntryPoints->selectAllAccessibleSelectionFromContext((jobject)pkg->AccessibleContext); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage)); + } + break; + + + // ------------ event notification management packages ------------------ + + case cAddJavaEventNotificationPackage: + PrintDebugString(" type = cAddJavaEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage))) { + AddJavaEventNotificationPackage *pkg = + (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + addJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow ) ); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)); + } + break; + + case cRemoveJavaEventNotificationPackage: + PrintDebugString(" type = cRemoveJavaEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage))) { + RemoveJavaEventNotificationPackage *pkg = + (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + removeJavaEventNotification(pkg->type, (HWND)ABLongToHandle( pkg->DLLwindow )); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)); + } + break; + + case cAddAccessibilityEventNotificationPackage: + PrintDebugString(" type = cAddAccessibilityEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage))) { + AddAccessibilityEventNotificationPackage *pkg = + (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + addAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)); + } + break; + + case cRemoveAccessibilityEventNotificationPackage: + PrintDebugString(" type = cRemoveAccessibilityEventNotificationPackage"); + if (bufsize == (sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage))) { + RemoveAccessibilityEventNotificationPackage *pkg = + (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + removeAccessibilityEventNotification(pkg->type, (HWND)ABLongToHandle(pkg->DLLwindow)); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)); + } + break; + + default: + PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + returnVal = -1; + break; + } + + PrintDebugString(" package processing completed"); + return returnVal; +} + + +// ----------------------------- + + +/** + * MemoryMappedFileCreated + * - WindowsDLL letting us know it's created a memory-mapped file + * for IPC. We need to open it and write a magic string into + * it to let the WindowsDLL know all is OK. Also we need to + * set up our own data structures to communicate with the + * WindowsDLL + * + */ +LRESULT +JavaAccessBridge::MemoryMappedFileCreated(HWND ATBridgeDLLWindow, char *filename) { + PrintDebugString(" in MemoryMappedFileCreated(%p, %s)!", ATBridgeDLLWindow, filename); + AccessBridgeATInstance *newAT = + new AccessBridgeATInstance(dialogWindow, ATBridgeDLLWindow, filename, ATs); + PrintDebugString(" just created a new ATInstance = %p, old = %p", newAT, ATs); + ATs = newAT; + + LRESULT returnVal = ATs->initiateIPC(); + if (returnVal == 0) { + PrintDebugString(" Successfully initiated IPC with AT!!!"); + } else { + PrintDebugString(" ERROR: Failed to initiate IPC with AT!!!"); + } + + return returnVal; +} + + +/** + * WindowsATDestroyed - lets the JavaABDLL know a Windows AT disappeared + * + */ +void +JavaAccessBridge::WindowsATDestroyed(HWND ATBridgeDLLWindow) { + PrintDebugString("\r\nin JavaAccessBridge::WindowsATDestroyed(%p)", ATBridgeDLLWindow); + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! -> ATs == 0! (shouldn't happen here)"); + return; + } + + AccessBridgeATInstance *currentAT = ATs; + AccessBridgeATInstance *previousAT = ATs; + if (ATs->winAccessBridgeWindow == ATBridgeDLLWindow) { + ATs = ATs->nextATInstance; + // remove event notification for this AT + removeJavaEventNotification(currentAT->javaEventMask, ATBridgeDLLWindow); + removeAccessibilityEventNotification(currentAT->accessibilityEventMask, ATBridgeDLLWindow); + delete currentAT; + PrintDebugString(" data structures successfully removed"); + } else { + while (currentAT != (AccessBridgeATInstance *) NULL) { + if (currentAT->winAccessBridgeWindow == ATBridgeDLLWindow) { + previousAT->nextATInstance = currentAT->nextATInstance; + delete currentAT; + PrintDebugString(" data structures successfully removed"); + return; + } else { + previousAT = currentAT; + currentAT = currentAT->nextATInstance; + } + } + PrintDebugString(" ERROR!! couldn't find matching data structures!"); + } +} + + +// ----------------------------- + + +/** + * releaseJavaObject - lets the JavaVM know it can release the Java Object + * + * Note: once you have made this call, the JavaVM will garbage collect + * the jobject you pass in. If you later use that jobject in another + * call, you will cause all maner of havoc! + * + */ +void +JavaAccessBridge::releaseJavaObject(jobject object) { + PrintDebugString("In JavaAccessBridge::releaseJavaObject"); + PrintDebugString(" object X: %p", object); + if (windowsThreadJNIEnv != (JNIEnv *) 0) { + windowsThreadJNIEnv->DeleteGlobalRef(object); + PrintDebugString(" global reference deleted.", object); + } else { + PrintDebugString(" Error! windowsThreadJNIEnv == 0"); + } +} + +// ----------------------------- + +/** + * addJavaEventNotification - this AT now wants this type of events + * + */ +void +JavaAccessBridge::addJavaEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and add this type + // and, if we weren't listening for these before, ask Java for 'em + PrintDebugString(" adding Java event type %016I64X to HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->javaEventMask |= type; + PrintDebugString(" found HWND, javaEventMask now is %X", ati->javaEventMask); + } else { + globalEventMask |= ati->javaEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Java AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // start getting them from Java + PrintDebugString(" no other AT wanted this Java event (so not registered); adding to AccessBridge.java"); + windowsThreadEntryPoints->addJavaEventNotification(type); + } +} + +/** + * removeJavaEventNotification - this AT no longer wants this type of events + * + */ +void +JavaAccessBridge::removeJavaEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and remove this type + // and, if no other AT wants 'em either, tell Java we no longer want 'em + PrintDebugString(" removing Java event type %016I64X from HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->javaEventMask &= (0xFFFFFFFF - type); + PrintDebugString(" found HWND, javaEventMask now is %X", ati->javaEventMask); + } else { + globalEventMask |= ati->javaEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Java AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // stop getting them from Java + PrintDebugString(" no other AT wanted this Java event (so can remove); removing from AccessBridge.java"); + windowsThreadEntryPoints->removeJavaEventNotification(type); + } +} + + +/** + * addAccesibilityEventNotification - this AT now wants this type of events + * + */ +void +JavaAccessBridge::addAccessibilityEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and add this type + // and, if we weren't listening for these before, ask Java for 'em + PrintDebugString(" adding Accesibility event type %016I64X to HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->accessibilityEventMask |= type; + PrintDebugString(" found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); + } else { + globalEventMask |= ati->accessibilityEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Accessibility AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // start getting them from Java + PrintDebugString(" no other AT wanted this Accesibility event (so not registered); adding to AccessBridge.java"); + windowsThreadEntryPoints->addAccessibilityEventNotification(type); + } +} + +/** + * removeAccesibilityEventNotification - this AT no longer wants this type of events + * + */ +void +JavaAccessBridge::removeAccessibilityEventNotification(jlong type, HWND DLLwindow) { + // walk through list of ATs, find this one and remove this type + // and, if no other AT wants 'em either, tell Java we no longer want 'em + PrintDebugString(" removing Accesibility event type %016I64X from HWND %p", type, DLLwindow); + AccessBridgeATInstance *ati = ATs; + long globalEventMask = 0; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->winAccessBridgeWindow == DLLwindow) { + ati->accessibilityEventMask &= (0xFFFFFFFF - type); + PrintDebugString(" found HWND, accessibilityEventMask now is %X", ati->accessibilityEventMask); + } else { + globalEventMask |= ati->accessibilityEventMask; + } + ati = ati->nextATInstance; + } + PrintDebugString(" union of all Accessibility AT event masks: %X", globalEventMask); + if (!(globalEventMask & type)) { + // no other ATs wanted this event; + // stop getting them from Java + PrintDebugString(" no other AT wanted this Accessibility event (so can remove); removing from AccessBridge.java"); + windowsThreadEntryPoints->removeAccessibilityEventNotification(type); + } +} + + + + +/** + * firePropertyCaretChange + * + */ +void +JavaAccessBridge::firePropertyCaretChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jint oldValue, jint newValue) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyCaretChanged(%p, %p, %p, %p, %d, %d)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyCaretChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyCaretChangePackage *pkg = (PropertyCaretChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyCaretChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + pkg->oldPosition = oldValue; + pkg->newPosition = newValue; + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyCaretChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyCaretChange event"); +} + +/** + * firePropertyDescriptionChange + * + */ +void +JavaAccessBridge::firePropertyDescriptionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyDescriptionChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyDescriptionChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyDescriptionChangePackage *pkg = (PropertyDescriptionChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyDescriptionChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyCaretChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldDescription, stringBytes, (sizeof(pkg->oldDescription) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldDescription, L"(null)", (sizeof(pkg->oldDescription) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newDescription, stringBytes, (sizeof(pkg->newDescription) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newDescription, L"(null)", (sizeof(pkg->newDescription) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyDescriptionChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyDescriptionChange event"); +} + +/** + * firePropertyNameChange + * + */ +void +JavaAccessBridge::firePropertyNameChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyNameChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyNameChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyNameChangePackage *pkg = (PropertyNameChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyNameChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyNameChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldName, stringBytes, (sizeof(pkg->oldName) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldName, L"(null)", (sizeof(pkg->oldName) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newName, stringBytes, (sizeof(pkg->newName) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newName, L"(null)", (sizeof(pkg->newName) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyNameChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyNameChange event"); +} + + +/** + * firePropertySelectionChange + * + */ +void +JavaAccessBridge::firePropertySelectionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertySelectionChanged(%p, %p, %p, %p)", + env, callingObj, event, source); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertySelectionChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertySelectionChangePackage *pkg = (PropertySelectionChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertySelectionChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertySelectionChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertySelectionChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertySelectionChange event"); +} + + +/** + * firePropertyStateChange + * + */ +void +JavaAccessBridge::firePropertyStateChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyStateChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyStateChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyStateChangePackage *pkg = (PropertyStateChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyStateChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyStateChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldState, stringBytes, (sizeof(pkg->oldState) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldState, L"(null)", (sizeof(pkg->oldState) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newState, stringBytes, (sizeof(pkg->newState) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newState, L"(null)", (sizeof(pkg->newState) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyStateChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyStateChange event"); +} + + +/** + * firePropertyTextChange + * + */ +void +JavaAccessBridge::firePropertyTextChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTextChanged(%p, %p, %p, %p)", + env, callingObj, event, source); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyTextChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyTextChangePackage *pkg = (PropertyTextChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyTextChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyTextChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTextChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyTextChange event"); +} + + +/** + * firePropertyValueChange + * + */ +void +JavaAccessBridge::firePropertyValueChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyValueChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyValueChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyValueChangePackage *pkg = (PropertyValueChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyValueChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyValueChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyValueChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyValueChange event"); +} + +/** + * firePropertyVisibleDataChange + * + */ +void +JavaAccessBridge::firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChanged(%p, %p, %p, %p)", + env, callingObj, event, source); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyVisibleDataChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyVisibleDataChangePackage *pkg = (PropertyVisibleDataChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyVisibleDataChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyVisibleDataChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyVisibleDataChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyVisibleDataChange event"); +} + + +/** + * firePropertyChildChange + * + */ +void +JavaAccessBridge::firePropertyChildChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyChildPropertyChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyChildChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyChildChangePackage *pkg = (PropertyChildChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyChildChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyChildChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); + pkg->oldChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue); + pkg->newChildAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldChildAC: %p", pkg->oldChildAccessibleContext); + PrintDebugString(" GlobalRef'd NewChildAC: %p", pkg->newChildAccessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldChildAC: %016I64X", pkg->oldChildAccessibleContext); + PrintDebugString(" GlobalRef'd NewChildAC: %016I64X", pkg->newChildAccessibleContext); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyChildChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyChildChange event"); +} + + +/** + * firePropertyActiveDescendentChange + * + */ +void +JavaAccessBridge::firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentPropertyChanged(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + char buffer[sizeof(PackageType) + sizeof(PropertyActiveDescendentChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyActiveDescendentChangePackage *pkg = (PropertyActiveDescendentChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyActiveDescendentChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyActiveDescendentChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); + pkg->oldActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(oldValue); + pkg->newActiveDescendentAccessibleContext = (JOBJECT64)env->NewGlobalRef(newValue); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldActiveDescendentAC: %p", pkg->oldActiveDescendentAccessibleContext); + PrintDebugString(" GlobalRef'd NewActiveDescendentAC: %p", pkg->newActiveDescendentAccessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); + PrintDebugString(" GlobalRef'd OldActiveDescendentAC: %016I64X", pkg->oldActiveDescendentAccessibleContext); + PrintDebugString(" GlobalRef'd NewActiveDescendentAC: %016I64X", pkg->newActiveDescendentAccessibleContext); +#endif + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyActiveDescendentChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyActiveChange event"); +} + +/** + * firePropertyValueChange + * + */ +void +JavaAccessBridge::firePropertyTableModelChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue){ + + PrintDebugString("\r\nJava_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(%p, %p, %p, %p, %p, %p)", + env, callingObj, event, + source, oldValue, newValue); + + // sanity check + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; // panic! + } + + // common setup + const wchar_t *stringBytes; + char buffer[sizeof(PackageType) + sizeof(PropertyTableModelChangePackage)]; + PackageType *type = (PackageType *) buffer; + PropertyTableModelChangePackage *pkg = (PropertyTableModelChangePackage *) (buffer + sizeof(PackageType)); + *type = cPropertyTableModelChangePackage; + pkg->vmID = (long) dialogWindow; + + // make new Global Refs and send events only to those ATs that want 'em + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->accessibilityEventMask & cPropertyTableModelChangeEvent) { + + PrintDebugString(" sending to AT"); + + // make new GlobalRefs for this AT + pkg->Event = (JOBJECT64)env->NewGlobalRef(event); + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + + if (oldValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(oldValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->oldValue, stringBytes, (sizeof(pkg->oldValue) / sizeof(wchar_t))); + env->ReleaseStringChars(oldValue, stringBytes); + } else { + wcsncpy(pkg->oldValue, L"(null)", (sizeof(pkg->oldValue) / sizeof(wchar_t))); + } + + if (newValue != (jstring) 0) { + stringBytes = (const wchar_t *) env->GetStringChars(newValue, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wcsncpy(pkg->newValue, stringBytes, (sizeof(pkg->newValue) / sizeof(wchar_t))); + env->ReleaseStringChars(newValue, stringBytes); + } else { + wcsncpy(pkg->newValue, L"(null)", (sizeof(pkg->newValue) / sizeof(wchar_t))); + } + + ati->sendAccessibilityEventPackage(buffer, sizeof(buffer), cPropertyTableModelChangeEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with propertyTableModelChange event"); +} + + + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +#define PRINT_GLOBALREFS() \ + PrintDebugString(" GlobalRef'd Event: %p", pkg->Event); \ + PrintDebugString(" GlobalRef'd Source: %p", pkg->AccessibleContextSource); +#else // JOBJECT64 is jlong (64 bit) +#define PRINT_GLOBALREFS() \ + PrintDebugString(" GlobalRef'd Event: %016I64X", pkg->Event); \ + PrintDebugString(" GlobalRef'd Source: %016I64X", pkg->AccessibleContextSource); +#endif + +#define FIRE_EVENT(function, packageStruct, packageConstant, eventConstant) \ + void JavaAccessBridge::function(JNIEnv *env, jobject callingObj, \ + jobject eventObj, jobject source) { \ + \ + PrintDebugString("\r\nFiring event id = %d(%p, %p, %p, %p); vmID = %X", \ + eventConstant, env, callingObj, eventObj, source, javaVM); \ + \ + /* sanity check */ \ + if (ATs == (AccessBridgeATInstance *) 0) { \ + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); \ + return; /* panic! */ \ + } \ + \ + /* common setup */ \ + char buffer[sizeof(PackageType) + sizeof(packageStruct)]; \ + PackageType *type = (PackageType *) buffer; \ + packageStruct *pkg = (packageStruct *) (buffer + sizeof(PackageType)); \ + *type = packageConstant; \ + pkg->vmID = (long) dialogWindow; \ + \ + /* make new Global Refs, send events only to those ATs that want 'em */ \ + AccessBridgeATInstance *ati = ATs; \ + while (ati != (AccessBridgeATInstance *) 0) { \ + PrintDebugString("\r\njavaEventMask = %X eventConstant=%d pkg->vmID=%X", \ + ati->javaEventMask, eventConstant, pkg->vmID ); \ + if (ati->javaEventMask & eventConstant) { \ + \ + PrintDebugString(" sending to AT"); \ + /* make new GlobalRefs for this AT */ \ + pkg->Event = (JOBJECT64)env->NewGlobalRef(eventObj); \ + pkg->AccessibleContextSource = (JOBJECT64)env->NewGlobalRef(source); \ + PRINT_GLOBALREFS() \ + \ + ati->sendJavaEventPackage(buffer, sizeof(buffer), eventConstant); \ + } \ + ati = ati->nextATInstance; \ + } \ + PrintDebugString(" done with firing AWT event"); \ + } + + void JavaAccessBridge::javaShutdown(JNIEnv *env, jobject callingObj) { + + PrintDebugString("\r\nFiring event id = %d(%p, %p); vmID = %X", + cJavaShutdownEvent, env, callingObj, javaVM); + + /* sanity check */ + if (ATs == (AccessBridgeATInstance *) 0) { + PrintDebugString(" ERROR!! ATs == 0! (shouldn't happen here!)"); + return; /* panic! */ + } + + /* common setup */ + char buffer[sizeof(PackageType) + sizeof(JavaShutdownPackage)]; + PackageType *type = (PackageType *) buffer; + JavaShutdownPackage *pkg = (JavaShutdownPackage *) (buffer + sizeof(PackageType)); + *type = cJavaShutdownPackage; + pkg->vmID = (long) dialogWindow; + + /* make new Global Refs, send events only to those ATs that want 'em */ + AccessBridgeATInstance *ati = ATs; + while (ati != (AccessBridgeATInstance *) 0) { + if (ati->javaEventMask & cJavaShutdownEvent) { + PrintDebugString(" sending to AT"); + ati->sendJavaEventPackage(buffer, sizeof(buffer), cJavaShutdownEvent); + } + ati = ati->nextATInstance; + } + PrintDebugString(" done with firing AWT event"); + } + + FIRE_EVENT(fireFocusGained, FocusGainedPackage, cFocusGainedPackage, cFocusGainedEvent) + FIRE_EVENT(fireFocusLost, FocusLostPackage, cFocusLostPackage, cFocusLostEvent) + FIRE_EVENT(fireCaretUpdate, CaretUpdatePackage, cCaretUpdatePackage, cCaretUpdateEvent) + FIRE_EVENT(fireMouseClicked, MouseClickedPackage, cMouseClickedPackage, cMouseClickedEvent) + FIRE_EVENT(fireMouseEntered, MouseEnteredPackage, cMouseEnteredPackage, cMouseEnteredEvent) + FIRE_EVENT(fireMouseExited, MouseExitedPackage, cMouseExitedPackage, cMouseExitedEvent) + FIRE_EVENT(fireMousePressed, MousePressedPackage, cMousePressedPackage, cMousePressedEvent) + FIRE_EVENT(fireMouseReleased, MouseReleasedPackage, cMouseReleasedPackage, cMouseReleasedEvent) + FIRE_EVENT(fireMenuCanceled, MenuCanceledPackage, cMenuCanceledPackage, cMenuCanceledEvent) + FIRE_EVENT(fireMenuDeselected, MenuDeselectedPackage, cMenuDeselectedPackage, cMenuDeselectedEvent) + FIRE_EVENT(fireMenuSelected, MenuSelectedPackage, cMenuSelectedPackage, cMenuSelectedEvent) + FIRE_EVENT(firePopupMenuCanceled, PopupMenuCanceledPackage, cPopupMenuCanceledPackage, cPopupMenuCanceledEvent) + FIRE_EVENT(firePopupMenuWillBecomeInvisible, PopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisiblePackage, cPopupMenuWillBecomeInvisibleEvent) + FIRE_EVENT(firePopupMenuWillBecomeVisible, PopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisiblePackage, cPopupMenuWillBecomeVisibleEvent) + + + // ----------------------------- + + +extern "C" { // event stuff from AccessBridge.h, generated by JNI + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_sendDebugString(JNIEnv *env, jobject callingObj, jstring debugStr) { + + const wchar_t *stringBytes; + stringBytes = (const wchar_t *) env->GetStringChars(debugStr, 0); + if (stringBytes == NULL) { + if (!env->ExceptionCheck()) { + jclass cls = env->FindClass("java/lang/OutOfMemoryError"); + if (cls != NULL) { + env->ThrowNew(cls, NULL); + } + } + return; + } + wPrintJavaDebugString(L"AccessBridge.java: %ls", stringBytes); + env->ReleaseStringChars(debugStr, stringBytes); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyCaretChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jint oldValue, jint newValue) { + theJavaAccessBridge->firePropertyCaretChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyDescriptionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyDescriptionChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyNameChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyNameChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertySelectionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + theJavaAccessBridge->firePropertySelectionChange(env, callingObj, + event, source); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyStateChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyStateChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyTextChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + theJavaAccessBridge->firePropertyTextChange(env, callingObj, + event, source); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyValueChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + theJavaAccessBridge->firePropertyValueChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyVisibleDataChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source) { + theJavaAccessBridge->firePropertyVisibleDataChange(env, callingObj, + event, source); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyChildChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue) { + theJavaAccessBridge->firePropertyChildChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyActiveDescendentChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, + jobject newValue) { + theJavaAccessBridge->firePropertyActiveDescendentChange(env, callingObj, + event, source, + oldValue, newValue); + } + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_propertyTableModelChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue) { + + theJavaAccessBridge->firePropertyTableModelChange(env, callingObj, + event, source, + oldValue, newValue); + } + +#define HANDLE_STANDARD_EVENT_FROM_JAVA(function, method) \ + JNIEXPORT void JNICALL \ + function(JNIEnv *env, jobject callingObj, jobject event, jobject source) { \ + theJavaAccessBridge->method(env, callingObj, event, source); \ + } + + + JNIEXPORT void JNICALL + Java_com_sun_java_accessibility_AccessBridge_javaShutdown(JNIEnv *env, jobject callingObj) { + theJavaAccessBridge->javaShutdown(env, callingObj); + } + + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusGained, fireFocusGained) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_focusLost, fireFocusLost) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_caretUpdate, fireCaretUpdate) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseClicked, fireMouseClicked) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseEntered, fireMouseEntered) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseExited, fireMouseExited) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mousePressed, fireMousePressed) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_mouseReleased, fireMouseReleased) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuCanceled, fireMenuCanceled) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuDeselected, fireMenuDeselected) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_menuSelected, fireMenuSelected) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuCanceled, firePopupMenuCanceled) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeInvisible, firePopupMenuWillBecomeInvisible) + HANDLE_STANDARD_EVENT_FROM_JAVA(Java_com_sun_java_accessibility_AccessBridge_popupMenuWillBecomeVisible, firePopupMenuWillBecomeVisible) + + /* + * Map a HWND to a Java component + * + * Class: com_sun_java_accessibility_AccessBridge + * Method: jawtGetComponentFromNativeWindowHandle + * Signature: (I)Ljava/awt/Component; + */ + JNIEXPORT jobject JNICALL + Java_com_sun_java_accessibility_AccessBridge_jawtGetComponentFromNativeWindowHandle + (JNIEnv *env, jobject callingObj, jint windowHandle) { + + JAWT awt; + jboolean result; + jobject component = (jobject)0; + + // Get the AWT + awt.version = JAWT_VERSION_1_4; + result = JAWT_GetAWT(env, &awt); + if (result == JNI_FALSE) { + return (jobject)0; + } + + // Get the component + return awt.GetComponent(env, (void *)windowHandle); + } + + + /* + * Map a Java component to a HWND + * + * Class: com_sun_java_accessibility_AccessBridge + * Method: jawtGetNativeWindowHandleFromComponent + * Signature: (Ljava/awt/Component;)I + */ + JNIEXPORT jint JNICALL + Java_com_sun_java_accessibility_AccessBridge_jawtGetNativeWindowHandleFromComponent + (JNIEnv *env, jobject callingObj, jobject component) { + + JAWT awt; + JAWT_DrawingSurface* ds; + JAWT_DrawingSurfaceInfo* dsi; + JAWT_Win32DrawingSurfaceInfo* dsi_win; + jboolean result; + // jint lock; + jint windowHandle = -1; + + // Get the AWT + awt.version = JAWT_VERSION_1_4; + result = JAWT_GetAWT(env, &awt); + if (result == JNI_FALSE) { + return -1; + } + + // Get the drawing surface + ds = awt.GetDrawingSurface(env, component); + if (ds == NULL) { + return -1; + } + + // Get the drawing surface info + dsi = ds->GetDrawingSurfaceInfo(ds); + + // Get the platform-specific drawing info + dsi_win = (JAWT_Win32DrawingSurfaceInfo *)dsi->platformInfo; + + // Get the window handle + windowHandle = (jint)dsi_win->hwnd; + + // Free the drawing surface info + ds->FreeDrawingSurfaceInfo(dsi); + + // Free the drawing surface + awt.FreeDrawingSurface(ds); + + return windowHandle; + } + +} diff --git a/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.h b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.h new file mode 100644 index 00000000000..d03960f7f00 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libjavaaccessbridge/JavaAccessBridge.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Java applications to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include +#include + +#include "AccessBridgePackages.h" +#include "AccessBridgeATInstance.h" +#include "AccessBridgeJavaEntryPoints.h" + +#ifndef __JavaAccessBridge_H__ +#define __JavaAccessBridge_H__ + + +extern "C" { + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, + LPVOID lpvReserved); + void AppendToCallOutput(char *s); + BOOL APIENTRY AccessBridgeDialogProc(HWND hDlg, UINT message, + UINT wParam, LONG lParam); +} + +/** + * The JavaAccessBridge class. The core of the Windows AT AccessBridge dll + */ +class JavaAccessBridge { +// for debugging +public: +// for debugging + HINSTANCE windowsInstance; + HWND dialogWindow; + AccessBridgeATInstance *ATs; + JavaVM *javaVM; + JNIEnv *windowsThreadJNIEnv; // for calls initiated from Windows + AccessBridgeJavaEntryPoints *javaThreadEntryPoints; + AccessBridgeJavaEntryPoints *windowsThreadEntryPoints; + jobject javaThreadABObject; // for calls initiated from Java + jobject windowsThreadABObject; // for calls initiated from Windows + +public: + JavaAccessBridge(HINSTANCE hInstance); + ~JavaAccessBridge(); + void javaRun(JNIEnv *env, jobject obj); + BOOL initWindow(); + + // IPC with the Java AccessBridge DLL + void postHelloToWindowsDLLMsg(HWND destHwnd); + LRESULT MemoryMappedFileCreated(HWND srcHwnd, char *filename); + + void sendPackage(char *buffer, int bufsize, HWND destHwnd); + void sendJavaEventPackage(char *buffer, int bufsize, long type); + void sendAccessibilityEventPackage(char *buffer, int bufsize, long type); + BOOL sendMemoryPackage(char *buffer, long bufsize, HWND destWindow); + LRESULT processPackage(char *buffer, int bufsize); + BOOL receiveMemoryPackage(HWND srcWindow, long bufsize); + void WindowsATDestroyed(HWND ATBridgeDLLWindow); + + // Java VM object memory management + void releaseJavaObject(jobject object); + + // Event handling methods + void addJavaEventNotification(jlong type, HWND DLLwindow); + void removeJavaEventNotification(jlong type, HWND DLLwindow); + void addAccessibilityEventNotification(jlong type, HWND DLLwindow); + void removeAccessibilityEventNotification(jlong type, HWND DLLwindow); + + // Event firing methods +/* + void firePropertyChange(JNIEnv *env, jobject callingObj, + jobject propertyChangeEvent, + jobject source, jstring propertyName, + jstring oldValue, jstring newValue); +*/ + + void javaShutdown(JNIEnv *env, jobject callingObj); + + void fireFocusGained(JNIEnv *env, jobject callingObj, + jobject focusEvent, jobject source); + void fireFocusLost(JNIEnv *env, jobject callingObj, + jobject focusEvent,jobject source); + void fireCaretUpdate(JNIEnv *env, jobject callingObj, + jobject caretEvent, jobject source); + void fireMouseClicked(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMouseEntered(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMouseExited(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMousePressed(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMouseReleased(JNIEnv *env, jobject callingObj, + jobject mouseEvent, jobject source); + void fireMenuCanceled(JNIEnv *env, jobject callingObj, + jobject menuEvent, jobject source); + void fireMenuDeselected(JNIEnv *env, jobject callingObj, + jobject menuEvent, jobject source); + void fireMenuSelected(JNIEnv *env, jobject callingObj, + jobject menuEvent, jobject source); + void firePopupMenuCanceled(JNIEnv *env, jobject callingObj, + jobject popupMenuEvent, jobject source); + void firePopupMenuWillBecomeInvisible(JNIEnv *env, jobject callingObj, + jobject popupMenuEvent, jobject source); + void firePopupMenuWillBecomeVisible(JNIEnv *env, jobject callingObj, + jobject popupMenuEvent, jobject source); + + void firePropertyCaretChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jint oldValue, jint newValue); + void firePropertyDescriptionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertyNameChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertySelectionChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source); + void firePropertyStateChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertyTextChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source); + void firePropertyValueChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); + void firePropertyVisibleDataChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source); + void firePropertyChildChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue); + void firePropertyActiveDescendentChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jobject oldValue, jobject newValue); + + void firePropertyTableModelChange(JNIEnv *env, jobject callingObj, + jobject event, jobject source, + jstring oldValue, jstring newValue); +}; + + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.cpp b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.cpp new file mode 100644 index 00000000000..a445d6b21e3 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.cpp @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage firing Accessibility events to Windows AT + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeEventHandler.h" +#include "AccessBridgePackages.h" +#include "WinAccessBridge.h" + +DEBUG_CODE(extern HWND theDialogWindow); +extern "C" { +DEBUG_CODE(void AppendToCallInfo(char *s)); +} + + +// ----------------------------- + +/** + * Initialization. Set all callbacks to null + */ +AccessBridgeEventHandler::AccessBridgeEventHandler() { + javaEventMask = 0; + accessibilityEventMask = 0; + + propertyChangeFP = (AccessBridge_PropertyChangeFP) NULL; + javaShutdownFP = (AccessBridge_JavaShutdownFP) NULL; + focusGainedFP = (AccessBridge_FocusGainedFP) NULL; + focusLostFP = (AccessBridge_FocusLostFP) NULL; + caretUpdateFP = (AccessBridge_CaretUpdateFP) NULL; + mouseClickedFP = (AccessBridge_MouseClickedFP) NULL; + mouseEnteredFP = (AccessBridge_MouseEnteredFP) NULL; + mouseExitedFP = (AccessBridge_MouseExitedFP) NULL; + mousePressedFP = (AccessBridge_MousePressedFP) NULL; + mouseReleasedFP = (AccessBridge_MouseReleasedFP) NULL; + menuCanceledFP = (AccessBridge_MenuCanceledFP) NULL; + menuDeselectedFP = (AccessBridge_MenuDeselectedFP) NULL; + menuSelectedFP = (AccessBridge_MenuSelectedFP) NULL; + popupMenuCanceledFP = (AccessBridge_PopupMenuCanceledFP) NULL; + popupMenuWillBecomeInvisibleFP = (AccessBridge_PopupMenuWillBecomeInvisibleFP) NULL; + popupMenuWillBecomeVisibleFP = (AccessBridge_PopupMenuWillBecomeVisibleFP) NULL; + + propertyNameChangeFP = (AccessBridge_PropertyNameChangeFP) NULL; + propertyDescriptionChangeFP = (AccessBridge_PropertyDescriptionChangeFP) NULL; + propertyStateChangeFP = (AccessBridge_PropertyStateChangeFP) NULL; + propertyValueChangeFP = (AccessBridge_PropertyValueChangeFP) NULL; + propertySelectionChangeFP = (AccessBridge_PropertySelectionChangeFP) NULL; + propertyTextChangeFP = (AccessBridge_PropertyTextChangeFP) NULL; + propertyCaretChangeFP = (AccessBridge_PropertyCaretChangeFP) NULL; + propertyVisibleDataChangeFP = (AccessBridge_PropertyVisibleDataChangeFP) NULL; + propertyChildChangeFP = (AccessBridge_PropertyChildChangeFP) NULL; + propertyActiveDescendentChangeFP = (AccessBridge_PropertyActiveDescendentChangeFP) NULL; + + propertyTableModelChangeFP = (AccessBridge_PropertyTableModelChangeFP) NULL; + +} + +/** + * Destruction. + */ +AccessBridgeEventHandler::~AccessBridgeEventHandler() { +} + + +// ------------ Event handling methods + +#define SET_JAVA_EVENT_FP(function, eventFP, callbackFP, eventConstant) \ + void AccessBridgeEventHandler::function(eventFP fp, WinAccessBridge *wab) { \ + callbackFP = fp; \ + if (fp != (eventFP) 0) { \ + javaEventMask |= eventConstant; \ + wab->addJavaEventNotification(eventConstant); \ + } else { \ + javaEventMask &= (0xFFFFFFFF - eventConstant); \ + wab->removeJavaEventNotification(eventConstant); \ + } \ + } + +SET_JAVA_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP, propertyChangeFP, cPropertyChangeEvent) +SET_JAVA_EVENT_FP(setJavaShutdownFP, AccessBridge_JavaShutdownFP, javaShutdownFP, cJavaShutdownEvent) +SET_JAVA_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP, focusGainedFP, cFocusGainedEvent) +SET_JAVA_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP, focusLostFP, cFocusLostEvent) +SET_JAVA_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP, caretUpdateFP, cCaretUpdateEvent) +SET_JAVA_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP, mouseClickedFP, cMouseClickedEvent) +SET_JAVA_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP, mouseEnteredFP, cMouseEnteredEvent) +SET_JAVA_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP, mouseExitedFP, cMouseExitedEvent) +SET_JAVA_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP, mousePressedFP, cMousePressedEvent) +SET_JAVA_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP, mouseReleasedFP, cMouseReleasedEvent) +SET_JAVA_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP, menuCanceledFP, cMenuCanceledEvent) +SET_JAVA_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP, menuDeselectedFP, cMenuDeselectedEvent) +SET_JAVA_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP, menuSelectedFP, cMenuSelectedEvent) +SET_JAVA_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP, popupMenuCanceledFP, cPopupMenuCanceledEvent) +SET_JAVA_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP, popupMenuWillBecomeInvisibleFP, cPopupMenuWillBecomeInvisibleEvent) +SET_JAVA_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP, popupMenuWillBecomeVisibleFP, cPopupMenuWillBecomeVisibleEvent) + +#define SET_ACCESSIBILITY_EVENT_FP(function, eventFP, callbackFP, eventConstant) \ + void AccessBridgeEventHandler::function(eventFP fp, WinAccessBridge *wab) { \ + callbackFP = fp; \ + if (fp != (eventFP) 0) { \ + accessibilityEventMask |= eventConstant; \ + wab->addAccessibilityEventNotification(eventConstant); \ + } else { \ + accessibilityEventMask &= (0xFFFFFFFF - eventConstant); \ + wab->removeAccessibilityEventNotification(eventConstant); \ + } \ + } + + +SET_ACCESSIBILITY_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP, propertyNameChangeFP, cPropertyNameChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP, propertyDescriptionChangeFP, cPropertyDescriptionChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP, propertyStateChangeFP, cPropertyStateChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP, propertyValueChangeFP, cPropertyValueChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP, propertySelectionChangeFP, cPropertySelectionChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP, propertyTextChangeFP, cPropertyTextChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP, propertyCaretChangeFP, cPropertyCaretChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP, propertyVisibleDataChangeFP, cPropertyVisibleDataChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP, propertyChildChangeFP, cPropertyChildChangeEvent) +SET_ACCESSIBILITY_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP, propertyActiveDescendentChangeFP, cPropertyActiveDescendentChangeEvent) + +SET_ACCESSIBILITY_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP, propertyTableModelChangeFP, cPropertyTableModelChangeEvent) + + +/** + * propertyChange - extends the Java method call to Windows: + * propertyChange(PropertyChangeEvent e, ) + * + * Note: PropertyChangeEvent object passed in is a globalReference; + * It is critical that releaseJavaObject() be called + * on the PropertyChangeEvent once it is no longer needed, + * otherwise the JavaVM/JNI will suffer memory leaks + * + */ +void +AccessBridgeEventHandler::firePropertyChange(long vmID, + JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldName, + wchar_t *newName) { + DEBUG_CODE(char debugBuf[255]); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + DEBUG_CODE(sprintf(debugBuf, "\r\nCalling firePropertyChange(%p, %p):\r\n", event, source)); +#else // JOBJECT64 is jlong (64 bit) + DEBUG_CODE(sprintf(debugBuf, "\r\nCalling firePropertyChange(%016I64X, %016I64X):\r\n", event, source)); +#endif + DEBUG_CODE(AppendToCallInfo(debugBuf)); + + if (propertyChangeFP != (AccessBridge_PropertyChangeFP) 0) { + propertyChangeFP(vmID, event, source, property, oldName, newName); + } else { + DEBUG_CODE(AppendToCallInfo(" Error! propertyChangeFP == 0\r\n")); + } +} + + +/** + * FIRE_EVENT - macro for all fireXXX methods (which + * all are basically identical to one another...) + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%p, %p); vmID = %X\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireEventDebugString[] = "\r\nIn AccessBridgeEventHandler::%s(%016I64X, %016I64X); vmID = %X\r\n"; +#endif + +#define FIRE_EVENT(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireEventDebugString, #method, event, source, vmID)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + + void AccessBridgeEventHandler::fireJavaShutdown(long vmID) { + DEBUG_CODE(char debugBuf[255]); + DEBUG_CODE(sprintf(debugBuf, "\r\nCalling fireJavaShutdown; vmID = %X\r\n", vmID)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + if (javaShutdownFP != (AccessBridge_JavaShutdownFP) 0) { + javaShutdownFP(vmID); + } else { + DEBUG_CODE(AppendToCallInfo(" Error! javaShutdownFP == 0\r\n")); + } + } + +FIRE_EVENT(fireFocusGained, AccessBridge_FocusGainedFP, focusGainedFP) +FIRE_EVENT(fireFocusLost, AccessBridge_FocusLostFP, focusLostFP) +FIRE_EVENT(fireCaretUpdate, AccessBridge_CaretUpdateFP, caretUpdateFP) +FIRE_EVENT(fireMouseClicked, AccessBridge_MouseClickedFP, mouseClickedFP) +FIRE_EVENT(fireMouseEntered, AccessBridge_MouseEnteredFP, mouseEnteredFP) +FIRE_EVENT(fireMouseExited, AccessBridge_MouseExitedFP, mouseExitedFP) +FIRE_EVENT(fireMousePressed, AccessBridge_MousePressedFP, mousePressedFP) +FIRE_EVENT(fireMouseReleased, AccessBridge_MouseReleasedFP, mouseReleasedFP) +FIRE_EVENT(fireMenuCanceled, AccessBridge_MenuCanceledFP, menuCanceledFP) +FIRE_EVENT(fireMenuDeselected, AccessBridge_MenuDeselectedFP, menuDeselectedFP) +FIRE_EVENT(fireMenuSelected, AccessBridge_MenuSelectedFP, menuSelectedFP) +FIRE_EVENT(firePopupMenuCanceled, AccessBridge_PopupMenuCanceledFP, popupMenuCanceledFP) +FIRE_EVENT(firePopupMenuWillBecomeInvisible, AccessBridge_PopupMenuWillBecomeInvisibleFP, popupMenuWillBecomeInvisibleFP) +FIRE_EVENT(firePopupMenuWillBecomeVisible, AccessBridge_PopupMenuWillBecomeVisibleFP, popupMenuWillBecomeVisibleFP) + + +/** + * FIRE_PROPERTY_CHANGE - macro for all fireXXX methods (which + * all are basically identical to one another... + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%p, %p):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char firePropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a no-param property change (%016I64X, %016I64X):\r\n"; +#endif + +#define FIRE_PROPERTY_CHANGE(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, firePropertyChangeDebugString, #method, event, source)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +/** + * FIRE_STRING_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods + * that have strings as the old/new values + + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%p, %p, %ls, %ls):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireStringPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing a string property change (%016I64X, %016I64X, %ls, %ls):\r\n"; +#endif + +#define FIRE_STRING_PROPERTY_CHANGE(method, FPprototype, eventFP, oldValue, newValue) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \ + wchar_t *oldValue, wchar_t *newValue) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireStringPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source, oldValue, newValue); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +/** + * FIRE_INT_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods + * that have ints as the old/new values + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%p, %p, %d, %d):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireIntPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an int property change (%016I64X, %016I64X, %d, %d):\r\n"; +#endif + +#define FIRE_INT_PROPERTY_CHANGE(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \ + int oldValue, int newValue) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireIntPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source, oldValue, newValue); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +/** + * FIRE_AC_PROPERTY_CHANGE - macro for all firePropertyXXXChange methods + * that have jobjects (AccessibleContexts) as the old/new values + * + * Note: the event and source objects passed in are globalReferences; + * It is critical that releaseJavaObject() be called + * on them once they are no longer needed, otherwise + * the JavaVM/JNI will suffer memory leaks + * + */ +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) +const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%p, %p, %p, %p):\r\n"; +#else // JOBJECT64 is jlong (64 bit) +const char fireACPropertyChangeDebugString[] = "\r\nIn AccessBridgeEventHandler::%s, Firing an AC property change (%016I64X, %016I64X, %016I64X, %016I64X):\r\n"; +#endif + +#define FIRE_AC_PROPERTY_CHANGE(method, FPprototype, eventFP) \ + void AccessBridgeEventHandler::method(long vmID, JOBJECT64 event, JOBJECT64 source, \ + JOBJECT64 oldValue, JOBJECT64 newValue) { \ + DEBUG_CODE(char debugBuf[255]); \ + DEBUG_CODE(sprintf(debugBuf, fireACPropertyChangeDebugString, #method, event, source, oldValue, newValue)); \ + DEBUG_CODE(AppendToCallInfo(debugBuf)); \ + if (eventFP != (FPprototype) 0) { \ + eventFP(vmID, event, source, oldValue, newValue); \ + } else { \ + DEBUG_CODE(AppendToCallInfo(" Error! eventFP == 0\r\n")); \ + } \ + } + +FIRE_STRING_PROPERTY_CHANGE(firePropertyNameChange, + AccessBridge_PropertyNameChangeFP, + propertyNameChangeFP, oldName, newName) +FIRE_STRING_PROPERTY_CHANGE(firePropertyDescriptionChange, + AccessBridge_PropertyDescriptionChangeFP, + propertyDescriptionChangeFP, + oldDescription, newDescription) +FIRE_STRING_PROPERTY_CHANGE(firePropertyStateChange, + AccessBridge_PropertyStateChangeFP, + propertyStateChangeFP, oldState, newState) +FIRE_STRING_PROPERTY_CHANGE(firePropertyValueChange, + AccessBridge_PropertyValueChangeFP, + propertyValueChangeFP, oldValue, newValue) +FIRE_PROPERTY_CHANGE(firePropertySelectionChange, + AccessBridge_PropertySelectionChangeFP, + propertySelectionChangeFP) +FIRE_PROPERTY_CHANGE(firePropertyTextChange, + AccessBridge_PropertyTextChangeFP, + propertyTextChangeFP); +FIRE_INT_PROPERTY_CHANGE(firePropertyCaretChange, + AccessBridge_PropertyCaretChangeFP, + propertyCaretChangeFP) +FIRE_PROPERTY_CHANGE(firePropertyVisibleDataChange, + AccessBridge_PropertyVisibleDataChangeFP, + propertyVisibleDataChangeFP) +FIRE_AC_PROPERTY_CHANGE(firePropertyChildChange, + AccessBridge_PropertyChildChangeFP, + propertyChildChangeFP) +FIRE_AC_PROPERTY_CHANGE(firePropertyActiveDescendentChange, + AccessBridge_PropertyActiveDescendentChangeFP, + propertyActiveDescendentChangeFP) + +FIRE_STRING_PROPERTY_CHANGE(firePropertyTableModelChange, + AccessBridge_PropertyTableModelChangeFP, + propertyTableModelChangeFP, oldValue, newValue) diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.h b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.h new file mode 100644 index 00000000000..f56e9bf518a --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeEventHandler.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage firing Accessibility events to Windows AT + */ + +#ifndef __AccessBridgeEventHandler_H__ +#define __AccessBridgeEventHandler_H__ + +#include "AccessBridgeCallbacks.h" +#include "AccessBridgePackages.h" + +class WinAccessBridge; + +class AccessBridgeEventHandler { + long javaEventMask; + long accessibilityEventMask; + + AccessBridge_PropertyChangeFP propertyChangeFP; + AccessBridge_JavaShutdownFP javaShutdownFP; + AccessBridge_FocusGainedFP focusGainedFP; + AccessBridge_FocusLostFP focusLostFP; + AccessBridge_CaretUpdateFP caretUpdateFP; + AccessBridge_MouseClickedFP mouseClickedFP; + AccessBridge_MouseEnteredFP mouseEnteredFP; + AccessBridge_MouseExitedFP mouseExitedFP; + AccessBridge_MousePressedFP mousePressedFP; + AccessBridge_MouseReleasedFP mouseReleasedFP; + AccessBridge_MenuCanceledFP menuCanceledFP; + AccessBridge_MenuDeselectedFP menuDeselectedFP; + AccessBridge_MenuSelectedFP menuSelectedFP; + AccessBridge_PopupMenuCanceledFP popupMenuCanceledFP; + AccessBridge_PopupMenuWillBecomeInvisibleFP popupMenuWillBecomeInvisibleFP; + AccessBridge_PopupMenuWillBecomeVisibleFP popupMenuWillBecomeVisibleFP; + + AccessBridge_PropertyNameChangeFP propertyNameChangeFP; + AccessBridge_PropertyDescriptionChangeFP propertyDescriptionChangeFP; + AccessBridge_PropertyStateChangeFP propertyStateChangeFP; + AccessBridge_PropertyValueChangeFP propertyValueChangeFP; + AccessBridge_PropertySelectionChangeFP propertySelectionChangeFP; + AccessBridge_PropertyTextChangeFP propertyTextChangeFP; + AccessBridge_PropertyCaretChangeFP propertyCaretChangeFP; + AccessBridge_PropertyVisibleDataChangeFP propertyVisibleDataChangeFP; + AccessBridge_PropertyChildChangeFP propertyChildChangeFP; + AccessBridge_PropertyActiveDescendentChangeFP propertyActiveDescendentChangeFP; + + AccessBridge_PropertyTableModelChangeFP propertyTableModelChangeFP; + + + +public: + AccessBridgeEventHandler(); + ~AccessBridgeEventHandler(); + long getJavaEventMask() {return javaEventMask;}; + long getAccessibilityEventMask() {return accessibilityEventMask;}; + + // ------- Registry methods + void setPropertyChangeFP(AccessBridge_PropertyChangeFP fp, WinAccessBridge *wab); + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp, WinAccessBridge *wab); + void setFocusGainedFP(AccessBridge_FocusGainedFP fp, WinAccessBridge *wab); + void setFocusLostFP(AccessBridge_FocusLostFP fp, WinAccessBridge *wab); + void setCaretUpdateFP(AccessBridge_CaretUpdateFP fp, WinAccessBridge *wab); + void setMouseClickedFP(AccessBridge_MouseClickedFP fp, WinAccessBridge *wab); + void setMouseEnteredFP(AccessBridge_MouseEnteredFP fp, WinAccessBridge *wab); + void setMouseExitedFP(AccessBridge_MouseExitedFP fp, WinAccessBridge *wab); + void setMousePressedFP(AccessBridge_MousePressedFP fp, WinAccessBridge *wab); + void setMouseReleasedFP(AccessBridge_MouseReleasedFP fp, WinAccessBridge *wab); + void setMenuCanceledFP(AccessBridge_MenuCanceledFP fp, WinAccessBridge *wab); + void setMenuDeselectedFP(AccessBridge_MenuDeselectedFP fp, WinAccessBridge *wab); + void setMenuSelectedFP(AccessBridge_MenuSelectedFP fp, WinAccessBridge *wab); + void setPopupMenuCanceledFP(AccessBridge_PopupMenuCanceledFP fp, WinAccessBridge *wab); + void setPopupMenuWillBecomeInvisibleFP(AccessBridge_PopupMenuWillBecomeInvisibleFP fp, + WinAccessBridge *wab); + void setPopupMenuWillBecomeVisibleFP(AccessBridge_PopupMenuWillBecomeVisibleFP fp, + WinAccessBridge *wab); + + void setPropertyNameChangeFP(AccessBridge_PropertyNameChangeFP fp, WinAccessBridge *wab); + void setPropertyDescriptionChangeFP(AccessBridge_PropertyDescriptionChangeFP fp, + WinAccessBridge *wab); + void setPropertyStateChangeFP(AccessBridge_PropertyStateChangeFP fp, WinAccessBridge *wab); + void setPropertyValueChangeFP(AccessBridge_PropertyValueChangeFP fp, WinAccessBridge *wab); + void setPropertySelectionChangeFP(AccessBridge_PropertySelectionChangeFP fp, + WinAccessBridge *wab); + void setPropertyTextChangeFP(AccessBridge_PropertyTextChangeFP fp, WinAccessBridge *wab); + void setPropertyCaretChangeFP(AccessBridge_PropertyCaretChangeFP fp, WinAccessBridge *wab); + void setPropertyVisibleDataChangeFP(AccessBridge_PropertyVisibleDataChangeFP fp, + WinAccessBridge *wab); + void setPropertyChildChangeFP(AccessBridge_PropertyChildChangeFP fp, WinAccessBridge *wab); + void setPropertyActiveDescendentChangeFP(AccessBridge_PropertyActiveDescendentChangeFP fp, + WinAccessBridge *wab); + + void setPropertyTableModelChangeFP(AccessBridge_PropertyTableModelChangeFP fp, + WinAccessBridge *wab); + + // ------- Event notification methods + void firePropertyChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *property, wchar_t *oldName, wchar_t *newName); + void fireJavaShutdown(long vmID); + void fireFocusGained(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireFocusLost(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireCaretUpdate(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseClicked(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseEntered(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseExited(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMousePressed(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMouseReleased(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMenuCanceled(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMenuDeselected(long vmID, JOBJECT64 event, JOBJECT64 source); + void fireMenuSelected(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePopupMenuCanceled(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePopupMenuWillBecomeInvisible(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePopupMenuWillBecomeVisible(long vmID, JOBJECT64 event, JOBJECT64 source); + + void firePropertyNameChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldName, wchar_t *newName); + void firePropertyDescriptionChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldDescription, wchar_t *newDescription); + void firePropertyStateChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldState, wchar_t *newState); + void firePropertyValueChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); + void firePropertySelectionChange(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePropertyTextChange(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePropertyCaretChange(long vmID, JOBJECT64 event, JOBJECT64 source, + int oldPosition, int newPosition); + void firePropertyVisibleDataChange(long vmID, JOBJECT64 event, JOBJECT64 source); + void firePropertyChildChange(long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldChild, JOBJECT64 newChild); + void firePropertyActiveDescendentChange(long vmID, JOBJECT64 event, JOBJECT64 source, + JOBJECT64 oldActiveDescendent, JOBJECT64 newActiveDescendent); + + void firePropertyTableModelChange(long vmID, JOBJECT64 event, JOBJECT64 source, + wchar_t *oldValue, wchar_t *newValue); + +}; + + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.cpp b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.cpp new file mode 100644 index 00000000000..7294a3e5c6b --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.cpp @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key JVM instance info from the AT WinAccessBridge + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeJavaVMInstance.h" +#include "AccessBridgeMessages.h" +#include "AccessBridgePackages.h" +#include "accessBridgeResource.h" // for debugging messages + +#include +#include + +// The initialization must only be done one time and to provide for that the initialization +// is now done in WinAccessBridge and the CRITICAL_SECTION memory has been moved to there. +// send memory lock +//CRITICAL_SECTION sendMemoryIPCLock; +extern CRITICAL_SECTION sendMemoryIPCLock; + +// protects the javaVMs chain while in use +extern bool isVMInstanceChainInUse; + +DEBUG_CODE(extern HWND theDialogWindow); +extern "C" { + DEBUG_CODE(void AppendToCallInfo(char *s)); +} + + +/** + * + * + */ +AccessBridgeJavaVMInstance::AccessBridgeJavaVMInstance(HWND ourABWindow, + HWND javaABWindow, + long javaVMID, + AccessBridgeJavaVMInstance *next) { + goingAway = FALSE; + // This should be called once. Moved to WinAccessBridge c'tor + //InitializeCriticalSection(&sendMemoryIPCLock); + ourAccessBridgeWindow = ourABWindow; + javaAccessBridgeWindow = javaABWindow; + vmID = javaVMID; + nextJVMInstance = next; + memoryMappedFileMapHandle = (HANDLE) 0; + memoryMappedView = (char *) 0; + sprintf(memoryMappedFileName, "AccessBridge-%p-%p.mmf", + ourAccessBridgeWindow, javaAccessBridgeWindow); +} + +/** + * + * + */ +AccessBridgeJavaVMInstance::~AccessBridgeJavaVMInstance() { + DEBUG_CODE(char buffer[256]); + + DEBUG_CODE(AppendToCallInfo("***** in AccessBridgeJavaVMInstance::~AccessBridgeJavaVMInstance\r\n")); + EnterCriticalSection(&sendMemoryIPCLock); + + // if IPC memory mapped file view is valid, unmap it + goingAway = TRUE; + if (memoryMappedView != (char *) 0) { + DEBUG_CODE(sprintf(buffer, " unmapping memoryMappedView; view = %p\r\n", memoryMappedView)); + DEBUG_CODE(AppendToCallInfo(buffer)); + UnmapViewOfFile(memoryMappedView); + memoryMappedView = (char *) 0; + } + // if IPC memory mapped file handle map is open, close it + if (memoryMappedFileMapHandle != (HANDLE) 0) { + DEBUG_CODE(sprintf(buffer, " closing memoryMappedFileMapHandle; handle = %p\r\n", memoryMappedFileMapHandle)); + DEBUG_CODE(AppendToCallInfo(buffer)); + CloseHandle(memoryMappedFileMapHandle); + memoryMappedFileMapHandle = (HANDLE) 0; + } + LeaveCriticalSection(&sendMemoryIPCLock); + +} + +/** + * initiateIPC - sets up the memory-mapped file to do IPC messaging + * 1 file is created: to handle requests for information + * initiated from Windows AT. The package is placed into + * the memory-mapped file (char *memoryMappedView), + * and then a special SendMessage() is sent. When the + * JavaDLL returns from SendMessage() processing, the + * data will be in memoryMappedView. The SendMessage() + * return value tells us if all is right with the world. + * + * The set-up proces involves creating the memory-mapped + * file, and handshaking with the JavaDLL so it knows + * about it as well. + * + */ +LRESULT +AccessBridgeJavaVMInstance::initiateIPC() { + DEBUG_CODE(char debugBuf[256]); + DWORD errorCode; + + DEBUG_CODE(AppendToCallInfo(" in AccessBridgeJavaVMInstance::initiateIPC()\r\n")); + + // create Windows-initiated IPC file & map it to a ptr + memoryMappedFileMapHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, + // 8 bytes for return code + sizeof(WindowsInitiatedPackages) + 8, + memoryMappedFileName); + if (memoryMappedFileMapHandle == NULL) { + errorCode = GetLastError(); + DEBUG_CODE(sprintf(debugBuf, " Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + return errorCode; + } else { + DEBUG_CODE(sprintf(debugBuf, " CreateFileMapping worked - filename: %s\r\n", memoryMappedFileName)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + } + + memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle, + FILE_MAP_READ | FILE_MAP_WRITE, + 0, 0, 0); + if (memoryMappedView == NULL) { + errorCode = GetLastError(); + DEBUG_CODE(sprintf(debugBuf, " Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + return errorCode; + } else { + DEBUG_CODE(sprintf(debugBuf, " MapViewOfFile worked - view: %p\r\n", memoryMappedView)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + } + + + // write some data to the memory mapped file + strcpy(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY); + + + // inform the JavaDLL that we've a memory mapped file ready for it + char buffer[sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage)]; + PackageType *type = (PackageType *) buffer; + MemoryMappedFileCreatedPackage *pkg = (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType)); + *type = cMemoryMappedFileCreatedPackage; + pkg->bridgeWindow = ABHandleToLong(ourAccessBridgeWindow); + strncpy(pkg->filename, memoryMappedFileName, cMemoryMappedNameSize); + sendPackage(buffer, sizeof(buffer)); + + + // look for the JavaDLL's answer to see if it could read the file + if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_ANSWER) != 0) { + DEBUG_CODE(sprintf(debugBuf, " JavaVM failed to deal with memory mapped file %s\r\n", + memoryMappedFileName)); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + return -1; + } else { + DEBUG_CODE(sprintf(debugBuf, " Success! JavaVM accpeted our file\r\n")); + DEBUG_CODE(AppendToCallInfo(debugBuf)); + } + + return 0; +} + +// ----------------------- + +/** + * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging + * with the Java AccessBridge DLL + * + * NOTE: WM_COPYDATA is only for one-way IPC; there + * is now way to return parameters (especially big ones) + * Use sendMemoryPackage() to do that! + */ +LRESULT +AccessBridgeJavaVMInstance::sendPackage(char *buffer, long bufsize) { + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = bufsize; + toCopy.lpData = buffer; + + PrintDebugString("In AccessBridgeVMInstance::sendPackage"); + PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); + /* This was SendMessage. Normally that is a blocking call. However, if + * SendMessage is sent to another process, e.g. another JVM and an incoming + * SendMessage is pending, control will be passed to the DialogProc to handle + * the incoming message. A bug occurred where this allowed an AB_DLL_GOING_AWAY + * message to be processed deleting an AccessBridgeJavaVMInstance object in + * the javaVMs chain. SendMessageTimeout with SMTO_BLOCK set will prevent the + * calling thread from processing other requests while waiting, i.e control + * will not be passed to the DialogProc. Also note that PostMessage or + * SendNotifyMessage can't be used. Although they don't allow transfer to + * the DialogProc they can't be used in cases where pointers are passed. This + * is because the referenced memory needs to be available when the other thread + * gets control. + */ + UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; + DWORD_PTR out; // not used + LRESULT lr = SendMessageTimeout( javaAccessBridgeWindow, WM_COPYDATA, + (WPARAM)ourAccessBridgeWindow, (LPARAM)&toCopy, + flags, 4000, &out ); + return lr; +} + + +/** + * sendMemoryPackage - uses Memory-Mapped files to do IPC messaging + * with the Java AccessBridge DLL, informing the + * Java AccessBridge DLL via SendMessage that something + * is waiting for it in the shared file... + * + * In the SendMessage call, the third param (WPARAM) is + * the source HWND (ourAccessBridgeWindow in this case), + * and the fourth param (LPARAM) is the size in bytes of + * the package put into shared memory. + * + */ +BOOL +AccessBridgeJavaVMInstance::sendMemoryPackage(char *buffer, long bufsize) { + + // Protect against race condition where the memory mapped file is + // deallocated before the memory package is being sent + if (goingAway) { + return FALSE; + } + BOOL retval = FALSE; + + DEBUG_CODE(char outputBuf[256]); + DEBUG_CODE(sprintf(outputBuf, "AccessBridgeJavaVMInstance::sendMemoryPackage(, %d)", bufsize)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + + DEBUG_CODE(PackageType *type = (PackageType *) buffer); + DEBUG_CODE(if (*type == cGetAccessibleTextRangePackage) {) + DEBUG_CODE(AppendToCallInfo(" 'buffer' contains:")); + DEBUG_CODE(GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType))); + DEBUG_CODE(sprintf(outputBuf, " PackageType = %X", *type)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + DEBUG_CODE(sprintf(outputBuf, " GetAccessibleTextRange: start = %d, end = %d, rText = %ls", + pkg->start, pkg->end, pkg->rText)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + DEBUG_CODE(}) + + EnterCriticalSection(&sendMemoryIPCLock); + { + // copy the package into shared memory + if (!goingAway) { + memcpy(memoryMappedView, buffer, bufsize); + + DEBUG_CODE(PackageType *type = (PackageType *) memoryMappedView); + DEBUG_CODE(if (*type == cGetAccessibleTextItemsPackage) {) + DEBUG_CODE(AppendToCallInfo(" 'memoryMappedView' now contains:")); + DEBUG_CODE(GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType))); + DEBUG_CODE(sprintf(outputBuf, " PackageType = %X", *type)); + DEBUG_CODE(AppendToCallInfo(outputBuf)); + DEBUG_CODE(}) + } + + if (!goingAway) { + // Let the recipient know there is a package waiting for them. The unset byte + // at end of buffer which will only be set if message is properly received + char *done = &memoryMappedView[bufsize]; + *done = 0; + + PrintDebugString(" javaAccessBridgeWindow: %p", javaAccessBridgeWindow); + // See the comment above the call to SendMessageTimeout in SendPackage method above. + UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG; + DWORD_PTR out; // not used + SendMessageTimeout( javaAccessBridgeWindow, AB_MESSAGE_WAITING, (WPARAM)ourAccessBridgeWindow, (LPARAM)bufsize, + flags, 4000, &out ); + + // only succeed if message has been properly received + if(!goingAway) retval = (*done == 1); + } + + // copy the package back from shared memory + if (!goingAway) { + memcpy(buffer, memoryMappedView, bufsize); + } + } + LeaveCriticalSection(&sendMemoryIPCLock); + return retval; +} + + +/** + * findAccessBridgeWindow - walk through linked list from where we are, + * return the HWND of the ABJavaVMInstance that + * matches the passed in vmID; no match: return 0 + * + */ +HWND +AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) { + PrintDebugString("In findAccessBridgeWindow"); + // no need to recurse really + if (vmID == javaVMID) { + return javaAccessBridgeWindow; + } else { + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = nextJVMInstance; + while (current != (AccessBridgeJavaVMInstance *) 0) { + if (current->vmID == javaVMID) { + isVMInstanceChainInUse = false; + return current->javaAccessBridgeWindow; + } + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; + } + return 0; +} + +/** + * findABJavaVMInstanceFromJavaHWND - walk through linked list from + * where we are. Return the + * AccessBridgeJavaVMInstance + * of the ABJavaVMInstance that + * matches the passed in vmID; + * no match: return 0 + */ +AccessBridgeJavaVMInstance * +AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) { + PrintDebugString("In findABJavaInstanceFromJavaHWND"); + // no need to recurse really + if (javaAccessBridgeWindow == window) { + return this; + } else { + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = nextJVMInstance; + while (current != (AccessBridgeJavaVMInstance *) 0) { + if (current->javaAccessBridgeWindow == window) { + isVMInstanceChainInUse = false; + return current; + } + current = current->nextJVMInstance; + } + } + isVMInstanceChainInUse = false; + return (AccessBridgeJavaVMInstance *) 0; +} diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.h b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.h new file mode 100644 index 00000000000..ea461c65fb2 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeJavaVMInstance.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to track key JVM instance info from the AT WinAccessBridge + */ + +#ifndef __AccessBridgeJavaVMInstance_H__ +#define __AccessBridgeJavaVMInstance_H__ + +#include "AccessBridgePackages.h" + +#include +#include + +/** + * The AccessBridgeJavaVMInstance class. + */ +class AccessBridgeJavaVMInstance { + friend class WinAccessBridge; + + AccessBridgeJavaVMInstance *nextJVMInstance; + HWND ourAccessBridgeWindow; + HWND javaAccessBridgeWindow; + long vmID; + + // IPC variables + HANDLE memoryMappedFileMapHandle; // handle to file map + char *memoryMappedView; // ptr to shared memory + char memoryMappedFileName[cMemoryMappedNameSize]; + BOOL goingAway; + + +public: + AccessBridgeJavaVMInstance(HWND ourABWindow, HWND javaABWindow, + long javaVMID, + AccessBridgeJavaVMInstance *next); + ~AccessBridgeJavaVMInstance(); + LRESULT initiateIPC(); + LRESULT sendPackage(char *buffer, long bufsize); + BOOL sendMemoryPackage(char *buffer, long bufsize); + HWND findAccessBridgeWindow(long javaVMID); + AccessBridgeJavaVMInstance *findABJavaVMInstanceFromJavaHWND(HWND window); +}; + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeMessageQueue.cpp b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeMessageQueue.cpp new file mode 100644 index 00000000000..f96e3342870 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeMessageQueue.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage queueing of messages for IPC + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeMessageQueue.h" +#include "AccessBridgePackages.h" // for debugging only +#include +#include + +DEBUG_CODE(extern HWND theDialogWindow); +extern "C" { + DEBUG_CODE(void AppendToCallInfo(char *s)); +} + +// ------------------- + + +AccessBridgeQueueElement::AccessBridgeQueueElement(char *buf, int size) { + bufsize = size; + next = (AccessBridgeQueueElement *) 0; + previous = (AccessBridgeQueueElement *) 0; + buffer = (char *) malloc(bufsize); + memcpy(buffer, buf, bufsize); +} + +AccessBridgeQueueElement::~AccessBridgeQueueElement() { + // delete buffer; + free(buffer); +} + + +// ------------------- + + +AccessBridgeMessageQueue::AccessBridgeMessageQueue() { + queueLocked = FALSE; + queueRemoveLocked = FALSE; + start = (AccessBridgeQueueElement *) 0; + end = (AccessBridgeQueueElement *) 0; + size = 0; +} + +AccessBridgeMessageQueue::~AccessBridgeMessageQueue() { + // empty queue, then exit +} + +/** + * getEventsWaiting - gets the number of events waiting to fire + */ +int +AccessBridgeMessageQueue::getEventsWaiting() { + return size; +} + +/** + * add - add an element to the queue, which is locked with semaphores + * + */ +QueueReturns +AccessBridgeMessageQueue::add(AccessBridgeQueueElement *element) { + PrintDebugString(" in AccessBridgeMessageQueue::add()"); + PrintDebugString(" queue size = %d", size); + + QueueReturns returnVal = cElementPushedOK; + if (queueLocked) { + PrintDebugString(" queue was locked; returning cQueueInUse!"); + return cQueueInUse; + } + queueLocked = TRUE; + { + PrintDebugString(" adding element to queue!"); + if (end == (AccessBridgeQueueElement *) 0) { + if (start == (AccessBridgeQueueElement *) 0 && size == 0) { + start = element; + end = element; + element->previous = (AccessBridgeQueueElement *) 0; + element->next = (AccessBridgeQueueElement *) 0; + size++; + } else { + returnVal = cQueueBroken; // bad voodo! + } + } else { + element->previous = end; + element->next = (AccessBridgeQueueElement *) 0; + end->next = element; + end = element; + size++; + } + } + queueLocked = FALSE; + PrintDebugString(" returning from AccessBridgeMessageQueue::add()"); + return returnVal; +} + + +/** + * remove - remove an element from the queue, which is locked with semaphores + * + */ +QueueReturns +AccessBridgeMessageQueue::remove(AccessBridgeQueueElement **element) { + PrintDebugString(" in AccessBridgeMessageQueue::remove()"); + PrintDebugString(" queue size = %d", size); + + QueueReturns returnVal = cMoreMessages; + if (queueLocked) { + PrintDebugString(" queue was locked; returning cQueueInUse!"); + return cQueueInUse; + } + queueLocked = TRUE; + { + PrintDebugString(" removing element from queue!"); + if (size > 0) { + if (start != (AccessBridgeQueueElement *) 0) { + *element = start; + start = start->next; + if (start != (AccessBridgeQueueElement *) 0) { + start->previous = (AccessBridgeQueueElement *) 0; + } else { + end = (AccessBridgeQueueElement *) 0; + if (size != 1) { + returnVal = cQueueBroken; // bad voodo, should only be 1 in this situation + } + } + size--; + } else { + returnVal = cQueueBroken; // bad voodo! + } + } else { + returnVal = cQueueEmpty; + } + } + queueLocked = FALSE; + PrintDebugString(" returning from AccessBridgeMessageQueue::remove()"); + return returnVal; +} + + +/** + * setRemoveLock - set the state of the removeLock (TRUE or FALSE) + * + */ +QueueReturns +AccessBridgeMessageQueue::setRemoveLock(BOOL removeLockSetting) { + if (queueLocked) { + return cQueueInUse; + } + queueRemoveLocked = removeLockSetting; + + return cQueueOK; +} + +/** + * setRemoveLock - set the state of the removeLock (TRUE or FALSE) + * + */ +BOOL +AccessBridgeMessageQueue::getRemoveLockSetting() { + return queueRemoveLocked; +} diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeMessageQueue.h b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeMessageQueue.h new file mode 100644 index 00000000000..33a071a8d4e --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeMessageQueue.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A class to manage queueing of messages for IPC + */ + +#include + +#ifndef __AccessBridgeMessageQueue_H__ +#define __AccessBridgeMessageQueue_H__ + + +enum QueueReturns { + cQueueEmpty = 0, + cMoreMessages = 1, + cQueueInUse, + cElementPushedOK, + cQueueFull, + cQueueOK, + cQueueBroken // shouldn't ever happen! +}; + +class AccessBridgeQueueElement { + friend class AccessBridgeMessageQueue; + friend class WinAccessBridge; + char *buffer; + int bufsize; + AccessBridgeQueueElement *next; + AccessBridgeQueueElement *previous; + +public: + AccessBridgeQueueElement(char *buf, int size); + ~AccessBridgeQueueElement(); +}; + +class AccessBridgeMessageQueue { + BOOL queueLocked; + BOOL queueRemoveLocked; + AccessBridgeQueueElement *start; + AccessBridgeQueueElement *end; + int size; + +public: + AccessBridgeMessageQueue(); + ~AccessBridgeMessageQueue(); + + int getEventsWaiting(); + + QueueReturns add(AccessBridgeQueueElement *element); + QueueReturns remove(AccessBridgeQueueElement **element); + QueueReturns setRemoveLock(BOOL removeLockSetting); + BOOL getRemoveLockSetting(); +}; + + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeWindowsEntryPoints.cpp b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeWindowsEntryPoints.cpp new file mode 100644 index 00000000000..afd5677550f --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeWindowsEntryPoints.cpp @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Glue routines called by Windows AT into the WindowsAccessBridge dll + */ + +#include "AccessBridgeDebug.h" +#include "AccessBridgeWindowsEntryPoints.h" +#include "WinAccessBridge.h" +#include "accessBridgeResource.h" + +#include +#include + + +extern WinAccessBridge *theWindowsAccessBridge; +extern HWND theDialogWindow; + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Windows_run - where Windows executables will load/unload us + * + */ + void Windows_run() { + // open our window + if (theWindowsAccessBridge != (WinAccessBridge *) 0) { + theWindowsAccessBridge->initWindow(); + DEBUG_CODE(SetDlgItemText(theDialogWindow, cInvokedByText, "Windows")); + } + } + + /* + /** + * Windows_shutdown - where Windows executables will load/unload us + * + * + void Windows_shutdown() { + if (theWindowsAccessBridge != (WinAccessBridge *) 0) { + theWindowsAccessBridge->initWindow(); + } + } + */ + + /** + * getTopLevelHWND - returns the top-level window parent of the descendent + * + */ + HWND getTopLevelHWND(HWND descendent) { + HWND hwnd; + if (descendent == NULL) { + return NULL; + } + + if (!IsWindow(descendent)) { + return NULL; + } + + hwnd = descendent; + for(;;) { + LONG style = GetWindowLong(hwnd, GWL_STYLE); + if ( (style & WS_CHILD) == 0 ) { + // found a non-child window so terminate + break; + } + hwnd = GetParent(hwnd); + } + + return hwnd; + } + + void releaseJavaObject(long vmID, JOBJECT64 object) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->releaseJavaObject(vmID, object); + } + } + + void getVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->getVersionInfo(vmID, info); + } + } + + + BOOL isJavaWindow(HWND window) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->isJavaWindow(window); + } + return FALSE; + } + + /* + * Returns whether two object references refer to the same object + */ + BOOL isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("\r\nAccessBridgeWindowsEntryPoints::isSameObject(%p %p)", obj1, obj2); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("\r\nAccessBridgeWindowsEntryPoints::isSameObject(%016I64X %016I64X)", obj1, obj2); +#endif + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->isSameObject(vmID, obj1, obj2); + } + return FALSE; + } + + /** + * Sets a text field to the specified string. Returns whether successful + */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext,const wchar_t *text) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->setTextContents(vmID, accessibleContext, text); + } + return FALSE; + } + + /** + * Returns the Accessible Context of an object of the specified role that is the + * ancestor of a given object. If the object is of the specified role + * or an ancestor object of the specified role was found, returns the object's + * AccessibleContext. + * If there is no ancestor object of the specified role, + * returns (AccessibleContext)0. + */ + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getParentWithRole(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + + /** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getTopLevelObject(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + /** + * If there is an Ancestor object of the specified role, + * returns the Accessible Context of the found object. + * Otherwise, returns the top level object for that + * Java Window. Returns (AccessibleContext)0 on error. + */ + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getParentWithRoleElseRoot(vmID, accessibleContext, role); + } + return (AccessibleContext)0; + } + + /** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getObjectDepth(vmID, accessibleContext); + } + return -1; + } + + /** + * Returns the Accessible Context of the currently ActiveDescendent of an object. + * Returns (AccessibleContext)0 on error. + */ + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getActiveDescendent(vmID, accessibleContext); + } + return (AccessibleContext)0; + } + + // -------- Accessible Context methods ------------- + + BOOL getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextFromHWND(window, vmID, AccessibleContext); + } + return FALSE; + } + + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getHWNDFromAccessibleContext(vmID, accessibleContext); + } + return (HWND)0; + } + + BOOL getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextAt(vmID, AccessibleContextParent, + x, y, AccessibleContext); + } + return FALSE; + } + + BOOL getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextWithFocus(window, vmID, AccessibleContext); + } + return FALSE; + } + + BOOL getAccessibleContextInfo(long vmID, + JOBJECT64 AccessibleContext, + AccessibleContextInfo *info) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleContextInfo( + vmID, + AccessibleContext, + info); + } + return FALSE; + } + + JOBJECT64 getAccessibleChildFromContext(long vmID, + JOBJECT64 AccessibleContext, + jint childIndex) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleChildFromContext( + vmID, + AccessibleContext, + childIndex); + } + return (JOBJECT64) 0; + } + + JOBJECT64 getAccessibleParentFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleParentFromContext( + vmID, + AccessibleContext); + } + return (JOBJECT64) 0; + } + + // -------- begin AccessibleTable routines ------------- + + BOOL getAccessibleTableInfo(long vmID, JOBJECT64 ac, + AccessibleTableInfo *tableInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableInfo( + vmID, + ac, + tableInfo); + } + return FALSE; + } + + BOOL getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, + jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableCellInfo( + vmID, + accessibleTable, + row, column, tableCellInfo); + } + return FALSE; + } + + BOOL getAccessibleTableRowHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableRowHeader( + vmID, + acParent, + tableInfo); + } + return FALSE; + } + + BOOL getAccessibleTableColumnHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableColumnHeader( + vmID, + acParent, + tableInfo); + } + return FALSE; + } + + JOBJECT64 getAccessibleTableRowDescription(long vmID, JOBJECT64 acParent, jint row) { + + if (theWindowsAccessBridge != 0) { + return (JOBJECT64)theWindowsAccessBridge->getAccessibleTableRowDescription( + vmID, + acParent, + row); + } + return (JOBJECT64)0; + } + + JOBJECT64 getAccessibleTableColumnDescription(long vmID, JOBJECT64 acParent, jint column) { + + if (theWindowsAccessBridge != 0) { + return (JOBJECT64)theWindowsAccessBridge->getAccessibleTableColumnDescription( + vmID, + acParent, + column); + } + return (JOBJECT64)0; + } + + jint getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTableRowSelectionCount(vmID, accessibleTable); + } + return -1; + } + + BOOL isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->isAccessibleTableRowSelected(vmID, accessibleTable, row); + } + return FALSE; + } + + BOOL getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableRowSelections(vmID, accessibleTable, count, + selections); + } + return FALSE; + } + + + jint getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableColumnSelectionCount(vmID, accessibleTable); + } + return -1; + } + + BOOL isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->isAccessibleTableColumnSelected(vmID, accessibleTable, column); + } + return FALSE; + } + + BOOL getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableColumnSelections(vmID, accessibleTable, count, + selections); + } + return FALSE; + } + + jint getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableRow(vmID, accessibleTable, index); + } + return -1; + } + + jint getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableColumn(vmID, accessibleTable, index); + } + return -1; + } + + jint getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) { + if (theWindowsAccessBridge != 0 ) { + return theWindowsAccessBridge->getAccessibleTableIndex(vmID, accessibleTable, row, column); + } + return -1; + } + + /* --------- end AccessibleTable routines ------- */ + + // --------- AccessibleRelationSet methods + + BOOL getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleRelationSet(vmID, accessibleContext, relationSetInfo); + } + return FALSE; + } + + // --------- AccessibleHypertext methods + + BOOL getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, + AccessibleHypertextInfo *accessibleHypertextInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHypertext(vmID, accessibleContext, + accessibleHypertextInfo); + } + return FALSE; + } + + BOOL activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, JOBJECT64 accessibleHyperlink) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->activateAccessibleHyperlink(vmID, accessibleContext, + accessibleHyperlink); + } + return FALSE; + } + + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHyperlinkCount(vmID, accessibleContext); + } + return -1; + } + + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHypertextExt(vmID, + accessibleContext, + nStartIndex, + hypertextInfo); + } + return FALSE; + } + + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHypertextLinkIndex(vmID, + hypertext, + nIndex); + } + return -1; + } + + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleHyperlink(vmID, + hypertext, + nIndex, + hyperlinkInfo); + } + return FALSE; + } + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, AccessibleKeyBindings *keyBindings) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleKeyBindings(vmID, accessibleContext, keyBindings); + } + return FALSE; + } + + BOOL getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleIcons(vmID, accessibleContext, icons); + } + return FALSE; + } + + BOOL getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleActions(vmID, accessibleContext, actions); + } + return FALSE; + } + + BOOL doAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActionsToDo *actionsToDo, + jint *failure) { + + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->doAccessibleActions(vmID, accessibleContext, actionsToDo, + failure); + } + return FALSE; + } + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, wchar_t *name, int len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getVirtualAccessibleName(vmID, accessibleContext, name, len); + } + return FALSE; + } + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(long vmID, AccessibleContext accessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->requestFocus(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->selectTextRange(vmID, accessibleContext, startIndex, endIndex); + } + return FALSE; + } + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getTextAttributesInRange(vmID, accessibleContext, + startIndex, endIndex, attributes, len); + } + return FALSE; + } + + /** + * Gets the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getVisibleChildrenCount(vmID, accessibleContext); + } + return FALSE; + } + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getVisibleChildren(vmID, accessibleContext, startIndex, + visibleChildrenInfo); + } + return FALSE; + } + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext, + const int position) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->setCaretPosition(vmID, accessibleContext, position); + } + return FALSE; + } + + // -------- Accessible Text methods ------------- + + BOOL getAccessibleTextInfo(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextInfo *textInfo, jint x, jint y) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextInfo( + vmID, + AccessibleContext, + textInfo, x, y); + } + return FALSE; + } + + BOOL getAccessibleTextItems(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextItemsInfo *textItems, jint index) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextItems( + vmID, + AccessibleContext, + textItems, index); + } + return FALSE; + } + + BOOL getAccessibleTextSelectionInfo(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextSelectionInfo *selectionInfo) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextSelectionInfo( + vmID, + AccessibleContext, + selectionInfo); + } + return FALSE; + } + + BOOL getAccessibleTextAttributes(long vmID, JOBJECT64 AccessibleContext, + jint index, AccessibleTextAttributesInfo *attributes) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextAttributes( + vmID, + AccessibleContext, + index, attributes); + } + return FALSE; + } + + BOOL getAccessibleTextRect(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, jint index) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextRect( + vmID, + AccessibleContext, + rectInfo, index); + } + return FALSE; + } + + BOOL getCaretLocation(long vmID, JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, jint index) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getCaretLocation(vmID, + AccessibleContext, + rectInfo, index); + } + return FALSE; + } + + int getEventsWaiting() { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getEventsWaiting(); + } + return FALSE; + } + + BOOL getAccessibleTextLineBounds(long vmID, JOBJECT64 AccessibleContext, + jint index, jint *startIndex, jint *endIndex) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextLineBounds( + vmID, + AccessibleContext, + index, startIndex, endIndex); + } + return FALSE; + } + + BOOL getAccessibleTextRange(long vmID, JOBJECT64 AccessibleContext, + jint start, jint end, wchar_t *text, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleTextRange( + vmID, + AccessibleContext, + start, end, text, len); + } + return FALSE; + } + + + // -------- Accessible Value methods ------------- + + BOOL getCurrentAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getCurrentAccessibleValueFromContext( + vmID, AccessibleContext, value, len); + } + return FALSE; + } + + BOOL getMaximumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getMaximumAccessibleValueFromContext( + vmID, AccessibleContext, value, len); + } + return FALSE; + } + + BOOL getMinimumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getMinimumAccessibleValueFromContext( + vmID, AccessibleContext, value, len); + } + return FALSE; + } + + // -------- Accessible Selection methods ------------- + + void addAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->addAccessibleSelectionFromContext( + vmID, AccessibleContext, i); + } + } + + void clearAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->clearAccessibleSelectionFromContext( + vmID, AccessibleContext); + } + } + + JOBJECT64 getAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleSelectionFromContext( + vmID, AccessibleContext, i); + } + return (JOBJECT64) 0; + } + + int getAccessibleSelectionCountFromContext(long vmID, JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->getAccessibleSelectionCountFromContext( + vmID, AccessibleContext); + } + return -1; + } + + BOOL isAccessibleChildSelectedFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + return theWindowsAccessBridge->isAccessibleChildSelectedFromContext( + vmID, AccessibleContext, i); + } + return FALSE; + } + + void removeAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->removeAccessibleSelectionFromContext( + vmID, AccessibleContext, i); + } + } + + void selectAllAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->selectAllAccessibleSelectionFromContext( + vmID, AccessibleContext); + } + } + + + // -------- Event Handler methods ------------- + +#define SET_EVENT_FP(function, callbackFP) \ + void function(callbackFP fp) { \ + if (theWindowsAccessBridge != 0) { \ + theWindowsAccessBridge->function(fp); \ + } \ +} + + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) { + if (theWindowsAccessBridge != 0) { + theWindowsAccessBridge->setJavaShutdownFP(fp); + } + } + + SET_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP) + SET_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP) + SET_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP) + SET_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP) + SET_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP) + SET_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP) + SET_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP) + SET_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP) + SET_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP) + SET_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP) + SET_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP) + SET_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP) + SET_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP) + SET_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP) + SET_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP) + + SET_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP) + SET_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP) + SET_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP) + SET_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP) + SET_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP) + SET_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP) + SET_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP) + SET_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP) + SET_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP) + SET_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP) + + SET_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP) + +#ifdef __cplusplus + } +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeWindowsEntryPoints.h b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeWindowsEntryPoints.h new file mode 100644 index 00000000000..289a2e48d9d --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/AccessBridgeWindowsEntryPoints.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Glue routines called by Windows AT into the WindowsAccessBridge dll + */ + +#ifndef __AccessBridgeWindowsEntryPoints_H__ +#define __AccessBridgeWindowsEntryPoints_H__ + +#include +#include + +#include "AccessBridgePackages.h" +#include "AccessBridgeCallbacks.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void Windows_run(); + + void releaseJavaObject(long vmID, JOBJECT64 object); + void getVersionInfo(long vmID, AccessBridgeVersionInfo *info); + + // Window related functions + HWND getTopLevelHWND(HWND descendent); + BOOL isJavaWindow(HWND window); + BOOL getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext); + + // returns whether two objects are the same + BOOL isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + // Accessible Context functions + BOOL getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleContextInfo *info); + JOBJECT64 getAccessibleChildFromContext(long vmID, JOBJECT64 AccessibleContext, jint childIndex); + JOBJECT64 getAccessibleParentFromContext(long vmID, JOBJECT64 AccessibleContext); + + /* begin AccessibleTable */ + BOOL getAccessibleTableInfo(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + + JOBJECT64 getAccessibleTableRowDescription(long vmID, JOBJECT64 acParent, jint row); + JOBJECT64 getAccessibleTableColumnDescription(long vmID, JOBJECT64 acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row); + BOOL getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column); + + /* end AccessibleTable */ + + BOOL getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, + AccessibleRelationSetInfo *relationSetInfo); + + // AccessibleHypertext methods + BOOL getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, AccessibleHypertextInfo *hypertextInfo); + + BOOL activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, JOBJECT64 accessibleHyperlink); + + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext); + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, + AccessibleKeyBindings *keyBindings); + + BOOL getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, + AccessibleIcons *icons); + + BOOL getAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActions *actions); + + BOOL doAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + /* ----- Additional AccessibleHypertext methods for Teton */ + + + jint getAccessibleHypertextLinkCount(const long vmID, + const AccessibleContext accessibleContext); + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleContext accessibleContext, + const jint nIndex); + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleContext accessibleContext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Additional utility methods */ + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role); + + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role); + + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(long vmID, AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Returns the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(long vmID, AccessibleContext accessibleContext, int position); + + /** + * Gets the text caret bounding rectangle + */ + BOOL getCaretLocation(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + + // Accessible Text functions + BOOL getAccessibleTextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL getAccessibleTextItems(long vmID, JOBJECT64 AccessibleContext, AccessibleTextItemsInfo *textItems, jint index); + BOOL getAccessibleTextSelectionInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextSelectionInfo *selectionInfo); + BOOL getAccessibleTextAttributes(long vmID, JOBJECT64 AccessibleContext, jint index, AccessibleTextAttributesInfo *attributes); + BOOL getAccessibleTextRect(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleTextLineBounds(long vmID, JOBJECT64 AccessibleContext, jint index, jint *startIndex, jint *endIndex); + BOOL getAccessibleTextRange(long vmID, JOBJECT64 AccessibleContext, jint start, jint end, wchar_t *text, short len); + + // Accessible Value methods + BOOL getCurrentAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMaximumAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMinimumAccessibleValueFromContext(long vmID,JOBJECT64 AccessibleContext, wchar_t *value, short len); + + // Accessible Selection methods + void addAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + void clearAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext); + JOBJECT64 getAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + int getAccessibleSelectionCountFromContext(long vmID,JOBJECT64 AccessibleContext); + BOOL isAccessibleChildSelectedFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + void removeAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext, int i); + void selectAllAccessibleSelectionFromContext(long vmID,JOBJECT64 AccessibleContext); + + + // PropertyChange Event registry routines + void setPropertyChangeFP(AccessBridge_PropertyChangeFP fp); + + // Java application shutdown + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp); + + // Focus Event registry routines + void setFocusGainedFP(AccessBridge_FocusGainedFP fp); + void setFocusLostFP(AccessBridge_FocusLostFP fp); + + // Caret Event registry routines + void setCaretUpdateFP(AccessBridge_CaretUpdateFP fp); + + // Mouse Event registry routines + void setMouseClickedFP(AccessBridge_MouseClickedFP fp); + void setMouseEnteredFP(AccessBridge_MouseEnteredFP fp); + void setMouseExitedFP(AccessBridge_MouseExitedFP fp); + void setMousePressedFP(AccessBridge_MousePressedFP fp); + void setMouseReleasedFP(AccessBridge_MouseReleasedFP fp); + + // Menu/PopupMenu Event registry routines + void setMenuCanceledFP(AccessBridge_MenuCanceledFP fp); + void setMenuDeselectedFP(AccessBridge_MenuDeselectedFP fp); + void setMenuSelectedFP(AccessBridge_MenuSelectedFP fp); + void setPopupMenuCanceledFP(AccessBridge_PopupMenuCanceledFP fp); + void setPopupMenuWillBecomeInvisibleFP(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void setPopupMenuWillBecomeVisibleFP(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + // Accessibility PropertyChange Event registry routines + void setPropertyNameChangeFP(AccessBridge_PropertyNameChangeFP fp); + void setPropertyDescriptionChangeFP(AccessBridge_PropertyDescriptionChangeFP fp); + void setPropertyStateChangeFP(AccessBridge_PropertyStateChangeFP fp); + void setPropertyValueChangeFP(AccessBridge_PropertyValueChangeFP fp); + void setPropertySelectionChangeFP(AccessBridge_PropertySelectionChangeFP fp); + void setPropertyTextChangeFP(AccessBridge_PropertyTextChangeFP fp); + void setPropertyCaretChangeFP(AccessBridge_PropertyCaretChangeFP fp); + void setPropertyVisibleDataChangeFP(AccessBridge_PropertyVisibleDataChangeFP fp); + void setPropertyChildChangeFP(AccessBridge_PropertyChildChangeFP fp); + void setPropertyActiveDescendentChangeFP(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void setPropertyTableModelChangeFP(AccessBridge_PropertyTableModelChangeFP fp); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.DEF b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.DEF new file mode 100644 index 00000000000..44cf8437aea --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.DEF @@ -0,0 +1,154 @@ +; +; Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. +; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +; +; This code is free software; you can redistribute it and/or modify it +; under the terms of the GNU General Public License version 2 only, as +; published by the Free Software Foundation. Oracle designates this +; particular file as subject to the "Classpath" exception as provided +; by Oracle in the LICENSE file that accompanied this code. +; +; This code is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; version 2 for more details (a copy is included in the LICENSE file that +; accompanied this code). +; +; You should have received a copy of the GNU General Public License version +; 2 along with this work; if not, write to the Free Software Foundation, +; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +; +; Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +; or visit www.oracle.com if you need additional information or have any +; questions. +; +; +;LIBRARY WINDOWSACCESSBRIDGE + +;DESCRIPTION 'WINDOWSACCESSBRIDGE.DLL' +HEAPSIZE 4096 +EXPORTS + + addJavaEventNotification + removeJavaEventNotification + addAccessibilityEventNotification + removeAccessibilityEventNotification + + Windows_run + + getAccessibleTableInfo + getAccessibleTableCellInfo + + getAccessibleTableRowHeader + getAccessibleTableColumnHeader + + getAccessibleTableRowDescription + getAccessibleTableColumnDescription + + isAccessibleTableRowSelected + isAccessibleTableColumnSelected + + getAccessibleTableColumnSelectionCount + getAccessibleTableRowSelectionCount + + getAccessibleTableColumnSelections + getAccessibleTableRowSelections + + getAccessibleTableRow + getAccessibleTableColumn + getAccessibleTableIndex + + getAccessibleRelationSet + + getAccessibleHypertext + activateAccessibleHyperlink + getAccessibleHyperlinkCount + getAccessibleHypertextExt + getAccessibleHypertextLinkIndex + getAccessibleHyperlink + + getAccessibleKeyBindings + getAccessibleIcons + getAccessibleActions + doAccessibleActions + + setTextContents + getParentWithRole + getParentWithRoleElseRoot + getTopLevelObject + getObjectDepth + getActiveDescendent + + getVirtualAccessibleName + requestFocus + selectTextRange + getTextAttributesInRange + getVisibleChildrenCount + getVisibleChildren + setCaretPosition + getCaretLocation + + getEventsWaiting + + releaseJavaObject + getVersionInfo + + isJavaWindow + isSameObject + getAccessibleContextFromHWND + getHWNDFromAccessibleContext + + getAccessibleContextAt + getAccessibleContextWithFocus + getAccessibleContextInfo + getAccessibleChildFromContext + getAccessibleParentFromContext + + getAccessibleTextInfo + getAccessibleTextItems + getAccessibleTextSelectionInfo + getAccessibleTextAttributes + getAccessibleTextRect + getAccessibleTextLineBounds + getAccessibleTextRange + + getCurrentAccessibleValueFromContext + getMaximumAccessibleValueFromContext + getMinimumAccessibleValueFromContext + + addAccessibleSelectionFromContext + clearAccessibleSelectionFromContext + getAccessibleSelectionFromContext + getAccessibleSelectionCountFromContext + isAccessibleChildSelectedFromContext + removeAccessibleSelectionFromContext + selectAllAccessibleSelectionFromContext + + setPropertyChangeFP + setJavaShutdownFP + setFocusGainedFP + setFocusLostFP + setCaretUpdateFP + setMouseClickedFP + setMouseEnteredFP + setMouseExitedFP + setMousePressedFP + setMouseReleasedFP + setMenuCanceledFP + setMenuDeselectedFP + setMenuSelectedFP + setPopupMenuCanceledFP + setPopupMenuWillBecomeInvisibleFP + setPopupMenuWillBecomeVisibleFP + + setPropertyNameChangeFP + setPropertyDescriptionChangeFP + setPropertyStateChangeFP + setPropertyValueChangeFP + setPropertySelectionChangeFP + setPropertyTextChangeFP + setPropertyCaretChangeFP + setPropertyVisibleDataChangeFP + setPropertyChildChangeFP + setPropertyActiveDescendentChangeFP + setPropertyTableModelChangeFP diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp new file mode 100644 index 00000000000..a24e8fa45a3 --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp @@ -0,0 +1,3503 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Windows executables to handle communication + * between Java VMs purposes of Accessbility. + */ + +#include "AccessBridgeDebug.h" +#include "WinAccessBridge.h" +#include "accessBridgeResource.h" +#include "accessBridgeCallbacks.h" +#include "AccessBridgeMessages.h" +#include "AccessBridgeMessageQueue.h" + +#include +#include +#include + +// send memory lock +// +// This lock is need to serialize access to the buffer used by sendMemoryPackage. +// If a JVM goes away while the associated memory buffer is in use, a thread switch +// allows a call to JavaVMDestroyed and deallocation of the memory buffer. +CRITICAL_SECTION sendMemoryIPCLock; + +// registry paths to newly found JVMs that don't have the bridge installed +char **newJVMs; + +WinAccessBridge *theWindowsAccessBridge; +HWND theDialogWindow; + +// unique broadcast msg. IDs gotten dymanically +extern UINT theFromJavaHelloMsgID; +extern UINT theFromWindowsHelloMsgID; + +// protects the javaVMs chain while in use +bool isVMInstanceChainInUse; + +/* =================================================================================== */ + + + +/** + * Proc for "New JVM Found" dialog + */ +BOOL CALLBACK newJVMFoundDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { + + switch (message) { + case WM_COMMAND: + // PrintDebugString(" newJVMDialogProc: LOWORD(wParam) = %d", LOWORD(wParam)); + + switch (LOWORD(wParam)) { + + // Remind user later that a new JVM was installed + case cRemindThereIsNewJVM: + PrintDebugString(" newJVMDialogProc: cRemindThereIsNewJVM"); + // do nothing + EndDialog(hwndDlg, wParam); + return TRUE; + + // Do not remind user later that a new JVM was installed + /* + case cDoNotRemindThereIsNewJVM: + PrintDebugString(" newJVMDialogProc: cDoNotRemindThereIsNewJVM"); + // remember to not remind the user there are new JVMs + PrintDebugString("theWindowsAccessBridge = %x", theWindowsAccessBridge); + if (theWindowsAccessBridge != NULL) { + dontRemindUser(newJVMs); + } + EndDialog(hwndDlg, wParam); + return TRUE; + */ + + // Run the AccessBridge installer + /* + case cInstallAccessBridge: + PrintDebugString(" newJVMDialogProc: cInstallAccessBridge"); + // start the installer + if (theWindowsAccessBridge != NULL) { + startInstaller(newJVMs); + } + EndDialog(hwndDlg, wParam); + return TRUE; + */ + + default: + ; + } + default: + ; + } + return FALSE; +} + + + +/* =========================================================================== */ + +// --------------------------------------------------------------------------- + +extern "C" { + /** + * DllMain - where Windows executables will load/unload us + * + */ + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) { + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: // A Windows executable loaded us + PrintDebugString("DLL_PROCESS_ATTACH"); + theWindowsAccessBridge = new WinAccessBridge(hinstDll); + break; + + case DLL_PROCESS_DETACH: // A Windows executable unloaded us + if (theWindowsAccessBridge != (WinAccessBridge *) 0) { + PrintDebugString("*** AccessBridgeDialogProc -> deleting theWindowsAccessBridge"); + delete theWindowsAccessBridge; + } + break; + } + + return(TRUE); + } + + /** + * Append debug info to dialog + * + * replaced with code to send output to debug file + * + */ + void AppendToCallInfo(char *s) { + + /* + _CrtDbgReport(_CRT_WARN, (const char *) NULL, NULL, (const char *) NULL, + (const char *) "WinAccessBridge: %s", s); + */ + + char buf[1024]; + sprintf(buf, "WinAccessBridge: %s", s); + OutputDebugString(buf); + } + + /** + * Our window proc + * + */ + BOOL CALLBACK AccessBridgeDialogProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) { + COPYDATASTRUCT *sentToUs; + char *package; + + switch (message) { + case WM_INITDIALOG: + PrintDebugString("AccessBridgeDialogProc -> Initializing"); + break; + + // call from Java with data for us to deliver + case WM_COPYDATA: + if (theDialogWindow == (HWND) wParam) { + PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from Java Bridge DLL"); + } else { + PrintDebugString("AccessBridgeDialogProc -> Got WM_COPYDATA from HWND %p", wParam); + sentToUs = (COPYDATASTRUCT *) lParam; + package = (char *) sentToUs->lpData; + theWindowsAccessBridge->preProcessPackage(package, sentToUs->cbData); + } + break; + + // message to ourselves -> de-queue messages and send 'em + case AB_MESSAGE_QUEUED: + PrintDebugString("AccessBridgeDialogProc -> Got AB_MESSAGE_QUEUED from ourselves"); + theWindowsAccessBridge->receiveAQueuedPackage(); + break; + + // a JavaAccessBridge DLL is going away + // + // When JavaVMDestroyed is called a AccessBridgeJavaVMInstance in the + // javaVMs chain will be removed. If that chain is in use this will + // cause a crash. One way AB_DLL_GOING_AWAY can arrive is on any + // outgoing SendMessage call. SendMessage normally spins waiting for + // a response. However, if there is an incoming SendMessage, e.g. for + // AB_DLL_GOING_AWAY Windows will send that request to this DialogProc. + // One seemingly easy way to combat that is to use SendMessageTimeout + // with the SMTO_BLOCK flag set. However, it has been the case that + // even after using that technique AB_DLL_GOING_AWAY can still arrive + // in the middle of processing the javaVMs chain. An alternative that + // was tried was to use a critical section around any access ot the + // javaVMs chain but unfortunately the AB_DLL_GOING_AWAY message arrives + // on the same thread and thus the use of a critical section is ineffective. + // The solution then is to set a flag whenever the javaVMs chain is being + // used and if that flag is set at this point the message will be posted + // to the message queue. That would delay the destruction of the instance + // until the chain is not being traversed. + case AB_DLL_GOING_AWAY: + PrintDebugString("***** AccessBridgeDialogProc -> Got AB_DLL_GOING_AWAY message"); + if (isVMInstanceChainInUse) { + PrintDebugString(" javaVMs chain in use, calling PostMessage"); + PostMessage(hDlg, AB_DLL_GOING_AWAY, wParam, (LPARAM)0); + } else { + PrintDebugString(" calling javaVMDestroyed"); + theWindowsAccessBridge->JavaVMDestroyed((HWND) wParam); + } + break; + + default: + // the JavaVM is saying "hi"! + // wParam == sourceHwnd; lParam == JavaVMID + if (message == theFromJavaHelloMsgID) { + PrintDebugString("AccessBridgeDialogProc -> Got theFromJavaHelloMsgID; wParam = %p, lParam = %p", wParam, lParam); + theWindowsAccessBridge->rendezvousWithNewJavaDLL((HWND) wParam, (long ) lParam); + } + break; + } + + return (FALSE); + } + +} + + + + +// --------------------------------------------------------------------------- + +/** + * Initialize the WinAccessBridge + * + */ +WinAccessBridge::WinAccessBridge(HINSTANCE hInstance) { + + PrintDebugString("WinAccessBridge ctor"); + + // IntializeCriticalSection should only be called once. + InitializeCriticalSection(&sendMemoryIPCLock); + windowsInstance = hInstance; + javaVMs = (AccessBridgeJavaVMInstance *) 0; + eventHandler = new AccessBridgeEventHandler(); + messageQueue = new AccessBridgeMessageQueue(); + initBroadcastMessageIDs(); // get the unique to us broadcast msg. IDs + theWindowsAccessBridge = this; + isVMInstanceChainInUse = false; + + + // notify the user if new JVMs are found + /* + newJVMs = (char **)malloc(MAX_NEW_JVMS_FOUND); + for (int i = 0; i < MAX_NEW_JVMS_FOUND; i++) { + newJVMs[i] = (char *)malloc(SHORT_STRING_SIZE); + newJVMs[i][0] = 0; + } + + BOOL newJ2SEFound = findNewJVMs(J2SE_REG_PATH, newJVMs); + BOOL newJ2REFound = TRUE; // findNewJVMs(J2RE_REG_PATH, newJVMs); + + if (newJ2SEFound || newJ2REFound) { + + int result = DialogBox(windowsInstance, + "FOUNDNEWJVMDIALOG", + NULL, + (DLGPROC)newJVMFoundDialogProc); + if (result < 0) { + printError("DialogBox failed"); + } + + PrintDebugString(" FOUNDNEWJVMDIALOG: result = %d", result); + + ShowWindow((HWND)result, SW_SHOW); + } + */ + + ShowWindow(theDialogWindow, SW_SHOW); +} + + + +/** + * Destroy the WinAccessBridge + * + */ +WinAccessBridge::~WinAccessBridge() { + // inform all other AccessBridges that we're going away + // -> shut down all event listening + // -> release all objects held in the JVM by us + + PrintDebugString("*****in WinAccessBridge::~WinAccessBridge()"); + + // send a broadcast msg.; let other AccessBridge DLLs know we're going away + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + PrintDebugString(" telling %p we're going away", current->javaAccessBridgeWindow); + SendMessage(current->javaAccessBridgeWindow, + AB_DLL_GOING_AWAY, (WPARAM) dialogWindow, (LPARAM) 0); + current = current->nextJVMInstance; + } + + PrintDebugString(" finished telling JVMs about our demise"); + + delete eventHandler; + delete messageQueue; + delete javaVMs; + + PrintDebugString(" finished deleting eventHandler, messageQueue, and javaVMs"); + PrintDebugString("GOODBYE CRUEL WORLD..."); + + DestroyWindow(theDialogWindow); +} + + +/** + * Bring up our window; make a connection to the rest of the world + * + */ +BOOL +WinAccessBridge::initWindow() { + theDialogWindow = CreateDialog(windowsInstance, + "ACCESSBRIDGESTATUSWINDOW", NULL, + (DLGPROC) AccessBridgeDialogProc); + + // If window could not be created, return "failure". + if (!theDialogWindow) + return (FALSE); + + dialogWindow = theDialogWindow; + + // Make the window visible, update its client area, & return "success". + // DEBUG_CODE(ShowWindow (theDialogWindow, SW_SHOWNORMAL)); + // DEBUG_CODE(UpdateWindow (theDialogWindow)); + + // post a broadcast msg.; let other AccessBridge DLLs know we exist + PostMessage(HWND_BROADCAST, theFromWindowsHelloMsgID, (WPARAM) dialogWindow, (LPARAM) 0); + + return (TRUE); +} + +// ----------------------- + +/** + * rendezvousWithNewJavaDLL + * - Build AccessBridgeJavaVMInstance data structure + * (including setting up Memory-Mapped file info) + * + */ +LRESULT +WinAccessBridge::rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID) { + LRESULT returnVal; + + PrintDebugString("in JavaAccessBridge::rendezvousWithNewJavaDLL(%p, %X)", + JavaBridgeDLLwindow, vmID); + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *newVM = + new AccessBridgeJavaVMInstance(dialogWindow, JavaBridgeDLLwindow, vmID, javaVMs); + javaVMs = newVM; + isVMInstanceChainInUse = false; + + returnVal = javaVMs->initiateIPC(); + if (returnVal == 0) { + + // tell the newly created JavaVM what events we're interested in, if any + long javaEventMask = eventHandler->getJavaEventMask(); + long accessibilityEventMask = eventHandler->getAccessibilityEventMask(); + + PrintDebugString(" Setting Java event mask to: %X", javaEventMask); + + if (javaEventMask != 0) { + addJavaEventNotification(javaEventMask); + } + + PrintDebugString(" Setting Accessibility event mask to: %X", accessibilityEventMask); + + if (accessibilityEventMask != 0) { + addAccessibilityEventNotification(accessibilityEventMask); + } + } else { + PrintDebugString(" ERROR: Failed to initiate IPC with newly created JavaVM!!!"); + return FALSE; + } + + PrintDebugString(" Success!! We rendezvoused with the JavaDLL"); + return returnVal; +} + +// ----------------------- + +/** + * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging + * with the Java AccessBridge DLL + * + * NOTE: WM_COPYDATA is only for one-way IPC; there + * is now way to return parameters (especially big ones) + * Use sendMemoryPackage() to do that! + */ +void +WinAccessBridge::sendPackage(char *buffer, long bufsize, HWND destWindow) { + COPYDATASTRUCT toCopy; + toCopy.dwData = 0; // 32-bits we could use for something... + toCopy.cbData = bufsize; + toCopy.lpData = buffer; + + SendMessage(destWindow, WM_COPYDATA, (WPARAM) dialogWindow, (LPARAM) &toCopy); +} + + +/** + * sendMemoryPackage - uses Memory-Mapped files to do IPC messaging + * with the Java AccessBridge DLL, informing the + * Java AccessBridge DLL via SendMessage that something + * is waiting for it in the shared file... + * + * In the SendMessage call, the third param (WPARAM) is + * the source HWND (theDialogWindow in this case), and + * the fourth param (LPARAM) is the size in bytes of + * the package put into shared memory. + * + */ +BOOL +WinAccessBridge::sendMemoryPackage(char *buffer, long bufsize, HWND destWindow) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + AccessBridgeJavaVMInstance *ourABJavaVMInstance; + ourABJavaVMInstance = javaVMs->findABJavaVMInstanceFromJavaHWND(destWindow); + if (ourABJavaVMInstance != (AccessBridgeJavaVMInstance *) 0) { + if (!ourABJavaVMInstance->sendMemoryPackage(buffer, bufsize)) { + // return falue to the caller + memset(buffer, 0, bufsize); + return FALSE; + } + } else { + PrintDebugString("ERROR sending memory package: couldn't find destWindow"); + return FALSE; + } + return TRUE; +} + + +/** + * queuePackage - put a package onto the queue for latter processing + * + */ +BOOL +WinAccessBridge::queuePackage(char *buffer, long bufsize) { + PrintDebugString(" in WinAccessBridge::queuePackage(%p, %d)", buffer, bufsize); + + AccessBridgeQueueElement *element = new AccessBridgeQueueElement(buffer, bufsize); + + messageQueue->add(element); + PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); + return TRUE; +} + + +/** + * receiveAQueuedPackage - remove a pending packge from the queue and + * handle it. If the queue is busy, post a + * message to self to retrieve it later + * + */ +BOOL +WinAccessBridge::receiveAQueuedPackage() { + AccessBridgeQueueElement *element; + + PrintDebugString("in WinAccessBridge::receiveAQueuedPackage()"); + + // ensure against re-entrancy problems... + if (messageQueue->getRemoveLockSetting() == FALSE) { + messageQueue->setRemoveLock(TRUE); + + PrintDebugString(" dequeueing message"); + + QueueReturns result = messageQueue->remove(&element); + + PrintDebugString(" 'element->buffer' contains:"); + DEBUG_CODE(PackageType *type = (PackageType *) element->buffer); + DEBUG_CODE(FocusGainedPackageTag *pkg = (FocusGainedPackageTag *) (((char *) element->buffer) + sizeof(PackageType))); + DEBUG_CODE(PrintDebugString(" PackageType = %X", *type)); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + DEBUG_CODE(PrintDebugString(" EventPackage: vmID = %X, event = %p, source = %p", pkg->vmID, pkg->Event, pkg->AccessibleContextSource)); +#else // JOBJECT64 is jlong (64 bit) + DEBUG_CODE(PrintDebugString(" EventPackage: vmID = %X, event = %016I64X, source = %016I64X", pkg->vmID, pkg->Event, pkg->AccessibleContextSource)); +#endif + switch (result) { + + case cQueueBroken: + PrintDebugString(" ERROR!!! Queue seems to be broken!"); + messageQueue->setRemoveLock(FALSE); + return FALSE; + + case cMoreMessages: + case cQueueEmpty: + if (element != (AccessBridgeQueueElement *) 0) { + PrintDebugString(" found one; sending it!"); + processPackage(element->buffer, element->bufsize); + delete element; + } else { + PrintDebugString(" ODD... element == 0!"); + return FALSE; + } + break; + + case cQueueInUse: + PrintDebugString(" Queue in use, will try again later..."); + PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); + break; + + default: + messageQueue->setRemoveLock(FALSE); + return FALSE; // should never get something we don't recognize! + } + } else { + PrintDebugString(" unable to dequeue message; remove lock is set"); + PostMessage(dialogWindow, AB_MESSAGE_QUEUED, (WPARAM) 0, (LPARAM) 0); // Fix for 6995891 + } + + messageQueue->setRemoveLock(FALSE); + return TRUE; +} + +// ----------------------- + +/** + * preProcessPackage + * - do triage on incoming packages; queue some, deal with others + * + */ +void +WinAccessBridge::preProcessPackage(char *buffer, long bufsize) { + PrintDebugString("PreProcessing package sent from Java:"); + + PackageType *type = (PackageType *) buffer; + + switch (*type) { + + PrintDebugString(" type == %X", *type); + + // event packages all get queued for later handling + //case cPropertyChangePackage: + case cJavaShutdownPackage: + case cFocusGainedPackage: + case cFocusLostPackage: + case cCaretUpdatePackage: + case cMouseClickedPackage: + case cMouseEnteredPackage: + case cMouseExitedPackage: + case cMousePressedPackage: + case cMouseReleasedPackage: + case cMenuCanceledPackage: + case cMenuDeselectedPackage: + case cMenuSelectedPackage: + case cPopupMenuCanceledPackage: + case cPopupMenuWillBecomeInvisiblePackage: + case cPopupMenuWillBecomeVisiblePackage: + + case cPropertyCaretChangePackage: + case cPropertyDescriptionChangePackage: + case cPropertyNameChangePackage: + case cPropertySelectionChangePackage: + case cPropertyStateChangePackage: + case cPropertyTextChangePackage: + case cPropertyValueChangePackage: + case cPropertyVisibleDataChangePackage: + case cPropertyChildChangePackage: + case cPropertyActiveDescendentChangePackage: + + case cPropertyTableModelChangePackage: + + queuePackage(buffer, bufsize); + break; + + // perhaps there will be some other packages to process at some point... // + + default: + PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + break; + } + + PrintDebugString(" package preprocessing completed"); +} + + +#define DISPATCH_EVENT_PACKAGE(packageID, eventPackage, fireEventMethod) \ + case packageID: \ + if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ + eventPackage *pkg = \ + (eventPackage *) (buffer + sizeof(PackageType)); \ + PrintDebugString(" begin callback to AT, type == %X", *type); \ + theWindowsAccessBridge->eventHandler->fireEventMethod( \ + pkg->vmID, pkg->Event, pkg->AccessibleContextSource); \ + PrintDebugString(" event callback complete!"); \ + } else { \ + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ + } \ + break; + +#define DISPATCH_PROPERTY_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \ + case packageID: \ + if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ + eventPackage *pkg = \ + (eventPackage *) (buffer + sizeof(PackageType)); \ + PrintDebugString(" begin callback to AT, type == %X", *type); \ + theWindowsAccessBridge->eventHandler->fireEventMethod( \ + pkg->vmID, pkg->Event, pkg->AccessibleContextSource, \ + pkg->oldValue, pkg->newValue); \ + PrintDebugString(" event callback complete!"); \ + } else { \ + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ + } \ + break; + +#define DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(packageID, eventPackage, fireEventMethod, oldValue, newValue) \ + case packageID: \ + if (bufsize == sizeof(PackageType) + sizeof(eventPackage)) { \ + eventPackage *pkg = \ + (eventPackage *) (buffer + sizeof(PackageType)); \ + PrintDebugString(" begin callback to AT, type == %X", *type); \ + theWindowsAccessBridge->eventHandler->fireEventMethod( \ + pkg->vmID, pkg->Event, pkg->AccessibleContextSource, \ + pkg->oldValue, pkg->newValue); \ + PrintDebugString(" event callback complete!"); \ + } else { \ + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", \ + bufsize, sizeof(PackageType) + sizeof(eventPackage)); \ + } \ + break; + +/** + * processPackage - processes the output of SendMessage(WM_COPYDATA) + * to do IPC messaging with the Java AccessBridge DLL + * + */ +void +WinAccessBridge::processPackage(char *buffer, long bufsize) { + PrintDebugString("WinAccessBridge::Processing package sent from Java:"); + + PackageType *type = (PackageType *) buffer; + + switch (*type) { + + PrintDebugString(" type == %X", *type); + + case cJavaShutdownPackage: + PrintDebugString(" type == cJavaShutdownPackage"); + if (bufsize == sizeof(PackageType) + sizeof(JavaShutdownPackage)) { + JavaShutdownPackage *pkg = + (JavaShutdownPackage *) (buffer + sizeof(PackageType)); + theWindowsAccessBridge->eventHandler->fireJavaShutdown(pkg->vmID); + PrintDebugString(" event callback complete!"); + PrintDebugString(" event fired!"); + } else { + PrintDebugString(" processing FAILED!! -> bufsize = %d; expectation = %d", + bufsize, sizeof(PackageType) + sizeof(JavaShutdownPackage)); + } + break; + + + DISPATCH_EVENT_PACKAGE(cFocusGainedPackage, FocusGainedPackage, fireFocusGained); + DISPATCH_EVENT_PACKAGE(cFocusLostPackage, FocusLostPackage, fireFocusLost); + + DISPATCH_EVENT_PACKAGE(cCaretUpdatePackage, CaretUpdatePackage, fireCaretUpdate); + + DISPATCH_EVENT_PACKAGE(cMouseClickedPackage, MouseClickedPackage, fireMouseClicked); + DISPATCH_EVENT_PACKAGE(cMouseEnteredPackage, MouseEnteredPackage, fireMouseEntered); + DISPATCH_EVENT_PACKAGE(cMouseExitedPackage, MouseExitedPackage, fireMouseExited); + DISPATCH_EVENT_PACKAGE(cMousePressedPackage, MousePressedPackage, fireMousePressed); + DISPATCH_EVENT_PACKAGE(cMouseReleasedPackage, MouseReleasedPackage, fireMouseReleased); + + DISPATCH_EVENT_PACKAGE(cMenuCanceledPackage, MenuCanceledPackage, fireMenuCanceled); + DISPATCH_EVENT_PACKAGE(cMenuDeselectedPackage, MenuDeselectedPackage, fireMenuDeselected); + DISPATCH_EVENT_PACKAGE(cMenuSelectedPackage, MenuSelectedPackage, fireMenuSelected); + DISPATCH_EVENT_PACKAGE(cPopupMenuCanceledPackage, PopupMenuCanceledPackage, firePopupMenuCanceled); + DISPATCH_EVENT_PACKAGE(cPopupMenuWillBecomeInvisiblePackage, PopupMenuWillBecomeInvisiblePackage, firePopupMenuWillBecomeInvisible); + DISPATCH_EVENT_PACKAGE(cPopupMenuWillBecomeVisiblePackage, PopupMenuWillBecomeVisiblePackage, firePopupMenuWillBecomeVisible); + + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyNameChangePackage, + PropertyNameChangePackage, + firePropertyNameChange, oldName, newName) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyDescriptionChangePackage, + PropertyDescriptionChangePackage, + firePropertyDescriptionChange, + oldDescription, newDescription) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyStateChangePackage, + PropertyStateChangePackage, + firePropertyStateChange, oldState, newState) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyValueChangePackage, + PropertyValueChangePackage, + firePropertyValueChange, oldValue, newValue) + DISPATCH_EVENT_PACKAGE(cPropertySelectionChangePackage, + PropertySelectionChangePackage, firePropertySelectionChange) + DISPATCH_EVENT_PACKAGE(cPropertyTextChangePackage, + PropertyTextChangePackage, firePropertyTextChange) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyCaretChangePackage, + PropertyCaretChangePackage, + firePropertyCaretChange, oldPosition, newPosition) + DISPATCH_EVENT_PACKAGE(cPropertyVisibleDataChangePackage, + PropertyVisibleDataChangePackage, firePropertyVisibleDataChange) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyChildChangePackage, + PropertyChildChangePackage, + firePropertyChildChange, + oldChildAccessibleContext, + newChildAccessibleContext) + DISPATCH_PROPERTY_CHANGE_PACKAGE(cPropertyActiveDescendentChangePackage, + PropertyActiveDescendentChangePackage, + firePropertyActiveDescendentChange, + oldActiveDescendentAccessibleContext, + newActiveDescendentAccessibleContext) + + DISPATCH_PROPERTY_TABLE_MODEL_CHANGE_PACKAGE(cPropertyTableModelChangePackage, + PropertyTableModelChangePackage, + firePropertyTableModelChange, + oldValue, newValue) + + + default: + PrintDebugString(" processing FAILED!! -> don't know how to handle type = %X", *type); + break; + } + + PrintDebugString(" package processing completed"); +} + + +// ----------------------------- + +void +WinAccessBridge::JavaVMDestroyed(HWND VMBridgeDLLWindow) { + PrintDebugString("***** WinAccessBridge::JavaVMDestroyed(%p)", VMBridgeDLLWindow); + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *currentVM = javaVMs; + AccessBridgeJavaVMInstance *previousVM = javaVMs; + if (javaVMs->javaAccessBridgeWindow == VMBridgeDLLWindow) { + javaVMs = javaVMs->nextJVMInstance; + delete currentVM; + + PrintDebugString(" data structures successfully removed"); + + // [[[FIXME]]] inform Windows AT that a JVM went away, + // and that any jobjects it's got lying around for that JVM + // are now invalid + + } else { + while (currentVM != (AccessBridgeJavaVMInstance *) 0) { + if (currentVM->javaAccessBridgeWindow == VMBridgeDLLWindow) { + previousVM->nextJVMInstance = currentVM->nextJVMInstance; + delete currentVM; + + PrintDebugString(" data structures successfully removed"); + + // [[[FIXME]]] inform Windows AT that a JVM went away, + // and that any jobjects it's got lying around for that JVM + // are now invalid + isVMInstanceChainInUse = false; + return; + } else { + previousVM = currentVM; + currentVM = currentVM->nextJVMInstance; + } + } + PrintDebugString(" ERROR!! couldn't find matching data structures!"); + } + isVMInstanceChainInUse = false; +} + +// ----------------------- + +/** + * releaseJavaObject - lets the JavaVM know it can release the Java Object + * + * Note: once you have made this call, the JavaVM will garbage collect + * the jobject you pass in. If you later use that jobject in another + * call, you will cause all maner of havoc! + * + */ +void +WinAccessBridge::releaseJavaObject(long vmID, JOBJECT64 object) { +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %p)", vmID, object); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::releaseJavaObject(%X, %016I64X)", vmID, object); +#endif + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(ReleaseJavaObjectPackage)]; + PackageType *type = (PackageType *) buffer; + ReleaseJavaObjectPackage *pkg = (ReleaseJavaObjectPackage *) (buffer + sizeof(PackageType)); + *type = cReleaseJavaObjectPackage; + pkg->vmID = vmID; + pkg->object = object; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendPackage(buffer, sizeof(buffer), destABWindow); // no return values! + } +} + +// ----------------------- + +/** + * getVersionInfo - fill the AccessBridgeVersionInfo struct + * + */ +BOOL +WinAccessBridge::getVersionInfo(long vmID, AccessBridgeVersionInfo *info) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessBridgeVersionPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessBridgeVersionPackage *pkg = (GetAccessBridgeVersionPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessBridgeVersionPackage; + pkg->vmID = vmID; + + PrintDebugString("WinAccessBridge::getVersionInfo(%X, )", vmID); + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(info, &(pkg->rVersionInfo), sizeof(AccessBridgeVersionInfo)); + PrintDebugString(" VMversion: %ls", info->VMversion); + PrintDebugString(" bridgeJavaClassVersion: %ls", info->bridgeJavaClassVersion); + PrintDebugString(" bridgeJavaDLLVersion: %ls", info->bridgeJavaDLLVersion); + PrintDebugString(" bridgeWinDLLVersion: %ls", info->bridgeWinDLLVersion); + return TRUE; + } + } + return FALSE; +} + + +/********** Window-related routines ***********************************/ + +/** + * isJavaWindow - returns TRUE if the HWND is a top-level Java Window + * + * Note: just because the Windnow is a top-level Java window, that doesn't + * mean that it is accessible. Call getAccessibleContextFromHWND(HWND) to get the + * AccessibleContext, if any, for an HWND that is a Java Window. + * + */ +BOOL +WinAccessBridge::isJavaWindow(HWND window) { + HWND hwnd; + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + // quick check to see if 'window' is top-level; if not, it's not interesting... + // [[[FIXME]]] is this for sure an OK optimization? + hwnd = getTopLevelHWND(window); + if (hwnd == (HWND) NULL) { + return FALSE; + } + + PrintDebugString(" in WinAccessBridge::isJavaWindow"); + + + + char buffer[sizeof(PackageType) + sizeof(IsJavaWindowPackage)]; + PackageType *type = (PackageType *) buffer; + IsJavaWindowPackage *pkg = (IsJavaWindowPackage *) (buffer + sizeof(PackageType)); + *type = cIsJavaWindowPackage; + pkg->window = (jint) window; + + PrintDebugString("WinAccessBridge::isJavaWindow(%p)", window); + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) { + if (pkg->rResult != 0) { + isVMInstanceChainInUse = false; + return TRUE; + } + } + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; + return FALSE; + + + /* + char classname[256]; + HWND hwnd; + + hwnd = getTopLevelHWND(window); + if (hwnd == (HWND) NULL) { + return FALSE; + } + GetClassName(hwnd, classname, 256); + + if (strstr(classname, "AwtFrame") != 0) { + return TRUE; + } else if (strstr(classname, "AwtWindow") != 0) { + return TRUE; + } else if (strstr(classname, "AwtDialog") != 0) { + return TRUE; + } + */ + // JDK 1.4 introduces new (and changes old) classnames + /* + else if (strstr(classname, "SunAwtToolkit") != 0) { + return TRUE; + } else if (strstr(classname, "javax.swing.JFrame") != 0) { + return TRUE; + } + */ + + return FALSE; +} + +/** + * isSameObject - returns TRUE if the two object references refer to + * the same object. Otherwise, this method returns FALSE: + */ +BOOL +WinAccessBridge::isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::isSameObject(%p %p)", obj1, obj2); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::isSameObject(%016I64X %016I64X)", obj1, obj2); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(IsSameObjectPackage)]; + PackageType *type = (PackageType *) buffer; + IsSameObjectPackage *pkg = (IsSameObjectPackage *) (buffer + sizeof(PackageType)); + *type = cIsSameObjectPackage; + pkg->vmID = vmID; + pkg->obj1 = obj1; + pkg->obj2 = obj2; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + if (pkg->rResult != 0) { + PrintDebugString(" WinAccessBridge::isSameObject returning TRUE (same object)"); + return TRUE; + } else { + PrintDebugString(" WinAccessBridge::isSameObject returning FALSE (different object)"); + return FALSE; + } + } + PrintDebugString(" WinAccessBridge::isSameObject returning FALSE (sendMemoryPackage failed)"); + return FALSE; +} + +/** + * FromHWND - returns the AccessibleContext jobject for the HWND + * + * Note: this routine can return null, even if the HWND is a Java Window, + * because the Java Window may not be accessible. + * + */ +BOOL +WinAccessBridge::getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextFromHWNDPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextFromHWNDPackage *pkg = (GetAccessibleContextFromHWNDPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextFromHWNDPackage; + pkg->window = (jint) window; + + PrintDebugString("WinAccessBridge::getAccessibleContextFromHWND(%p, )", window); + + DEBUG_CODE(pkg->rVMID = (long ) 0x01010101); + DEBUG_CODE(pkg->rAccessibleContext = (JOBJECT64) 0x01010101); + + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + + if (sendMemoryPackage(buffer, sizeof(buffer), current->javaAccessBridgeWindow) == TRUE) { + if (pkg->rAccessibleContext != 0) { + *vmID = pkg->rVMID; + *AccessibleContext = (JOBJECT64)pkg->rAccessibleContext; + PrintDebugString(" current->vmID = %X", current->vmID); + PrintDebugString(" pkg->rVMID = %X", pkg->rVMID); +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" pkg->rAccessibleContext = %p", pkg->rAccessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" pkg->rAccessibleContext = %016I64X", pkg->rAccessibleContext); +#endif + if (pkg->rVMID != current->vmID) { + PrintDebugString(" ERROR! getAccessibleContextFromHWND vmIDs don't match!"); + isVMInstanceChainInUse = false; + return FALSE; + } + isVMInstanceChainInUse = false; + return TRUE; + } + } + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; + + // This isn't really an error; it just means that the HWND was for a non-Java + // window. It's also possible the HWND was for a Java window but the JVM has + // since been shut down and sendMemoryPackage returned FALSE. + PrintDebugString(" ERROR! getAccessibleContextFromHWND no matching HWND found!"); + return FALSE; +} + +/** + * Returns the HWND for an AccessibleContext. Returns (HWND)0 on error. + */ +HWND +WinAccessBridge::getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext) { + PrintDebugString(" in WinAccessBridge::getHWNDFromAccessibleContext"); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (HWND)0; + } + + char buffer[sizeof(PackageType) + sizeof(GetHWNDFromAccessibleContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetHWNDFromAccessibleContextPackage *pkg = (GetHWNDFromAccessibleContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetHWNDFromAccessibleContextPackage; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%p)", accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getHWNDFromAccessibleContext(%016I64X)", accessibleContext); +#endif + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return ((HWND)ABLongToHandle(pkg->rHWND)); + } + } + return (HWND)0; +} + +/********** AccessibleContext routines ***********************************/ + +/** + * Walk through Java Windows, in front-to-back Z-order. + * If NULL is passed it, this function starts at the top. + * + */ +HWND +WinAccessBridge::getNextJavaWindow(HWND previous) { + HWND current = previous; + if (current == NULL) { + current = GetTopWindow(NULL); + } else { + current = GetNextWindow(current, GW_HWNDNEXT); + } + while (current != NULL) { + if (isJavaWindow(current)) { + return current; + } + current = GetNextWindow(current, GW_HWNDNEXT); + } + return NULL; +} + + +/** + * getAccessibleContextAt - performs the Java code: + * Accessible a = EventQueueMonitor.getAccessibleAt(x, y); + * return a.getAccessibleContext(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +BOOL +WinAccessBridge::getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextAtPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextAtPackage *pkg = (GetAccessibleContextAtPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextAtPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContextParent; + pkg->x = x; + pkg->y = y; + + PrintDebugString("WinAccessBridge::getAccessibleContextAt(%X, %p, %d, %c)", vmID, AccessibleContextParent, x, y); + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *AccessibleContext = pkg->rAccessibleContext; + return TRUE; + } + + return FALSE; +} + + +/** + * getAccessibleContextWithFocus - performs the Java code: + * Accessible a = Translator.getAccessible(SwingEventMonitor.getComponentWithFocus()); + * return a.getAccessibleContext(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +BOOL +WinAccessBridge::getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextWithFocusPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextWithFocusPackage *pkg = (GetAccessibleContextWithFocusPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextWithFocusPackage; + + PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID); + // find vmID, etc. from HWND; ask that VM for the AC w/Focus + HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ; + if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) { + HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID); // ineffecient [[[FIXME]]] + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *vmID = pkg->rVMID; + *AccessibleContext = pkg->rAccessibleContext; + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleContextInfo - fills a struct with a bunch of information + * contained in the Java Accessibility API + * + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleContextInfo(long vmID, + JOBJECT64 accessibleContext, + AccessibleContextInfo *info) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleContextInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleContextInfoPackage *pkg = (GetAccessibleContextInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleContextInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %p, )", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleContextInfo(%X, %016I64X, )", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(info, &(pkg->rAccessibleContextInfo), sizeof(AccessibleContextInfo)); + PrintDebugString(" name: %ls", info->name); + PrintDebugString(" description: %ls", info->description); + PrintDebugString(" role: %ls", info->role); + PrintDebugString(" role_en_US: %ls", info->role_en_US); + PrintDebugString(" states: %ls", info->states); + PrintDebugString(" states_en_US: %ls", info->states_en_US); + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleChildFromContext - performs the Java code: + * Accessible child = ac.getAccessibleChild(i); + * return child.getAccessibleContext(); + * + * Note: this call explicitly goes through the AccessBridge, + * so that the AccessBridge can hide expected changes in how this functions + * between JDK 1.1.x w/AccessibilityUtility classes, and JDK 1.2, when some + * of this functionality may be built into the platform + * + */ +JOBJECT64 +WinAccessBridge::getAccessibleChildFromContext(long vmID, + JOBJECT64 AccessibleContext, + jint childIndex) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleChildFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleChildFromContextPackage *pkg = (GetAccessibleChildFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleChildFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->childIndex = childIndex; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %p, %d)", vmID, AccessibleContext, childIndex); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleChildFromContext(%X, %016I64X, %d)", vmID, AccessibleContext, childIndex); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + + return (JOBJECT64) 0; +} + +/** + * getAccessibleParentFromContext - returns the parent AccessibleContext jobject + * + * Note: this may be null, if the AccessibleContext passed in is a top-level + * window, then it has no parent. + * + */ +JOBJECT64 +WinAccessBridge::getAccessibleParentFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleParentFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleParentFromContextPackage *pkg = (GetAccessibleParentFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleParentFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + PrintDebugString("WinAccessBridge::getAccessibleParentFromContext(%X, %p)", vmID, AccessibleContext); + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + + return (JOBJECT64) 0; +} + +/********** AccessibleTable routines ***********************************/ + +BOOL +WinAccessBridge::getAccessibleTableInfo(long vmID, + JOBJECT64 accessibleContext, + AccessibleTableInfo *tableInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %p, %p)", vmID, accessibleContext, + tableInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableInfo(%X, %016I64X, %p)", vmID, accessibleContext, + tableInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableInfoPackage *pkg = (GetAccessibleTableInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableInfoPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); + if (pkg->rTableInfo.rowCount != -1) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableInfo succeeded"); + return TRUE; + } + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableInfo failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, + jint row, jint column, + AccessibleTableCellInfo *tableCellInfo) { + + PrintDebugString("##### WinAccessBridge::getAccessibleTableCellInfo(%X, %p, %d, %d, %p)", vmID, + accessibleTable, row, column, tableCellInfo); + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableCellInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableCellInfoPackage *pkg = (GetAccessibleTableCellInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableCellInfoPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->row = row; + pkg->column = column; + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" XXXX pkg->rTableCellInfo.accessibleContext = %p", pkg->rTableCellInfo.accessibleContext); + memcpy(tableCellInfo, &(pkg->rTableCellInfo), sizeof(AccessibleTableCellInfo)); + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableCellInfo succeeded"); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableCellInfo failed"); + return FALSE; +} + + +BOOL +WinAccessBridge::getAccessibleTableRowHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowHeader(%X, %016I64X)", vmID, accessibleContext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowHeaderPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowHeaderPackage *pkg = (GetAccessibleTableRowHeaderPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowHeaderPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowHeader succeeded"); + memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowHeader failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableColumnHeader(long vmID, JOBJECT64 accessibleContext, AccessibleTableInfo *tableInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnHeader(%X, %016I64X)", vmID, accessibleContext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnHeaderPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnHeaderPackage *pkg = (GetAccessibleTableColumnHeaderPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnHeaderPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnHeader succeeded"); + memcpy(tableInfo, &(pkg->rTableInfo), sizeof(AccessibleTableInfo)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnHeader failed"); + return FALSE; +} + +JOBJECT64 +WinAccessBridge::getAccessibleTableRowDescription(long vmID, + JOBJECT64 accessibleContext, + jint row) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %p, %d)", vmID, accessibleContext, + row); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowDescription(%X, %016I64X, %d)", vmID, accessibleContext, + row); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowDescriptionPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowDescriptionPackage *pkg = (GetAccessibleTableRowDescriptionPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowDescriptionPackage; + pkg->vmID = vmID; + pkg->row = row; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowDescription succeeded"); + return pkg->rAccessibleContext; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowDescription failed"); + return (JOBJECT64)0; +} + +JOBJECT64 +WinAccessBridge::getAccessibleTableColumnDescription(long vmID, + JOBJECT64 accessibleContext, + jint column) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %p, %d)", vmID, accessibleContext, + column); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnDescription(%X, %016I64X, %d)", vmID, accessibleContext, + column); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnDescriptionPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnDescriptionPackage *pkg = + (GetAccessibleTableColumnDescriptionPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnDescriptionPackage; + pkg->vmID = vmID; + pkg->column = column; + pkg->accessibleContext = accessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnDescription succeeded"); + return pkg->rAccessibleContext; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnDescription failed"); + return (JOBJECT64)0; +} + +jint +WinAccessBridge::getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelectionCount(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return 0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowSelectionCountPackage *pkg = + (GetAccessibleTableRowSelectionCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowSelectionCountPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelectionCount succeeded"); + return pkg->rCount; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelectionCount failed"); + return 0; +} + +BOOL +WinAccessBridge::isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::isAccessibleTableRowSelected(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableRowSelectedPackage)]; + PackageType *type = (PackageType *) buffer; + IsAccessibleTableRowSelectedPackage *pkg = (IsAccessibleTableRowSelectedPackage *) (buffer + sizeof(PackageType)); + *type = cIsAccessibleTableRowSelectedPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->row = row; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableRowSelected succeeded"); + return pkg->rResult; + } + } + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableRowSelected failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, jint *selections) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRowSelections(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowSelectionsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowSelectionsPackage *pkg = + (GetAccessibleTableRowSelectionsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowSelectionsPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->count = count; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelections succeeded"); + memcpy(selections, pkg->rSelections, count * sizeof(jint)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRowSelections failed"); + return FALSE; +} + + +jint +WinAccessBridge::getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %p)", vmID, + accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelectionCount(%X, %016I64X)", vmID, + accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnSelectionCountPackage *pkg = + (GetAccessibleTableColumnSelectionCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnSelectionCountPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelectionCount succeeded"); + return pkg->rCount; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelectionCount failed"); + return 0; +} + +BOOL +WinAccessBridge::isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column) { +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::isAccessibleTableColumnSelected(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(IsAccessibleTableColumnSelectedPackage)]; + PackageType *type = (PackageType *) buffer; + IsAccessibleTableColumnSelectedPackage *pkg = (IsAccessibleTableColumnSelectedPackage *) (buffer + sizeof(PackageType)); + *type = cIsAccessibleTableColumnSelectedPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->column = column; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableColumnSelected succeeded"); + return pkg->rResult; + } + } + PrintDebugString(" ##### WinAccessBridge::isAccessibleTableColumnSelected failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %p)", vmID, accessibleTable); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumnSelections(%X, %016I64X)", vmID, accessibleTable); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnSelectionsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnSelectionsPackage *pkg = + (GetAccessibleTableColumnSelectionsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnSelectionsPackage; + pkg->vmID = vmID; + pkg->count = count; + pkg->accessibleTable = accessibleTable; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelections succeeded"); + memcpy(selections, pkg->rSelections, count * sizeof(jint)); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumnSelections failed"); + return FALSE; +} + +jint +WinAccessBridge::getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %p, index=%d)", vmID, + accessibleTable, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableRow(%X, %016I64X, index=%d)", vmID, + accessibleTable, index); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableRowPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableRowPackage *pkg = + (GetAccessibleTableRowPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableRowPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->index = index; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRow succeeded"); + return pkg->rRow; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableRow failed"); + return 0; +} + +jint +WinAccessBridge::getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %p, index=%d)", vmID, + accessibleTable, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableColumn(%X, %016I64X, index=%d)", vmID, + accessibleTable, index); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableColumnPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableColumnPackage *pkg = + (GetAccessibleTableColumnPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableColumnPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->index = index; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumn succeeded"); + return pkg->rColumn; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableColumn failed"); + return 0; +} + +jint +WinAccessBridge::getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %p, row=%d, col=%d)", vmID, + accessibleTable, row, column); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleTableIndex(%X, %016I64X, row=%d, col=%d)", vmID, + accessibleTable, row, column); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTableIndexPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTableIndexPackage *pkg = + (GetAccessibleTableIndexPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTableIndexPackage; + pkg->vmID = vmID; + pkg->accessibleTable = accessibleTable; + pkg->row = row; + pkg->column = column; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableIndex succeeded"); + return pkg->rIndex; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleTableIndex failed"); + return 0; +} + +/********** end AccessibleTable routines ******************************/ + +BOOL +WinAccessBridge::getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, + AccessibleRelationSetInfo *relationSetInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %p, %X)", vmID, + accessibleContext, relationSetInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleRelationSet(%X, %016I64X, %X)", vmID, + accessibleContext, relationSetInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleRelationSetPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleRelationSetPackage *pkg = (GetAccessibleRelationSetPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleRelationSetPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### pkg->rAccessibleRelationSetInfo.relationCount = %X", + pkg->rAccessibleRelationSetInfo.relationCount); + memcpy(relationSetInfo, &(pkg->rAccessibleRelationSetInfo), sizeof(AccessibleRelationSetInfo)); + PrintDebugString(" ##### WinAccessBridge::getAccessibleRelationSet succeeded"); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleRelationSet failed"); + return FALSE; +} + + +/********** AccessibleHypertext routines ***********/ + +BOOL +WinAccessBridge::getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, + AccessibleHypertextInfo *hypertextInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %p, %X)", vmID, + accessibleContext, hypertextInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertext(%X, %016I64X, %X)", vmID, + accessibleContext, hypertextInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHypertextPackage *pkg = (GetAccessibleHypertextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHypertextPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo)); + + PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext failed"); + return FALSE; +} + + +BOOL +WinAccessBridge::activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, + JOBJECT64 accessibleHyperlink) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%p %p)", accessibleContext, + accessibleHyperlink); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::activateAccessibleHyperlink(%016I64X %016I64X)", accessibleContext, + accessibleHyperlink); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(ActivateAccessibleHyperlinkPackage)]; + PackageType *type = (PackageType *) buffer; + ActivateAccessibleHyperlinkPackage *pkg = (ActivateAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + *type = cActivateAccessibleHyperlinkPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->accessibleHyperlink = accessibleHyperlink; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rResult; + } + PrintDebugString(" WinAccessBridge::activateAccessibleHyperlink returning FALSE (sendMemoryPackage failed)"); + return FALSE; +} + +/* + * Returns the number of hyperlinks in a component + * Maps to AccessibleHypertext.getLinkCount. + * Returns -1 on error. + */ +jint +WinAccessBridge::getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %p)", + vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlinkCount(%X, %016I64X)", + vmID, accessibleContext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHyperlinkCountPackage *pkg = (GetAccessibleHyperlinkCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHyperlinkCountPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### hypetext link count = %d", pkg->rLinkCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHyperlinkCount succeeded"); + return pkg->rLinkCount; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHyperlinkCount failed"); + return -1; +} + +/* + * This method is used to iterate through the hyperlinks in a component. It + * returns hypertext information for a component starting at hyperlink index + * nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will + * be returned for each call to this method. + * returns FALSE on error. + */ +BOOL +WinAccessBridge::getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint startIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %p %p)", vmID, + accessibleContext, hypertextInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextExt(%X, %016I64X %p)", vmID, + accessibleContext, hypertextInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextExtPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHypertextExtPackage *pkg = (GetAccessibleHypertextExtPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHypertextExtPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### pkg->rSuccess = %d", pkg->rSuccess); + + memcpy(hypertextInfo, &(pkg->rAccessibleHypertextInfo), sizeof(AccessibleHypertextInfo)); + if (pkg->rSuccess == TRUE) { + PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + PrintDebugString(" ##### hypertextInfo.linkCount = %d", hypertextInfo->linkCount); + } else { + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextExt failed"); + } + return pkg->rSuccess;; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextExt failed"); + return FALSE; +} + + +/* + * Returns the index into an array of hyperlinks that is associated with + * a character index in document; + * Maps to AccessibleHypertext.getLinkIndex. + * Returns -1 on error. + */ +jint +WinAccessBridge::getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHyperlink hypertext, + const jint charIndex) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %p)", + vmID, hypertext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHypertextLinkIndex(%X, %016I64X)", + vmID, hypertext); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHypertextLinkIndexPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHypertextLinkIndexPackage *pkg = (GetAccessibleHypertextLinkIndexPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHypertextLinkIndexPackage; + pkg->vmID = vmID; + pkg->hypertext = hypertext; + pkg->charIndex = charIndex; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" ##### hypetext link index = %d", pkg->rLinkIndex); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextLinkIndex succeeded"); + return pkg->rLinkIndex; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertextLinkIndex failed"); + return -1; +} + +/* + * Returns the nth hyperlink in a document. + * Maps to AccessibleHypertext.getLink. + * Returns -1 on error + */ +BOOL +WinAccessBridge::getAccessibleHyperlink(const long vmID, + const AccessibleHyperlink hypertext, + const jint linkIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %p, %p)", vmID, + hypertext, hyperlinkInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleHyperlink(%X, %016I64X, %p)", vmID, + hypertext, hyperlinkInfo); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleHyperlinkPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleHyperlinkPackage *pkg = (GetAccessibleHyperlinkPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleHyperlinkPackage; + pkg->vmID = vmID; + pkg->hypertext = hypertext; + pkg->linkIndex = linkIndex; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(hyperlinkInfo, &(pkg->rAccessibleHyperlinkInfo), + sizeof(AccessibleHyperlinkInfo)); + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext succeeded"); + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleHypertext failed"); + return FALSE; +} + + +/********** AccessibleKeyBinding routines ***********/ + +BOOL +WinAccessBridge::getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, + AccessibleKeyBindings *keyBindings) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %p, %p)", vmID, + accessibleContext, keyBindings); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleKeyBindings(%X, %016I64X, %p)", vmID, + accessibleContext, keyBindings); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleKeyBindingsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleKeyBindingsPackage *pkg = (GetAccessibleKeyBindingsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleKeyBindingsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(keyBindings, &(pkg->rAccessibleKeyBindings), sizeof(AccessibleKeyBindings)); + + PrintDebugString(" ##### keyBindings.keyBindingsCount = %d", keyBindings->keyBindingsCount); + for (int i = 0; i < keyBindings->keyBindingsCount; ++i) { + PrintDebugString(" Key Binding # %d", i+1); + PrintDebugString(" Modifiers: 0x%x", keyBindings->keyBindingInfo[i].modifiers); + PrintDebugString(" Character (hex): 0x%x", keyBindings->keyBindingInfo[i].character); + PrintDebugString(" Character (wide char): %lc", keyBindings->keyBindingInfo[i].character); + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleKeyBindings succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleKeyBindings failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, AccessibleIcons *icons) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %p, %p)", vmID, + accessibleContext, icons); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleIcons(%X, %016I64X, %p)", vmID, + accessibleContext, icons); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleIconsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleIconsPackage *pkg = (GetAccessibleIconsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleIconsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(icons, &(pkg->rAccessibleIcons), sizeof(AccessibleIcons)); + + PrintDebugString(" ##### icons.iconsCount = %d", icons->iconsCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleIcons succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleIcons failed"); + return FALSE; +} + +BOOL +WinAccessBridge::getAccessibleActions(long vmID, JOBJECT64 accessibleContext, AccessibleActions *actions) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %p, %p)", vmID, + accessibleContext, actions); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("##### WinAccessBridge::getAccessibleActions(%X, %016I64X, %p)", vmID, + accessibleContext, actions); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + + char buffer[sizeof(PackageType) + sizeof(GetAccessibleActionsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleActionsPackage *pkg = (GetAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleActionsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(actions, &(pkg->rAccessibleActions), sizeof(AccessibleActions)); + + PrintDebugString(" ##### actions.actionsCount = %d", actions->actionsCount); + PrintDebugString(" ##### WinAccessBridge::getAccessibleActions succeeded"); + + return TRUE; + } + } + PrintDebugString(" ##### WinAccessBridge::getAccessibleActions failed"); + return FALSE; +} + +BOOL +WinAccessBridge::doAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure) { + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::doAccessibleActions(%p #actions %d %ls)", accessibleContext, + actionsToDo->actionsCount, + actionsToDo->actions[0].name); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::doAccessibleActions(%016I64X #actions %d %ls)", accessibleContext, + actionsToDo->actionsCount, + actionsToDo->actions[0].name); +#endif + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(DoAccessibleActionsPackage)]; + PackageType *type = (PackageType *) buffer; + DoAccessibleActionsPackage *pkg = (DoAccessibleActionsPackage *) (buffer + sizeof(PackageType)); + *type = cDoAccessibleActionsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + memcpy((void *)(&(pkg->actionsToDo)), (void *)actionsToDo, sizeof(AccessibleActionsToDo)); + pkg->failure = -1; + + HWND destABWindow = javaVMs->findAccessBridgeWindow(pkg->vmID); + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *failure = pkg->failure; + return pkg->rResult; + } + PrintDebugString(" WinAccessBridge::doAccessibleActions returning FALSE (sendMemoryPackage failed)"); + return FALSE; +} + +/* ====== Utility methods ====== */ + +/** + * Sets a text field to the specified string. Returns whether successful. + */ +BOOL +WinAccessBridge::setTextContents (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *text) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(SetTextContentsPackage)]; + PackageType *type = (PackageType *) buffer; + SetTextContentsPackage *pkg = (SetTextContentsPackage *) (buffer + sizeof(PackageType)); + *type = cSetTextContentsPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + wcsncpy(pkg->text, text, sizeof(pkg->text)/sizeof(wchar_t)); // wide character copy + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::setTextContents(%X, %016I64X %ls)", vmID, accessibleContext, text); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::setTextContents(%X, %p %ls)", vmID, accessibleContext, text); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rResult; + } + } + return FALSE; +} + +/** + * Returns the Accessible Context of a Page Tab object that is the + * ancestor of a given object. If the object is a Page Tab object + * or a Page Tab ancestor object was found, returns the object + * AccessibleContext. + * If there is no ancestor object that has an Accessible Role of Page Tab, + * returns (AccessibleContext)0. + */ +AccessibleContext +WinAccessBridge::getParentWithRole (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetParentWithRolePackage)]; + PackageType *type = (PackageType *) buffer; + GetParentWithRolePackage *pkg = (GetParentWithRolePackage *) (buffer + sizeof(PackageType)); + *type = cGetParentWithRolePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role)); + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getParentWithRole(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getParentWithRole(%X, %016I64X)", vmID, accessibleContext); +#endif + PrintDebugString(" pkg->vmID: %X", pkg->vmID); + PrintDebugString(" pkg->accessibleContext: %p", pkg->accessibleContext); + PrintDebugString(" pkg->role: %ls", pkg->role); + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + PrintDebugString(" pkg->rAccessibleContext: %p", pkg->rAccessibleContext); + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + + +/** + * Returns the Accessible Context for the top level object in + * a Java Window. This is same Accessible Context that is obtained + * from GetAccessibleContextFromHWND for that window. Returns + * (AccessibleContext)0 on error. + */ +AccessibleContext +WinAccessBridge::getTopLevelObject (const long vmID, const AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetTopLevelObjectPackage)]; + PackageType *type = (PackageType *) buffer; + GetTopLevelObjectPackage *pkg = (GetTopLevelObjectPackage *) (buffer + sizeof(PackageType)); + *type = cGetTopLevelObjectPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getTopLevelObject(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + +/** + * If there is an Ancestor object that has an Accessible Role of + * Internal Frame, returns the Accessible Context of the Internal + * Frame object. Otherwise, returns the top level object for that + * Java Window. Returns (AccessibleContext)0 on error. + */ +AccessibleContext +WinAccessBridge::getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, const wchar_t *role) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetParentWithRoleElseRootPackage)]; + PackageType *type = (PackageType *) buffer; + GetParentWithRoleElseRootPackage *pkg = (GetParentWithRoleElseRootPackage *) (buffer + sizeof(PackageType)); + *type = cGetParentWithRoleElseRootPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + memcpy((void *)(&(pkg->role)), (void *)role, sizeof(pkg->role)); + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getParentWithRoleElseRoot(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + +/** + * Returns how deep in the object hierarchy a given object is. + * The top most object in the object hierarchy has an object depth of 0. + * Returns -1 on error. + */ +int +WinAccessBridge::getObjectDepth (const long vmID, const AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return -1; + } + char buffer[sizeof(PackageType) + sizeof(GetObjectDepthPackage)]; + PackageType *type = (PackageType *) buffer; + GetObjectDepthPackage *pkg = (GetObjectDepthPackage *) (buffer + sizeof(PackageType)); + *type = cGetObjectDepthPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getObjectDepth(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getObjectDepth(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rResult; + } + } + return -1; +} + +/** + * Returns the Accessible Context of the currently ActiveDescendent of an object. + * Returns (AccessibleContext)0 on error. + */ +AccessibleContext +WinAccessBridge::getActiveDescendent (const long vmID, const AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetActiveDescendentPackage)]; + PackageType *type = (PackageType *) buffer; + GetActiveDescendentPackage *pkg = (GetActiveDescendentPackage *) (buffer + sizeof(PackageType)); + *type = cGetActiveDescendentPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getActiveDescendent(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + return (JOBJECT64) 0; +} + +/** + * Additional methods for Teton + */ + +/** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ +BOOL +WinAccessBridge::getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, + wchar_t *name, int len) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetVirtualAccessibleNamePackage)]; + PackageType *type = (PackageType *) buffer; + GetVirtualAccessibleNamePackage *pkg = (GetVirtualAccessibleNamePackage *) (buffer + sizeof(PackageType)); + *type = cGetVirtualAccessibleNamePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + size_t max = (len > sizeof(pkg->rName)) ? sizeof(pkg->rName) : len; + pkg->len = (int)max; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getVirtualAccessibleName(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(name, pkg->rName, max); + PrintDebugString(" WinAccessBridge::getVirtualAccessibleName: Virtual name = %ls", name); + return TRUE; + } + } + return FALSE; +} + +/** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ +BOOL +WinAccessBridge::requestFocus(long vmID, AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(RequestFocusPackage)]; + PackageType *type = (PackageType *) buffer; + RequestFocusPackage *pkg = (RequestFocusPackage *) (buffer + sizeof(PackageType)); + *type = cRequestFocusPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::requestFocus(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::requestFocus(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return TRUE; + } + } + return FALSE; +} + +/** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ +BOOL +WinAccessBridge::selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(SelectTextRangePackage)]; + PackageType *type = (PackageType *) buffer; + SelectTextRangePackage *pkg = (SelectTextRangePackage *) (buffer + sizeof(PackageType)); + *type = cSelectTextRangePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + pkg->endIndex = endIndex; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" WinAccessBridge::selectTextRange(%X, %p %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" WinAccessBridge::selectTextRange(%X, %016I64X %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return TRUE; + } + } + return FALSE; +} + +/** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ +BOOL +WinAccessBridge::getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, + int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetTextAttributesInRangePackage)]; + PackageType *type = (PackageType *) buffer; + GetTextAttributesInRangePackage *pkg = (GetTextAttributesInRangePackage *) (buffer + sizeof(PackageType)); + *type = cGetTextAttributesInRangePackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + pkg->endIndex = endIndex; + memcpy(&(pkg->attributes), attributes, sizeof(AccessibleTextAttributesInfo)); + + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString(" WinAccessBridge::getTextAttributesInRange(%X, %p %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString(" WinAccessBridge::getTextAttributesInRange(%X, %016I64X %d %d)", vmID, accessibleContext, + startIndex, endIndex); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *attributes = pkg->attributes; + *len = pkg->rLength; + return TRUE; + } + } + return FALSE; +} + +/** + * Gets the number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +int +WinAccessBridge::getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return -1; + } + char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenCountPackage)]; + PackageType *type = (PackageType *) buffer; + GetVisibleChildrenCountPackage *pkg = (GetVisibleChildrenCountPackage *) (buffer + sizeof(PackageType)); + *type = cGetVisibleChildrenCountPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getVisibleChildrenCount(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rChildrenCount; + } + } + return -1; +} + +/** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ +BOOL +WinAccessBridge::getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetVisibleChildrenPackage)]; + PackageType *type = (PackageType *) buffer; + GetVisibleChildrenPackage *pkg = (GetVisibleChildrenPackage *) (buffer + sizeof(PackageType)); + *type = cGetVisibleChildrenPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->startIndex = startIndex; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %p)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getVisibleChildren(%X, %016I64X)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(visibleChildrenInfo, &(pkg->rVisibleChildrenInfo), sizeof(pkg->rVisibleChildrenInfo)); + return pkg->rSuccess; + } + } + return FALSE; +} + +/** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ +BOOL +WinAccessBridge::setCaretPosition(long vmID, AccessibleContext accessibleContext, int position) { + + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(SetCaretPositionPackage)]; + PackageType *type = (PackageType *) buffer; + SetCaretPositionPackage *pkg = (SetCaretPositionPackage *) (buffer + sizeof(PackageType)); + *type = cSetCaretPositionPackage; + pkg->vmID = vmID; + pkg->accessibleContext = accessibleContext; + pkg->position = position; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::setCaretPosition(%X, %p %ls)", vmID, accessibleContext); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::setCaretPosition(%X, %016I64X %ls)", vmID, accessibleContext); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return TRUE; + } + } + return FALSE; +} + + +/********** AccessibleText routines ***********************************/ + +/** + * getAccessibleTextInfo - fills a struct with a bunch of information + * contained in the Java Accessibility AccessibleText API + * + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextInfo(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextInfo *textInfo, + jint x, jint y) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextInfoPackage *pkg = (GetAccessibleTextInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->x = x; + pkg->y = y; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %p, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextInfo(%X, %016I64X, %p, %d, %d)", vmID, AccessibleContext, textInfo, x, y); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(textInfo, &(pkg->rTextInfo), sizeof(AccessibleTextInfo)); + if (pkg->rTextInfo.charCount != -1) { + PrintDebugString(" charCount: %d", textInfo->charCount); + PrintDebugString(" caretIndex: %d", textInfo->caretIndex); + PrintDebugString(" indexAtPoint: %d", textInfo->indexAtPoint); + return TRUE; + } + } + } + + return FALSE; +} + +/** + * getAccessibleTextItems - fills a struct with letter, word, and sentence info + * of the AccessibleText interface at a given index + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextItems(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextItemsInfo *textItems, + jint index) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextItemsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextItemsPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + // zero things out, in case the call fails + pkg->rTextItemsInfo.letter = '\0'; + pkg->rTextItemsInfo.word[0] = '\0'; + pkg->rTextItemsInfo.sentence[0] = '\0'; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %p, %p, %d)", vmID, AccessibleContext, textItems, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextItems(%X, %016I64X, %p, %d)", vmID, AccessibleContext, textItems, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(textItems, &(pkg->rTextItemsInfo), sizeof(AccessibleTextItemsInfo)); + if (pkg->rTextItemsInfo.letter != '/0') { + return TRUE; + } + } + } + + return FALSE; +} + +/** + * getAccessibleTextSelectionInfo - returns information about the selected + * text of the object implementing AccessibleText + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextSelectionInfo(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextSelectionInfo *selectionInfo) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextSelectionInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextSelectionInfoPackage *pkg = (GetAccessibleTextSelectionInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextSelectionInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %p, %p)", vmID, AccessibleContext, selectionInfo); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextSelectionInfo(%X, %016I64X, %p)", vmID, AccessibleContext, selectionInfo); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(selectionInfo, &(pkg->rTextSelectionItemsInfo), sizeof(AccessibleTextSelectionInfo)); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleTextAttributes - performs the Java code: + * ...[[[FIXME]]] fill in this comment... + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextAttributes(long vmID, + JOBJECT64 AccessibleContext, + jint index, + AccessibleTextAttributesInfo *attributes) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextAttributeInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextAttributeInfoPackage *pkg = (GetAccessibleTextAttributeInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextAttributeInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %p, %d, %p)", vmID, AccessibleContext, index, attributes); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextAttributes(%X, %016I64X, %d, %p)", vmID, AccessibleContext, index, attributes); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(attributes, &(pkg->rAttributeInfo), sizeof(AccessibleTextAttributesInfo)); + return TRUE; + } + } + + return FALSE; +} + +/** + * getAccessibleTextRect - gets the text bounding rectangle + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextRect(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, + jint index) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRectInfoPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextRectInfoPackage *pkg = (GetAccessibleTextRectInfoPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextRectInfoPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextRect(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo)); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + +/** + * getAccessibleTextRect - gets the text bounding rectangle + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getCaretLocation(long vmID, + JOBJECT64 AccessibleContext, + AccessibleTextRectInfo *rectInfo, + jint index) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetCaretLocationPackage)]; + PackageType *type = (PackageType *) buffer; + GetCaretLocationPackage *pkg = (GetCaretLocationPackage *) (buffer + sizeof(PackageType)); + *type = cGetCaretLocationPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getCaretLocation(%X, %p, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getCaretLocation(%X, %016I64X, %p, %d)", vmID, AccessibleContext, rectInfo, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + memcpy(rectInfo, (&pkg->rTextRectInfo), sizeof(AccessibleTextRectInfo)); + return TRUE; + } + } + + return FALSE; +} + + +/** + * getEventsWaiting - gets the number of events waiting to fire + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +int +WinAccessBridge::getEventsWaiting() { + if(messageQueue) { + return(messageQueue->getEventsWaiting()); + } + return(0); +} + + +/** + * getAccessibleTextLineBounds - gets the bounding rectangle for the text line + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextLineBounds(long vmID, + JOBJECT64 AccessibleContext, + jint index, jint *startIndex, jint *endIndex) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextLineBoundsPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextLineBoundsPackage *pkg = (GetAccessibleTextLineBoundsPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextLineBoundsPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = index; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %p, %d, )", vmID, AccessibleContext, index); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextLineBounds(%X, %016I64X, %d, )", vmID, AccessibleContext, index); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + *startIndex = pkg->rLineStart; + *endIndex = pkg->rLineEnd; + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + +/** + * getAccessibleTextLineBounds - performs the Java code: + * ...[[[FIXME]]] fill in this comment... + * + * Note: if the AccessibleContext parameter is bogus, this call will blow up + */ +BOOL +WinAccessBridge::getAccessibleTextRange(long vmID, + JOBJECT64 AccessibleContext, + jint start, jint end, wchar_t *text, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleTextRangePackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleTextRangePackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->start = start; + pkg->end = end; + +#ifdef ACCESSBRIDGE_ARCH_LEGACY // JOBJECT64 is jobject (32 bit pointer) + PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %p, %d, %d, )", vmID, AccessibleContext, start, end); +#else // JOBJECT64 is jlong (64 bit) + PrintDebugString("WinAccessBridge::getAccessibleTextRange(%X, %016I64X, %d, %d, )", vmID, AccessibleContext, start, end); +#endif + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(text, pkg->rText, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + + + +/********** AccessibleValue routines ***************/ + +BOOL +WinAccessBridge::getCurrentAccessibleValueFromContext(long vmID, + JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetCurrentAccessibleValueFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetCurrentAccessibleValueFromContextPackage *pkg = (GetCurrentAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetCurrentAccessibleValueFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(value, pkg->rValue, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + +BOOL +WinAccessBridge::getMaximumAccessibleValueFromContext(long vmID, + JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetMaximumAccessibleValueFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetMaximumAccessibleValueFromContextPackage *pkg = (GetMaximumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetMaximumAccessibleValueFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(value, pkg->rValue, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + +BOOL +WinAccessBridge::getMinimumAccessibleValueFromContext(long vmID, + JOBJECT64 AccessibleContext, + wchar_t *value, short len) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(GetMinimumAccessibleValueFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetMinimumAccessibleValueFromContextPackage *pkg = (GetMinimumAccessibleValueFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetMinimumAccessibleValueFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + wcsncpy(value, pkg->rValue, len); + // [[[FIXME]]] should test to see if valid info returned; return FALSE if not + return TRUE; + } + } + + return FALSE; +} + + +/********** AccessibleSelection routines ***************/ + +void +WinAccessBridge::addAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(AddAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + AddAccessibleSelectionFromContextPackage *pkg = (AddAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cAddAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + +void +WinAccessBridge::clearAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(ClearAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + ClearAccessibleSelectionFromContextPackage *pkg = (ClearAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cClearAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + +JOBJECT64 +WinAccessBridge::getAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return (JOBJECT64)0; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleSelectionFromContextPackage *pkg = (GetAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return pkg->rAccessibleContext; + } + } + + return (JOBJECT64) 0; +} + +int +WinAccessBridge::getAccessibleSelectionCountFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return -1; + } + char buffer[sizeof(PackageType) + sizeof(GetAccessibleSelectionCountFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + GetAccessibleSelectionCountFromContextPackage *pkg = (GetAccessibleSelectionCountFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cGetAccessibleSelectionCountFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + return (int) pkg->rCount; + } + } + + return -1; +} + +BOOL +WinAccessBridge::isAccessibleChildSelectedFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return FALSE; + } + char buffer[sizeof(PackageType) + sizeof(IsAccessibleChildSelectedFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + IsAccessibleChildSelectedFromContextPackage *pkg = (IsAccessibleChildSelectedFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cIsAccessibleChildSelectedFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) { + if (pkg->rResult != 0) { + return TRUE; + } + } + } + + return FALSE; +} + + +void +WinAccessBridge::removeAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext, int i) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(RemoveAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + RemoveAccessibleSelectionFromContextPackage *pkg = (RemoveAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cRemoveAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + pkg->index = i; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + +void +WinAccessBridge::selectAllAccessibleSelectionFromContext(long vmID, + JOBJECT64 AccessibleContext) { + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(SelectAllAccessibleSelectionFromContextPackage)]; + PackageType *type = (PackageType *) buffer; + SelectAllAccessibleSelectionFromContextPackage *pkg = (SelectAllAccessibleSelectionFromContextPackage *) (buffer + sizeof(PackageType)); + *type = cSelectAllAccessibleSelectionFromContextPackage; + pkg->vmID = vmID; + pkg->AccessibleContext = AccessibleContext; + + // need to call only the HWND/VM that contains this AC + HWND destABWindow = javaVMs->findAccessBridgeWindow(vmID); + if (destABWindow != (HWND) 0) { + sendMemoryPackage(buffer, sizeof(buffer), destABWindow); + } +} + + +/*********** Event handling methods **********************************/ + +/** + * addEventNotification - tell all Java-launched AccessBridge DLLs + * that we want events of the specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::addJavaEventNotification(jlong type) { + PrintDebugString("WinAccessBridge::addJavaEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + + char buffer[sizeof(PackageType) + sizeof(AddJavaEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + AddJavaEventNotificationPackage *pkg = (AddJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cAddJavaEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", + *pkgType, pkg->type, pkg->DLLwindow); + + // send addEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + +/** + * removeEventNotification - tell all Java-launched AccessBridge DLLs + * that we no longer want events of the + * specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::removeJavaEventNotification(jlong type) { + PrintDebugString("in WinAccessBridge::removeJavaEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(RemoveJavaEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + RemoveJavaEventNotificationPackage *pkg = (RemoveJavaEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cRemoveJavaEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %p", + *pkgType, pkg->type, pkg->DLLwindow); + + // send removeEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + + +/*********** Event handling methods **********************************/ + +/** + * addAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs + * that we want events of the specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::addAccessibilityEventNotification(jlong type) { + PrintDebugString("in WinAccessBridge::addAccessibilityEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(AddAccessibilityEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + AddAccessibilityEventNotificationPackage *pkg = (AddAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cAddAccessibilityEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", + *pkgType, pkg->type, pkg->DLLwindow); + + // send addEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + +/** + * removeAccessibilityEventNotification - tell all Java-launched AccessBridge DLLs + * that we no longer want events of the + * specified type + * + * [[[FIXME]]] since we're just sending a long & a source window, + * we could use a private message rather than WM_COPYDATA + * (though we still may want it to be synchronous; dunno...) + * + */ +void +WinAccessBridge::removeAccessibilityEventNotification(jlong type) { + PrintDebugString("in WinAccessBridge::removeAccessibilityEventNotification(%016I64X)", type); + if ((AccessBridgeJavaVMInstance *) 0 == javaVMs) { + return; + } + char buffer[sizeof(PackageType) + sizeof(RemoveAccessibilityEventNotificationPackage)]; + PackageType *pkgType = (PackageType *) buffer; + RemoveAccessibilityEventNotificationPackage *pkg = (RemoveAccessibilityEventNotificationPackage *) (buffer + sizeof(PackageType)); + *pkgType = cRemoveAccessibilityEventNotificationPackage; + pkg->type = type; + pkg->DLLwindow = ABHandleToLong(dialogWindow); + + PrintDebugString(" ->pkgType = %X, eventType = %016I64X, DLLwindow = %X", + *pkgType, pkg->type, pkg->DLLwindow); + + // send removeEventNotification message to all JVMs + isVMInstanceChainInUse = true; + AccessBridgeJavaVMInstance *current = javaVMs; + while (current != (AccessBridgeJavaVMInstance *) 0) { + current->sendPackage(buffer, sizeof(buffer)); // no return values! + current = current->nextJVMInstance; + } + isVMInstanceChainInUse = false; +} + + +#define CALL_SET_EVENT_FP(function, callbackFP) \ + void WinAccessBridge::function(callbackFP fp) { \ + eventHandler->function(fp, this); \ + /* eventHandler calls back to winAccessBridgeDLL to set eventMask */ \ + } + + void WinAccessBridge::setJavaShutdownFP(AccessBridge_JavaShutdownFP fp) { + eventHandler->setJavaShutdownFP(fp, this); + } + + CALL_SET_EVENT_FP(setPropertyChangeFP, AccessBridge_PropertyChangeFP) + CALL_SET_EVENT_FP(setFocusGainedFP, AccessBridge_FocusGainedFP) + CALL_SET_EVENT_FP(setFocusLostFP, AccessBridge_FocusLostFP) + CALL_SET_EVENT_FP(setCaretUpdateFP, AccessBridge_CaretUpdateFP) + CALL_SET_EVENT_FP(setMouseClickedFP, AccessBridge_MouseClickedFP) + CALL_SET_EVENT_FP(setMouseEnteredFP, AccessBridge_MouseEnteredFP) + CALL_SET_EVENT_FP(setMouseExitedFP, AccessBridge_MouseExitedFP) + CALL_SET_EVENT_FP(setMousePressedFP, AccessBridge_MousePressedFP) + CALL_SET_EVENT_FP(setMouseReleasedFP, AccessBridge_MouseReleasedFP) + CALL_SET_EVENT_FP(setMenuCanceledFP, AccessBridge_MenuCanceledFP) + CALL_SET_EVENT_FP(setMenuDeselectedFP, AccessBridge_MenuDeselectedFP) + CALL_SET_EVENT_FP(setMenuSelectedFP, AccessBridge_MenuSelectedFP) + CALL_SET_EVENT_FP(setPopupMenuCanceledFP, AccessBridge_PopupMenuCanceledFP) + CALL_SET_EVENT_FP(setPopupMenuWillBecomeInvisibleFP, AccessBridge_PopupMenuWillBecomeInvisibleFP) + CALL_SET_EVENT_FP(setPopupMenuWillBecomeVisibleFP, AccessBridge_PopupMenuWillBecomeVisibleFP) + + CALL_SET_EVENT_FP(setPropertyNameChangeFP, AccessBridge_PropertyNameChangeFP) + CALL_SET_EVENT_FP(setPropertyDescriptionChangeFP, AccessBridge_PropertyDescriptionChangeFP) + CALL_SET_EVENT_FP(setPropertyStateChangeFP, AccessBridge_PropertyStateChangeFP) + CALL_SET_EVENT_FP(setPropertyValueChangeFP, AccessBridge_PropertyValueChangeFP) + CALL_SET_EVENT_FP(setPropertySelectionChangeFP, AccessBridge_PropertySelectionChangeFP) + CALL_SET_EVENT_FP(setPropertyTextChangeFP, AccessBridge_PropertyTextChangeFP) + CALL_SET_EVENT_FP(setPropertyCaretChangeFP, AccessBridge_PropertyCaretChangeFP) + CALL_SET_EVENT_FP(setPropertyVisibleDataChangeFP, AccessBridge_PropertyVisibleDataChangeFP) + CALL_SET_EVENT_FP(setPropertyChildChangeFP, AccessBridge_PropertyChildChangeFP) + CALL_SET_EVENT_FP(setPropertyActiveDescendentChangeFP, AccessBridge_PropertyActiveDescendentChangeFP) + + CALL_SET_EVENT_FP(setPropertyTableModelChangeFP, AccessBridge_PropertyTableModelChangeFP) diff --git a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.h b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.h new file mode 100644 index 00000000000..097cb0a9c6c --- /dev/null +++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.h @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * A DLL which is loaded by Windows executables to handle communication + * between Java VMs purposes of Accessbility. + */ + +#ifndef __WinAccessBridge_H__ +#define __WinAccessBridge_H__ + +#include +#include "AccessBridgePackages.h" +#include "AccessBridgeEventHandler.h" +#include "AccessBridgeJavaVMInstance.h" +#include "AccessBridgeMessageQueue.h" + + +extern "C" { + BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, + LPVOID lpvReserved); + void AppendToCallOutput(char *s); + BOOL CALLBACK AccessBridgeDialogProc(HWND hDlg, UINT message, + UINT wParam, LONG lParam); + HWND getTopLevelHWND(HWND descendent); +} + +LRESULT CALLBACK WinAccessBridgeWindowProc(HWND hWnd, UINT message, + UINT wParam, LONG lParam); + +BOOL CALLBACK DeleteItemProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); + +/** + * The WinAccessBridge class. The core of the Windows AT AccessBridge dll + */ +class WinAccessBridge { + HINSTANCE windowsInstance; + HWND dialogWindow; + AccessBridgeJavaVMInstance *javaVMs; + AccessBridgeEventHandler *eventHandler; + AccessBridgeMessageQueue *messageQueue; + +public: + WinAccessBridge(HINSTANCE hInstance); + ~WinAccessBridge(); + BOOL initWindow(); + + HWND showWinAccessBridgeGUI(int showCommand); + + // IPC with the Java AccessBridge DLL + LRESULT rendezvousWithNewJavaDLL(HWND JavaBridgeDLLwindow, long vmID); + + void sendPackage(char *buffer, long bufsize, HWND destWindow); + BOOL sendMemoryPackage(char *buffer, long bufsize, HWND destWindow); + BOOL queuePackage(char *buffer, long bufsize); + BOOL receiveAQueuedPackage(); + void preProcessPackage(char *buffer, long bufsize); + void processPackage(char *buffer, long bufsize); + void JavaVMDestroyed(HWND VMBridgeDLLWindow); + + // Java VM object memory management + void releaseJavaObject(long vmID, JOBJECT64 object); + + // Version info + BOOL getVersionInfo(long vmID, AccessBridgeVersionInfo *info); + + // HWND management methods + HWND getNextJavaWindow(HWND previous); + BOOL isJavaWindow(HWND window); + BOOL getAccessibleContextFromHWND(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + HWND getHWNDFromAccessibleContext(long vmID, JOBJECT64 accessibleContext); + + /* Additional utility methods */ + BOOL isSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2); + + BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text); + + AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext, + const wchar_t *role); + + int getObjectDepth (const long vmID, const AccessibleContext accessibleContext); + + AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext); + + + // Accessible Context methods + BOOL getAccessibleContextAt(long vmID, JOBJECT64 AccessibleContextParent, + jint x, jint y, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextWithFocus(HWND window, long *vmID, JOBJECT64 *AccessibleContext); + BOOL getAccessibleContextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleContextInfo *info); + JOBJECT64 getAccessibleChildFromContext(long vmID, JOBJECT64 AccessibleContext, jint childIndex); + JOBJECT64 getAccessibleParentFromContext(long vmID, JOBJECT64 AccessibleContext); + + /* begin AccessibleTable methods */ + BOOL getAccessibleTableInfo(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableCellInfo(long vmID, JOBJECT64 accessibleTable, jint row, jint column, + AccessibleTableCellInfo *tableCellInfo); + + BOOL getAccessibleTableRowHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + BOOL getAccessibleTableColumnHeader(long vmID, JOBJECT64 acParent, AccessibleTableInfo *tableInfo); + + JOBJECT64 getAccessibleTableRowDescription(long vmID, JOBJECT64 acParent, jint row); + JOBJECT64 getAccessibleTableColumnDescription(long vmID, JOBJECT64 acParent, jint column); + + jint getAccessibleTableRowSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableRowSelected(long vmID, JOBJECT64 accessibleTable, jint row); + BOOL getAccessibleTableRowSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableColumnSelectionCount(long vmID, JOBJECT64 accessibleTable); + BOOL isAccessibleTableColumnSelected(long vmID, JOBJECT64 accessibleTable, jint column); + BOOL getAccessibleTableColumnSelections(long vmID, JOBJECT64 accessibleTable, jint count, + jint *selections); + + jint getAccessibleTableRow(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableColumn(long vmID, JOBJECT64 accessibleTable, jint index); + jint getAccessibleTableIndex(long vmID, JOBJECT64 accessibleTable, jint row, jint column); + + /* end AccessibleTable methods */ + + // --------- AccessibleRelationSet methods + BOOL getAccessibleRelationSet(long vmID, JOBJECT64 accessibleContext, AccessibleRelationSetInfo *relationSet); + + // --------- AccessibleHypertext methods + BOOL getAccessibleHypertext(long vmID, JOBJECT64 accessibleContext, AccessibleHypertextInfo *hypertextInfo); + BOOL activateAccessibleHyperlink(long vmID, JOBJECT64 accessibleContext, JOBJECT64 accessibleHyperlink); + + jint getAccessibleHyperlinkCount(const long vmID, + const AccessibleContext accessibleContext); + + BOOL getAccessibleHypertextExt(const long vmID, + const AccessibleContext accessibleContext, + const jint nStartIndex, + /* OUT */ AccessibleHypertextInfo *hypertextInfo); + + jint getAccessibleHypertextLinkIndex(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex); + + BOOL getAccessibleHyperlink(const long vmID, + const AccessibleHypertext hypertext, + const jint nIndex, + /* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo); + + + /* Accessible KeyBindings, Icons and Actions */ + BOOL getAccessibleKeyBindings(long vmID, JOBJECT64 accessibleContext, + AccessibleKeyBindings *keyBindings); + + BOOL getAccessibleIcons(long vmID, JOBJECT64 accessibleContext, + AccessibleIcons *icons); + + BOOL getAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActions *actions); + + BOOL doAccessibleActions(long vmID, JOBJECT64 accessibleContext, + AccessibleActionsToDo *actionsToDo, jint *failure); + + + // Accessible Text methods + BOOL getAccessibleTextInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextInfo *textInfo, jint x, jint y); + BOOL getAccessibleTextItems(long vmID, JOBJECT64 AccessibleContext, AccessibleTextItemsInfo *textItems, jint index); + BOOL getAccessibleTextSelectionInfo(long vmID, JOBJECT64 AccessibleContext, AccessibleTextSelectionInfo *selectionInfo); + BOOL getAccessibleTextAttributes(long vmID, JOBJECT64 AccessibleContext, jint index, AccessibleTextAttributesInfo *attributes); + BOOL getAccessibleTextRect(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + BOOL getAccessibleTextLineBounds(long vmID, JOBJECT64 AccessibleContext, jint index, jint *startIndex, jint *endIndex); + BOOL getAccessibleTextRange(long vmID, JOBJECT64 AccessibleContext, jint start, jint end, wchar_t *text, short len); + + // Accessible Value methods + BOOL getCurrentAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMaximumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, wchar_t *value, short len); + BOOL getMinimumAccessibleValueFromContext(long vmID, JOBJECT64 AccessibleContext, wchar_t *value, short len); + + // Accessible Selection methods + void addAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + void clearAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext); + JOBJECT64 getAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + int getAccessibleSelectionCountFromContext(long vmID, JOBJECT64 AccessibleContext); + BOOL isAccessibleChildSelectedFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + void removeAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext, int i); + void selectAllAccessibleSelectionFromContext(long vmID, JOBJECT64 AccessibleContext); + + // Event handling methods + void addJavaEventNotification(jlong type); + void removeJavaEventNotification(jlong type); + void addAccessibilityEventNotification(jlong type); + void removeAccessibilityEventNotification(jlong type); + + void setPropertyChangeFP(AccessBridge_PropertyChangeFP fp); + void setJavaShutdownFP(AccessBridge_JavaShutdownFP fp); + void setFocusGainedFP(AccessBridge_FocusGainedFP fp); + void setFocusLostFP(AccessBridge_FocusLostFP fp); + void setCaretUpdateFP(AccessBridge_CaretUpdateFP fp); + void setMouseClickedFP(AccessBridge_MouseClickedFP fp); + void setMouseEnteredFP(AccessBridge_MouseEnteredFP fp); + void setMouseExitedFP(AccessBridge_MouseExitedFP fp); + void setMousePressedFP(AccessBridge_MousePressedFP fp); + void setMouseReleasedFP(AccessBridge_MouseReleasedFP fp); + void setMenuCanceledFP(AccessBridge_MenuCanceledFP fp); + void setMenuDeselectedFP(AccessBridge_MenuDeselectedFP fp); + void setMenuSelectedFP(AccessBridge_MenuSelectedFP fp); + void setPopupMenuCanceledFP(AccessBridge_PopupMenuCanceledFP fp); + void setPopupMenuWillBecomeInvisibleFP(AccessBridge_PopupMenuWillBecomeInvisibleFP fp); + void setPopupMenuWillBecomeVisibleFP(AccessBridge_PopupMenuWillBecomeVisibleFP fp); + + void setPropertyNameChangeFP(AccessBridge_PropertyNameChangeFP fp); + void setPropertyDescriptionChangeFP(AccessBridge_PropertyDescriptionChangeFP fp); + void setPropertyStateChangeFP(AccessBridge_PropertyStateChangeFP fp); + void setPropertyValueChangeFP(AccessBridge_PropertyValueChangeFP fp); + void setPropertySelectionChangeFP(AccessBridge_PropertySelectionChangeFP fp); + void setPropertyTextChangeFP(AccessBridge_PropertyTextChangeFP fp); + void setPropertyCaretChangeFP(AccessBridge_PropertyCaretChangeFP fp); + void setPropertyVisibleDataChangeFP(AccessBridge_PropertyVisibleDataChangeFP fp); + void setPropertyChildChangeFP(AccessBridge_PropertyChildChangeFP fp); + void setPropertyActiveDescendentChangeFP(AccessBridge_PropertyActiveDescendentChangeFP fp); + + void setPropertyTableModelChangeFP(AccessBridge_PropertyTableModelChangeFP fp); + + /** + * Additional methods for Teton + */ + + /** + * Gets the AccessibleName for a component based upon the JAWS algorithm. Returns + * whether successful. + * + * Bug ID 4916682 - Implement JAWS AccessibleName policy + */ + BOOL getVirtualAccessibleName(long vmID, AccessibleContext accessibleContext, wchar_t *name, int len); + + /** + * Request focus for a component. Returns whether successful; + * + * Bug ID 4944757 - requestFocus method needed + */ + BOOL requestFocus(long vmID, AccessibleContext accessibleContext); + + /** + * Selects text between two indices. Selection includes the text at the start index + * and the text at the end index. Returns whether successful; + * + * Bug ID 4944758 - selectTextRange method needed + */ + BOOL selectTextRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex); + + /** + * Get text attributes between two indices. The attribute list includes the text at the + * start index and the text at the end index. Returns whether successful; + * + * Bug ID 4944761 - getTextAttributes between two indices method needed + */ + BOOL getTextAttributesInRange(long vmID, AccessibleContext accessibleContext, int startIndex, int endIndex, + AccessibleTextAttributesInfo *attributes, short *len); + + /** + * Gets number of visible children of a component. Returns -1 on error. + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + int getVisibleChildrenCount(long vmID, AccessibleContext accessibleContext); + + /** + * Gets the visible children of an AccessibleContext. Returns whether successful; + * + * Bug ID 4944762- getVisibleChildren for list-like components needed + */ + BOOL getVisibleChildren(long vmID, AccessibleContext accessibleContext, int startIndex, + VisibleChildrenInfo *visibleChildrenInfo); + + /** + * Set the caret to a text position. Returns whether successful; + * + * Bug ID 4944770 - setCaretPosition method needed + */ + BOOL setCaretPosition(long vmID, AccessibleContext accessibleContext, int position); + + + /** + * Gets the text caret bounding rectangle + */ + BOOL getCaretLocation(long vmID, JOBJECT64 AccessibleContext, AccessibleTextRectInfo *rectInfo, jint index); + + /** + * Gets number of events waiting in the message queue + */ + int getEventsWaiting(); + +}; + +#endif diff --git a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java index ec4f231ec37..634a2980562 100644 --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -42,6 +42,7 @@ import javax.security.auth.callback.ConfirmationCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.TextOutputCallback; +import sun.misc.ManagedLocalsThread; import sun.security.util.Debug; import sun.security.util.ResourcesMgr; @@ -811,7 +812,7 @@ public final class SunPKCS11 extends AuthProvider { return; } TokenPoller poller = new TokenPoller(this); - Thread t = new Thread(poller, "Poller " + getName()); + Thread t = new ManagedLocalsThread(poller, "Poller " + getName()); t.setDaemon(true); t.setPriority(Thread.MIN_PRIORITY); t.start(); diff --git a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java index 24ab8b014db..5b97c16477c 100644 --- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java +++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java @@ -36,6 +36,7 @@ import javax.net.ssl.*; import com.sun.net.httpserver.*; import java.security.AccessController; import java.security.PrivilegedAction; +import sun.misc.ManagedLocalsThread; import sun.net.httpserver.HttpConnection.State; /** @@ -142,7 +143,7 @@ class ServerImpl implements TimeSource { if (executor == null) { executor = new DefaultExecutor(); } - dispatcherThread = new Thread (dispatcher); + dispatcherThread = new ManagedLocalsThread(dispatcher); started = true; dispatcherThread.start(); } diff --git a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java index a39e7de22f4..32bffbaebc9 100644 --- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java +++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,8 +74,9 @@ class Main { * Mflag: DO NOT generate a manifest file (just ZIP) * iflag: generate jar index * nflag: Perform jar normalization at the end + * pflag: preserve/don't strip leading slash and .. component from file name */ - boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag; + boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag; static final String MANIFEST_DIR = "META-INF/"; static final String VERSION = "1.0"; @@ -187,6 +188,7 @@ class Main { addMainClass(manifest, ename); } } + expand(null, files, false); OutputStream out; if (fname != null) { out = new FileOutputStream(fname); @@ -208,7 +210,6 @@ class Main { tmpfile = createTemporaryFile(tmpbase, ".jar"); out = new FileOutputStream(tmpfile); } - expand(null, files, false); create(new BufferedOutputStream(out, 4096), manifest); if (in != null) { in.close(); @@ -424,6 +425,9 @@ class Main { case 'e': ename = args[count++]; break; + case 'P': + pflag = true; + break; default: error(formatMsg("error.illegal.option", String.valueOf(flags.charAt(i)))); @@ -713,6 +717,47 @@ class Main { return true; } + private static final boolean isWinDriveLetter(char c) { + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); + } + + private String safeName(String name) { + if (!pflag) { + int len = name.length(); + int i = name.lastIndexOf("../"); + if (i == -1) { + i = 0; + } else { + i += 3; // strip any dot-dot components + } + if (File.separatorChar == '\\') { + // the spec requests no drive letter. skip if + // the entry name has one. + while (i < len) { + int off = i; + if (i + 1 < len && + name.charAt(i + 1) == ':' && + isWinDriveLetter(name.charAt(i))) { + i += 2; + } + while (i < len && name.charAt(i) == '/') { + i++; + } + if (i == off) { + break; + } + } + } else { + while (i < len && name.charAt(i) == '/') { + i++; + } + } + if (i != 0) { + name = name.substring(i); + } + } + return name; + } private String entryName(String name) { name = name.replace(File.separatorChar, '/'); @@ -723,11 +768,10 @@ class Main { matchPath = path; } } - name = name.substring(matchPath.length()); - - if (name.startsWith("/")) { - name = name.substring(1); - } else if (name.startsWith("./")) { + name = safeName(name.substring(matchPath.length())); + // the old implementaton doesn't remove + // "./" if it was led by "/" (?) + if (name.startsWith("./")) { name = name.substring(2); } return name; @@ -927,8 +971,11 @@ class Main { for (ZipEntry ze : zes) { long lastModified = ze.getTime(); if (lastModified != -1) { - File f = new File(ze.getName().replace('/', File.separatorChar)); - f.setLastModified(lastModified); + String name = safeName(ze.getName().replace(File.separatorChar, '/')); + if (name.length() != 0) { + File f = new File(name.replace('/', File.separatorChar)); + f.setLastModified(lastModified); + } } } } @@ -1002,8 +1049,16 @@ class Main { */ ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException { ZipEntry rc = null; - String name = e.getName(); - File f = new File(e.getName().replace('/', File.separatorChar)); + // The spec requres all slashes MUST be forward '/', it is possible + // an offending zip/jar entry may uses the backwards slash in its + // name. It might cause problem on Windows platform as it skips + // our "safe" check for leading slahs and dot-dot. So replace them + // with '/'. + String name = safeName(e.getName().replace(File.separatorChar, '/')); + if (name.length() == 0) { + return rc; // leading '/' or 'dot-dot' only path + } + File f = new File(name.replace('/', File.separatorChar)); if (e.isDirectory()) { if (f.exists()) { if (!f.isDirectory()) { diff --git a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties index beefbd2ddd0..3b87385c40b 100644 --- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties +++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties @@ -68,7 +68,7 @@ out.size=\ (in = {0}) (out= {1}) usage=\ -Usage: jar {ctxui}[vfmn0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\ +Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\ Options:\n\ \ \ -c create new archive\n\ \ \ -t list table of contents for archive\n\ @@ -81,6 +81,7 @@ Options:\n\ \ \ -e specify application entry point for stand-alone application \n\ \ \ bundled into an executable jar file\n\ \ \ -0 store only; use no ZIP compression\n\ +\ \ -P preserve leading '/' (absolute path) and ".." (parent directory) components from file names\n\ \ \ -M do not create a manifest file for the entries\n\ \ \ -i generate index information for the specified jar files\n\ \ \ -C change to the specified directory and include the following file\n\ diff --git a/jdk/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest b/jdk/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest index 739f9b994fa..b2583b5b744 100644 --- a/jdk/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest +++ b/jdk/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest @@ -1,11 +1,12 @@ - - + + type="win32"/> - Java(TM) SE Runtime Environment unpack200 Process. + Java(TM) SE Runtime Environment unpack200 Process. diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 6b211498f8f..fb8d79c7b5e 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -164,9 +164,6 @@ javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java generi # 6988950 demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java generic-all -# 8071968 -javax/xml/ws/8046817/GenerateEnumSchema.java windows-all - ############################################################################ # jdk_net diff --git a/jdk/test/TEST.ROOT b/jdk/test/TEST.ROOT index 0e6fa003234..cf9bdb246ff 100644 --- a/jdk/test/TEST.ROOT +++ b/jdk/test/TEST.ROOT @@ -8,7 +8,7 @@ keys=2d dnd i18n intermittent othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces javax/xml/jaxp/testng/validation # Tests that cannot run concurrently -exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi java/util/stream +exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi java/util/stream javax/rmi # Group definitions groups=TEST.groups [closed/TEST.groups] diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index 94103f534b8..73ac408f90e 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -138,7 +138,6 @@ jdk_time = \ jdk_rmi = \ java/rmi \ - javax/rmi/ssl \ sun/rmi jdk_security1 = \ @@ -237,6 +236,7 @@ jdk_tools = \ jdk_other = \ java/sql \ javax/sql \ + javax/rmi \ javax/naming \ javax/script \ javax/smartcardio \ diff --git a/jdk/test/com/sun/jdi/JdbReadTwiceTest.sh b/jdk/test/com/sun/jdi/JdbReadTwiceTest.sh index 0c78fe5ec81..a166f2c54f1 100644 --- a/jdk/test/com/sun/jdi/JdbReadTwiceTest.sh +++ b/jdk/test/com/sun/jdi/JdbReadTwiceTest.sh @@ -204,39 +204,6 @@ if [ ! -r c:/ ] ; then clean fi -echo -echo "+++++++++++++++++++++++++++++++++++" -echo "Read an unreadable file - verify the read fails." - -canMakeUnreadable=No -id > $HOME/jdb.ini -if chmod a-r $HOME/jdb.ini -then - grep -q 'uid=0(' $HOME/jdb.ini 2> /dev/null - case $? in - 0) - echo "Error! Can't make file unreadable running as root" - ;; - 1) - echo "Error! Can't make file unreadable for some other reason (windows?)" - ;; - *) - echo "OK. the file is unreadable" - canMakeUnreadable=Yes - ;; - esac -else - echo "Error! Can't create or chmod file" -fi - -if [ "$canMakeUnreadable" = "Yes" ] -then - doit - failIfNot 1 "open: $HOME/jdb.ini" -fi -clean - - echo echo "+++++++++++++++++++++++++++++++++++" echo "Read a directory - verify the read fails" diff --git a/jdk/test/com/sun/jndi/dns/IPv6NameserverPlatformParsingTest.java b/jdk/test/com/sun/jndi/dns/IPv6NameserverPlatformParsingTest.java new file mode 100644 index 00000000000..fac68ba0756 --- /dev/null +++ b/jdk/test/com/sun/jndi/dns/IPv6NameserverPlatformParsingTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Field; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.NamingManager; + +import com.sun.jndi.dns.DnsContext; + +/** + * @test + * @bug 6991580 + * @summary IPv6 Nameservers in resolv.conf throws NumberFormatException + * @run main/manual IPv6NameserverPlatformParsingTest + * + * In order to run this test be sure to place, for example, the following + * snippet into your platform's {@code /etc/resolv.conf}: + *
                                  + * nameserver 127.0.0.1
                                  + * nameserver 2001:4860:4860::8888
                                  + * nameserver [::1]:5353
                                  + * nameserver 127.0.0.1:5353
                                  + * 
                                  + * + * Then, run this test as manual jtreg test. + * + * @author Severin Gehwolf + * + */ +public class IPv6NameserverPlatformParsingTest { + + private static boolean foundIPv6 = false; + + public static void main(String[] args) { + Hashtable env = new Hashtable<>(); + env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.dns.DnsContextFactory.class.getName()); + + String[] servers; + try { + Context ctx = NamingManager.getInitialContext(env); + if (!com.sun.jndi.dns.DnsContextFactory.platformServersAvailable()) { + throw new RuntimeException("FAIL: no platform servers available, test does not make sense"); + } + DnsContext context = (DnsContext)ctx; + servers = getServersFromContext(context); + } catch (NamingException e) { + throw new RuntimeException(e); + } + for (String server: servers) { + System.out.println("DEBUG: 'nameserver = " + server + "'"); + if (server.indexOf(':') >= 0 && server.indexOf('.') < 0) { + System.out.println("DEBUG: ==> Found IPv6 address in servers list: " + server); + foundIPv6 = true; + } + } + try { + new com.sun.jndi.dns.DnsClient(servers, 100, 1); + } catch (NumberFormatException e) { + throw new RuntimeException("FAIL: Tried to parse non-[]-encapsulated IPv6 address.", e); + } catch (Exception e) { + throw new RuntimeException("ERROR: Something unexpected happened."); + } + if (!foundIPv6) { + // This is a manual test, since it requires changing /etc/resolv.conf on Linux/Unix + // platforms. See comment as to how to run this test. + throw new RuntimeException("ERROR: No IPv6 address returned from platform."); + } + System.out.println("PASS: Found IPv6 address and DnsClient parsed it correctly."); + } + + private static String[] getServersFromContext(DnsContext context) { + try { + Field serversField = DnsContext.class.getDeclaredField("servers"); + serversField.setAccessible(true); + return (String[])serversField.get(context); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/jdk/test/com/sun/jndi/ldap/LdapURLOptionalFields.java b/jdk/test/com/sun/jndi/ldap/LdapURLOptionalFields.java new file mode 100644 index 00000000000..86b5c1a442b --- /dev/null +++ b/jdk/test/com/sun/jndi/ldap/LdapURLOptionalFields.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8074761 + * @summary RFC-2255 allows attribute, scope and filter to be empty. + */ + +import com.sun.jndi.ldap.LdapURL; + +public class LdapURLOptionalFields { + + private static final String[] TEST_URLS = { + "ldap://localhost:10389/ou=RefPeople,dc=example,dc=com", + "ldap://localhost:10389/ou=RefPeople,dc=example,dc=com?", + "ldap://localhost:10389/ou=RefPeople,dc=example,dc=com??", + "ldap://localhost:10389/ou=RefPeople,dc=example,dc=com???", + "ldap://localhost:10389/ou=RefPeople,dc=example,dc=com????" + }; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < TEST_URLS.length; i++) { + String url = TEST_URLS[i]; + checkEmptyAttributes(url); + } + } + + private static void checkEmptyAttributes(String urlString) throws Exception { + LdapURL url = new LdapURL(urlString); + if (url.getAttributes() != null) { + throw new Exception("Expected null attributes for url: '" + urlString + "'"); + } + if (url.getScope() != null) { + throw new Exception("Expected null scope for url: '" + urlString + "'"); + } + if (url.getFilter() != null) { + throw new Exception("Expected null filter for url: '" + urlString + "'"); + } + } + +} diff --git a/jdk/test/com/sun/security/auth/login/ConfigFile/InconsistentError.java b/jdk/test/com/sun/security/auth/login/ConfigFile/InconsistentError.java index 8bece1cb668..6dd48251ed9 100644 --- a/jdk/test/com/sun/security/auth/login/ConfigFile/InconsistentError.java +++ b/jdk/test/com/sun/security/auth/login/ConfigFile/InconsistentError.java @@ -26,6 +26,7 @@ * @bug 4406033 * @summary ConfigFile throws an inconsistent error message * when the configuration file is not found + * @run main/othervm -Duser.language=en InconsistentError */ import com.sun.security.auth.login.*; diff --git a/jdk/test/com/sun/security/auth/module/KeyStoreLoginModule/OptionTest.java b/jdk/test/com/sun/security/auth/module/KeyStoreLoginModule/OptionTest.java index 585b3b63994..3b918760200 100644 --- a/jdk/test/com/sun/security/auth/module/KeyStoreLoginModule/OptionTest.java +++ b/jdk/test/com/sun/security/auth/module/KeyStoreLoginModule/OptionTest.java @@ -25,6 +25,7 @@ * @test * @bug 4919147 * @summary Support for token-based KeyStores + * @run main/othervm -Duser.language=en OptionTest */ import java.io.File; diff --git a/jdk/test/java/awt/Checkbox/SetStateExcessEvent/SetStateExcessEvent.java b/jdk/test/java/awt/Checkbox/SetStateExcessEvent/SetStateExcessEvent.java new file mode 100644 index 00000000000..f7235beeb35 --- /dev/null +++ b/jdk/test/java/awt/Checkbox/SetStateExcessEvent/SetStateExcessEvent.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Frame; +import java.awt.GridBagLayout; +import java.awt.Robot; + +/** + * @test + * @bug 8074500 + * @summary Checkbox.setState() call should not post ItemEvent + * @author Sergey Bylokhov + */ +public final class SetStateExcessEvent { + + private static boolean failed; + + public static void main(final String[] args) throws Exception { + final Robot robot = new Robot(); + final CheckboxGroup group = new CheckboxGroup(); + final Checkbox[] cbs = {new Checkbox("checkbox1", true, group), + new Checkbox("checkbox2", false, group), + new Checkbox("checkbox3", true, group), + + new Checkbox("checkbox4", true), + new Checkbox("checkbox5", false), + new Checkbox("checkbox6", true)}; + final Frame frame = new Frame(); + frame.setLayout(new GridBagLayout()); + try { + for (final Checkbox cb : cbs) { + cb.addItemListener(e -> { + failed = true; + }); + } + for (final Checkbox cb : cbs) { + frame.add(cb); + } + frame.pack(); + + for (final Checkbox cb : cbs) { + cb.setState(!cb.getState()); + } + + for (final Checkbox cb : cbs) { + group.setSelectedCheckbox(cb); + } + robot.waitForIdle(); + } finally { + frame.dispose(); + } + if (failed) { + throw new RuntimeException("Listener should not be called"); + } + System.out.println("Test passed"); + } +} diff --git a/jdk/test/java/awt/TrayIcon/8072769/bug8072769.java b/jdk/test/java/awt/TrayIcon/8072769/bug8072769.java new file mode 100644 index 00000000000..26b64a087bd --- /dev/null +++ b/jdk/test/java/awt/TrayIcon/8072769/bug8072769.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8072769 + @summary System tray icon title freezes java + @author Semyon Sadetsky + @library ../../../../lib/testlibrary + @build jdk.testlibrary.OSInfo + */ + +import jdk.testlibrary.OSInfo; + +import javax.swing.*; +import java.awt.*; +import java.util.Arrays; + +public class bug8072769 { + + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) { + if (SystemTray.isSupported()) { + test(); + } else { + System.out.println("SystemTray not supported. " + + "Test is skipped."); + } + } else { + System.out.println("Test will only run on Windows platform. " + + "Test is skipped."); + } + System.out.println("ok"); + } + + private static void test() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final SystemTray tray = SystemTray.getSystemTray(); + final TrayIcon trayIcon = new TrayIcon(icon.getImage()); + try { + tray.add(trayIcon); + } catch (AWTException e) { + throw new RuntimeException( + "TrayIcon could not be added."); + } + + + try { + trayIcon.displayMessage(createString(63, 'A'), + createString(255, 'C'), TrayIcon.MessageType.ERROR); + + trayIcon.setToolTip(createString(127, 'B')); + + trayIcon.displayMessage(createString(64, 'A'), + createString(256, 'C'), TrayIcon.MessageType.ERROR); + + trayIcon.setToolTip(createString(128, 'B')); + + trayIcon.displayMessage(createString(65, 'A'), + createString(257, 'C'), TrayIcon.MessageType.ERROR); + + trayIcon.setToolTip(createString(129, 'B')); + } + finally { + tray.remove(trayIcon); + } + } + }); + } + + private static String createString(int len, char letter) { + char[] chars = new char[len]; + Arrays.fill(chars, letter); + chars[len - 2] = '='; + chars[len - 1] = '>'; + return new String(chars); + } + + private static ImageIcon icon = new ImageIcon( + new byte[]{71, 73, 70, 56, 57, 97, 32, 0, 35, 0, -43, 0, 0, -1, -1, + -1, -19, -101, 9, -18, -95, 24, -14, -76, 71, -4, -19, -46, + -3, -13, -31, -17, -88, 40, -12, -63, 102, -10, -51, -124, + -16, -82, 55, -11, -57, 117, -2, -7, -15, -7, -32, -77, -9, + -45, -108, -5, -26, -62, -13, -70, 86, -8, -39, -94, 83, + -126, -95, -8, -38, -93, -6, -26, -63, -9, -45, -109, -4, + -14, -32, -15, -76, 70, -12, -58, 116, -17, -89, 39, 77, + 121, -106, -3, -8, -17, 104, -111, -84, 126, -95, -72, 93, + -119, -90, -14, -70, 85, -13, -64, 101, -16, -83, 55, -109, + -80, -60, -7, -33, -78, -100, -84, -85, 94, -127, -104, -32, + -99, 39, 127, -120, -114, 83, 113, -124, -12, -9, -7, -16, + -16, -16, -115, 108, 45, 57, 89, 110, -50, -41, -35, 104, + -111, -83, 41, 65, 80, 72, 113, -116, 115, -103, -78, 88, + 106, 112, -82, -78, -82, -45, -38, -40, -5, -20, -48, -65, + -48, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, -7, 4, 0, 0, 0, + 0, 0, 44, 0, 0, 0, 0, 32, 0, 35, 0, 0, 6, -1, 64, -128, 112, + 72, 4, 16, 0, 14, -57, 2, 1, 96, 30, -117, -48, 40, -78, + -55, 96, 28, 28, -125, -62, 0, 96, 48, 74, -91, -116, 102, + 3, 97, 64, 4, 20, -25, -128, 68, -80, 16, 24, 11, 95, 98, + -29, -64, 72, 11, 2, 120, -68, 96, -64, 39, 116, -29, 0, 12, + 13, 5, 1, 3, 121, -121, -120, 9, 2, 7, 5, 15, 82, 11, 11, + 92, 15, 6, -120, -107, -121, 7, 2, 18, 0, 112, 80, 3, 8, + 104, -106, -95, 122, 88, 97, 68, 5, 11, 4, -95, 32, 8, 16, + 19, 16, 8, 22, -106, -114, 79, 66, 5, 2, 15, 9, -120, 22, + 19, 81, 21, 31, -120, 7, 6, 10, 67, 71, 4, 119, -121, 20, + -128, 16, -57, 120, 7, -101, -111, -58, 9, -108, 121, -55, + -128, 0, 16, 121, 123, -117, 67, 5, -71, 121, 30, -42, 67, + 23, -121, 13, 66, 14, 6, 3, -34, 120, 21, -31, 66, 26, -39, + 3, 6, -50, 11, -96, 120, 31, -19, 67, 30, 121, 9, 14, 0, 13, + 124, -121, 68, -32, 19, 98, 6, 15, 58, 71, 18, 12, -27, 97, + 55, 80, 68, 54, 5, 5, 24, 40, 80, 23, 96, -96, -112, 9, -39, + 30, 52, -112, 72, -47, 34, 0, 10, 25, -53, 37, 60, -60, 16, + -33, 56, 61, 16, -1, 41, -60, 83, 13, 31, -122, 60, 7, 1, + -48, 59, -124, 65, 3, 62, -116, 48, -5, 57, 72, -112, -18, + -48, 5, -103, 124, 32, -32, 37, 112, -74, -119, 98, 0, 8, + -31, 64, -110, 35, 38, 64, 26, 34, -92, 113, 42, 48, -45, + 70, -76, 24, -77, 60, 80, -91, -60, -70, -12, 76, -120, 49, + 92, -120, 4, -40, -116, -126, 51, 79, -80, 97, -36, 80, 89, + -6, 25, -91, 96, -98, 89, -99, 62, 33, -62, 32, -59, -83, 0, + 82, 80, 32, 1, -72, 53, 13, -113, -42, 102, -103, 54, -127, + 25, 84, 40, 15, -115, 40, 37, 20, 49, 34, 26, 103, 78, 29, + 52, 42, 88, 16, 65, 17, -94, -49, 31, 107, 97, 16, -116, 49, + 32, 35, -61, 6, 14, 33, 56, 68, -120, -80, -96, 11, 1, 78, + -31, -6, 33, 96, 48, -93, -61, -122, 21, 46, 50, -116, -10, + -30, -47, -117, -125, 24, 29, 94, -100, -112, 61, -94, 54, + -108, 20, 38, 90, -112, -128, 81, -61, 90, 16, 0, 59}, + "try icon"); + +} diff --git a/jdk/test/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java b/jdk/test/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java new file mode 100644 index 00000000000..fd1fa7cf302 --- /dev/null +++ b/jdk/test/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8071668 + @summary Check whether clipboard see changes from external process after taking ownership + @author Anton Nashatyrev: area=datatransfer + @library /lib/testlibrary + @build jdk.testlibrary.Utils + @run main ClipboardInterVMTest +*/ + +import jdk.testlibrary.Utils; + +import java.awt.*; +import java.awt.datatransfer.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ClipboardInterVMTest { + + static CountDownLatch lostOwnershipMonitor = new CountDownLatch(1); + static CountDownLatch flavorChangedMonitor = new CountDownLatch(1); + static Process process; + + public static void main(String[] args) throws Throwable { + Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); + + if (args.length > 0) { + System.out.println("Changing clip..."); + clip.setContents(new StringSelection("pong"), null); + System.out.println("done"); + // keeping this process running for a while since on Mac the clipboard + // will be invalidated via NSApplicationDidBecomeActiveNotification + // callback in the main process after this child process finishes + Thread.sleep(60 * 1000); + return; + }; + + + clip.setContents(new CustomSelection(), new ClipboardOwner() { + @Override + public void lostOwnership(Clipboard clipboard, Transferable contents) { + System.out.println("ClipboardInterVMTest.lostOwnership"); + lostOwnershipMonitor.countDown(); + } + }); + + clip.addFlavorListener(new FlavorListener() { + @Override + public void flavorsChanged(FlavorEvent e) { + System.out.println("ClipboardInterVMTest.flavorsChanged"); + flavorChangedMonitor.countDown(); + } + }); + + System.out.println("Starting external clipborad modifier..."); + new Thread(() -> runTest(ClipboardInterVMTest.class.getCanonicalName(), "pong")).start(); + + String content = ""; + long startTime = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTime < 30 * 1000) { + Transferable c = clip.getContents(null); + if (c.isDataFlavorSupported(DataFlavor.plainTextFlavor)) { + Reader reader = DataFlavor.plainTextFlavor.getReaderForText(c); + content = new BufferedReader(reader).readLine(); + System.out.println(content); + if (content.equals("pong")) { + break; + } + } + Thread.sleep(200); + } + + if (!lostOwnershipMonitor.await(10, TimeUnit.SECONDS)) { + throw new RuntimeException("No LostOwnership event received."); + }; + + if (!flavorChangedMonitor.await(10, TimeUnit.SECONDS)) { + throw new RuntimeException("No LostOwnership event received."); + }; + + if (!content.equals("pong")) { + throw new RuntimeException("Content was not passed."); + } + + process.destroy(); + + System.out.println("Passed."); + } + + private static void runTest(String main, String... args) { + + try { + List opts = new ArrayList<>(); + opts.add(getJavaExe()); + opts.addAll(Arrays.asList(Utils.getTestJavaOpts())); + opts.add("-cp"); + opts.add(System.getProperty("test.class.path", System.getProperty("java.class.path"))); + + opts.add(main); + opts.addAll(Arrays.asList(args)); + + ProcessBuilder pb = new ProcessBuilder(opts.toArray(new String[0])); + process = pb.start(); + } catch (Throwable throwable) { + throw new RuntimeException(throwable); + } + } + + private static String getJavaExe() throws IOException { + File p = new File(System.getProperty("java.home"), "bin"); + File j = new File(p, "java"); + if (!j.canRead()) { + j = new File(p, "java.exe"); + } + if (!j.canRead()) { + throw new RuntimeException("Can't find java executable in " + p); + } + return j.getCanonicalPath(); + } + + static class CustomSelection implements Transferable { + private static final DataFlavor[] flavors = { DataFlavor.allHtmlFlavor }; + + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavors[0].equals(flavor); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, java.io.IOException { + if (isDataFlavorSupported(flavor)) { + return "ping"; + } else { + throw new UnsupportedFlavorException(flavor); + } + } + } +} \ No newline at end of file diff --git a/jdk/test/java/awt/geom/Path2D/Path2DCopyConstructor.java b/jdk/test/java/awt/geom/Path2D/Path2DCopyConstructor.java new file mode 100644 index 00000000000..5413d5138c5 --- /dev/null +++ b/jdk/test/java/awt/geom/Path2D/Path2DCopyConstructor.java @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.IllegalPathStateException; +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.Arrays; + +/** + * @test + * @bug 8076419 + * @summary Check Path2D copy constructor (trims arrays) + * and constructor with zero capacity + * @run main Path2DTrimCopy + */ +public class Path2DCopyConstructor { + + private final static float EPSILON = 5e-6f; + private final static float FLATNESS = 1e-2f; + + private final static AffineTransform at + = AffineTransform.getScaleInstance(1.3, 2.4); + + private final static Rectangle2D.Double rect2d + = new Rectangle2D.Double(3.2, 4.1, 5.0, 10.0); + + private final static Point2D.Double pt2d + = new Point2D.Double(2.0, 2.5); + + public static boolean verbose; + + static void log(String msg) { + if (verbose) { + System.out.println(msg); + } + } + + public static void main(String argv[]) { + verbose = (argv.length != 0); + + testEmptyDoublePaths(); + testDoublePaths(); + + testEmptyFloatPaths(); + testFloatPaths(); + + testEmptyGeneralPath(); + testGeneralPath(); + } + + static void testEmptyDoublePaths() { + log("\n - Test(Path2D.Double[0]) ---"); + test(() -> new Path2D.Double(Path2D.WIND_NON_ZERO, 0)); + } + + static void testDoublePaths() { + log("\n - Test(Path2D.Double) ---"); + test(() -> new Path2D.Double()); + } + + static void testEmptyFloatPaths() { + log("\n - Test(Path2D.Float[0]) ---"); + test(() -> new Path2D.Float(Path2D.WIND_NON_ZERO, 0)); + } + + static void testFloatPaths() { + log("\n - Test(Path2D.Float) ---"); + test(() -> new Path2D.Float()); + } + + static void testEmptyGeneralPath() { + log("\n - Test(GeneralPath[0]) ---"); + test(() -> new GeneralPath(Path2D.WIND_NON_ZERO, 0)); + } + + static void testGeneralPath() { + log("\n - Test(GeneralPath) ---"); + test(() -> new GeneralPath()); + } + + interface PathFactory { + Path2D makePath(); + } + + static void test(PathFactory pf) { + log("\n --- test: path(empty) ---"); + test(pf.makePath(), true); + log("\n\n --- test: path(addMove) ---"); + test(addMove(pf.makePath()), false); + log("\n\n --- test: path(addMoveAndLines) ---"); + test(addMoveAndLines(pf.makePath()), false); + log("\n\n --- test: path(addMoveAndQuads) ---"); + test(addMoveAndQuads(pf.makePath()), false); + log("\n\n --- test: path(addMoveAndCubics) ---"); + test(addMoveAndCubics(pf.makePath()), false); + log("\n\n --- test: path(addMoveAndClose) ---"); + test(addMoveAndClose(pf.makePath()), false); + } + + static Path2D addMove(Path2D p2d) { + p2d.moveTo(1.0, 0.5); + return p2d; + } + + static Path2D addMoveAndLines(Path2D p2d) { + addMove(p2d); + addLines(p2d); + return p2d; + } + + static Path2D addLines(Path2D p2d) { + for (int i = 0; i < 10; i++) { + p2d.lineTo(1.1 * i, 2.3 * i); + } + return p2d; + } + + static Path2D addMoveAndCubics(Path2D p2d) { + addMove(p2d); + addCubics(p2d); + return p2d; + } + + static Path2D addCubics(Path2D p2d) { + for (int i = 0; i < 10; i++) { + p2d.curveTo(1.1 * i, 1.2 * i, 1.3 * i, 1.4 * i, 1.5 * i, 1.6 * i); + } + return p2d; + } + + static Path2D addMoveAndQuads(Path2D p2d) { + addMove(p2d); + addQuads(p2d); + return p2d; + } + + static Path2D addQuads(Path2D p2d) { + for (int i = 0; i < 10; i++) { + p2d.quadTo(1.1 * i, 1.2 * i, 1.3 * i, 1.4 * i); + } + return p2d; + } + + static Path2D addMoveAndClose(Path2D p2d) { + addMove(p2d); + addClose(p2d); + return p2d; + } + + static Path2D addClose(Path2D p2d) { + p2d.closePath(); + return p2d; + } + + static void test(Path2D p2d, boolean isEmpty) { + testEqual(new Path2D.Float(p2d), p2d); + testEqual(new Path2D.Double(p2d), p2d); + testEqual(new GeneralPath(p2d), p2d); + + testIterator(new Path2D.Float(p2d), p2d); + testIterator(new Path2D.Double(p2d), p2d); + testIterator((Path2D) p2d.clone(), p2d); + + testFlattening(new Path2D.Float(p2d), p2d); + testFlattening(new Path2D.Double(p2d), p2d); + testFlattening((Path2D) p2d.clone(), p2d); + + testAddMove(new Path2D.Float(p2d)); + testAddMove(new Path2D.Double(p2d)); + testAddMove((Path2D) p2d.clone()); + + // These should expect exception if empty + testAddLine(new Path2D.Float(p2d), isEmpty); + testAddLine(new Path2D.Double(p2d), isEmpty); + testAddLine((Path2D) p2d.clone(), isEmpty); + + testAddQuad(new Path2D.Float(p2d), isEmpty); + testAddQuad(new Path2D.Double(p2d), isEmpty); + testAddQuad((Path2D) p2d.clone(), isEmpty); + + testAddCubic(new Path2D.Float(p2d), isEmpty); + testAddCubic(new Path2D.Double(p2d), isEmpty); + testAddCubic((Path2D) p2d.clone(), isEmpty); + + testAddClose(new Path2D.Float(p2d), isEmpty); + testAddClose(new Path2D.Double(p2d), isEmpty); + testAddClose((Path2D) p2d.clone(), isEmpty); + + testGetBounds(new Path2D.Float(p2d), p2d); + testGetBounds(new Path2D.Double(p2d), p2d); + testGetBounds((Path2D) p2d.clone(), p2d); + + testTransform(new Path2D.Float(p2d)); + testTransform(new Path2D.Double(p2d)); + testTransform((Path2D) p2d.clone()); + + testIntersect(new Path2D.Float(p2d), p2d); + testIntersect(new Path2D.Double(p2d), p2d); + testIntersect((Path2D) p2d.clone(), p2d); + + testContains(new Path2D.Float(p2d), p2d); + testContains(new Path2D.Double(p2d), p2d); + testContains((Path2D) p2d.clone(), p2d); + + testGetCurrentPoint(new Path2D.Float(p2d), p2d); + testGetCurrentPoint(new Path2D.Double(p2d), p2d); + testGetCurrentPoint((Path2D) p2d.clone(), p2d); + } + + static void testEqual(Path2D pathA, Path2D pathB) { + final PathIterator itA = pathA.getPathIterator(null); + final PathIterator itB = pathB.getPathIterator(null); + + float[] coordsA = new float[6]; + float[] coordsB = new float[6]; + + int n = 0; + for (; !itA.isDone() && !itB.isDone(); itA.next(), itB.next(), n++) { + int typeA = itA.currentSegment(coordsA); + int typeB = itB.currentSegment(coordsB); + + if (typeA != typeB) { + throw new IllegalStateException("Path-segment[" + n + "] " + + " type are not equals [" + typeA + "|" + typeB + "] !"); + } + if (!equalsArray(coordsA, coordsB, getLength(typeA))) { + throw new IllegalStateException("Path-segment[" + n + "] coords" + + " are not equals [" + Arrays.toString(coordsA) + "|" + + Arrays.toString(coordsB) + "] !"); + } + } + if (!itA.isDone() || !itB.isDone()) { + throw new IllegalStateException("Paths do not have same lengths !"); + } + log("testEqual: " + n + " segments."); + } + + static void testIterator(Path2D pathA, Path2D pathB) { + final PathIterator itA = pathA.getPathIterator(at); + final PathIterator itB = pathB.getPathIterator(at); + + float[] coordsA = new float[6]; + float[] coordsB = new float[6]; + + int n = 0; + for (; !itA.isDone() && !itB.isDone(); itA.next(), itB.next(), n++) { + int typeA = itA.currentSegment(coordsA); + int typeB = itB.currentSegment(coordsB); + + if (typeA != typeB) { + throw new IllegalStateException("Path-segment[" + n + "] " + + "type are not equals [" + typeA + "|" + typeB + "] !"); + } + // Take care of floating-point precision: + if (!equalsArrayEps(coordsA, coordsB, getLength(typeA))) { + throw new IllegalStateException("Path-segment[" + n + "] coords" + + " are not equals [" + Arrays.toString(coordsA) + "|" + + Arrays.toString(coordsB) + "] !"); + } + } + if (!itA.isDone() || !itB.isDone()) { + throw new IllegalStateException("Paths do not have same lengths !"); + } + log("testIterator: " + n + " segments."); + } + + static void testFlattening(Path2D pathA, Path2D pathB) { + final PathIterator itA = pathA.getPathIterator(at, FLATNESS); + final PathIterator itB = pathB.getPathIterator(at, FLATNESS); + + float[] coordsA = new float[6]; + float[] coordsB = new float[6]; + + int n = 0; + for (; !itA.isDone() && !itB.isDone(); itA.next(), itB.next(), n++) { + int typeA = itA.currentSegment(coordsA); + int typeB = itB.currentSegment(coordsB); + + if (typeA != typeB) { + throw new IllegalStateException("Path-segment[" + n + "] " + + "type are not equals [" + typeA + "|" + typeB + "] !"); + } + // Take care of floating-point precision: + if (!equalsArrayEps(coordsA, coordsB, getLength(typeA))) { + throw new IllegalStateException("Path-segment[" + n + "] coords" + + " are not equals [" + Arrays.toString(coordsA) + "|" + + Arrays.toString(coordsB) + "] !"); + } + } + if (!itA.isDone() || !itB.isDone()) { + throw new IllegalStateException("Paths do not have same lengths !"); + } + log("testFlattening: " + n + " segments."); + } + + static void testAddMove(Path2D pathA) { + addMove(pathA); + log("testAddMove: passed."); + } + + static void testAddLine(Path2D pathA, boolean isEmpty) { + try { + addLines(pathA); + } + catch (IllegalPathStateException ipse) { + if (isEmpty) { + log("testAddLine: passed " + + "(expected IllegalPathStateException catched)."); + return; + } else { + throw ipse; + } + } + if (isEmpty) { + throw new IllegalStateException("IllegalPathStateException not thrown !"); + } + log("testAddLine: passed."); + } + + static void testAddQuad(Path2D pathA, boolean isEmpty) { + try { + addQuads(pathA); + } + catch (IllegalPathStateException ipse) { + if (isEmpty) { + log("testAddQuad: passed " + + "(expected IllegalPathStateException catched)."); + return; + } else { + throw ipse; + } + } + if (isEmpty) { + throw new IllegalStateException("IllegalPathStateException not thrown !"); + } + log("testAddQuad: passed."); + } + + static void testAddCubic(Path2D pathA, boolean isEmpty) { + try { + addCubics(pathA); + } + catch (IllegalPathStateException ipse) { + if (isEmpty) { + log("testAddCubic: passed " + + "(expected IllegalPathStateException catched)."); + return; + } else { + throw ipse; + } + } + if (isEmpty) { + throw new IllegalStateException("IllegalPathStateException not thrown !"); + } + log("testAddCubic: passed."); + } + + static void testAddClose(Path2D pathA, boolean isEmpty) { + try { + addClose(pathA); + } + catch (IllegalPathStateException ipse) { + if (isEmpty) { + log("testAddClose: passed " + + "(expected IllegalPathStateException catched)."); + return; + } else { + throw ipse; + } + } + if (isEmpty) { + throw new IllegalStateException("IllegalPathStateException not thrown !"); + } + log("testAddClose: passed."); + } + + static void testGetBounds(Path2D pathA, Path2D pathB) { + final Rectangle rA = pathA.getBounds(); + final Rectangle rB = pathB.getBounds(); + + if (!rA.equals(rB)) { + throw new IllegalStateException("Bounds are not equals [" + rA + + "|" + rB + "] !"); + } + final Rectangle2D r2dA = pathA.getBounds2D(); + final Rectangle2D r2dB = pathB.getBounds2D(); + + if (!equalsRectangle2D(r2dA, r2dB)) { + throw new IllegalStateException("Bounds2D are not equals [" + + r2dA + "|" + r2dB + "] !"); + } + log("testGetBounds: passed."); + } + + static void testTransform(Path2D pathA) { + pathA.transform(at); + log("testTransform: passed."); + } + + static void testIntersect(Path2D pathA, Path2D pathB) { + boolean resA = pathA.intersects(rect2d); + boolean resB = pathB.intersects(rect2d); + if (resA != resB) { + throw new IllegalStateException("Intersects(rect2d) are not equals [" + + resA + "|" + resB + "] !"); + } + resA = pathA.intersects(1.0, 2.0, 13.0, 17.0); + resB = pathB.intersects(1.0, 2.0, 13.0, 17.0); + if (resA != resB) { + throw new IllegalStateException("Intersects(doubles) are not equals [" + + resA + "|" + resB + "] !"); + } + log("testIntersect: passed."); + } + + static void testContains(Path2D pathA, Path2D pathB) { + boolean resA = pathA.contains(pt2d); + boolean resB = pathB.contains(pt2d); + if (resA != resB) { + throw new IllegalStateException("Contains(pt) are not equals [" + + resA + "|" + resB + "] !"); + } + resA = pathA.contains(pt2d.getX(), pt2d.getY()); + resB = pathB.contains(pt2d.getX(), pt2d.getY()); + if (resA != resB) { + throw new IllegalStateException("Contains(x,y) are not equals [" + + resA + "|" + resB + "] !"); + } + resA = pathA.contains(rect2d); + resB = pathB.contains(rect2d); + if (resA != resB) { + throw new IllegalStateException("Contains(rect2d) are not equals [" + + resA + "|" + resB + "] !"); + } + resA = pathA.contains(1.0, 2.0, 13.0, 17.0); + resB = pathB.contains(1.0, 2.0, 13.0, 17.0); + if (resA != resB) { + throw new IllegalStateException("Contains(doubles) are not equals [" + + resA + "|" + resB + "] !"); + } + log("testContains: passed."); + } + + static void testGetCurrentPoint(Path2D pathA, Path2D pathB) { + final Point2D ptA = pathA.getCurrentPoint(); + final Point2D ptB = pathA.getCurrentPoint(); + if (((ptA == null) && (ptB != null)) + || ((ptA != null) && !ptA.equals(ptB))) + { + throw new IllegalStateException("getCurrentPoint() are not equals [" + + ptA + "|" + ptB + "] !"); + } + log("testGetCurrentPoint: passed."); + } + + static int getLength(int type) { + switch(type) { + case PathIterator.SEG_CUBICTO: + return 6; + case PathIterator.SEG_QUADTO: + return 4; + case PathIterator.SEG_LINETO: + case PathIterator.SEG_MOVETO: + return 2; + case PathIterator.SEG_CLOSE: + return 0; + default: + throw new IllegalStateException("Invalid type: " + type); + } + } + + + // Custom equals methods --- + + public static boolean equalsArray(float[] a, float[] a2, final int len) { + for (int i = 0; i < len; i++) { + if (Float.floatToIntBits(a[i]) != Float.floatToIntBits(a2[i])) { + return false; + } + } + return true; + } + + static boolean equalsArrayEps(float[] a, float[] a2, final int len) { + for (int i = 0; i < len; i++) { + if (!equalsEps(a[i], a2[i])) { + return false; + } + } + + return true; + } + + static boolean equalsRectangle2D(Rectangle2D a, Rectangle2D b) { + if (a == b) { + return true; + } + return equalsEps(a.getX(), b.getX()) + && equalsEps(a.getY(), b.getY()) + && equalsEps(a.getWidth(), b.getWidth()) + && equalsEps(a.getHeight(), b.getHeight()); + } + + static boolean equalsEps(float a, float b) { + return (Math.abs(a - b) <= EPSILON); + } + + static boolean equalsEps(double a, double b) { + return (Math.abs(a - b) <= EPSILON); + } +} diff --git a/jdk/test/java/beans/SimpleBeanInfo/LoadingStandardIcons/LoadingStandardIcons.java b/jdk/test/java/beans/SimpleBeanInfo/LoadingStandardIcons/LoadingStandardIcons.java new file mode 100644 index 00000000000..9b96bd2f668 --- /dev/null +++ b/jdk/test/java/beans/SimpleBeanInfo/LoadingStandardIcons/LoadingStandardIcons.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Image; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; + +import javax.swing.JButton; + +/** + * @test + * @bug 4141523 + * @run main/othervm/policy=java.policy -Djava.security.manager LoadingStandardIcons + */ +public final class LoadingStandardIcons { + + public static void main(final String[] args) { + final Object bi; + try { + bi = Introspector.getBeanInfo(JButton.class); + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + final Image m16 = ((BeanInfo) bi).getIcon(BeanInfo.ICON_MONO_16x16); + final Image m32 = ((BeanInfo) bi).getIcon(BeanInfo.ICON_MONO_32x32); + final Image c16 = ((BeanInfo) bi).getIcon(BeanInfo.ICON_COLOR_16x16); + final Image c32 = ((BeanInfo) bi).getIcon(BeanInfo.ICON_COLOR_32x32); + if (m16 == null || m32 == null || c16 == null || c32 == null) { + throw new RuntimeException("Image should not be null"); + } + } +} diff --git a/jdk/test/java/beans/SimpleBeanInfo/LoadingStandardIcons/java.policy b/jdk/test/java/beans/SimpleBeanInfo/LoadingStandardIcons/java.policy new file mode 100644 index 00000000000..1c8a0e79762 --- /dev/null +++ b/jdk/test/java/beans/SimpleBeanInfo/LoadingStandardIcons/java.policy @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/jdk/test/java/net/URL/HandlersPkgPrefix/HandlersPkgPrefix.java b/jdk/test/java/net/URL/HandlersPkgPrefix/HandlersPkgPrefix.java new file mode 100644 index 00000000000..83b06ccd621 --- /dev/null +++ b/jdk/test/java/net/URL/HandlersPkgPrefix/HandlersPkgPrefix.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.function.Consumer; + +/* + * @test + * @bug 8075139 + * @summary Basic test for java.protocol.handler.pkgs + * @compile handlers/foo/Handler.java handlers/bar/Handler.java HandlersPkgPrefix.java + * @run main/othervm HandlersPkgPrefix + */ + +public class HandlersPkgPrefix { + static final Consumer KNOWN = r -> { + if (r.exception != null) + throw new RuntimeException("Unexpected exception " + r.exception); + String p = r.url.getProtocol(); + if (!r.protocol.equals(p)) + throw new RuntimeException("Expected:" + r.protocol + ", got:" + p); + }; + static final Consumer UNKNOWN = r -> { + if (r.url != null) + throw new RuntimeException("Unexpected url:" + r.url); + if (!(r.exception instanceof MalformedURLException)) + throw new RuntimeException("Expected MalformedURLException, got:" + + r.exception); + }; + + public static void main(String[] args) { + withPrefix("unknown", "", UNKNOWN); + withPrefix("unknown", "handlers", UNKNOWN); + + withPrefix("foo", "", UNKNOWN); + withPrefix("foo", "xxx|yyy|zzz", UNKNOWN); + withPrefix("foo", "||||", UNKNOWN); + withPrefix("foo", "|a|b|c|handlers", KNOWN); + + withPrefix("bar", "", UNKNOWN); + withPrefix("bar", "x.y.z|y.y.y|z.z.z", UNKNOWN); + withPrefix("bar", " x.y.z | y.y.y | z.z.z| | ", UNKNOWN); + withPrefix("bar", "| a | b | c | handlers | d | e", KNOWN); + } + + static void withPrefix(String protocol, String pkgPrefix, + Consumer resultChecker) { + System.out.println("Testing, " + protocol + ", " + pkgPrefix); + + // The long standing implementation behavior is that the + // property is read multiple times, not cached. + System.setProperty("java.protocol.handler.pkgs", pkgPrefix); + URL url = null; + Exception exception = null; + try { + url = new URL(protocol + "://"); + } catch (MalformedURLException x) { + exception = x; + } + resultChecker.accept(new Result(protocol, url, exception)); + } + + static class Result { + final String protocol; + final URL url; + final Exception exception; + Result(String protocol, URL url, Exception exception) { + this.protocol = protocol; + this.url = url; + this.exception = exception; + } + } +} + diff --git a/jdk/test/java/net/URL/HandlersPkgPrefix/handlers/bar/Handler.java b/jdk/test/java/net/URL/HandlersPkgPrefix/handlers/bar/Handler.java new file mode 100644 index 00000000000..c94e9288ebc --- /dev/null +++ b/jdk/test/java/net/URL/HandlersPkgPrefix/handlers/bar/Handler.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package handlers.bar; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class Handler extends URLStreamHandler { + @Override + protected URLConnection openConnection(URL u) throws IOException { + return null; + } +} + diff --git a/jdk/test/java/net/URL/HandlersPkgPrefix/handlers/foo/Handler.java b/jdk/test/java/net/URL/HandlersPkgPrefix/handlers/foo/Handler.java new file mode 100644 index 00000000000..21bde96c13a --- /dev/null +++ b/jdk/test/java/net/URL/HandlersPkgPrefix/handlers/foo/Handler.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package handlers.foo; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class Handler extends URLStreamHandler { + @Override + protected URLConnection openConnection(URL u) throws IOException { + return null; + } +} + diff --git a/jdk/test/java/time/test/java/time/format/TestTextParser.java b/jdk/test/java/time/test/java/time/format/TestTextParser.java index 07bd2146212..a1b264a756b 100644 --- a/jdk/test/java/time/test/java/time/format/TestTextParser.java +++ b/jdk/test/java/time/test/java/time/format/TestTextParser.java @@ -68,10 +68,20 @@ import static org.testng.Assert.assertTrue; import java.text.ParsePosition; import java.time.DayOfWeek; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.HijrahDate; +import java.time.chrono.JapaneseDate; +import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistDate; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; import java.time.format.TextStyle; +import java.time.format.SignStyle; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalField; +import java.time.temporal.TemporalQueries; +import java.time.temporal.ChronoField; import java.util.Locale; import org.testng.annotations.DataProvider; @@ -243,6 +253,8 @@ public class TestTextParser extends AbstractTestPrinterParser { }; } + + @Test(dataProvider="parseText") public void test_parseText(TemporalField field, TextStyle style, int value, String input) throws Exception { ParsePosition pos = new ParsePosition(0); @@ -433,4 +445,42 @@ public class TestTextParser extends AbstractTestPrinterParser { assertEquals(pos.getIndex(), input.length()); } + //----------------------------------------------------------------------- + @DataProvider(name="parseChronoLocalDate") + Object[][] provider_chronoLocalDate() { + return new Object[][] { + { HijrahDate.now() }, + { JapaneseDate.now() }, + { MinguoDate.now() }, + { ThaiBuddhistDate.now() }}; + } + + private static final DateTimeFormatter fmt_chrono = + new DateTimeFormatterBuilder() + .optionalStart() + .appendChronologyId() + .appendLiteral(' ') + .optionalEnd() + .optionalStart() + .appendText(ChronoField.ERA, TextStyle.SHORT) + .appendLiteral(' ') + .optionalEnd() + .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL) + .appendLiteral('-') + .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER) + .appendLiteral('-') + .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER) + .toFormatter(); + + @Test(dataProvider="parseChronoLocalDate") + public void test_chronoLocalDate(ChronoLocalDate date) throws Exception { + System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date)); + assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from)); + + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd") + .withChronology(date.getChronology()); + System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date)); + assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from)); + } + } diff --git a/jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java b/jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java index edd991b4cd1..8eab9947dd7 100644 --- a/jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java +++ b/jdk/test/java/util/PluggableLocale/TimeZoneNameProviderTest.java @@ -25,6 +25,7 @@ */ import java.text.*; +import java.time.format.TextStyle; import java.util.*; import sun.util.locale.provider.*; import sun.util.resources.*; @@ -42,6 +43,7 @@ public class TimeZoneNameProviderTest extends ProviderTest { test2(); test3(); aliasTest(); + genericFallbackTest(); } void test1() { @@ -169,9 +171,9 @@ public class TimeZoneNameProviderTest extends ProviderTest { for (int style : new int[] { TimeZone.LONG, TimeZone.SHORT }) { String osakaStd = tz.getDisplayName(false, style, OSAKA); if (osakaStd != null) { - // No API for getting generic time zone names - String generic = TimeZoneNameUtility.retrieveGenericDisplayName(tzname, - style, GENERIC); + String generic = tz.toZoneId().getDisplayName( + style == TimeZone.LONG ? TextStyle.FULL : TextStyle.SHORT, + GENERIC); String expected = "Generic " + osakaStd; if (!expected.equals(generic)) { throw new RuntimeException("Wrong generic name: got=\"" + generic @@ -230,4 +232,20 @@ public class TimeZoneNameProviderTest extends ProviderTest { throw new RuntimeException("Provider's localized name is not available for an alias ID: "+JAPAN+". result: "+japan+" expected: "+JST_IN_OSAKA); } } + + /* + * Tests whether generic names can be retrieved through fallback. + * The test assumes the provider impl for OSAKA locale does NOT + * provide generic names. + */ + final String PT = "PT"; // SHORT generic name for "America/Los_Angeles" + void genericFallbackTest() { + String generic = + TimeZone.getTimeZone(LATIME) + .toZoneId() + .getDisplayName(TextStyle.SHORT, OSAKA); + if (!PT.equals(generic)) { + throw new RuntimeException("Generic name fallback failed. got: "+generic); + } + } } diff --git a/jdk/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java b/jdk/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java index 24bf863dc88..538658f7b06 100644 --- a/jdk/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java +++ b/jdk/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,37 +34,31 @@ // java imports // import java.net.MalformedURLException; -import java.util.Map; - -// JMX imports -// -import javax.management.* ; - -import javax.management.remote.*; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.MBeanServerFactory; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; public class NotSerializableNotifTest { private static final MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer(); private static ObjectName emitter; - private static int port = 2468; private static String[] protocols; private static final int sentNotifs = 10; - private static double timeoutFactor = 1.0; - private static final double defaultTimeout = 10; - public static void main(String[] args) throws Exception { System.out.println(">>> Test to send a not serializable notification"); - String timeoutVal = System.getProperty("test.timeout.factor"); - if (timeoutVal != null) { - timeoutFactor = Double.parseDouble( - System.getProperty("test.timeout.factor") - ); - } - // IIOP fails on JDK1.4, see 5034318 final String v = System.getProperty("java.version"); float f = Float.parseFloat(v.substring(0, 3)); @@ -77,35 +71,18 @@ public class NotSerializableNotifTest { emitter = new ObjectName("Default:name=NotificationEmitter"); mbeanServer.registerMBean(new NotificationEmitter(), emitter); - boolean ok = true; for (int i = 0; i < protocols.length; i++) { - try { - if (!test(protocols[i])) { - System.out.println(">>> Test failed for " + protocols[i]); - ok = false; - } else { - System.out.println(">>> Test successed for " + protocols[i]); - } - } catch (Exception e) { - System.out.println(">>> Test failed for " + protocols[i]); - e.printStackTrace(System.out); - ok = false; - } + test(protocols[i]); } - if (ok) { - System.out.println(">>> Test passed"); - } else { - System.out.println(">>> TEST FAILED"); - System.exit(1); - } + System.out.println(">>> Test passed"); } - private static boolean test(String proto) throws Exception { + private static void test(String proto) throws Exception { System.out.println("\n>>> Test for protocol " + proto); - JMXServiceURL url = new JMXServiceURL(proto, null, port++); + JMXServiceURL url = new JMXServiceURL(proto, null, 0); System.out.println(">>> Create a server: "+url); @@ -115,7 +92,7 @@ public class NotSerializableNotifTest { } catch (MalformedURLException e) { System.out.println("System does not recognize URL: " + url + "; ignoring"); - return true; + return; } server.start(); @@ -146,34 +123,17 @@ public class NotSerializableNotifTest { // waiting ... synchronized (listener) { - int top = (int)Math.ceil(timeoutFactor * defaultTimeout); - for (int i=0; i commands = new ArrayList<>(); + commands.add(ConcurrentHashMapTest.JAVA); + commands.add("-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory"); + commands.add("-Djava.naming.provider.url=iiop://localhost:1050"); + commands.add("-cp"); + commands.add(ConcurrentHashMapTest.CLASSPATH); + commands.add("HelloServer"); + + System.out.println("ConcurrentHashMapTest: Executing: " + commands); + ProcessBuilder pb = new ProcessBuilder(commands); + pb.redirectError(ProcessBuilder.Redirect.INHERIT); + rmiServerProcess = pb.start(); + } + + static boolean isResponseReceived() { + return HelloClient.isResponseReceived(); + } + + static void stopRmiIiopServer() throws Exception { + rmiServerProcess.destroy(); + rmiServerProcess.waitFor(); + //rmiServerProcess.waitFor(30, TimeUnit.SECONDS); + System.out.println("serverProcess exitCode:" + + rmiServerProcess.exitValue()); + } + + static void stopOrbd() throws Exception { + orbdProcess.destroy(); + orbdProcess.waitFor(); + //orbdProcess.waitFor(30, TimeUnit.SECONDS); + System.out.println("orbd exitCode:" + + orbdProcess.exitValue()); + } + + static void executeRmiIiopClient() throws Exception { + try { + HelloClient.executeRmiClientCall(); + } catch (Exception ex) { + clientException = ex; + exceptionInClient = true; + } + } +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/HelloClient.java b/jdk/test/javax/rmi/PortableRemoteObject/HelloClient.java new file mode 100644 index 00000000000..d3baa64e56b --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/HelloClient.java @@ -0,0 +1,98 @@ +import java.rmi.RemoteException; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.rmi.NotBoundException; +import java.util.HashMap; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; + +import javax.naming.NamingException; +import javax.naming.InitialContext; +import javax.naming.Context; +import javax.naming.NameNotFoundException; +import javax.naming.NamingException; +import javax.rmi.PortableRemoteObject; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; + +public class HelloClient implements Runnable { + static final int MAX_RETRY = 10; + static final int ONE_SECOND = 1000; + private static boolean responseReceived; + + public static void main(String args[]) throws Exception { + executeRmiClientCall(); + } + + @Override + public void run() { + try { + executeRmiClientCall(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + + public static boolean isResponseReceived () { + return responseReceived; + } + + public static void executeRmiClientCall() throws Exception { + Context ic; + Object objref; + HelloInterface helloSvc; + String response; + int retryCount = 0; + + Test test = new Test(); + System.out.println("HelloClient.main: enter ..."); + while (retryCount < MAX_RETRY) { + try { + ic = new InitialContext(); + System.out.println("HelloClient.main: HelloService lookup ..."); + // STEP 1: Get the Object reference from the Name Service + // using JNDI call. + objref = ic.lookup("HelloService"); + System.out.println("HelloClient: Obtained a ref. to Hello server."); + + // STEP 2: Narrow the object reference to the concrete type and + // invoke the method. + helloSvc = (HelloInterface) PortableRemoteObject.narrow(objref, + HelloInterface.class); + System.out.println("HelloClient: Invoking on remote server with ConcurrentHashMap parameter"); + ConcurrentHashMap testConcurrentHashMap = new ConcurrentHashMap(); + response = helloSvc.sayHelloWithHashMap(testConcurrentHashMap); + System.out.println("HelloClient: Server says: " + response); + if (!response.contains("Hello with hashMapSize ==")) { + System.out.println("HelloClient: expected response not received"); + throw new RuntimeException("Expected Response Hello with hashMapSize == 0 not received"); + } + responseReceived = true; + break; + } catch (NameNotFoundException nnfEx) { + System.err.println("NameNotFoundException Caught .... try again"); + retryCount++; + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e) { + e.printStackTrace(); + } + continue; + } catch (Exception e) { + System.err.println("Exception " + e + "Caught"); + e.printStackTrace(); + throw new RuntimeException(e); + } + } + System.err.println("HelloClient terminating "); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/HelloImpl.java b/jdk/test/javax/rmi/PortableRemoteObject/HelloImpl.java new file mode 100644 index 00000000000..e6b24948852 --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/HelloImpl.java @@ -0,0 +1,60 @@ +import java.net.InetAddress; +import java.rmi.RemoteException; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; + +import javax.rmi.PortableRemoteObject; + +public class HelloImpl extends PortableRemoteObject implements HelloInterface { + public HelloImpl() throws java.rmi.RemoteException { + super(); // invoke rmi linking and remote object initialization + } + + public String sayHello(String from) throws java.rmi.RemoteException { + System.out.println("Hello from " + from + "!!"); + System.out.flush(); + String reply = "Hello from us to you " + from; + return reply; + } + + @Override + public String sayHelloToTest(Test test) throws RemoteException { + return "Test says Hello"; + } + + @Override + public String sayHelloWithInetAddress(InetAddress ipAddr) + throws RemoteException { + String response = "Hello with InetAddress " + ipAddr.toString(); + return response; + } + + @Override + public String sayHelloWithHashMap(ConcurrentHashMap receivedHashMap) + throws RemoteException { + int hashMapSize = 0; + + hashMapSize = receivedHashMap.size(); + String response = "Hello with hashMapSize == " + hashMapSize; + return response; + } + + @Override + public String sayHelloWithHashMap2(HashMap receivedHashMap) + throws RemoteException { + int hashMapSize = 0; + + hashMapSize = receivedHashMap.size(); + String response = "Hello with hashMapSize == " + hashMapSize; + return response; + } + + @Override + public String sayHelloWithReentrantLock(ReentrantLock receivedLock) + throws RemoteException { + + String response = "Hello with lock == " + receivedLock.isLocked(); + return response; + } +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/HelloInterface.java b/jdk/test/javax/rmi/PortableRemoteObject/HelloInterface.java new file mode 100644 index 00000000000..0c1a1635b0f --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/HelloInterface.java @@ -0,0 +1,14 @@ +import java.net.InetAddress; +import java.rmi.Remote; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; + +public interface HelloInterface extends Remote { + public String sayHello( String from ) throws java.rmi.RemoteException; + public String sayHelloToTest( Test test ) throws java.rmi.RemoteException; + public String sayHelloWithInetAddress( InetAddress ipAddr ) throws java.rmi.RemoteException; + public String sayHelloWithHashMap(ConcurrentHashMap hashMap ) throws java.rmi.RemoteException; + public String sayHelloWithHashMap2(HashMap hashMap ) throws java.rmi.RemoteException; + public String sayHelloWithReentrantLock(ReentrantLock lock ) throws java.rmi.RemoteException; +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/HelloServer.java b/jdk/test/javax/rmi/PortableRemoteObject/HelloServer.java new file mode 100644 index 00000000000..f3ec3991531 --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/HelloServer.java @@ -0,0 +1,36 @@ +import javax.naming.InitialContext; +import javax.naming.Context; + +public class HelloServer { + + static final int MAX_RETRY = 10; + static final int ONE_SECOND = 1000; + + public static void main(String[] args) { + int retryCount = 0; + while (retryCount < MAX_RETRY) { + try { + //HelloServer.set("SETTING TEST ITL"); + // Step 1: Instantiate the Hello servant + HelloImpl helloRef = new HelloImpl(); + + // Step 2: Publish the reference in the Naming Service + // using JNDI API + Context initialNamingContext = new InitialContext(); + initialNamingContext.rebind("HelloService", helloRef); + + System.out.println("Hello Server: Ready..."); + break; + } catch (Exception e) { + System.out.println("Server initialization problem: " + e); + e.printStackTrace(); + retryCount++; + try { + Thread.sleep(ONE_SECOND); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + } + } +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/Test.java b/jdk/test/javax/rmi/PortableRemoteObject/Test.java new file mode 100644 index 00000000000..1fc3ecf939f --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/Test.java @@ -0,0 +1,6 @@ +import java.io.Serializable; + + +public class Test implements Serializable { + +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/_HelloImpl_Tie.java b/jdk/test/javax/rmi/PortableRemoteObject/_HelloImpl_Tie.java new file mode 100644 index 00000000000..040500d8aeb --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/_HelloImpl_Tie.java @@ -0,0 +1,128 @@ +// Tie class generated by rmic, do not edit. +// Contents subject to change without notice. + +import java.io.Serializable; +import java.net.InetAddress; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; +import javax.rmi.CORBA.Tie; +import javax.rmi.CORBA.Util; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.UnknownException; +import org.omg.CORBA_2_3.portable.ObjectImpl; + + +public class _HelloImpl_Tie extends ObjectImpl implements Tie { + + private HelloImpl target = null; + + private static final String[] _type_ids = { + "RMI:HelloInterface:0000000000000000" + }; + + public void setTarget(Remote target) { + this.target = (HelloImpl) target; + } + + public Remote getTarget() { + return target; + } + + public org.omg.CORBA.Object thisObject() { + return this; + } + + public void deactivate() { + _orb().disconnect(this); + _set_delegate(null); + target = null; + } + + public ORB orb() { + return _orb(); + } + + public void orb(ORB orb) { + orb.connect(this); + } + + public String[] _ids() { + return (String[]) _type_ids.clone(); + } + + public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException { + try { + org.omg.CORBA_2_3.portable.InputStream in = + (org.omg.CORBA_2_3.portable.InputStream) _in; + switch (method.length()) { + case 8: + if (method.equals("sayHello")) { + String arg0 = (String) in.read_value(String.class); + String result = target.sayHello(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,String.class); + return out; + } + case 14: + if (method.equals("sayHelloToTest")) { + Test arg0 = (Test) in.read_value(Test.class); + String result = target.sayHelloToTest(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,String.class); + return out; + } + case 19: + if (method.equals("sayHelloWithHashMap")) { + ConcurrentHashMap arg0 = (ConcurrentHashMap) in.read_value(ConcurrentHashMap.class); + String result = target.sayHelloWithHashMap(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,String.class); + return out; + } + case 20: + if (method.equals("sayHelloWithHashMap2")) { + HashMap arg0 = (HashMap) in.read_value(HashMap.class); + String result = target.sayHelloWithHashMap2(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,String.class); + return out; + } + case 23: + if (method.equals("sayHelloWithInetAddress")) { + InetAddress arg0 = (InetAddress) in.read_value(InetAddress.class); + String result = target.sayHelloWithInetAddress(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,String.class); + return out; + } + case 25: + if (method.equals("sayHelloWithReentrantLock")) { + ReentrantLock arg0 = (ReentrantLock) in.read_value(ReentrantLock.class); + String result = target.sayHelloWithReentrantLock(arg0); + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply(); + out.write_value(result,String.class); + return out; + } + } + throw new BAD_OPERATION(); + } catch (SystemException ex) { + throw ex; + } catch (Throwable ex) { + throw new UnknownException(ex); + } + } +} diff --git a/jdk/test/javax/rmi/PortableRemoteObject/_HelloInterface_Stub.java b/jdk/test/javax/rmi/PortableRemoteObject/_HelloInterface_Stub.java new file mode 100644 index 00000000000..4098143151f --- /dev/null +++ b/jdk/test/javax/rmi/PortableRemoteObject/_HelloInterface_Stub.java @@ -0,0 +1,272 @@ +// Stub class generated by rmic, do not edit. +// Contents subject to change without notice. + +import java.io.Serializable; +import java.net.InetAddress; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.UnexpectedException; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReentrantLock; +import javax.rmi.CORBA.Stub; +import javax.rmi.CORBA.Util; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.ServantObject; + + +public class _HelloInterface_Stub extends Stub implements HelloInterface { + + private static final String[] _type_ids = { + "RMI:HelloInterface:0000000000000000" + }; + + public String[] _ids() { + return (String[]) _type_ids.clone(); + } + + public String sayHello(String arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHello", true); + out.write_value(arg0,String.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (String) in.read_value(String.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHello(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHello",HelloInterface.class); + if (so == null) { + return sayHello(arg0); + } + try { + return ((HelloInterface)so.servant).sayHello(arg0); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + + public String sayHelloToTest(Test arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloToTest", true); + out.write_value(arg0,Test.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (String) in.read_value(String.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloToTest(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloToTest",HelloInterface.class); + if (so == null) { + return sayHelloToTest(arg0); + } + try { + Test arg0Copy = (Test) Util.copyObject(arg0,_orb()); + return ((HelloInterface)so.servant).sayHelloToTest(arg0Copy); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + + public String sayHelloWithInetAddress(InetAddress arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloWithInetAddress", true); + out.write_value(arg0,InetAddress.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (String) in.read_value(String.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloWithInetAddress(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloWithInetAddress",HelloInterface.class); + if (so == null) { + return sayHelloWithInetAddress(arg0); + } + try { + InetAddress arg0Copy = (InetAddress) Util.copyObject(arg0,_orb()); + return ((HelloInterface)so.servant).sayHelloWithInetAddress(arg0Copy); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + + public String sayHelloWithHashMap(ConcurrentHashMap arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloWithHashMap", true); + out.write_value(arg0,ConcurrentHashMap.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (String) in.read_value(String.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloWithHashMap(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloWithHashMap",HelloInterface.class); + if (so == null) { + return sayHelloWithHashMap(arg0); + } + try { + ConcurrentHashMap arg0Copy = (ConcurrentHashMap) Util.copyObject(arg0,_orb()); + return ((HelloInterface)so.servant).sayHelloWithHashMap(arg0Copy); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + + public String sayHelloWithHashMap2(HashMap arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloWithHashMap2", true); + out.write_value(arg0,HashMap.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (String) in.read_value(String.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloWithHashMap2(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloWithHashMap2",HelloInterface.class); + if (so == null) { + return sayHelloWithHashMap2(arg0); + } + try { + HashMap arg0Copy = (HashMap) Util.copyObject(arg0,_orb()); + return ((HelloInterface)so.servant).sayHelloWithHashMap2(arg0Copy); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } + + public String sayHelloWithReentrantLock(ReentrantLock arg0) throws java.rmi.RemoteException { + if (!Util.isLocal(this)) { + try { + org.omg.CORBA_2_3.portable.InputStream in = null; + try { + org.omg.CORBA_2_3.portable.OutputStream out = + (org.omg.CORBA_2_3.portable.OutputStream) + _request("sayHelloWithReentrantLock", true); + out.write_value(arg0,ReentrantLock.class); + in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out); + return (String) in.read_value(String.class); + } catch (ApplicationException ex) { + in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream(); + String $_id = in.read_string(); + throw new UnexpectedException($_id); + } catch (RemarshalException ex) { + return sayHelloWithReentrantLock(arg0); + } finally { + _releaseReply(in); + } + } catch (SystemException ex) { + throw Util.mapSystemException(ex); + } + } else { + ServantObject so = _servant_preinvoke("sayHelloWithReentrantLock",HelloInterface.class); + if (so == null) { + return sayHelloWithReentrantLock(arg0); + } + try { + ReentrantLock arg0Copy = (ReentrantLock) Util.copyObject(arg0,_orb()); + return ((HelloInterface)so.servant).sayHelloWithReentrantLock(arg0Copy); + } catch (Throwable ex) { + Throwable exCopy = (Throwable)Util.copyObject(ex,_orb()); + throw Util.wrapException(exCopy); + } finally { + _servant_postinvoke(so); + } + } + } +} diff --git a/jdk/test/javax/security/auth/login/LoginContext/CustomLoginModule.java b/jdk/test/javax/security/auth/login/LoginContext/CustomLoginModule.java new file mode 100644 index 00000000000..e47f3de56e7 --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/CustomLoginModule.java @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.security.Principal; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.ChoiceCallback; +import javax.security.auth.callback.ConfirmationCallback; +import javax.security.auth.callback.LanguageCallback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.TextInputCallback; +import javax.security.auth.callback.TextOutputCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +public class CustomLoginModule implements LoginModule { + + static final String HELLO = "Hello"; + + private Subject subject; + private CallbackHandler callbackHandler; + private boolean loginSucceeded = false; + private String username; + private char[] password; + + /* + * Initialize this LoginModule. + */ + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + this.subject = subject; + this.callbackHandler = callbackHandler; + + // check if custom parameter is passed from comfiguration + if (options == null) { + throw new RuntimeException("options is null"); + } + + // read username/password from configuration + Object o = options.get("username"); + if (o == null) { + throw new RuntimeException("Custom parameter not passed"); + } + if (!(o instanceof String)) { + throw new RuntimeException("Password is not a string"); + } + username = (String) o; + + o = options.get("password"); + if (o == null) { + throw new RuntimeException("Custom parameter not passed"); + } + if (!(o instanceof String)) { + throw new RuntimeException("Password is not a string"); + } + password = ((String) o).toCharArray(); + } + + /* + * Authenticate the user. + */ + @Override + public boolean login() throws LoginException { + // prompt for a user name and password + if (callbackHandler == null) { + throw new LoginException("No CallbackHandler available"); + } + + // standard callbacks + NameCallback name = new NameCallback("username: ", "default"); + PasswordCallback passwd = new PasswordCallback("password: ", false); + + LanguageCallback language = new LanguageCallback(); + + TextOutputCallback error = new TextOutputCallback( + TextOutputCallback.ERROR, "This is an error"); + TextOutputCallback warning = new TextOutputCallback( + TextOutputCallback.WARNING, "This is a warning"); + TextOutputCallback info = new TextOutputCallback( + TextOutputCallback.INFORMATION, "This is a FYI"); + + TextInputCallback text = new TextInputCallback("Please type " + HELLO, + "Bye"); + + ChoiceCallback choice = new ChoiceCallback("Choice: ", + new String[] { "pass", "fail" }, 1, true); + + ConfirmationCallback confirmation = new ConfirmationCallback( + "confirmation: ", ConfirmationCallback.INFORMATION, + ConfirmationCallback.YES_NO_OPTION, ConfirmationCallback.NO); + + CustomCallback custom = new CustomCallback(); + + Callback[] callbacks = new Callback[] { + choice, info, warning, error, name, passwd, text, language, + confirmation, custom + }; + + boolean uce = false; + try { + callbackHandler.handle(callbacks); + } catch (UnsupportedCallbackException e) { + Callback callback = e.getCallback(); + if (custom.equals(callback)) { + uce = true; + System.out.println("CustomLoginModule: " + + "custom callback not supported as expected"); + } else { + throw new LoginException("Unsupported callback: " + callback); + } + } catch (IOException ioe) { + throw new LoginException(ioe.toString()); + } + + if (!uce) { + throw new RuntimeException("UnsupportedCallbackException " + + "not thrown"); + } + + if (!HELLO.equals(text.getText())) { + System.out.println("Text: " + text.getText()); + throw new FailedLoginException("No hello"); + } + + if (!Locale.GERMANY.equals(language.getLocale())) { + System.out.println("Selected locale: " + language.getLocale()); + throw new FailedLoginException("Achtung bitte"); + } + + String readUsername = name.getName(); + char[] readPassword = passwd.getPassword(); + if (readPassword == null) { + // treat a NULL password as an empty password + readPassword = new char[0]; + } + passwd.clearPassword(); + + // verify the username/password + if (!username.equals(readUsername) + || !Arrays.equals(password, readPassword)) { + loginSucceeded = false; + throw new FailedLoginException("Username/password is not correct"); + } + + // check chosen option + int[] selected = choice.getSelectedIndexes(); + if (selected == null || selected.length == 0) { + throw new FailedLoginException("Nothing selected"); + } + + if (selected[0] != 0) { + throw new FailedLoginException("Wrong choice: " + selected[0]); + } + + // check confirmation + if (confirmation.getSelectedIndex() != ConfirmationCallback.YES) { + throw new FailedLoginException("Not confirmed: " + + confirmation.getSelectedIndex()); + } + + loginSucceeded = true; + System.out.println("CustomLoginModule: authentication succeeded"); + return true; + } + + /* + * This method is called if the LoginContext's overall authentication + * succeeded. + */ + @Override + public boolean commit() throws LoginException { + if (loginSucceeded) { + // add a Principal to the Subject + Principal principal = new TestPrincipal(username); + if (!subject.getPrincipals().contains(principal)) { + subject.getPrincipals().add(principal); + } + return true; + } + + return false; + } + + /* + * This method is called if the LoginContext's overall authentication + * failed. + */ + @Override + public boolean abort() throws LoginException { + loginSucceeded = false; + return true; + } + + /* + * Logout the user. + */ + @Override + public boolean logout() throws LoginException { + loginSucceeded = false; + boolean removed = subject.getPrincipals().remove( + new TestPrincipal(username)); + if (!removed) { + throw new LoginException("Coundn't remove a principal: " + + username); + } + return true; + } + + static class TestPrincipal implements Principal { + + private final String name; + + public TestPrincipal(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return("TestPrincipal [name =" + name + "]"); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof TestPrincipal)) { + return false; + } + TestPrincipal other = (TestPrincipal) o; + return name != null ? name.equals(other.name) : other.name == null; + } + } + + static class CustomCallback implements Callback {} +} diff --git a/jdk/test/javax/security/auth/login/LoginContext/SharedState.java b/jdk/test/javax/security/auth/login/LoginContext/SharedState.java new file mode 100644 index 00000000000..d944e5a46db --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/SharedState.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +/** + * @test + * @bug 8048138 + * @summary Check if shared state is passed to login module + * @run main/othervm SharedState + */ +public class SharedState { + + static final String NAME = "name"; + static final String VALUE = "shared"; + + public static void main(String[] args) throws LoginException { + System.setProperty("java.security.auth.login.config", + System.getProperty("test.src") + + System.getProperty("file.separator") + + "shared.config"); + + new LoginContext("SharedState").login(); + } + + public static abstract class Module implements LoginModule { + + @Override + public boolean login() throws LoginException { + return true; + } + + @Override + public boolean commit() throws LoginException { + return true; + } + + @Override + public boolean abort() throws LoginException { + return true; + } + + @Override + public boolean logout() throws LoginException { + return true; + } + } + + public static class FirstModule extends Module { + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + ((Map)sharedState).put(NAME, VALUE); + } + + } + + public static class SecondModule extends Module { + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) { + // check shared object + Object shared = sharedState.get(NAME); + if (!VALUE.equals(shared)) { + throw new RuntimeException("Unexpected shared object: " + + shared); + } + } + + } +} diff --git a/jdk/test/javax/security/auth/login/LoginContext/StandardCallbacks.java b/jdk/test/javax/security/auth/login/LoginContext/StandardCallbacks.java new file mode 100644 index 00000000000..4b69f84cdbf --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/StandardCallbacks.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Principal; +import java.util.Arrays; +import java.util.Locale; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.ChoiceCallback; +import javax.security.auth.callback.ConfirmationCallback; +import javax.security.auth.callback.LanguageCallback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.TextInputCallback; +import javax.security.auth.callback.TextOutputCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 8048138 + * @summary Checks if JAAS login works fine with standard callbacks + * @compile DefaultHandlerModule.java + * @run main/othervm StandardCallbacks + */ +public class StandardCallbacks { + + private static final String USERNAME = "username"; + private static final char[] PASSWORD = "password".toCharArray(); + + public static void main(String[] args) throws LoginException { + System.setProperty("java.security.auth.login.config", + System.getProperty("test.src") + + System.getProperty("file.separator") + + "custom.config"); + + CustomCallbackHandler handler = new CustomCallbackHandler(USERNAME); + LoginContext context = new LoginContext("StandardCallbacks", handler); + + handler.setPassword(PASSWORD); + System.out.println("Try to login with correct password, " + + "successful authentication is expected"); + context.login(); + System.out.println("Authentication succeeded!"); + + Subject subject = context.getSubject(); + System.out.println("Authenticated user has the following principals [" + + subject.getPrincipals().size() + " ]:"); + boolean found = true; + for (Principal principal : subject.getPrincipals()) { + System.out.println("principal: " + principal); + if (principal instanceof CustomLoginModule.TestPrincipal) { + CustomLoginModule.TestPrincipal testPrincipal = + (CustomLoginModule.TestPrincipal) principal; + if (USERNAME.equals(testPrincipal.getName())) { + System.out.println("Found test principal: " + + testPrincipal); + found = true; + break; + } + } + } + + if (!found) { + throw new RuntimeException("TestPrincipal not found"); + } + + // check if all expected text output callbacks have been called + if (!handler.info) { + throw new RuntimeException("TextOutputCallback.INFO not called"); + } + + if (!handler.warning) { + throw new RuntimeException("TextOutputCallback.WARNING not called"); + } + + if (!handler.error) { + throw new RuntimeException("TextOutputCallback.ERROR not called"); + } + + System.out.println("Authenticated user has the following public " + + "credentials [" + subject.getPublicCredentials().size() + + "]:"); + subject.getPublicCredentials().stream(). + forEach((o) -> { + System.out.println("public credential: " + o); + }); + + context.logout(); + + System.out.println("Test passed"); + } + + private static class CustomCallbackHandler implements CallbackHandler { + + private final String username; + private char[] password; + private boolean info = false; + private boolean warning = false; + private boolean error = false; + + CustomCallbackHandler(String username) { + this.username = username; + } + + void setPassword(char[] password) { + this.password = password; + } + + @Override + public void handle(Callback[] callbacks) + throws UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof TextOutputCallback) { + TextOutputCallback toc = (TextOutputCallback) callback; + switch (toc.getMessageType()) { + case TextOutputCallback.INFORMATION: + System.out.println("INFO: " + toc.getMessage()); + info = true; + break; + case TextOutputCallback.ERROR: + System.out.println("ERROR: " + toc.getMessage()); + error = true; + break; + case TextOutputCallback.WARNING: + System.out.println("WARNING: " + toc.getMessage()); + warning = true; + break; + default: + throw new UnsupportedCallbackException(toc, + "Unsupported message type: " + + toc.getMessageType()); + } + } else if (callback instanceof TextInputCallback) { + TextInputCallback tic = (TextInputCallback) callback; + System.out.println(tic.getPrompt()); + tic.setText(CustomLoginModule.HELLO); + } else if (callback instanceof LanguageCallback) { + LanguageCallback lc = (LanguageCallback) callback; + lc.setLocale(Locale.GERMANY); + } else if (callback instanceof ConfirmationCallback) { + ConfirmationCallback cc = (ConfirmationCallback) callback; + System.out.println(cc.getPrompt()); + cc.setSelectedIndex(ConfirmationCallback.YES); + } else if (callback instanceof ChoiceCallback) { + ChoiceCallback cc = (ChoiceCallback) callback; + System.out.println(cc.getPrompt() + + Arrays.toString(cc.getChoices())); + cc.setSelectedIndex(0); + } else if (callback instanceof NameCallback) { + NameCallback nc = (NameCallback) callback; + System.out.println(nc.getPrompt()); + nc.setName(username); + } else if (callback instanceof PasswordCallback) { + PasswordCallback pc = (PasswordCallback) callback; + System.out.println(pc.getPrompt()); + pc.setPassword(password); + } else { + throw new UnsupportedCallbackException(callback, + "Unknown callback"); + } + } + } + + } + +} diff --git a/jdk/test/javax/security/auth/login/LoginContext/custom.config b/jdk/test/javax/security/auth/login/LoginContext/custom.config new file mode 100644 index 00000000000..6ecdc56e928 --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/custom.config @@ -0,0 +1,4 @@ +StandardCallbacks { + DefaultHandlerModule required; + CustomLoginModule required username="username" password="password"; +}; diff --git a/jdk/test/javax/security/auth/login/LoginContext/shared.config b/jdk/test/javax/security/auth/login/LoginContext/shared.config new file mode 100644 index 00000000000..86201e22435 --- /dev/null +++ b/jdk/test/javax/security/auth/login/LoginContext/shared.config @@ -0,0 +1,4 @@ +SharedState { + SharedState$FirstModule required; + SharedState$SecondModule required; +}; \ No newline at end of file diff --git a/jdk/test/javax/swing/GroupLayout/8013566/bug8013566.java b/jdk/test/javax/swing/GroupLayout/8013566/bug8013566.java new file mode 100644 index 00000000000..886da012d8a --- /dev/null +++ b/jdk/test/javax/swing/GroupLayout/8013566/bug8013566.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8013566 + @summary Failure of GroupLayout in combination of addPreferredGap and addGroup's + last row + @author Semyon Sadetsky +*/ + +import javax.swing.*; + +public class bug8013566 { + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final JFrame frame = new JFrame(); + try { + frame.setUndecorated(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + test(frame); + + + } finally { + frame.dispose(); + } + } + }); + + System.out.println("ok"); + } + + static void test(JFrame frame) { + JComponent c1 = new JButton("Label1"); + JComponent c2 = new JButton("Label22"); + JComponent c3 = new JButton("Label333"); + + JPanel panel = new JPanel(); + GroupLayout layout = new GroupLayout(panel); + layout.setAutoCreateContainerGaps(true); + layout.setAutoCreateGaps(true); + panel.setLayout(layout); + + layout.setHorizontalGroup(layout.createSequentialGroup().addGroup( + layout.createParallelGroup().addGroup( + layout.createSequentialGroup().addComponent(c1) + .addPreferredGap( + LayoutStyle.ComponentPlacement.RELATED, + 50, 200)) + .addComponent(c2)).addComponent(c3)); + + layout.setVerticalGroup(layout.createSequentialGroup() + .addComponent(c1).addComponent(c2).addComponent(c3) + ); + + frame.setContentPane(panel); + frame.pack(); + frame.setVisible(true); + + if (c3.getX() != c1.getX() + c1.getWidth() + 50) { + throw new RuntimeException( + "Gap between 1st and 3rd component is wrong"); + } + + } +} diff --git a/jdk/test/javax/swing/JInternalFrame/8075314/bug8075314.java b/jdk/test/javax/swing/JInternalFrame/8075314/bug8075314.java new file mode 100644 index 00000000000..a57e787f300 --- /dev/null +++ b/jdk/test/javax/swing/JInternalFrame/8075314/bug8075314.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8075314 + @summary All the InternalFrames will be maximized after maximizing only one + of the InternalFrame with the special options "-client -Xmixed + -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel". + @author Semyon Sadetsky + */ + + +import javax.swing.*; +import java.beans.PropertyVetoException; + +public class bug8075314 { + + + private static JFrame frame; + private static JInternalFrame frame1; + private static JInternalFrame frame2; + + public static void main(String[] args) throws Exception { + for (UIManager.LookAndFeelInfo lookAndFeelInfo : UIManager + .getInstalledLookAndFeels()) { + UIManager.setLookAndFeel(lookAndFeelInfo.getClassName()); + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame = new JFrame(); + frame.setUndecorated(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setup(frame); + } + }); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + try { + frame1.setMaximum(true); + frame1.setClosed(true); + if (frame2.isMaximum()) { + throw new RuntimeException( + "Frame2 is maximized!"); + } + } catch (PropertyVetoException e) { + throw new RuntimeException(e); + } + + } + }); + } finally { + frame.dispose(); + } + } + System.out.println("ok"); + } + + private static void setup(JFrame frame) { + JDesktopPane desktop = new JDesktopPane(); + frame.setContentPane(desktop); + + frame1 = new JInternalFrame("1", true, true, true, true); + frame1.setBounds(40, 40, 300, 200); + frame1.setVisible(true); + desktop.add(frame1); + frame2 = new JInternalFrame("2", true, true, true, true); + frame2.setBounds(20, 20, 300, 200); + frame2.setVisible(true); + desktop.add(frame2); + + frame.setSize(500, 400); + frame.setVisible(true); + } +} diff --git a/jdk/test/javax/swing/JScrollPane/8033000/bug8033000.java b/jdk/test/javax/swing/JScrollPane/8033000/bug8033000.java new file mode 100644 index 00000000000..4e5d23149ab --- /dev/null +++ b/jdk/test/javax/swing/JScrollPane/8033000/bug8033000.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.awt.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import jdk.testlibrary.OSInfo; + +/** + * @test + * @bug 8033000 + * @author Alexander Scherbatiy + * @summary No Horizontal Mouse Wheel Support In BasicScrollPaneUI + * @library ../../../../lib/testlibrary + * @build jdk.testlibrary.OSInfo + * @run main bug8033000 + */ +public class bug8033000 { + + private static JScrollPane scrollPane; + private static JTextArea textArea; + private static Point point; + private static final int delta; + + static { + delta = OSInfo.getOSType().equals(OSInfo.OSType.MACOSX) ? -30 : 30; + } + + public static void main(String[] args) throws Exception { + + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(bug8033000::createAndShowGUI); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(() -> { + Point locationOnScreen = scrollPane.getLocationOnScreen(); + point = new Point( + locationOnScreen.x + scrollPane.getWidth() / 2, + locationOnScreen.y + scrollPane.getHeight() / 2); + }); + + robot.mouseMove(point.x, point.y); + robot.waitForIdle(); + + // vertical scroll bar is enabled + initScrollPane(true, false); + robot.waitForIdle(); + robot.mouseWheel(delta); + robot.waitForIdle(); + checkScrollPane(true); + + // vertical scroll bar is enabled + shift + initScrollPane(true, false); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_SHIFT); + robot.mouseWheel(delta); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.waitForIdle(); + checkScrollPane(true); + + // horizontal scroll bar is enabled + initScrollPane(false, true); + robot.waitForIdle(); + robot.mouseWheel(delta); + robot.waitForIdle(); + checkScrollPane(false); + + // horizontal scroll bar is enabled + shift + initScrollPane(false, true); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_SHIFT); + robot.mouseWheel(delta); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.waitForIdle(); + checkScrollPane(false); + + // both scroll bars are enabled + initScrollPane(true, true); + robot.waitForIdle(); + robot.mouseWheel(delta); + robot.waitForIdle(); + checkScrollPane(true); + + // both scroll bars are enabled + shift + initScrollPane(true, true); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_SHIFT); + robot.mouseWheel(delta); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.waitForIdle(); + checkScrollPane(false); + } + + static void initScrollPane(boolean vVisible, boolean hVisible) throws Exception { + SwingUtilities.invokeAndWait(() -> { + scrollPane.getVerticalScrollBar().setValue(0); + scrollPane.getHorizontalScrollBar().setValue(0); + + textArea.setRows(vVisible ? 100 : 1); + textArea.setColumns(hVisible ? 100 : 1); + scrollPane.getVerticalScrollBar().setVisible(vVisible); + scrollPane.getHorizontalScrollBar().setVisible(hVisible); + }); + } + + static void checkScrollPane(boolean verticalScrolled) throws Exception { + SwingUtilities.invokeAndWait(() -> { + + if (verticalScrolled) { + if (scrollPane.getVerticalScrollBar().getValue() == 0 + || scrollPane.getHorizontalScrollBar().getValue() != 0) { + throw new RuntimeException("Wrong vertical scrolling!"); + } + } else { + if (scrollPane.getVerticalScrollBar().getValue() != 0 + || scrollPane.getHorizontalScrollBar().getValue() == 0) { + throw new RuntimeException("Wrong horizontal scrolling!"); + } + } + }); + } + + static void createAndShowGUI() { + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(300, 300); + textArea = new JTextArea("Hello World!"); + scrollPane = new JScrollPane(textArea); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(scrollPane, BorderLayout.CENTER); + frame.getContentPane().add(panel); + frame.setVisible(true); + } +} diff --git a/jdk/test/javax/swing/JTable/6894632/bug6894632.java b/jdk/test/javax/swing/JTable/6894632/bug6894632.java new file mode 100644 index 00000000000..07cf5960605 --- /dev/null +++ b/jdk/test/javax/swing/JTable/6894632/bug6894632.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 6894632 + @summary Removing rows from a DefaultTableModel with a RowSorter deselectes + last row + @author Semyon Sadetsky +*/ + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; +import java.util.ArrayList; +import java.util.List; + +public class bug6894632 { + private static JTable table; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + + //init table with empty sort order + test(new ArrayList()); + + //init table as unsorted + List sortKeys = new ArrayList<>(); + sortKeys.add(0, new RowSorter.SortKey(0, SortOrder.UNSORTED)); + test(sortKeys); + } + }); + + System.out.println("ok"); + } + + static void test(final List sortKeys) { + final JFrame frame = new JFrame(); + try { + frame.setUndecorated(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + table = new JTable(); + DefaultTableModel tableModel = + new DefaultTableModel(10, 1) { + public Object getValueAt(int row, int column) { + return row == getRowCount() - 1 ? row + "==last" : + row; + } + }; + table.setModel(tableModel); + TableRowSorter sorter = + new TableRowSorter(tableModel); + sorter.setSortKeys(sortKeys); + table.setRowSorter(sorter); + + frame.setContentPane(table); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + int lastRow = table.getRowCount() - 1; + + //select last row + table.setRowSelectionInterval(lastRow, lastRow); + + //remove row above the last + tableModel.removeRow(lastRow - 1); + lastRow = table.getRowCount() - 1; + if (lastRow != table.getSelectedRow()) { + throw new RuntimeException("last row must be still selected"); + } + + //sort table + sortKeys.clear(); + sortKeys.add(0, new RowSorter.SortKey(0, SortOrder.ASCENDING)); + sorter.setSortKeys(sortKeys); + //remove row above the last + lastRow = table.getRowCount() - 1; + tableModel.removeRow(lastRow - 1); + + if (!table.getValueAt(table.getSelectedRow(), 0).toString() + .endsWith("==last")) { + throw new RuntimeException( + "row ends with \"==last\" row must be still selected"); + } + + //make table unsorted again + sortKeys.clear(); + sortKeys.add(0, new RowSorter.SortKey(0, SortOrder.UNSORTED)); + sorter.setSortKeys(sortKeys); + //remove row above the last + lastRow = table.getRowCount() - 1; + tableModel.removeRow(lastRow - 1); + + lastRow = table.getRowCount() - 1; + if (lastRow != table.getSelectedRow()) { + throw new RuntimeException( + "last row must be still selected"); + } + } finally { + frame.dispose(); + } + } + + +} diff --git a/jdk/test/javax/swing/plaf/nimbus/8041642/bug8041642.java b/jdk/test/javax/swing/plaf/nimbus/8041642/bug8041642.java new file mode 100644 index 00000000000..4ed00df642d --- /dev/null +++ b/jdk/test/javax/swing/plaf/nimbus/8041642/bug8041642.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8041642 + @summary Incorrect paint of JProgressBar in Nimbus LF + @author Semyon Sadetsky +*/ + +import javax.swing.*; +import java.awt.*; + +public class bug8041642 { + + private static JFrame frame; + private static Point point; + private static JProgressBar bar; + + public static void main(String[] args) throws Exception { + for (UIManager.LookAndFeelInfo info : UIManager + .getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + try { + UIManager.setLookAndFeel(info.getClassName()); + } catch (Exception ex) { + } + break; + } + } + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame = new JFrame(); + frame.setUndecorated(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setup(frame); + } + }); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + point = bar.getLocationOnScreen(); + } + }); + final Robot robot = new Robot(); + Color color = robot.getPixelColor(point.x + 1, point.y + 7); + System.out.println(color); + if (color.getGreen() < 150 || color.getBlue() > 30 || + color.getRed() > 200) { + throw new RuntimeException("Bar padding color should be green"); + } + + } finally { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + //frame.dispose(); + } + }); + } + + System.out.println("ok"); + } + + static void setup(JFrame frame) { + bar = new JProgressBar(); + bar.setBackground(Color.WHITE); + bar.setValue(2); + frame.getContentPane().add(bar, BorderLayout.NORTH); + frame.getContentPane().setBackground(Color.GREEN); + frame.setSize(200, 150); + frame.setLocation(100, 100); + frame.setVisible(true); + } +} diff --git a/jdk/test/javax/swing/plaf/windows/6921687/bug6921687.java b/jdk/test/javax/swing/plaf/windows/6921687/bug6921687.java new file mode 100644 index 00000000000..d8ad4069bbf --- /dev/null +++ b/jdk/test/javax/swing/plaf/windows/6921687/bug6921687.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 6921687 + @summary Mnemonic disappears after repeated attempts to open menu items using + mnemonics + @author Semyon Sadetsky + @library /lib/testlibrary + @build jdk.testlibrary.OSInfo + */ + + +import jdk.testlibrary.OSInfo; +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + + +public class bug6921687 { + + private static Class lafClass; + private static JFrame frame; + + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + System.out.println("Only Windows platform test. Test is skipped."); + System.out.println("ok"); + return; + } + lafClass = Class.forName(UIManager.getSystemLookAndFeelClassName()); + UIManager.setLookAndFeel((LookAndFeel) lafClass.newInstance()); + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame = new JFrame(); + frame.setUndecorated(true); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setup(frame); + } + }); + + final Robot robot = new Robot(); + robot.setAutoDelay(20); + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F); + robot.keyRelease(KeyEvent.VK_F); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + checkMnemonics(); + + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_ALT); + robot.waitForIdle(); + checkMnemonics(); + System.out.println("ok"); + } finally { + frame.dispose(); + } + + } + + private static void checkMnemonics() throws Exception { + if ((Boolean) lafClass.getMethod("isMnemonicHidden").invoke(lafClass)) { + throw new RuntimeException("Mnemonics are hidden"); + } + } + + private static void setup(JFrame frame) { + JMenuBar menuBar = new JMenuBar(); + frame.setJMenuBar(menuBar); + + // First Menu, F - Mnemonic + JMenu firstMenu = new JMenu("First Menu"); + firstMenu.setMnemonic(KeyEvent.VK_F); + firstMenu.add(new JMenuItem("One", KeyEvent.VK_O)); + firstMenu.add(new JMenuItem("Two", KeyEvent.VK_T)); + menuBar.add(firstMenu); + + // Second Menu, S - Mnemonic + JMenu secondMenu = new JMenu("Second Menu"); + secondMenu.setMnemonic(KeyEvent.VK_S); + secondMenu.add(new JMenuItem("A Menu Item", KeyEvent.VK_A)); + menuBar.add(secondMenu); + + frame.setSize(350, 250); + frame.setVisible(true); + + } +} \ No newline at end of file diff --git a/jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java b/jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java index 1edd3c23907..7617cfd9def 100644 --- a/jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java +++ b/jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,57 +23,83 @@ /* * @test - * @bug 8046817 - * @summary schemagen fails to generate xsd for enum types + * @bug 8046817 8073357 + * @summary schemagen fails to generate xsd for enum types. + * Check that order of Enum values is preserved. * @run main/othervm GenerateEnumSchema */ import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Scanner; +import java.util.stream.Collectors; public class GenerateEnumSchema { private static final String SCHEMA_OUTPUT_FILENAME = "schema1.xsd"; private static final File schemaOutputFile = new File(SCHEMA_OUTPUT_FILENAME); + private static final String[] expectedEnums = { + "\"FIRST\"", "\"ONE\"", "\"TWO\"", "\"THREE\"", + "\"FOUR\"", "\"FIVE\"", "\"SIX\"", "\"LAST\""}; + private static String schemaContent = ""; + + public static void main(String[] args) throws Exception { - public static void main(String[] args) throws Exception, IOException { //Check schema generation for class type runSchemaGen("TestClassType.java"); checkIfSchemaGenerated(); + readSchemaContent(); checkSchemaContent(""); checkSchemaContent(""); - schemaOutputFile.delete(); + //Check schema generation for enum type runSchemaGen("TestEnumType.java"); checkIfSchemaGenerated(); + readSchemaContent(); + //Check if Enum type schema is generated checkSchemaContent(""); - checkSchemaContent(""); - checkSchemaContent(""); - checkSchemaContent(""); + //Check the sequence of enum values order + checkEnumOrder(); schemaOutputFile.delete(); } + // Check if schema file successfully generated by schemagen private static void checkIfSchemaGenerated() { if (!schemaOutputFile.exists()) { throw new RuntimeException("FAIL:" + SCHEMA_OUTPUT_FILENAME + " was not generated by schemagen tool"); } } - private static void checkSchemaContent(String exp_token) throws FileNotFoundException { - System.out.print("Check if generated schema contains '" + exp_token + "' string: "); - try (Scanner scanner = new Scanner(schemaOutputFile)) { - if (scanner.findWithinHorizon(exp_token, 0) != null) { - System.out.println("OK"); - return; - } + //Read schema content from file + private static void readSchemaContent() throws Exception { + schemaContent = Files.lines(schemaOutputFile.toPath()).collect(Collectors.joining("")); + } + + // Check if schema file contains specific string + private static void checkSchemaContent(String expContent) { + System.out.print("Check if generated schema contains '" + expContent + "' string: "); + if (schemaContent.contains(expContent)) { + System.out.println("OK"); + return; } System.out.println("FAIL"); - throw new RuntimeException("The '" + exp_token + "' is not found in generated schema"); + throw new RuntimeException("The '" + expContent + "' is not found in generated schema"); + } + // Check if the generated schema contains all enum constants + // and their order is preserved + private static void checkEnumOrder() throws Exception { + int prevElem = -1; + for (String elem : expectedEnums) { + int curElem = schemaContent.indexOf(elem); + System.out.println(elem + " position = " + curElem); + if (curElem < prevElem) { + throw new RuntimeException("FAIL: Enum values order is incorrect or " + elem + " element is not found"); + } + prevElem = curElem; + } } private static String getClassFilePath(String filename) { diff --git a/jdk/test/javax/xml/ws/8046817/TestEnumType.java b/jdk/test/javax/xml/ws/8046817/TestEnumType.java index 785fb191c02..728e1b7187f 100644 --- a/jdk/test/javax/xml/ws/8046817/TestEnumType.java +++ b/jdk/test/javax/xml/ws/8046817/TestEnumType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,5 +25,5 @@ import javax.xml.bind.annotation.XmlEnum; @XmlEnum(String.class) public enum TestEnumType { - ONE, TWO, THREE + FIRST, ONE, TWO, THREE, FOUR, FIVE, SIX, LAST } diff --git a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh index a74fdd63622..f4cd49e2c66 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ # @library /lib/testlibrary # @build jdk.testlibrary.* TestLogger Utils RmiBootstrapTest # @run shell/timeout=300 RmiSslBootstrapTest.sh +# @ignore 8077924 # Define the Java class test name TESTCLASS="RmiBootstrapTest" diff --git a/jdk/test/sun/security/krb5/auto/SSL.java b/jdk/test/sun/security/krb5/auto/SSL.java index db7aae88bd4..f3d7f134a11 100644 --- a/jdk/test/sun/security/krb5/auto/SSL.java +++ b/jdk/test/sun/security/krb5/auto/SSL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,11 +39,10 @@ * @run main/othervm SSL TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */ import java.io.*; -import java.net.InetAddress; -import java.security.AccessControlException; import java.security.Permission; import javax.net.ssl.*; import java.security.Principal; +import java.security.Security; import java.util.Date; import java.util.List; import java.util.ArrayList; @@ -82,6 +81,9 @@ public class SSL extends SecurityManager { } public static void main(String[] args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.tls.disabledAlgorithms", ""); krb5Cipher = args[0]; diff --git a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java index ae5091e0b09..4ec23743b2a 100644 --- a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java +++ b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ import javax.net.ssl.*; public class CipherTest { // use any available port for the server socket - static int serverPort = 0; + static volatile int serverPort = 0; final int THREADS; diff --git a/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java b/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java index 0d1002b5834..af8d4b5a088 100644 --- a/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java +++ b/jdk/test/sun/security/pkcs11/sslecc/JSSEServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ class JSSEServer extends CipherTest.Server { serverContext.init(new KeyManager[] {cipherTest.keyManager}, new TrustManager[] {cipherTest.trustManager}, cipherTest.secureRandom); SSLServerSocketFactory factory = (SSLServerSocketFactory)serverContext.getServerSocketFactory(); - serverSocket = (SSLServerSocket)factory.createServerSocket(cipherTest.serverPort); + serverSocket = (SSLServerSocket)factory.createServerSocket(0); cipherTest.serverPort = serverSocket.getLocalPort(); serverSocket.setEnabledCipherSuites(factory.getSupportedCipherSuites()); serverSocket.setWantClientAuth(true); diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/BuildPath.java b/jdk/test/sun/security/provider/certpath/ReverseBuilder/BuildPath.java deleted file mode 100644 index 28ff643bd64..00000000000 --- a/jdk/test/sun/security/provider/certpath/ReverseBuilder/BuildPath.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @bug 6511784 - * @summary Make sure that building a path to a CRL issuer works in the - * reverse direction - * @library ../../../../../java/security/testlibrary - * @build CertUtils - * @run main BuildPath - */ -import java.security.cert.*; -import java.util.Collections; -import sun.security.provider.certpath.SunCertPathBuilderParameters; - -public class BuildPath { - - public static void main(String[] args) throws Exception { - - TrustAnchor anchor = - new TrustAnchor(CertUtils.getCertFromFile("mgrM2mgrM"), null); - X509Certificate target = CertUtils.getCertFromFile("mgrM2leadMA"); - X509CertSelector xcs = new X509CertSelector(); - xcs.setSubject("CN=leadMA,CN=mgrM,OU=prjM,OU=divE,OU=Comp,O=sun,C=us"); - xcs.setCertificate(target); - SunCertPathBuilderParameters params = - new SunCertPathBuilderParameters(Collections.singleton(anchor),xcs); - params.setBuildForward(false); - CertStore cs = CertUtils.createStore(new String[] - {"mgrM2prjM", "prjM2mgrM", "prjM2divE", "mgrM2leadMA" }); - params.addCertStore(cs); - CertStore cs2 = CertUtils.createCRLStore - (new String[] {"mgrMcrl", "prjMcrl"}); - params.addCertStore(cs2); - PKIXCertPathBuilderResult res = CertUtils.build(params); - } -} diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/ReverseBuild.java b/jdk/test/sun/security/provider/certpath/ReverseBuilder/ReverseBuild.java deleted file mode 100644 index abb18ebd439..00000000000 --- a/jdk/test/sun/security/provider/certpath/ReverseBuilder/ReverseBuild.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// -// Security properties, once set, cannot revert to unset. To avoid -// conflicts with tests running in the same VM isolate this test by -// running it in otherVM mode. -// - -/* - * @test - * @bug 7167988 - * @summary PKIX CertPathBuilder in reverse mode doesn't work if more than - * one trust anchor is specified - * @run main/othervm ReverseBuild - */ -import java.io.*; -import java.util.*; -import java.security.cert.*; -import java.security.Security; - -import sun.security.provider.certpath.SunCertPathBuilderParameters; - -public class ReverseBuild { - // Certificate information: - // Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org - // Validity - // Not Before: Dec 8 02:43:36 2008 GMT - // Not After : Aug 25 02:43:36 2028 GMT - // Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org - // X509v3 Subject Key Identifier: - // FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14 - // X509v3 Authority Key Identifier: - // keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14 - // DirName:/C=US/ST=Some-State/L=Some-City/O=Some-Org - // serial:00 - static String NoiceTrusedCertStr = - "-----BEGIN CERTIFICATE-----\n" + - "MIICrDCCAhWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" + - "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" + - "EwhTb21lLU9yZzAeFw0wODEyMDgwMjQzMzZaFw0yODA4MjUwMjQzMzZaMEkxCzAJ\n" + - "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" + - "dHkxETAPBgNVBAoTCFNvbWUtT3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n" + - "gQDLxDggB76Ip5OwoUNRLdeOha9U3a2ieyNbz5kTU5lFfe5tui2/461uPZ8a+QOX\n" + - "4BdVrhEmV94BKY4FPyH35zboLjfXSKxT1mAOx1Bt9sWF94umxZE1cjyU7vEX8HHj\n" + - "7BvOyk5AQrBt7moO1uWtPA/JuoJPePiJl4kqlRJM2Akq6QIDAQABo4GjMIGgMB0G\n" + - "A1UdDgQWBBT6uVG/TOfZhpgz+efLHvEzSfeoFDBxBgNVHSMEajBogBT6uVG/TOfZ\n" + - "hpgz+efLHvEzSfeoFKFNpEswSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUt\n" + - "U3RhdGUxEjAQBgNVBAcTCVNvbWUtQ2l0eTERMA8GA1UEChMIU29tZS1PcmeCAQAw\n" + - "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBcIm534U123Hz+rtyYO5uA\n" + - "ofd81G6FnTfEAV8Kw9fGyyEbQZclBv34A9JsFKeMvU4OFIaixD7nLZ/NZ+IWbhmZ\n" + - "LovmJXyCkOufea73pNiZ+f/4/ScZaIlM/PRycQSqbFNd4j9Wott+08qxHPLpsf3P\n" + - "6Mvf0r1PNTY2hwTJLJmKtg==\n" + - "-----END CERTIFICATE-----"; - - // Certificate information: - // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce - // Validity - // Not Before: Aug 19 01:52:19 2011 GMT - // Not After : Jul 29 01:52:19 2032 GMT - // Subject: C=US, O=Java, OU=SunJSSE Test Serivce - - // X509v3 Subject Key Identifier: - // B9:7C:D5:D9:DF:A7:4C:03:AE:FD:0E:27:5B:31:95:6C:C7:F3:75:E1 - // X509v3 Authority Key Identifier: - // keyid:B9:7C:D5:D9:DF:A7:4C:03:AE:FD:0E:27:5B:31:95:6C:C7:F3:75:E1 - // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce - // serial:00 - static String NoiceTrusedCertStr_2nd = - "-----BEGIN CERTIFICATE-----\n" + - "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + - "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + - "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + - "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + - "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" + - "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" + - "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" + - "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" + - "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" + - "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + - "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + - "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" + - "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" + - "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" + - "-----END CERTIFICATE-----"; - - - // Certificate information: - // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce - // Validity - // Not Before: May 5 02:40:50 2012 GMT - // Not After : Apr 15 02:40:50 2033 GMT - // Subject: C=US, O=Java, OU=SunJSSE Test Serivce - // X509v3 Subject Key Identifier: - // DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B - // X509v3 Authority Key Identifier: - // keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B - // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce - // serial:00 - static String trustedCertStr = - "-----BEGIN CERTIFICATE-----\n" + - "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" + - "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + - "MTIwNTA1MDI0MDUwWhcNMzMwNDE1MDI0MDUwWjA7MQswCQYDVQQGEwJVUzENMAsG\n" + - "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + - "KoZIhvcNAQEBBQADgY0AMIGJAoGBANtiq0AIJK+iVRwFrqcD7fYXTCbMYC5Qz/k6\n" + - "AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwvzuURbc9+paOBWeHbN+Sc\n" + - "x3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStFhSHXATjtdbskNOAYGLTV\n" + - "x8uEy9GbAgMBAAGjgaUwgaIwHQYDVR0OBBYEFN1OjSoRwIMD8Kzror/58n3IaR+b\n" + - "MGMGA1UdIwRcMFqAFN1OjSoRwIMD8Kzror/58n3IaR+boT+kPTA7MQswCQYDVQQG\n" + - "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + - "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" + - "BQADgYEAjjkJesQrkbr36N40egybaIxw7RcqT6iy5fkAGS1JYlBDk8uSCK1o6bCH\n" + - "ls5EpYcGeEoabSS73WRdkO1lgeyWDduO4ef8cCCSpmpT6/YdZG0QS1PtcREeVig+\n" + - "Zr25jNemS4ADHX0aaXP4kiV/G80cR7nX5t5XCUm4bYdbwM07NgI=\n" + - "-----END CERTIFICATE-----"; - static String trustedPrivateKey = // Private key in the format of PKCS#8 - "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANtiq0AIJK+iVRwF\n" + - "rqcD7fYXTCbMYC5Qz/k6AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwv\n" + - "zuURbc9+paOBWeHbN+Scx3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStF\n" + - "hSHXATjtdbskNOAYGLTVx8uEy9GbAgMBAAECgYEA2VjHkIiA0ABjkX+PqKeb+VLb\n" + - "fxS7tSca5C8zfdRhLxAWRui0/3ihst0eCJNrBDuxvAOACovsDWyLuaUjtI2v2ysz\n" + - "vz6SPyGy82PhQOFzyKQuQ814N6EpothpiZzF0yFchfKIGhUsdY89UrGs9nM7m6NT\n" + - "rztYvgIu4avg2VPR2AECQQD+pFAqipR2BplQRIuuRSZfHRxvoEyDjT1xnHJsC6WP\n" + - "I5hCLghL91MhQGWbP4EJMKYQOTRVukWlcp2Kycpf+P5hAkEA3I43gmVUAPEdyZdY\n" + - "fatW7OaLlbbYJb6qEtpCZ1Rwe/BIvm6H6E3qSi/lpz7Ia7WDulpbF6BawHH3pRFq\n" + - "CUY5ewJBAP3pUDqrRpBN0jB0uSeDslhjSciQ+dqvSpZv3rSYBHUvlBJhnkpJiy37\n" + - "7ZUZhIxqYxyIPgRBolLwb+FFh7OdL+ECQCtldDic9WVmC+VheRDpCKZ+SlK/8lGi\n" + - "7VXeShiIvcU1JysJFoa35fSI7hf1O3wt7+hX5PqGG7Un94EsJwACKEcCQQC1TWt6\n" + - "ArKH6tRxKjOxFtqfs8fgEVYUaOr3j1jF4KBUuX2mtQtddZe3VfJ2wPsuKMMxmhkB\n" + - "e7xWWZnJsErt2e+E"; - - // Certificate information: - // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce - // Validity - // Not Before: May 5 02:40:53 2012 GMT - // Not After : Jan 21 02:40:53 2032 GMT - // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner - // X509v3 Subject Key Identifier: - // 13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A - // X509v3 Authority Key Identifier: - // keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B - // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce - // serial:00 - static String caSignerStr = - "-----BEGIN CERTIFICATE-----\n" + - "MIICqDCCAhGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + - "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + - "MTIwNTA1MDI0MDUzWhcNMzIwMTIxMDI0MDUzWjBOMQswCQYDVQQGEwJVUzENMAsG\n" + - "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAPBgNV\n" + - "BAMTCGNhc2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+x8+o7oM0\n" + - "ct/LZmZLXBL4CQ8jrULD5P7NtEW0hg/zxBFZfBHf+44Oo2eMPYZj+7xaREOH5BmV\n" + - "KRYlzRtONAaC5Ng4Mrm5UKNPcMIIUjUOvm7vWM4oSTMSfoEcSX+vp99uUAkw3w7Z\n" + - "+frYDm1M4At/j0b+lLij71GFN2L8drpgPQIDAQABo4GoMIGlMB0GA1UdDgQWBBQT\n" + - "B+ARB9vrMyOHMdDbfhZWvhGQCjBjBgNVHSMEXDBagBTdTo0qEcCDA/Cs66K/+fJ9\n" + - "yGkfm6E/pD0wOzELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsT\n" + - "FFN1bkpTU0UgVGVzdCBTZXJpdmNlggEAMBIGA1UdEwEB/wQIMAYBAf8CAQEwCwYD\n" + - "VR0PBAQDAgEGMA0GCSqGSIb3DQEBBAUAA4GBAI+LXA/UCPkTANablUkt80JNPWsl\n" + - "pS4XLNgPxWaN0bkRDs5oI4ooWAz1rwpeJ/nfetOvWlpmrVjSeovBFja5Hl+dUHTf\n" + - "VfuyzkxXbhuNiJIpo1mVBpNsjwu9YRxuwX6UA2LTUQpgvtVJEE012x3zRvxBCbu2\n" + - "Y/v1R5fZ4c+hXDfC\n" + - "-----END CERTIFICATE-----"; - static String caSignerPrivateKey = // Private key in the format of PKCS#8 - "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL7Hz6jugzRy38tm\n" + - "ZktcEvgJDyOtQsPk/s20RbSGD/PEEVl8Ed/7jg6jZ4w9hmP7vFpEQ4fkGZUpFiXN\n" + - "G040BoLk2DgyublQo09wwghSNQ6+bu9YzihJMxJ+gRxJf6+n325QCTDfDtn5+tgO\n" + - "bUzgC3+PRv6UuKPvUYU3Yvx2umA9AgMBAAECgYBYvu30cW8LONyt62Zua9hPFTe7\n" + - "qt9B7QYyfkdmoG5PQMepTrOp84SzfoOukvgvDm0huFuJnSvhXQl2cCDhkgXskvFj\n" + - "Hh7KBCFViVXokGdq5YoS0/KYMyQV0TZfJUvILBl51uc4/siQ2tClC/N4sa+1JhgW\n" + - "a6dFGfRjiUKSSlmMwQJBAPWpIz3Q/c+DYMvoQr5OD8EaYwYIevlTdXb97RnJJh2b\n" + - "UnhB9jrqesJiHYVzPmP0ukyPOXOwlp2T5Am4Kw0LFOkCQQDGz150NoHOp28Mvyc4\n" + - "CTqz/zYzUhy2eCJESl196uyP4N65Y01VYQ3JDww4DlsXiU17tVSbgA9TCcfTYOzy\n" + - "vyw1AkARUky+1hafZCcWGZljK8PmnMKwsTZikCTvL/Zg5BMA8Wu+OQBwpQnk3OAy\n" + - "Aa87gw0DyvGFG8Vy9POWT9sRP1/JAkBqP0hrMvYMSs6+MSn0eHo2151PsAJIQcuO\n" + - "U2/Da1khSzu8N6WMi2GiobgV/RYRbf9KrY2ZzMZjykZQYOxAjopBAkEAghCu38cN\n" + - "aOsW6ueo24uzsWI1FTdE+qWNVEi3RSP120xXBCyhaBjIq4WVSlJK9K2aBaJpit3j\n" + - "iQ5tl6zrLlxQhg=="; - - // Certificate information: - // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner - // Validity - // Not Before: May 5 02:40:57 2012 GMT - // Not After : Jan 21 02:40:57 2032 GMT - // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer - // X509v3 Subject Key Identifier: - // 39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8 - // X509v3 Authority Key Identifier: - // keyid:13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A - // DirName:/C=US/O=Java/OU=SunJSSE Test Serivce - // serial:02 - static String certIssuerStr = - "-----BEGIN CERTIFICATE-----\n" + - "MIICvjCCAiegAwIBAgIBAzANBgkqhkiG9w0BAQQFADBOMQswCQYDVQQGEwJVUzEN\n" + - "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAP\n" + - "BgNVBAMTCGNhc2lnbmVyMB4XDTEyMDUwNTAyNDA1N1oXDTMyMDEyMTAyNDA1N1ow\n" + - "UDELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0Ug\n" + - "VGVzdCBTZXJpdmNlMRMwEQYDVQQDEwpjZXJ0aXNzdWVyMIGfMA0GCSqGSIb3DQEB\n" + - "AQUAA4GNADCBiQKBgQCyz55zinU6kNL/LeiTNiBI0QWYmDG0YTotuC4D75liBNqs\n" + - "7Mmladsh2mTtQUAwmuGaGzaZV25a+cUax0DXZoyBwdbTI09u1bUYsZcaUUKbPoCC\n" + - "HH26e4jLFL4olW13Sv4ZAd57tIYevMw+Fp5f4fLPFGegCJTFlv2Qjpmic/cuvQID\n" + - "AQABo4GpMIGmMB0GA1UdDgQWBBQ5DsYzsVC8cwcx5dgE97uXVc+byDBjBgNVHSME\n" + - "XDBagBQTB+ARB9vrMyOHMdDbfhZWvhGQCqE/pD0wOzELMAkGA1UEBhMCVVMxDTAL\n" + - "BgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlggECMBMG\n" + - "A1UdEwEB/wQJMAcBAf8CAgQAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQQFAAOB\n" + - "gQCQTagenCdClT98C+oTJGJrw/dUBD9K3tE6ZJKPMc/2bUia8G5ei1C0eXj4mWG2\n" + - "lu9umR6C90/A6qB050QB2h50qtqxSrkpu+ym1yypauZpg7U3nUY9wZWJNI1vqrQZ\n" + - "pqUMRcXY3iQIVKx+Qj+4/Za1wwFQzpEoGmqRW31V1SdMEw==\n" + - "-----END CERTIFICATE-----"; - static String certIssuerPrivateKey = // Private key in the format of PKCS#8 - "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBALLPnnOKdTqQ0v8t\n" + - "6JM2IEjRBZiYMbRhOi24LgPvmWIE2qzsyaVp2yHaZO1BQDCa4ZobNplXblr5xRrH\n" + - "QNdmjIHB1tMjT27VtRixlxpRQps+gIIcfbp7iMsUviiVbXdK/hkB3nu0hh68zD4W\n" + - "nl/h8s8UZ6AIlMWW/ZCOmaJz9y69AgMBAAECgYEAjtew2tgm4gxDojqIauF4VPM1\n" + - "pzsdqd1p3pAdomNLgrQiBLZ8N7oiph6TNb1EjA+OXc+ThFgF/oM9ZDD8qZZwcvjN\n" + - "qDZlpTkFs2TaGcyEZfUaMB45NHVs6Nn+pSkagSNwwy3xeyAct7sQEzGNTDlEwVv5\n" + - "7V9LQutQtBd6xT48KzkCQQDpNRfv2OFNG/6GtzJoO68oJhpnpl2MsYNi4ntRkre/\n" + - "6uXpiCYaDskcrPMRwOOs0m7mxG+Ev+uKnLnSoEMm1GCbAkEAxEmDtiD0Psb8Z9BL\n" + - "ZRb83Jqho3xe2MCAh3xUfz9b/Mhae9dZ44o4OCgQZuwvW1mczF0NtpgZl93BmYa2\n" + - "hTwHhwJBAKHrEj6ep/fA6x0gD2idoATRR94VfbiU+7NpqtO9ecVP0+gsdr/66hn1\n" + - "3yLBeZLh3MxvMTrLgkAQh1i9m0JXjOcCQQClLXAHHegrw+u3uNMZeKTFR+Lp3sk6\n" + - "AZSnbvr0Me9I45kxSeG81x3ENALJecvIRbrrRws5MvmmkNhQR8rkh8WVAkEAk6b+\n" + - "aVtmBgUaTS5+FFlHGHJY9HFrfT1a1C/dwyMuqlmbC3YsBmZaMOlKli5TXNybLff8\n" + - "5KMeGEpXMzgC7AscGA=="; - - // Certificate information: - // Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer - // Validity - // Not Before: May 5 02:41:01 2012 GMT - // Not After : Jan 21 02:41:01 2032 GMT - // Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=localhost - // X509v3 Subject Key Identifier: - // AD:C0:2C:4C:E4:C2:2E:A1:BB:5D:92:BE:66:E0:4E:E0:0D:2F:11:EF - // X509v3 Authority Key Identifier: - // keyid:39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8 - static String targetCertStr = - "-----BEGIN CERTIFICATE-----\n" + - "MIICjTCCAfagAwIBAgIBBDANBgkqhkiG9w0BAQQFADBQMQswCQYDVQQGEwJVUzEN\n" + - "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEzAR\n" + - "BgNVBAMTCmNlcnRpc3N1ZXIwHhcNMTIwNTA1MDI0MTAxWhcNMzIwMTIxMDI0MTAx\n" + - "WjBPMQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNT\n" + - "RSBUZXN0IFNlcml2Y2UxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0B\n" + - "AQEFAAOBjQAwgYkCgYEAvwaUd7wmBSKqycEstYLWD26vkU08DM39EtaT8wL9HnQ0\n" + - "fgPblwBFI4zdLa2cuYXRZcFUb04N8nrkcpR0D6kkE+AlFAoRWrrZF80B7JTbtEK4\n" + - "1PIeurihXvUT+4MpzGLOojIihMfvM4ufelblD56SInso4WFHm7t4qCln88J1gjkC\n" + - "AwEAAaN4MHYwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBStwCxM5MIuobtdkr5m4E7g\n" + - "DS8R7zAfBgNVHSMEGDAWgBQ5DsYzsVC8cwcx5dgE97uXVc+byDAnBgNVHSUEIDAe\n" + - "BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GB\n" + - "AGfwcfdvEG/nSCiAn2MGbYHp34mgF3OA1SJLWUW0LvWJhwm2cn4AXlSoyvbwrkaB\n" + - "IDDCwhJvvc0vUyL2kTx7sqVaFTq3mDs+ktlB/FfH0Pb+i8FE+g+7T42Iw/j0qxHL\n" + - "YmgbrjBQf5WYN1AvBE/rrPt9aOtS3UsqtVGW574b0shW\n" + - "-----END CERTIFICATE-----"; - static String targetPrivateKey = // Private key in the format of PKCS#8 - "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAL8GlHe8JgUiqsnB\n" + - "LLWC1g9ur5FNPAzN/RLWk/MC/R50NH4D25cARSOM3S2tnLmF0WXBVG9ODfJ65HKU\n" + - "dA+pJBPgJRQKEVq62RfNAeyU27RCuNTyHrq4oV71E/uDKcxizqIyIoTH7zOLn3pW\n" + - "5Q+ekiJ7KOFhR5u7eKgpZ/PCdYI5AgMBAAECf3CscOYvFD3zNMnMJ5LomVqA7w3F\n" + - "gKYM2jlCWAH+wU41PMEXhW6Lujw92jgXL1o+lERwxFzirVdZJWZwKgUSvzP1G0h3\n" + - "fkucq1/UWnToK+8NSXNM/yS8hXbBgSEoJo5f7LKcIi1Ev6doBVofMxs+njzyWKbM\n" + - "Nb7rOLHadghoon0CQQDgQzbzzSN8Dc1YmmylhI5v+0sQRHH0DL7D24k4Weh4vInG\n" + - "EAbt4x8M7ZKEo8/dv0s4hbmNmAnJl93/RRxIyEqLAkEA2g87DiswSQam2pZ8GlrO\n" + - "+w4Qg9mH8uxx8ou2rl0XlHzH1XiTNbkjfY0EZoL7L31BHFk9n11Fb2P85g6ws+Hy\n" + - "ywJAM/xgyLNM/nzUlS128geAXUULaYH0SHaL4isJ7B4rXZGW/mrIsGxtzjlkNYsj\n" + - "rGujrD6TfNc5rZmexIXowJZtcQJBAIww+pCzZ4mrgx5JXWQ8OZHiiu+ZrPOa2+9J\n" + - "r5sOMpi+WGN/73S8oHqZbNjTINZ5OqEVJq8MchWZPQBTNXuQql0CQHEjUzzkCQa3\n" + - "j6JTa2KAdqyvLOx0XF9zcc1gA069uNQI2gPUHS8V215z57f/gMGnDNhVfLs/vMKz\n" + - "sFkVZ3zg7As="; - - - public static void main(String args[]) throws Exception { - // MD5 is used in this test case, don't disable MD5 algorithm. - Security.setProperty( - "jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024"); - - // generate certificate from cert string - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - - // create a set of trust anchors - LinkedHashSet trustAnchors = new LinkedHashSet<>(); - - ByteArrayInputStream is = - new ByteArrayInputStream(NoiceTrusedCertStr.getBytes()); - Certificate trustedCert = cf.generateCertificate(is); - is.close(); - TrustAnchor anchor = - new TrustAnchor((X509Certificate)trustedCert, null); - trustAnchors.add(anchor); - - is = new ByteArrayInputStream(trustedCertStr.getBytes()); - trustedCert = cf.generateCertificate(is); - is.close(); - anchor = new TrustAnchor((X509Certificate)trustedCert, null); - trustAnchors.add(anchor); - - is = new ByteArrayInputStream(NoiceTrusedCertStr_2nd.getBytes()); - trustedCert = cf.generateCertificate(is); - is.close(); - anchor = new TrustAnchor((X509Certificate)trustedCert, null); - trustAnchors.add(anchor); - - // create a list of certificates - List chainList = new ArrayList<>(); - - is = new ByteArrayInputStream(targetCertStr.getBytes()); - Certificate cert = cf.generateCertificate(is); - is.close(); - chainList.add(cert); - - is = new ByteArrayInputStream(certIssuerStr.getBytes()); - cert = cf.generateCertificate(is); - is.close(); - chainList.add(cert); - - is = new ByteArrayInputStream(caSignerStr.getBytes()); - cert = cf.generateCertificate(is); - is.close(); - chainList.add(cert); - - // create a certificate selector - X509CertSelector xcs = new X509CertSelector(); - X509Certificate eeCert = (X509Certificate)chainList.get(0); - xcs.setSubject(eeCert.getSubjectX500Principal()); - - // reverse build - SunCertPathBuilderParameters params = - new SunCertPathBuilderParameters(trustAnchors, xcs); - params.setBuildForward(false); - params.setRevocationEnabled(false); - - CollectionCertStoreParameters ccsp = - new CollectionCertStoreParameters(chainList); - params.addCertStore(CertStore.getInstance("Collection", ccsp)); - - CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX"); - CertPathBuilderResult res = cpb.build(params); - } -} diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2leadMA b/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2leadMA deleted file mode 100644 index ed96b647b7b..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2leadMA and /dev/null differ diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2mgrM b/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2mgrM deleted file mode 100644 index 1953d3e0ba9..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2mgrM and /dev/null differ diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2prjM b/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2prjM deleted file mode 100644 index 7f306ed6f58..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrM2prjM and /dev/null differ diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrMcrl b/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrMcrl deleted file mode 100644 index 0977ea1b91b..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/mgrMcrl and /dev/null differ diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjM2divE b/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjM2divE deleted file mode 100644 index f0e5eddf289..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjM2divE and /dev/null differ diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjM2mgrM b/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjM2mgrM deleted file mode 100644 index 4004685dce2..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjM2mgrM and /dev/null differ diff --git a/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjMcrl b/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjMcrl deleted file mode 100644 index 88fb9d87ebd..00000000000 Binary files a/jdk/test/sun/security/provider/certpath/ReverseBuilder/prjMcrl and /dev/null differ diff --git a/jdk/test/sun/security/ssl/ClientHandshaker/CipherSuiteOrder.java b/jdk/test/sun/security/ssl/ClientHandshaker/CipherSuiteOrder.java index 5276fcba027..6f4a18edc07 100644 --- a/jdk/test/sun/security/ssl/ClientHandshaker/CipherSuiteOrder.java +++ b/jdk/test/sun/security/ssl/ClientHandshaker/CipherSuiteOrder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,7 @@ */ import java.io.*; -import java.net.*; +import java.security.Security; import javax.net.ssl.*; public class CipherSuiteOrder { @@ -196,6 +196,10 @@ public class CipherSuiteOrder { volatile Exception clientException = null; public static void main(String[] args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + String keyFilename = System.getProperty("test.src", "./") + "/" + pathToStores + "/" + keyStoreFile; diff --git a/jdk/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java b/jdk/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java index 5c784b4e9ec..b94381ae629 100644 --- a/jdk/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java +++ b/jdk/test/sun/security/ssl/DHKeyExchange/DHEKeySizing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,10 +102,10 @@ import java.io.*; import java.nio.*; import java.security.KeyStore; import java.security.KeyFactory; +import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.*; import java.security.interfaces.*; import java.util.Base64; @@ -377,6 +377,10 @@ public class DHEKeySizing { } public static void main(String args[]) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + if (args.length != 4) { System.out.println( "Usage: java DHEKeySizing cipher-suite " + diff --git a/jdk/test/sun/security/validator/EndEntityExtensionCheck.java b/jdk/test/sun/security/validator/EndEntityExtensionCheck.java new file mode 100644 index 00000000000..122bae237f2 --- /dev/null +++ b/jdk/test/sun/security/validator/EndEntityExtensionCheck.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8076117 + * @summary EndEntityChecker should not process custom extensions + * after PKIX validation + */ + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; +import java.security.cert.CertPathValidatorException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.PKIXCertPathChecker; +import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import sun.security.validator.KeyStores; +import sun.security.validator.Validator; + + +public class EndEntityExtensionCheck { + + /* + * Owner: CN=TestCA + * Issuer: CN=TestCA + */ + private static final String CA = + "-----BEGIN CERTIFICATE-----\n" + + "MIICgDCCAj2gAwIBAgIEC18hWjALBgcqhkjOOAQDBQAwETEPMA0GA1UEAxMGVGVz\n" + + "dENBMB4XDTE1MDQwNzIyMzUyMFoXDTI1MDQwNjIyMzUyMFowETEPMA0GA1UEAxMG\n" + + "VGVzdENBMIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2\n" + + "EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdr\n" + + "mVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXz\n" + + "rith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+Gghdab\n" + + "Pd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6Ewo\n" + + "FhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR\n" + + "kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAJOWy2hVy4iNwsi/idWG\n" + + "oksr9IZxQIFR2YavoUmD+rIgfYUpiCihzftDLMMaNYqp9PPxuOyoIPGPbwmKpAs5\n" + + "nq6gLwH2lSsN+EwyV2SJ0J26PHiMuRNZWWfKR3cpEqbQVb0CmvqSpj8zYfamPzp7\n" + + "eXSWwahzgLCGJM3SgCfDFC0uoyEwHzAdBgNVHQ4EFgQU7tLD8FnWM+r6jBr+mCXs\n" + + "8G5yBpgwCwYHKoZIzjgEAwUAAzAAMC0CFQCHCtzC3S0ST0EZBucikVui4WXD8QIU\n" + + "L3Oxy6989/FhZlZWJlhqc1ungEQ=\n" + + "-----END CERTIFICATE-----"; + + /* + * Owner: CN=TestEE + * Issuer: CN=TestCA + * Contains a custom critical extension with OID 1.2.3.4: + * #1: ObjectId: 1.2.3.4 Criticality=true + * 0000: 00 00 + */ + private static final String EE = + "-----BEGIN CERTIFICATE-----\n" + + "MIICrTCCAmugAwIBAgIELjciKzALBgcqhkjOOAQDBQAwETEPMA0GA1UEAxMGVGVz\n" + + "dENBMB4XDTE1MDQwNzIzMDA1OFoXDTE1MDcwNjIzMDA1OFowETEPMA0GA1UEAxMG\n" + + "VGVzdEVFMIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2\n" + + "EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdr\n" + + "mVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXz\n" + + "rith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+Gghdab\n" + + "Pd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6Ewo\n" + + "FhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhR\n" + + "kImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAN97otrAJEuUg/O97vScI\n" + + "01xs1jqTz5o0PGpKiDDJNB3tCCUbLqXoBQBvSefQ8vYL3mmlEJLxlwfbajRmJQp0\n" + + "tUy5SUCZHk3MdoKxSvrqYnVpYwJHFXKWs6lAawxfuWbkm9SREuepOWnVzy2ecf5z\n" + + "hvy9mgEBfi4E9Cy8Byq2TpyjUDBOMAwGAyoDBAEB/wQCAAAwHwYDVR0jBBgwFoAU\n" + + "7tLD8FnWM+r6jBr+mCXs8G5yBpgwHQYDVR0OBBYEFNRVqt5F+EAuJ5x1IZLDkoMs\n" + + "mDj4MAsGByqGSM44BAMFAAMvADAsAhQyNGhxIp5IshN1zqLs4pUY214IMAIUMmTL\n" + + "3ZMpMAjITbuHHlFNUqZ7A9s=\n" + + "-----END CERTIFICATE-----"; + + public static void main(String[] args) throws Exception { + X509Certificate[] chain = createChain(); + + /* Test 1: Test SimpleValidator + * SimpleValidator doesn't check for unsupported critical + * extensions in the end entity certificate, and leaves that up + * to EndEntityChecker, which should catch such extensions. + */ + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + ks.setCertificateEntry("testca", chain[chain.length - 1]); + + Validator v = Validator.getInstance(Validator.TYPE_SIMPLE, + Validator.VAR_TLS_CLIENT, + KeyStores.getTrustedCerts(ks)); + try { + v.validate(chain); + throw new Exception("Chain should not have validated " + + "successfully."); + } catch (CertificateException ex) { + // EE cert has an unsupported critical extension that is not + // checked by SimpleValidator's extension checks, so this + // failure is expected + } + + /* Test 2: Test PKIXValidator without custom checker + * PKIXValidator accepts PKIXParameters that can contain + * custom PKIXCertPathCheckers, which would be run against + * each cert in the chain, including EE certs. + * Check that if PKIXValidator is not provided a custom + * PKIXCertPathChecker for an unknown critical extension in + * the EE cert, chain validation will fail. + */ + TrustAnchor ta = new TrustAnchor(chain[chain.length - 1], null); + Set tas = new HashSet<>(); + tas.add(ta); + PKIXBuilderParameters params = new PKIXBuilderParameters(tas, null); + params.setDate(new Date(115, 5, 1)); // 2015-05-01 + params.setRevocationEnabled(false); + + v = Validator.getInstance(Validator.TYPE_PKIX, + Validator.VAR_TLS_CLIENT, + params); + try { + v.validate(chain); + throw new Exception("Chain should not have validated " + + "successfully."); + } catch (CertificateException ex) { + // EE cert has an unsupported critical extension and + // PKIXValidator was not provided any custom checker + // for it, so this failure ie expected. + } + + /* Test 3: Test PKIXValidator with custom checker + * Check that PKIXValidator will successfully validate a chain + * containing an EE cert with a critical custom extension, given + * a corresponding PKIXCertPathChecker for the extension. + */ + params = new PKIXBuilderParameters(tas, null); + params.addCertPathChecker(new CustomChecker()); + params.setDate(new Date(115, 5, 1)); // 2015-05-01 + params.setRevocationEnabled(false); + + v = Validator.getInstance(Validator.TYPE_PKIX, + Validator.VAR_TLS_CLIENT, + params); + v.validate(chain); // This should validate successfully + + System.out.println("Tests passed."); + } + + public static X509Certificate[] createChain() throws Exception { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate ee = (X509Certificate) + cf.generateCertificate((new ByteArrayInputStream(EE.getBytes()))); + X509Certificate ca = (X509Certificate) + cf.generateCertificate((new ByteArrayInputStream(CA.getBytes()))); + + X509Certificate[] chain = {ee, ca}; + return chain; + } + + /* + * A custom PKIXCertPathChecker. Looks for a critical extension + * in an end entity certificate with the OID 1.2.3.4. + */ + static class CustomChecker extends PKIXCertPathChecker { + + @Override + public void init(boolean forward) throws CertPathValidatorException { + // nothing to do + } + + @Override + public boolean isForwardCheckingSupported() { + return false; + } + + @Override + public Set getSupportedExtensions() { + Set exts = new HashSet<>(); + exts.add("1.2.3.4"); + return exts; + } + + @Override + public void check(Certificate cert, + Collection unresolvedCritExts) + throws CertPathValidatorException { + X509Certificate currCert = (X509Certificate)cert; + // check that this is an EE cert + if (currCert.getBasicConstraints() == -1) { + if (unresolvedCritExts != null && + !unresolvedCritExts.isEmpty()) { + unresolvedCritExts.remove("1.2.3.4"); + } + } + } + + } +} diff --git a/langtools/.hgtags b/langtools/.hgtags index c7a5d998d78..562ec0f2fae 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -302,3 +302,5 @@ ed34864f3b43a7df394fce6c3f0bc86b70a5d686 jdk9-b54 ec977a00cecbf0007b0fa26c7af2852d57a79cad jdk9-b57 07ce89fec30165a2f1212047bd23b30086ed1e74 jdk9-b58 a598534d277e170a0bbf177bd54d9d179245532b jdk9-b59 +81bdc4545337c404bb87373838c983584a49afd6 jdk9-b60 +0eb91327db5a840779cc5c35b9b858d6ef7959d1 jdk9-b61 diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java index c1627f23f6a..03a62b2019d 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,6 +108,7 @@ public class Checker extends DocTreePathScanner { public enum Flag { TABLE_HAS_CAPTION, HAS_ELEMENT, + HAS_HEADING, HAS_INLINE_TAG, HAS_TEXT, REPORTED_BAD_INLINE @@ -282,6 +283,8 @@ public class Checker extends DocTreePathScanner { final HtmlTag t = HtmlTag.get(treeName); if (t == null) { env.messages.error(HTML, tree, "dc.tag.unknown", treeName); + } else if (t.allowedVersion != HtmlVersion.ALL && t.allowedVersion != env.htmlVersion) { + env.messages.error(HTML, tree, "dc.tag.not.supported", treeName); } else { boolean done = false; for (TagStackItem tsi: tagStack) { @@ -345,6 +348,12 @@ public class Checker extends DocTreePathScanner { parent.flags.add(Flag.TABLE_HAS_CAPTION); break; + case H1: case H2: case H3: case H4: case H5: case H6: + if (parent != null && (parent.tag == HtmlTag.SECTION || parent.tag == HtmlTag.ARTICLE)) { + parent.flags.add(Flag.HAS_HEADING); + } + break; + case IMG: if (!top.attrs.contains(HtmlTag.Attr.ALT)) env.messages.error(ACCESSIBILITY, tree, "dc.no.alt.attr.for.image"); @@ -460,6 +469,14 @@ public class Checker extends DocTreePathScanner { env.messages.error(ACCESSIBILITY, tree, "dc.no.summary.or.caption.for.table"); } + break; + + case SECTION: + case ARTICLE: + if (env.htmlVersion == HtmlVersion.HTML5 && !top.flags.contains(Flag.HAS_HEADING)) { + env.messages.error(HTML, tree, "dc.tag.requires.heading", treeName); + } + break; } warnIfEmpty(top, tree); tagStack.pop(); @@ -519,25 +536,21 @@ public class Checker extends DocTreePathScanner { Name name = tree.getName(); HtmlTag.Attr attr = currTag.getAttr(name); if (attr != null) { + if (env.htmlVersion == HtmlVersion.HTML4 && attr.name().contains("-")) { + env.messages.error(HTML, tree, "dc.attr.not.supported.html4", name); + } boolean first = tagStack.peek().attrs.add(attr); if (!first) env.messages.error(HTML, tree, "dc.attr.repeated", name); } AttrKind k = currTag.getAttrKind(name); - switch (k) { - case OK: + switch (env.htmlVersion) { + case HTML4: + validateHtml4Attrs(tree, name, k); break; - case INVALID: - env.messages.error(HTML, tree, "dc.attr.unknown", name); - break; - - case OBSOLETE: - env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name); - break; - - case USE_CSS: - env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name); + case HTML5: + validateHtml5Attrs(tree, name, k); break; } @@ -590,6 +603,20 @@ public class Checker extends DocTreePathScanner { } } break; + + case BORDER: + if (currTag == HtmlTag.TABLE) { + String v = getAttrValue(tree); + try { + if (env.htmlVersion == HtmlVersion.HTML5 + && (v == null || (!v.isEmpty() && Integer.parseInt(v) != 1))) { + env.messages.error(HTML, tree, "dc.attr.table.border.html5", attr); + } + } catch (NumberFormatException ex) { + env.messages.error(HTML, tree, "dc.attr.table.border.html5", attr); + } + } + break; } } } @@ -599,6 +626,45 @@ public class Checker extends DocTreePathScanner { return super.visitAttribute(tree, ignore); } + private void validateHtml4Attrs(AttributeTree tree, Name name, AttrKind k) { + switch (k) { + case ALL: + case HTML4: + break; + + case INVALID: + env.messages.error(HTML, tree, "dc.attr.unknown", name); + break; + + case OBSOLETE: + env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name); + break; + + case USE_CSS: + env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name); + break; + + case HTML5: + env.messages.error(HTML, tree, "dc.attr.not.supported.html4", name); + break; + } + } + + private void validateHtml5Attrs(AttributeTree tree, Name name, AttrKind k) { + switch (k) { + case ALL: + case HTML5: + break; + + case INVALID: + case OBSOLETE: + case USE_CSS: + case HTML4: + env.messages.error(HTML, tree, "dc.attr.not.supported.html5", name); + break; + } + } + private boolean checkAnchor(String name) { Element e = getEnclosingPackageOrClass(env.currElement); if (e == null) diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java index e6ee1e4513b..580e3eb9e66 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,6 +80,7 @@ public class DocLint implements Plugin { private static final String STATS = "-stats"; public static final String XIMPLICIT_HEADERS = "-XimplicitHeaders:"; public static final String XCUSTOM_TAGS_PREFIX = "-XcustomTags:"; + public static final String XHTML_VERSION_PREFIX = "-XhtmlVersion:"; public static final String XCHECK_PACKAGE = "-XcheckPackage:"; public static final String SEPARATOR = ","; @@ -210,6 +211,14 @@ public class DocLint implements Plugin { env.messages.setOptions(arg.substring(arg.indexOf(":") + 1)); } else if (arg.startsWith(XCUSTOM_TAGS_PREFIX)) { env.setCustomTags(arg.substring(arg.indexOf(":") + 1)); + } else if (arg.startsWith(XHTML_VERSION_PREFIX)) { + String argsVersion = arg.substring(arg.indexOf(":") + 1); + HtmlVersion htmlVersion = HtmlVersion.getHtmlVersion(argsVersion); + if (htmlVersion != null) { + env.setHtmlVersion(htmlVersion); + } else { + throw new BadArgs("dc.bad.value.for.option", arg, argsVersion); + } } else if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help") || arg.equals("-?") || arg.equals("-usage")) { needHelp = true; @@ -274,6 +283,14 @@ public class DocLint implements Plugin { env.setImplicitHeaders(Character.digit(ch, 10)); } else if (arg.startsWith(XCUSTOM_TAGS_PREFIX)) { env.setCustomTags(arg.substring(arg.indexOf(":") + 1)); + } else if (arg.startsWith(XHTML_VERSION_PREFIX)) { + String argsVersion = arg.substring(arg.indexOf(":") + 1); + HtmlVersion htmlVersion = HtmlVersion.getHtmlVersion(argsVersion); + if (htmlVersion != null) { + env.setHtmlVersion(htmlVersion); + } else { + throw new IllegalArgumentException(argsVersion); + } } else if (arg.startsWith(XCHECK_PACKAGE)) { env.setCheckPackages(arg.substring(arg.indexOf(":") + 1)); } else diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java index 448e4d79c19..f7aaa5a4f01 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,6 +99,8 @@ public class Env { Set includePackages; Set excludePackages; + HtmlVersion htmlVersion = HtmlVersion.HTML4; + // Utility classes DocTrees trees; Elements elements; @@ -193,6 +195,10 @@ public class Env { return true; } + void setHtmlVersion(HtmlVersion version) { + htmlVersion = version; + } + /** Set the current declaration and its doc comment. */ void setCurrent(TreePath path, DocCommentTree comment) { currPath = path; diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java index ac33290e83c..6f42b903526 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,26 +51,37 @@ import com.sun.tools.javac.util.StringUtils; * * @see HTML 4.01 Specification * @see HTML 5 Specification + * @see WAI-ARIA Specification + * @see WAI-ARIA Recommendations Table * @author Bhavesh Patel * @author Jonathan Gibbons (revised) */ public enum HtmlTag { A(BlockType.INLINE, EndKind.REQUIRED, - attrs(AttrKind.OK, HREF, TARGET, NAME)), + attrs(AttrKind.ALL, HREF, TARGET, ID), + attrs(AttrKind.HTML4, REV, CHARSET, SHAPE, COORDS, NAME)), ABBR(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), - ACRONYM(BlockType.INLINE, EndKind.REQUIRED, + ACRONYM(HtmlVersion.HTML4, BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), ADDRESS(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + ARTICLE(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), + + ASIDE(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), + B(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), - BIG(BlockType.INLINE, EndKind.REQUIRED, + BDI(HtmlVersion.HTML5, BlockType.INLINE, EndKind.REQUIRED), + + BIG(HtmlVersion.HTML4, BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT)), BLOCKQUOTE(BlockType.BLOCK, EndKind.REQUIRED, @@ -82,9 +93,10 @@ public enum HtmlTag { attrs(AttrKind.USE_CSS, CLEAR)), CAPTION(BlockType.TABLE_ITEM, EndKind.REQUIRED, - EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)), + EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT), + attrs(AttrKind.USE_CSS, ALIGN)), - CENTER(BlockType.BLOCK, EndKind.REQUIRED, + CENTER(HtmlVersion.HTML4, BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), CITE(BlockType.INLINE, EndKind.REQUIRED, @@ -93,18 +105,30 @@ public enum HtmlTag { CODE(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + COL(BlockType.TABLE_ITEM, EndKind.NONE, + attrs(AttrKind.HTML4, ALIGN, CHAR, CHAROFF, VALIGN, WIDTH)), + + COLGROUP(BlockType.TABLE_ITEM, EndKind.REQUIRED, + attrs(AttrKind.HTML4, ALIGN, CHAR, CHAROFF, VALIGN, WIDTH)) { + @Override + public boolean accepts(HtmlTag t) { + return (t == COL); + } + }, + DD(BlockType.LIST_ITEM, EndKind.OPTIONAL, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)), DEL(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST), - attrs(AttrKind.OK, Attr.CITE, Attr.DATETIME)), + attrs(AttrKind.ALL, Attr.CITE, Attr.DATETIME)), DFN(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), DIV(BlockType.BLOCK, EndKind.REQUIRED, - EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE), + attrs(AttrKind.USE_CSS, ALIGN)), DL(BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT), @@ -121,49 +145,95 @@ public enum HtmlTag { EM(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.NO_NEST)), - FONT(BlockType.INLINE, EndKind.REQUIRED, // tag itself is deprecated + FONT(HtmlVersion.HTML4, BlockType.INLINE, EndKind.REQUIRED, // tag itself is deprecated EnumSet.of(Flag.EXPECT_CONTENT), attrs(AttrKind.USE_CSS, SIZE, COLOR, FACE)), - FRAME(BlockType.OTHER, EndKind.NONE), + FOOTER(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)) { + @Override + public boolean accepts(HtmlTag t) { + switch (t) { + case HEADER: case FOOTER: case MAIN: + return false; + default: + return (t.blockType == BlockType.BLOCK) || (t.blockType == BlockType.INLINE); + } + } + }, - FRAMESET(BlockType.OTHER, EndKind.REQUIRED), + FIGURE(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), - H1(BlockType.BLOCK, EndKind.REQUIRED), - H2(BlockType.BLOCK, EndKind.REQUIRED), - H3(BlockType.BLOCK, EndKind.REQUIRED), - H4(BlockType.BLOCK, EndKind.REQUIRED), - H5(BlockType.BLOCK, EndKind.REQUIRED), - H6(BlockType.BLOCK, EndKind.REQUIRED), + FIGCAPTION(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED), + + FRAME(HtmlVersion.HTML4, BlockType.OTHER, EndKind.NONE), + + FRAMESET(HtmlVersion.HTML4, BlockType.OTHER, EndKind.REQUIRED), + + H1(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.USE_CSS, ALIGN)), + H2(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.USE_CSS, ALIGN)), + H3(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.USE_CSS, ALIGN)), + H4(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.USE_CSS, ALIGN)), + H5(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.USE_CSS, ALIGN)), + H6(BlockType.BLOCK, EndKind.REQUIRED, + attrs(AttrKind.USE_CSS, ALIGN)), HEAD(BlockType.OTHER, EndKind.REQUIRED), + HEADER(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)) { + @Override + public boolean accepts(HtmlTag t) { + switch (t) { + case HEADER: case FOOTER: case MAIN: + return false; + default: + return (t.blockType == BlockType.BLOCK) || (t.blockType == BlockType.INLINE); + } + } + }, + HR(BlockType.BLOCK, EndKind.NONE, - attrs(AttrKind.OK, WIDTH)), // OK in 4.01; not allowed in 5 + attrs(AttrKind.HTML4, WIDTH), + attrs(AttrKind.USE_CSS, ALIGN, NOSHADE, SIZE)), HTML(BlockType.OTHER, EndKind.REQUIRED), I(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + IFRAME(BlockType.OTHER, EndKind.REQUIRED), + IMG(BlockType.INLINE, EndKind.NONE, - attrs(AttrKind.OK, SRC, ALT, HEIGHT, WIDTH), + attrs(AttrKind.ALL, SRC, ALT, HEIGHT, WIDTH), + attrs(AttrKind.HTML5, CROSSORIGIN), attrs(AttrKind.OBSOLETE, NAME), attrs(AttrKind.USE_CSS, ALIGN, HSPACE, VSPACE, BORDER)), INS(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST), - attrs(AttrKind.OK, Attr.CITE, Attr.DATETIME)), + attrs(AttrKind.ALL, Attr.CITE, Attr.DATETIME)), KBD(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), LI(BlockType.LIST_ITEM, EndKind.OPTIONAL, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE), - attrs(AttrKind.OK, VALUE)), + attrs(AttrKind.ALL, VALUE), + attrs(AttrKind.USE_CSS, TYPE)), LINK(BlockType.OTHER, EndKind.NONE), + MAIN(HtmlVersion.HTML5, BlockType.OTHER, EndKind.REQUIRED), + + MARK(HtmlVersion.HTML5, BlockType.INLINE, EndKind.REQUIRED), + MENU(BlockType.BLOCK, EndKind.REQUIRED) { @Override public boolean accepts(HtmlTag t) { @@ -173,13 +243,18 @@ public enum HtmlTag { META(BlockType.OTHER, EndKind.NONE), - NOFRAMES(BlockType.OTHER, EndKind.REQUIRED), + NAV(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), + + NOFRAMES(HtmlVersion.HTML4, BlockType.OTHER, EndKind.REQUIRED), NOSCRIPT(BlockType.BLOCK, EndKind.REQUIRED), OL(BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT), - attrs(AttrKind.OK, START, TYPE)) { + attrs(AttrKind.ALL, START, TYPE), + attrs(AttrKind.HTML5, REVERSED), + attrs(AttrKind.USE_CSS, COMPACT)) { @Override public boolean accepts(HtmlTag t) { return (t == LI); @@ -191,7 +266,8 @@ public enum HtmlTag { attrs(AttrKind.USE_CSS, ALIGN)), PRE(BlockType.BLOCK, EndKind.REQUIRED, - EnumSet.of(Flag.EXPECT_CONTENT)) { + EnumSet.of(Flag.EXPECT_CONTENT), + attrs(AttrKind.USE_CSS, WIDTH)) { @Override public boolean accepts(HtmlTag t) { switch (t) { @@ -214,13 +290,16 @@ public enum HtmlTag { SCRIPT(BlockType.OTHER, EndKind.REQUIRED), + SECTION(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), + SMALL(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT)), SPAN(BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT)), - STRIKE(BlockType.INLINE, EndKind.REQUIRED, + STRIKE(HtmlVersion.HTML4, BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT)), STRONG(BlockType.INLINE, EndKind.REQUIRED, @@ -234,13 +313,14 @@ public enum HtmlTag { TABLE(BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT), - attrs(AttrKind.OK, SUMMARY, Attr.FRAME, RULES, BORDER, - CELLPADDING, CELLSPACING, WIDTH), // width OK in 4.01; not allowed in 5 + attrs(AttrKind.ALL, BORDER), + attrs(AttrKind.HTML4, SUMMARY, CELLPADDING, CELLSPACING, Attr.FRAME, RULES, WIDTH), attrs(AttrKind.USE_CSS, ALIGN, BGCOLOR)) { @Override public boolean accepts(HtmlTag t) { switch (t) { case CAPTION: + case COLGROUP: case THEAD: case TBODY: case TFOOT: case TR: // HTML 3.2 return true; @@ -252,7 +332,8 @@ public enum HtmlTag { TBODY(BlockType.TABLE_ITEM, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT), - attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) { + attrs(AttrKind.ALL, VALIGN), + attrs(AttrKind.HTML4, ALIGN, CHAR, CHAROFF)) { @Override public boolean accepts(HtmlTag t) { return (t == TR); @@ -261,12 +342,16 @@ public enum HtmlTag { TD(BlockType.TABLE_ITEM, EndKind.OPTIONAL, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE), - attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, Attr.ABBR, AXIS, - ALIGN, CHAR, CHAROFF, VALIGN), + attrs(AttrKind.ALL, COLSPAN, ROWSPAN, HEADERS, VALIGN), + attrs(AttrKind.HTML4, AXIS, Attr.ABBR, SCOPE, ALIGN, CHAR, CHAROFF), attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)), + TEMPLATE(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED, + EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), + TFOOT(BlockType.TABLE_ITEM, EndKind.REQUIRED, - attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) { + attrs(AttrKind.ALL, VALIGN), + attrs(AttrKind.HTML4, ALIGN, CHAR, CHAROFF)) { @Override public boolean accepts(HtmlTag t) { return (t == TR); @@ -275,22 +360,27 @@ public enum HtmlTag { TH(BlockType.TABLE_ITEM, EndKind.OPTIONAL, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE), - attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, Attr.ABBR, AXIS, - ALIGN, CHAR, CHAROFF, VALIGN), + attrs(AttrKind.ALL, COLSPAN, ROWSPAN, HEADERS, SCOPE, Attr.ABBR, + VALIGN), + attrs(AttrKind.HTML4, AXIS, ALIGN, CHAR, CHAROFF), attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)), THEAD(BlockType.TABLE_ITEM, EndKind.REQUIRED, - attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) { + attrs(AttrKind.ALL, VALIGN), + attrs(AttrKind.HTML4, ALIGN, CHAR, CHAROFF)) { @Override public boolean accepts(HtmlTag t) { return (t == TR); } }, + TIME(HtmlVersion.HTML5, BlockType.INLINE, EndKind.REQUIRED), + TITLE(BlockType.OTHER, EndKind.REQUIRED), TR(BlockType.TABLE_ITEM, EndKind.OPTIONAL, - attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN), + attrs(AttrKind.ALL, VALIGN), + attrs(AttrKind.HTML4, ALIGN, CHAR, CHAROFF), attrs(AttrKind.USE_CSS, BGCOLOR)) { @Override public boolean accepts(HtmlTag t) { @@ -298,7 +388,7 @@ public enum HtmlTag { } }, - TT(BlockType.INLINE, EndKind.REQUIRED, + TT(HtmlVersion.HTML4, BlockType.INLINE, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), U(BlockType.INLINE, EndKind.REQUIRED, @@ -306,13 +396,15 @@ public enum HtmlTag { UL(BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.EXPECT_CONTENT), - attrs(AttrKind.OK, COMPACT, TYPE)) { // OK in 4.01; not allowed in 5 + attrs(AttrKind.HTML4, COMPACT, TYPE)) { @Override public boolean accepts(HtmlTag t) { return (t == LI); } }, + WBR(HtmlVersion.HTML5, BlockType.INLINE, EndKind.REQUIRED), + VAR(BlockType.INLINE, EndKind.REQUIRED); /** @@ -345,34 +437,66 @@ public enum HtmlTag { public static enum Attr { ABBR, ALIGN, + ALINK, ALT, + ARIA_ACTIVEDESCENDANT, + ARIA_CONTROLS, + ARIA_DESCRIBEDBY, + ARIA_EXPANDED, + ARIA_LABEL, + ARIA_LABELLEDBY, + ARIA_LEVEL, + ARIA_MULTISELECTABLE, + ARIA_OWNS, + ARIA_POSINSET, + ARIA_SETSIZE, + ARIA_READONLY, + ARIA_REQUIRED, + ARIA_SELECTED, + ARIA_SORT, AXIS, + BACKGROUND, BGCOLOR, BORDER, CELLSPACING, CELLPADDING, CHAR, CHAROFF, + CHARSET, CITE, CLEAR, CLASS, COLOR, COLSPAN, COMPACT, + COORDS, + CROSSORIGIN, DATETIME, FACE, FRAME, + FRAMEBORDER, HEADERS, HEIGHT, HREF, HSPACE, ID, + LINK, + LONGDESC, + MARGINHEIGHT, + MARGINWIDTH, NAME, + NOSHADE, NOWRAP, + PROFILE, + REV, REVERSED, + ROLE, ROWSPAN, RULES, + SCHEME, SCOPE, + SCROLLING, + SHAPE, SIZE, SPACE, SRC, @@ -380,14 +504,23 @@ public enum HtmlTag { STYLE, SUMMARY, TARGET, + TEXT, TYPE, VALIGN, VALUE, + VERSION, + VLINK, VSPACE, WIDTH; + private final String name; + + Attr() { + name = StringUtils.toLowerCase(name().replace("_", "-")); + } + public String getText() { - return StringUtils.toLowerCase(name()); + return name; } static final Map index = new HashMap<>(); @@ -399,10 +532,12 @@ public enum HtmlTag { } public static enum AttrKind { + HTML4, + HTML5, INVALID, OBSOLETE, USE_CSS, - OK + ALL } // This class exists to avoid warnings from using parameterized vararg type @@ -415,25 +550,52 @@ public enum HtmlTag { } + public final HtmlVersion allowedVersion; public final BlockType blockType; public final EndKind endKind; public final Set flags; private final Map attrs; HtmlTag(BlockType blockType, EndKind endKind, AttrMap... attrMaps) { - this(blockType, endKind, Collections.emptySet(), attrMaps); + this(HtmlVersion.ALL, blockType, endKind, Collections.emptySet(), attrMaps); + } + + HtmlTag(HtmlVersion allowedVersion, BlockType blockType, EndKind endKind, AttrMap... attrMaps) { + this(allowedVersion, blockType, endKind, Collections.emptySet(), attrMaps); } HtmlTag(BlockType blockType, EndKind endKind, Set flags, AttrMap... attrMaps) { + this(HtmlVersion.ALL, blockType, endKind, flags, attrMaps); + } + + HtmlTag(HtmlVersion allowedVersion, BlockType blockType, EndKind endKind, Set flags, AttrMap... attrMaps) { + this.allowedVersion = allowedVersion; this.blockType = blockType; this.endKind = endKind; this.flags = flags; this.attrs = new EnumMap<>(Attr.class); for (Map m: attrMaps) this.attrs.putAll(m); - attrs.put(Attr.CLASS, AttrKind.OK); - attrs.put(Attr.ID, AttrKind.OK); - attrs.put(Attr.STYLE, AttrKind.OK); + attrs.put(Attr.CLASS, AttrKind.ALL); + attrs.put(Attr.ID, AttrKind.ALL); + attrs.put(Attr.STYLE, AttrKind.ALL); + attrs.put(Attr.ROLE, AttrKind.HTML5); + // for now, assume that all ARIA attributes are allowed on all tags. + attrs.put(Attr.ARIA_ACTIVEDESCENDANT, AttrKind.HTML5); + attrs.put(Attr.ARIA_CONTROLS, AttrKind.HTML5); + attrs.put(Attr.ARIA_DESCRIBEDBY, AttrKind.HTML5); + attrs.put(Attr.ARIA_EXPANDED, AttrKind.HTML5); + attrs.put(Attr.ARIA_LABEL, AttrKind.HTML5); + attrs.put(Attr.ARIA_LABELLEDBY, AttrKind.HTML5); + attrs.put(Attr.ARIA_LEVEL, AttrKind.HTML5); + attrs.put(Attr.ARIA_MULTISELECTABLE, AttrKind.HTML5); + attrs.put(Attr.ARIA_OWNS, AttrKind.HTML5); + attrs.put(Attr.ARIA_POSINSET, AttrKind.HTML5); + attrs.put(Attr.ARIA_READONLY, AttrKind.HTML5); + attrs.put(Attr.ARIA_REQUIRED, AttrKind.HTML5); + attrs.put(Attr.ARIA_SELECTED, AttrKind.HTML5); + attrs.put(Attr.ARIA_SETSIZE, AttrKind.HTML5); + attrs.put(Attr.ARIA_SORT, AttrKind.HTML5); } public boolean accepts(HtmlTag t) { diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlVersion.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlVersion.java new file mode 100644 index 00000000000..cfa40ba30b9 --- /dev/null +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlVersion.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclint; + +/** + * Enum representing HTML version of the documentation comment. + * + * @author Bhavesh Patel + */ +public enum HtmlVersion { + + HTML4, + HTML5, + ALL; + + public static HtmlVersion getHtmlVersion(String argsVersion) { + switch (argsVersion) { + case "html4": + return HtmlVersion.HTML4; + case "html5": + return HtmlVersion.HTML5; + default: + return null; + } + } +} diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties index 1f47d94d3bc..03adb82aeaa 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -27,9 +27,12 @@ dc.anchor.already.defined = anchor already defined: "{0}" dc.anchor.value.missing = no value given for anchor dc.attr.lacks.value = attribute lacks value dc.attr.not.number = attribute value is not a number +dc.attr.not.supported.html4 = attribute not supported in HTML4: {0} +dc.attr.not.supported.html5 = attribute not supported in HTML5: {0} dc.attr.obsolete = attribute obsolete: {0} dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0} dc.attr.repeated = repeated attribute: {0} +dc.attr.table.border.html5 = attribute border for table only accepts "" or "1", use CSS instead: {0} dc.attr.unknown = unknown attribute: {0} dc.bad.option = bad option: {0} dc.bad.value.for.option = bad value for option: {0} {1} @@ -63,9 +66,11 @@ dc.tag.not.allowed.inline.tag = block element not allowed within @{1}: {0} dc.tag.not.allowed.inline.other = block element not allowed here: {0} dc.tag.not.closed= element not closed: {0} dc.tag.p.in.pre= unexpected use of

                                  inside

                                   element
                                  +dc.tag.requires.heading = heading not found for 
                                   dc.tag.self.closing = self-closing element not allowed
                                   dc.tag.start.unmatched = end tag missing: 
                                   dc.tag.unknown = unknown tag: {0}
                                  +dc.tag.not.supported = tag not supported in the generated HTML version: {0}
                                   dc.text.not.allowed = text not allowed in <{0}> element
                                   dc.type.arg.not.allowed = type arguments not allowed here
                                   dc.unexpected.comment=documentation comment not expected here
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
                                  index ad9e6291796..1818d9f7999 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java
                                  @@ -1293,9 +1293,21 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
                                           @DefinedBy(Api.LANGUAGE_MODEL)
                                           public String toString() {
                                               StringBuilder sb = new StringBuilder();
                                  -            sb.append(elemtype);
                                  -            appendAnnotationsString(sb, true);
                                  -            sb.append("[]");
                                  +
                                  +            // First append root component type
                                  +            Type t = elemtype;
                                  +            while (t.getKind() == TypeKind.ARRAY)
                                  +                t = ((ArrayType) t).getComponentType();
                                  +            sb.append(t);
                                  +
                                  +            // then append @Anno[] @Anno[] ... @Anno[]
                                  +            t = this;
                                  +            do {
                                  +                t.appendAnnotationsString(sb, true);
                                  +                sb.append("[]");
                                  +                t = ((ArrayType) t).getComponentType();
                                  +            } while (t.getKind() == TypeKind.ARRAY);
                                  +
                                               return sb.toString();
                                           }
                                   
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
                                  index 35fe5bb2b47..8394d321cf6 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
                                  @@ -31,6 +31,7 @@ import com.sun.tools.javac.code.Attribute.TypeCompound;
                                   import com.sun.tools.javac.code.Scope.WriteableScope;
                                   import com.sun.tools.javac.code.Symbol.*;
                                   import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
                                  +import com.sun.tools.javac.resources.CompilerProperties.Errors;
                                   import com.sun.tools.javac.tree.JCTree;
                                   import com.sun.tools.javac.tree.JCTree.*;
                                   import com.sun.tools.javac.tree.TreeInfo;
                                  @@ -778,9 +779,10 @@ public class Annotate {
                                                   Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
                                                   JCAnnotation annoTree = m.Annotation(c);
                                   
                                  -                if (!chk.annotationApplicable(annoTree, on))
                                  -                    log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target",
                                  -                            targetContainerType, origAnnoType);
                                  +                if (!chk.annotationApplicable(annoTree, on)) {
                                  +                    log.error(annoTree.pos(),
                                  +                              Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on));
                                  +                }
                                   
                                                   if (!chk.validateAnnotationDeferErrors(annoTree))
                                                       log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
                                  index 02340511e52..310786bc04d 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
                                  @@ -4657,7 +4657,7 @@ public class Attr extends JCTree.Visitor {
                                               for (JCAnnotation ai : annotations) {
                                                   if (!ai.type.isErroneous() &&
                                                           typeAnnotations.annotationTargetType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
                                  -                    log.error(ai.pos(), "annotation.type.not.applicable");
                                  +                    log.error(ai.pos(), Errors.AnnotationTypeNotApplicableToType(ai.type));
                                                   }
                                               }
                                           }
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
                                  index 3a31e365da9..3e9f80ea24e 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
                                  @@ -2783,7 +2783,7 @@ public class Check {
                                           if (a.hasTag(TYPE_ANNOTATION) &&
                                                   !a.annotationType.type.isErroneous() &&
                                                   !isTypeAnnotation(a, isTypeParameter)) {
                                  -            log.error(a.pos(), "annotation.type.not.applicable");
                                  +            log.error(a.pos(), Errors.AnnotationTypeNotApplicableToType(a.type));
                                           }
                                       }
                                   
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
                                  index 23c961ec638..10e9ea71e34 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -810,7 +810,9 @@ public class Infer {
                                                   Infer infer = inferenceContext.infer();
                                                   for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
                                                       for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
                                  -                        isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn , infer);
                                  +                        if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn , infer)) {
                                  +                            infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER_LOWER);
                                  +                        }
                                                       }
                                                   }
                                               }
                                  @@ -831,7 +833,9 @@ public class Infer {
                                                   Infer infer = inferenceContext.infer();
                                                   for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
                                                       for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
                                  -                        isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer);
                                  +                        if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer)) {
                                  +                            infer.reportBoundError(uv, BoundErrorKind.BAD_UPPER_EQUAL);
                                  +                        }
                                                       }
                                                   }
                                               }
                                  @@ -852,7 +856,9 @@ public class Infer {
                                                   Infer infer = inferenceContext.infer();
                                                   for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
                                                       for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
                                  -                        isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer);
                                  +                        if (!isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer)) {
                                  +                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQUAL_LOWER);
                                  +                        }
                                                       }
                                                   }
                                               }
                                  @@ -926,7 +932,9 @@ public class Infer {
                                                   for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
                                                       for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
                                                           if (b1 != b2) {
                                  -                            isSameType(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), infer);
                                  +                            if (!isSameType(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), infer)) {
                                  +                                infer.reportBoundError(uv, BoundErrorKind.BAD_EQ);
                                  +                            }
                                                           }
                                                       }
                                                   }
                                  @@ -1234,6 +1242,46 @@ public class Infer {
                                                           uv.getBounds(InferenceBound.UPPER));
                                               }
                                           },
                                  +        /**
                                  +         * The (uninstantiated) inference variable has incompatible equality constraints.
                                  +         */
                                  +        BAD_EQ() {
                                  +            @Override
                                  +            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
                                  +                return ex.setMessage("incompatible.eq.bounds", uv.qtype,
                                  +                        uv.getBounds(InferenceBound.EQ));
                                  +            }
                                  +        },
                                  +        /**
                                  +         * The (uninstantiated) inference variable has incompatible upper lower bounds.
                                  +         */
                                  +        BAD_UPPER_LOWER() {
                                  +            @Override
                                  +            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
                                  +                return ex.setMessage("incompatible.upper.lower.bounds", uv.qtype,
                                  +                        uv.getBounds(InferenceBound.UPPER), uv.getBounds(InferenceBound.LOWER));
                                  +            }
                                  +        },
                                  +        /**
                                  +         * The (uninstantiated) inference variable has incompatible upper equal bounds.
                                  +         */
                                  +        BAD_UPPER_EQUAL() {
                                  +            @Override
                                  +            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
                                  +                return ex.setMessage("incompatible.upper.eq.bounds", uv.qtype,
                                  +                        uv.getBounds(InferenceBound.UPPER), uv.getBounds(InferenceBound.EQ));
                                  +            }
                                  +        },
                                  +        /**
                                  +         * The (uninstantiated) inference variable has incompatible upper equal bounds.
                                  +         */
                                  +        BAD_EQUAL_LOWER() {
                                  +            @Override
                                  +            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
                                  +                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
                                  +                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
                                  +            }
                                  +        },
                                           /**
                                            * An equality constraint is not compatible with an upper bound.
                                            */
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
                                  index ba0e01df0a2..f77d34fdaa4 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
                                  @@ -833,20 +833,19 @@ public class Resolve {
                                                                       List formals,
                                                                       Warner warn) {
                                               super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
                                  -            //should we expand formals?
                                  +            // should we check varargs element type accessibility?
                                               if (deferredAttrContext.phase.isVarargsRequired()) {
                                  -                Type typeToCheck = null;
                                  -                if (!checkVarargsAccessAfterResolution) {
                                  -                    typeToCheck = types.elemtype(formals.last());
                                  -                } else if (deferredAttrContext.mode == AttrMode.CHECK) {
                                  -                    typeToCheck = types.erasure(types.elemtype(formals.last()));
                                  -                }
                                  -                if (typeToCheck != null) {
                                  -                    varargsAccessible(env, typeToCheck, deferredAttrContext.inferenceContext);
                                  +                if (deferredAttrContext.mode == AttrMode.CHECK || !checkVarargsAccessAfterResolution) {
                                  +                    varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext);
                                                   }
                                               }
                                           }
                                   
                                  +        /**
                                  +         * Test that the runtime array element type corresponding to 't' is accessible.  't' should be the
                                  +         * varargs element type of either the method invocation type signature (after inference completes)
                                  +         * or the method declaration signature (before inference completes).
                                  +         */
                                           private void varargsAccessible(final Env env, final Type t, final InferenceContext inferenceContext) {
                                               if (inferenceContext.free(t)) {
                                                   inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
                                  @@ -856,7 +855,7 @@ public class Resolve {
                                                       }
                                                   });
                                               } else {
                                  -                if (!isAccessible(env, t)) {
                                  +                if (!isAccessible(env, types.erasure(t))) {
                                                       Symbol location = env.enclClass.sym;
                                                       reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
                                                   }
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
                                  index 46d591ee93e..473fce690cb 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -222,6 +222,11 @@ public class Main {
                                           if (args.isEmpty())
                                               return Result.OK;
                                   
                                  +        // init Depeendencies
                                  +        if (options.isSet("completionDeps")) {
                                  +            Dependencies.GraphDependencies.preRegister(context);
                                  +        }
                                  +
                                           // init plugins
                                           Set> pluginOpts = args.getPluginOpts();
                                           if (!pluginOpts.isEmpty()) {
                                  @@ -229,6 +234,9 @@ public class Main {
                                               t.initPlugins(pluginOpts);
                                           }
                                   
                                  +        // init JavaCompiler
                                  +        JavaCompiler comp = JavaCompiler.instance(context);
                                  +
                                           // init doclint
                                           List docLintOpts = args.getDocLintOpts();
                                           if (!docLintOpts.isEmpty()) {
                                  @@ -236,13 +244,6 @@ public class Main {
                                               t.initDocLint(docLintOpts);
                                           }
                                   
                                  -        // init Depeendencies
                                  -        if (options.isSet("completionDeps")) {
                                  -            Dependencies.GraphDependencies.preRegister(context);
                                  -        }
                                  -
                                  -        // init JavaCompiler
                                  -        JavaCompiler comp = JavaCompiler.instance(context);
                                           if (options.get(Option.XSTDOUT) != null) {
                                               // Stdout reassigned - ask compiler to close it when it is done
                                               comp.closeables = comp.closeables.prepend(log.getWriter(WriterKind.NOTICE));
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
                                  index 6dc46740995..023043b30d3 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
                                  @@ -123,6 +123,10 @@ compiler.err.annotation.not.valid.for.type=\
                                   compiler.err.annotation.type.not.applicable=\
                                       annotation type not applicable to this kind of declaration
                                   
                                  +# 0: type
                                  +compiler.err.annotation.type.not.applicable.to.type=\
                                  +    annotation @{0} not applicable in this type context
                                  +
                                   compiler.err.annotation.value.must.be.annotation=\
                                       annotation value must be an annotation
                                   
                                  @@ -406,6 +410,10 @@ compiler.err.invalid.repeatable.annotation.incompatible.target=\
                                   compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\
                                       container {0} must not be present at the same time as the element it contains
                                   
                                  +# 0: type, 1: symbol
                                  +compiler.err.invalid.repeatable.annotation.not.applicable=\
                                  +    container {0} is not applicable to element {1}
                                  +
                                   # 0: name
                                   compiler.err.duplicate.class=\
                                       duplicate class: {0}
                                  @@ -1953,12 +1961,34 @@ compiler.misc.no.unique.minimal.instance.exists=\
                                   compiler.misc.incompatible.upper.bounds=\
                                       inference variable {0} has incompatible upper bounds {1}
                                   
                                  +# 0: type, 1: list of type
                                  +compiler.misc.incompatible.eq.bounds=\
                                  +    inference variable {0} has incompatible equality constraints {1}
                                  +
                                   # 0: type, 1: list of type, 2: list of type
                                   compiler.misc.incompatible.eq.upper.bounds=\
                                       inference variable {0} has incompatible bounds\n\
                                       equality constraints: {1}\n\
                                       upper bounds: {2}
                                   
                                  +# 0: type, 1: list of type, 2: list of type
                                  +compiler.misc.incompatible.upper.lower.bounds=\
                                  +    inference variable {0} has incompatible bounds\n\
                                  +    upper bounds: {1}\n\
                                  +    lower bounds: {2}
                                  +
                                  +# 0: type, 1: list of type, 2: list of type
                                  +compiler.misc.incompatible.upper.eq.bounds=\
                                  +    inference variable {0} has incompatible bounds\n\
                                  +    upper bounds: {1}\n\
                                  +    equality constraints: {2}
                                  +
                                  +# 0: type, 1: list of type, 2: list of type
                                  +compiler.misc.incompatible.eq.lower.bounds=\
                                  +    inference variable {0} has incompatible bounds\n\
                                  +    equality constraints: {1}\n\
                                  +    lower bounds: {2}
                                  +
                                   # 0: type, 1: list of type, 2: list of type
                                   compiler.misc.incompatible.eq.lower.bounds=\
                                       inference variable {0} has incompatible bounds\n\
                                  @@ -2564,6 +2594,7 @@ compiler.misc.where.description.captured.1=\
                                   compiler.misc.where.description.typevar.1=\
                                       where {0} are type-variables:
                                   
                                  +# 0: set of type
                                   compiler.misc.where.description.intersection.1=\
                                       where {0} are intersection types:
                                   
                                  diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties
                                  index 92f2d4ce0b3..5ae7933ea24 100644
                                  --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties
                                  +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties
                                  @@ -316,8 +316,8 @@ These options are non-standard and subject to change without notice.
                                   
                                   javac.msg.bug=\
                                   An exception has occurred in the compiler ({0}). \
                                  -Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  \
                                  -after checking the Bug Parade for duplicates. \
                                  +Please file a bug at the Java Bug Database (http://bugreport.java.com/bugreport/) \
                                  +after checking the database for duplicates. \
                                   Include your program and the following diagnostic in your report.  Thank you.
                                   
                                   javac.msg.io=\
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
                                  index c42a692803f..54d8046ff1d 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -415,8 +415,10 @@ public abstract class AbstractMemberWriter {
                                       protected void addDeprecatedAPI(List deprmembers, String headingKey,
                                               String tableSummary, String[] tableHeader, Content contentTree) {
                                           if (deprmembers.size() > 0) {
                                  -            Content table = HtmlTree.TABLE(HtmlStyle.deprecatedSummary, 0, 3, 0, tableSummary,
                                  -                writer.getTableCaption(configuration.getResource(headingKey)));
                                  +            Content caption = writer.getTableCaption(configuration.getResource(headingKey));
                                  +            Content table = (configuration.isOutputHtml5())
                                  +                    ? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
                                  +                    : HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
                                               table.addContent(writer.getSummaryTableHeader(tableHeader, "col"));
                                               Content tbody = new HtmlTree(HtmlTag.TBODY);
                                               for (int i = 0; i < deprmembers.size(); i++) {
                                  @@ -455,8 +457,10 @@ public abstract class AbstractMemberWriter {
                                           List members = mems;
                                           boolean printedUseTableHeader = false;
                                           if (members.size() > 0) {
                                  -            Content table = HtmlTree.TABLE(HtmlStyle.useSummary, 0, 3, 0, tableSummary,
                                  -                    writer.getTableCaption(heading));
                                  +            Content caption = writer.getTableCaption(heading);
                                  +            Content table = (configuration.isOutputHtml5())
                                  +                    ? HtmlTree.TABLE(HtmlStyle.useSummary, caption)
                                  +                    : HtmlTree.TABLE(HtmlStyle.useSummary, tableSummary, caption);
                                               Content tbody = new HtmlTree(HtmlTag.TBODY);
                                               Iterator it = members.iterator();
                                               for (int i = 0; it.hasNext(); i++) {
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
                                  index 76bf7aae7c8..9378865aacd 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -149,13 +149,17 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
                                       protected void addIndexContents(Collection packages, String text,
                                               String tableSummary, Content body) {
                                           if (!packages.isEmpty()) {
                                  -            HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                  -            div.addStyle(HtmlStyle.indexHeader);
                                  -            addAllClassesLink(div);
                                  +            HtmlTree htmlTree = (configuration.allowTag(HtmlTag.NAV))
                                  +                    ? HtmlTree.NAV()
                                  +                    : new HtmlTree(HtmlTag.DIV);
                                  +            htmlTree.addStyle(HtmlStyle.indexNav);
                                  +            HtmlTree ul = new HtmlTree(HtmlTag.UL);
                                  +            addAllClassesLink(ul);
                                               if (configuration.showProfiles) {
                                  -                addAllProfilesLink(div);
                                  +                addAllProfilesLink(ul);
                                               }
                                  -            body.addContent(div);
                                  +            htmlTree.addContent(ul);
                                  +            body.addContent(htmlTree);
                                               if (configuration.showProfiles && configuration.profilePackages.size() > 0) {
                                                   Content profileSummary = configuration.getResource("doclet.Profiles");
                                                   addProfilesList(profileSummary, body);
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java
                                  index c0f7ccf3976..debbdadc10b 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractProfileIndexWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -194,11 +194,15 @@ public abstract class AbstractProfileIndexWriter extends HtmlDocletWriter {
                                       protected void addIndexContents(Profiles profiles, String text,
                                               String tableSummary, Content body) {
                                           if (profiles.getProfileCount() > 0) {
                                  -            HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                  -            div.addStyle(HtmlStyle.indexHeader);
                                  -            addAllClassesLink(div);
                                  -            addAllPackagesLink(div);
                                  -            body.addContent(div);
                                  +            HtmlTree htmlTree = (configuration.allowTag(HtmlTag.NAV))
                                  +                    ? HtmlTree.NAV()
                                  +                    : new HtmlTree(HtmlTag.DIV);
                                  +            htmlTree.addStyle(HtmlStyle.indexNav);
                                  +            HtmlTree ul = new HtmlTree(HtmlTag.UL);
                                  +            addAllClassesLink(ul);
                                  +            addAllPackagesLink(ul);
                                  +            htmlTree.addContent(ul);
                                  +            body.addContent(htmlTree);
                                               addProfilesList(profiles, text, tableSummary, body);
                                           }
                                       }
                                  @@ -215,12 +219,16 @@ public abstract class AbstractProfileIndexWriter extends HtmlDocletWriter {
                                        */
                                       protected void addProfilePackagesIndexContents(Profiles profiles, String text,
                                               String tableSummary, Content body, String profileName) {
                                  -        HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                  -        div.addStyle(HtmlStyle.indexHeader);
                                  -        addAllClassesLink(div);
                                  -        addAllPackagesLink(div);
                                  -        addAllProfilesLink(div);
                                  -        body.addContent(div);
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.NAV))
                                  +                ? HtmlTree.NAV()
                                  +                : new HtmlTree(HtmlTag.DIV);
                                  +        htmlTree.addStyle(HtmlStyle.indexNav);
                                  +        HtmlTree ul = new HtmlTree(HtmlTag.UL);
                                  +        addAllClassesLink(ul);
                                  +        addAllPackagesLink(ul);
                                  +        addAllProfilesLink(ul);
                                  +        htmlTree.addContent(ul);
                                  +        body.addContent(htmlTree);
                                           addProfilePackagesList(profiles, text, tableSummary, body, profileName);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
                                  index fa02e59f692..cd4c70f47bb 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -53,8 +53,6 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
                                        */
                                       protected final ClassTree classtree;
                                   
                                  -    private static final String LI_CIRCLE  = "circle";
                                  -
                                       /**
                                        * Constructor initializes classtree variable. This constructor will be used
                                        * while generating global tree file "overview-tree.html".
                                  @@ -88,7 +86,7 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
                                               Content ul = new HtmlTree(HtmlTag.UL);
                                               for (ClassDoc local : list) {
                                                   HtmlTree li = new HtmlTree(HtmlTag.LI);
                                  -                li.addAttr(HtmlAttr.TYPE, LI_CIRCLE);
                                  +                li.addStyle(HtmlStyle.circle);
                                                   addPartialInfo(local, li);
                                                   addExtendsImplements(parent, local, li);
                                                   addLevelInfo(local, classtree.subs(local, isEnum),
                                  @@ -108,14 +106,24 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
                                        * @param heading heading for the tree
                                        * @param div the content tree to which the tree will be added
                                        */
                                  -    protected void addTree(SortedSet list, String heading, Content div) {
                                  +    protected void addTree(SortedSet list, String heading, HtmlTree div) {
                                           if (!list.isEmpty()) {
                                               ClassDoc firstClassDoc = list.first();
                                               Content headingContent = getResource(heading);
                                  -            div.addContent(HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
                                  -                    headingContent));
                                  +            Content sectionHeading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
                                  +                    headingContent);
                                  +            HtmlTree htmlTree;
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                htmlTree = HtmlTree.SECTION(sectionHeading);
                                  +            } else {
                                  +                div.addContent(sectionHeading);
                                  +                htmlTree = div;
                                  +            }
                                               addLevelInfo(!firstClassDoc.isInterface()? firstClassDoc : null,
                                  -                    list, list == classtree.baseEnums(), div);
                                  +                    list, list == classtree.baseEnums(), htmlTree);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                div.addContent(htmlTree);
                                  +            }
                                           }
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
                                  index 71e27df0266..32f30f3331b 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -119,8 +119,10 @@ public class AllClassesFrameWriter extends HtmlDocletWriter {
                                           Content ul = new HtmlTree(HtmlTag.UL);
                                           // Generate the class links and add it to the tdFont tree.
                                           addAllClasses(ul, wantFrames);
                                  -        Content div = HtmlTree.DIV(HtmlStyle.indexContainer, ul);
                                  -        body.addContent(div);
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
                                  +                ? HtmlTree.MAIN(HtmlStyle.indexContainer, ul)
                                  +                : HtmlTree.DIV(HtmlStyle.indexContainer, ul);
                                  +        body.addContent(htmlTree);
                                           printHtmlDocument(null, false, body);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java
                                  index 55dcd84fc64..87cf3a079dc 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -74,6 +74,13 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter
                                           return writer.getMemberTreeHeader();
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addMemberTree(Content memberSummaryTree, Content memberTree) {
                                  +        writer.addMemberTree(memberSummaryTree, memberTree);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  @@ -156,6 +163,10 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter
                                        * {@inheritDoc}
                                        */
                                       public Content getAnnotationDetails(Content annotationDetailsTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(annotationDetailsTree));
                                  +            return htmlTree;
                                  +        }
                                           return getMemberTree(annotationDetailsTree);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
                                  index 9a586a017f3..66f60f986d0 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -69,6 +69,13 @@ public class AnnotationTypeOptionalMemberWriterImpl extends
                                           return memberTree;
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addMemberTree(Content memberSummaryTree, Content memberTree) {
                                  +        writer.addMemberTree(memberSummaryTree, memberTree);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
                                  index a3392011ae2..63ed9459a17 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -75,6 +75,13 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
                                           return writer.getMemberTreeHeader();
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addMemberTree(Content memberSummaryTree, Content memberTree) {
                                  +        writer.addMemberTree(memberSummaryTree, memberTree);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  @@ -158,6 +165,10 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
                                        * {@inheritDoc}
                                        */
                                       public Content getAnnotationDetails(Content annotationDetailsTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(annotationDetailsTree));
                                  +            return htmlTree;
                                  +        }
                                           return getMemberTree(annotationDetailsTree);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
                                  index 1bbc147e75a..447b93bdbf1 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -151,9 +151,15 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
                                           String pkgname = (annotationType.containingPackage() != null)?
                                               annotationType.containingPackage().name(): "";
                                           String clname = annotationType.name();
                                  -        Content bodyTree = getBody(true, getWindowTitle(clname));
                                  -        addTop(bodyTree);
                                  -        addNavLinks(true, bodyTree);
                                  +        HtmlTree bodyTree = getBody(true, getWindowTitle(clname));
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
                                  +                ? HtmlTree.HEADER()
                                  +                : bodyTree;
                                  +        addTop(htmlTree);
                                  +        addNavLinks(true, htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.HEADER)) {
                                  +            bodyTree.addContent(htmlTree);
                                  +        }
                                           bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA);
                                           HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                           div.addStyle(HtmlStyle.header);
                                  @@ -169,7 +175,11 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
                                                   HtmlStyle.title, headerContent);
                                           heading.addContent(getTypeParameterLinks(linkInfo));
                                           div.addContent(heading);
                                  -        bodyTree.addContent(div);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(div);
                                  +        } else {
                                  +            bodyTree.addContent(div);
                                  +        }
                                           return bodyTree;
                                       }
                                   
                                  @@ -185,8 +195,14 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
                                        */
                                       public void addFooter(Content contentTree) {
                                           contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA);
                                  -        addNavLinks(false, contentTree);
                                  -        addBottom(contentTree);
                                  +        Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
                                  +                ? HtmlTree.FOOTER()
                                  +                : contentTree;
                                  +        addNavLinks(false, htmlTree);
                                  +        addBottom(htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            contentTree.addContent(htmlTree);
                                  +        }
                                       }
                                   
                                       /**
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
                                  index f805cc01c80..883e65795ae 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -90,6 +90,11 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                       final String methodUseTableSummary;
                                       final String constructorUseTableSummary;
                                   
                                  +    /**
                                  +     * The HTML tree for main tag.
                                  +     */
                                  +    protected HtmlTree mainTree = HtmlTree.MAIN();
                                  +
                                       /**
                                        * Constructor.
                                        *
                                  @@ -222,7 +227,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                        * Generate the class use list.
                                        */
                                       protected void generateClassUseFile() throws IOException {
                                  -        Content body = getClassUseHeader();
                                  +        HtmlTree body = getClassUseHeader();
                                           HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                           div.addStyle(HtmlStyle.classUseContainer);
                                           if (pkgSet.size() > 0) {
                                  @@ -231,9 +236,20 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                               div.addContent(getResource("doclet.ClassUse_No.usage.of.0",
                                                       classdoc.qualifiedName()));
                                           }
                                  -        body.addContent(div);
                                  -        addNavLinks(false, body);
                                  -        addBottom(body);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(div);
                                  +            body.addContent(mainTree);
                                  +        } else {
                                  +            body.addContent(div);
                                  +        }
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
                                  +                ? HtmlTree.FOOTER()
                                  +                : body;
                                  +        addNavLinks(false, htmlTree);
                                  +        addBottom(htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            body.addContent(htmlTree);
                                  +        }
                                           printHtmlDocument(null, true, body);
                                       }
                                   
                                  @@ -259,11 +275,12 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                        * @param contentTree the content tree to which the packages list will be added
                                        */
                                       protected void addPackageList(Content contentTree) throws IOException {
                                  -        Content table = HtmlTree.TABLE(HtmlStyle.useSummary, 0, 3, 0, useTableSummary,
                                  -                getTableCaption(configuration.getResource(
                                  +        Content caption = getTableCaption(configuration.getResource(
                                                   "doclet.ClassUse_Packages.that.use.0",
                                  -                getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc
                                  -                )))));
                                  +                getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc))));
                                  +        Content table = (configuration.isOutputHtml5())
                                  +                ? HtmlTree.TABLE(HtmlStyle.useSummary, caption)
                                  +                : HtmlTree.TABLE(HtmlStyle.useSummary, useTableSummary, caption);
                                           table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
                                           Content tbody = new HtmlTree(HtmlTag.TBODY);
                                           Iterator it = pkgSet.iterator();
                                  @@ -294,11 +311,13 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                                   pkgToPackageAnnotations.isEmpty()) {
                                               return;
                                           }
                                  -        Content table = HtmlTree.TABLE(HtmlStyle.useSummary, 0, 3, 0, useTableSummary,
                                  -                getTableCaption(configuration.getResource(
                                  +        Content caption = getTableCaption(configuration.getResource(
                                                   "doclet.ClassUse_PackageAnnotation",
                                                   getLink(new LinkInfoImpl(configuration,
                                  -                        LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)))));
                                  +                                LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc))));
                                  +        Content table = (configuration.isOutputHtml5())
                                  +                ? HtmlTree.TABLE(HtmlStyle.useSummary, caption)
                                  +                : HtmlTree.TABLE(HtmlStyle.useSummary, useTableSummary, caption);
                                           table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
                                           Content tbody = new HtmlTree(HtmlTag.TBODY);
                                           Iterator it = pkgToPackageAnnotations.iterator();
                                  @@ -333,15 +352,22 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                           HtmlTree ul = new HtmlTree(HtmlTag.UL);
                                           ul.addStyle(HtmlStyle.blockList);
                                           for (PackageDoc pkg : pkgSet) {
                                  -            Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(getPackageAnchorName(pkg)));
                                  +            Content markerAnchor = getMarkerAnchor(getPackageAnchorName(pkg));
                                  +            HtmlTree htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                    ? HtmlTree.SECTION(markerAnchor)
                                  +                    : HtmlTree.LI(HtmlStyle.blockList, markerAnchor);
                                               Content link = getResource("doclet.ClassUse_Uses.of.0.in.1",
                                                                          getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER,
                                                                                                   classdoc)),
                                                                          getPackageLink(pkg, utils.getPackageName(pkg)));
                                               Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link);
                                  -            li.addContent(heading);
                                  -            addClassUse(pkg, li);
                                  -            ul.addContent(li);
                                  +            htmlTree.addContent(heading);
                                  +            addClassUse(pkg, htmlTree);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +            } else {
                                  +                ul.addContent(htmlTree);
                                  +            }
                                           }
                                           Content li = HtmlTree.LI(HtmlStyle.blockList, ul);
                                           contentTree.addContent(li);
                                  @@ -443,15 +469,21 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                        *
                                        * @return a content tree representing the class use header
                                        */
                                  -    protected Content getClassUseHeader() {
                                  +    protected HtmlTree getClassUseHeader() {
                                           String cltype = configuration.getText(classdoc.isInterface()?
                                               "doclet.Interface":"doclet.Class");
                                           String clname = classdoc.qualifiedName();
                                           String title = configuration.getText("doclet.Window_ClassUse_Header",
                                                   cltype, clname);
                                  -        Content bodyTree = getBody(true, getWindowTitle(title));
                                  -        addTop(bodyTree);
                                  -        addNavLinks(true, bodyTree);
                                  +        HtmlTree bodyTree = getBody(true, getWindowTitle(title));
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
                                  +                ? HtmlTree.HEADER()
                                  +                : bodyTree;
                                  +        addTop(htmlTree);
                                  +        addNavLinks(true, htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.HEADER)) {
                                  +            bodyTree.addContent(htmlTree);
                                  +        }
                                           ContentBuilder headContent = new ContentBuilder();
                                           headContent.addContent(getResource("doclet.ClassUse_Title", cltype));
                                           headContent.addContent(new HtmlTree(HtmlTag.BR));
                                  @@ -459,7 +491,11 @@ public class ClassUseWriter extends SubWriterHolderWriter {
                                           Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING,
                                                   true, HtmlStyle.title, headContent);
                                           Content div = HtmlTree.DIV(HtmlStyle.header, heading);
                                  -        bodyTree.addContent(div);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(div);
                                  +        } else {
                                  +            bodyTree.addContent(div);
                                  +        }
                                           return bodyTree;
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
                                  index c364bd16e34..d9dafe97c23 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -35,6 +35,7 @@ import com.sun.tools.doclets.internal.toolkit.*;
                                   import com.sun.tools.doclets.internal.toolkit.builders.*;
                                   import com.sun.tools.doclets.internal.toolkit.taglets.*;
                                   import com.sun.tools.doclets.internal.toolkit.util.*;
                                  +
                                   import java.io.IOException;
                                   
                                   /**
                                  @@ -160,9 +161,15 @@ public class ClassWriterImpl extends SubWriterHolderWriter
                                           String pkgname = (classDoc.containingPackage() != null)?
                                               classDoc.containingPackage().name(): "";
                                           String clname = classDoc.name();
                                  -        Content bodyTree = getBody(true, getWindowTitle(clname));
                                  -        addTop(bodyTree);
                                  -        addNavLinks(true, bodyTree);
                                  +        HtmlTree bodyTree = getBody(true, getWindowTitle(clname));
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
                                  +                ? HtmlTree.HEADER()
                                  +                : bodyTree;
                                  +        addTop(htmlTree);
                                  +        addNavLinks(true, htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.HEADER)) {
                                  +            bodyTree.addContent(htmlTree);
                                  +        }
                                           bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA);
                                           HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                           div.addStyle(HtmlStyle.header);
                                  @@ -194,7 +201,11 @@ public class ClassWriterImpl extends SubWriterHolderWriter
                                                   HtmlStyle.title, headerContent);
                                           heading.addContent(getTypeParameterLinks(linkInfo));
                                           div.addContent(heading);
                                  -        bodyTree.addContent(div);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(div);
                                  +        } else {
                                  +            bodyTree.addContent(div);
                                  +        }
                                           return bodyTree;
                                       }
                                   
                                  @@ -210,8 +221,14 @@ public class ClassWriterImpl extends SubWriterHolderWriter
                                        */
                                       public void addFooter(Content contentTree) {
                                           contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA);
                                  -        addNavLinks(false, contentTree);
                                  -        addBottom(contentTree);
                                  +        Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
                                  +                ? HtmlTree.FOOTER()
                                  +                : contentTree;
                                  +        addNavLinks(false, htmlTree);
                                  +        addBottom(htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            contentTree.addContent(htmlTree);
                                  +        }
                                       }
                                   
                                       /**
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
                                  index 902a2709ac1..7c7882615b2 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -31,7 +31,7 @@ import java.util.*;
                                   import javax.tools.JavaFileManager;
                                   
                                   import com.sun.javadoc.*;
                                  -import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
                                  +import com.sun.tools.doclets.formats.html.markup.*;
                                   import com.sun.tools.doclets.internal.toolkit.*;
                                   import com.sun.tools.doclets.internal.toolkit.util.*;
                                   import com.sun.tools.doclint.DocLint;
                                  @@ -175,6 +175,11 @@ public class ConfigurationImpl extends Configuration {
                                        */
                                       public boolean createoverview = false;
                                   
                                  +    /**
                                  +     * This is the HTML version of the generated pages. HTML 4.01 is the default output version.
                                  +     */
                                  +    public HtmlVersion htmlVersion = HtmlVersion.HTML4;
                                  +
                                       /**
                                        * Collected set of doclint options
                                        */
                                  @@ -279,6 +284,10 @@ public class ConfigurationImpl extends Configuration {
                                                   nooverview = true;
                                               } else if (opt.equals("-overview")) {
                                                   overview = true;
                                  +            } else if (opt.equals("-html4")) {
                                  +                htmlVersion = HtmlVersion.HTML4;
                                  +            } else if (opt.equals("-html5")) {
                                  +                htmlVersion = HtmlVersion.HTML5;
                                               } else if (opt.equals("-xdoclint")) {
                                                   doclintOpts.add(null);
                                               } else if (opt.startsWith("-xdoclint:")) {
                                  @@ -300,7 +309,8 @@ public class ConfigurationImpl extends Configuration {
                                           setTopFile(root);
                                   
                                           if (root instanceof RootDocImpl) {
                                  -            ((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames());
                                  +            ((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames(),
                                  +                    StringUtils.toLowerCase(htmlVersion.name()));
                                           }
                                       }
                                   
                                  @@ -336,6 +346,8 @@ public class ConfigurationImpl extends Configuration {
                                               option.equals("-use") ||
                                               option.equals("-nonavbar") ||
                                               option.equals("-nooverview") ||
                                  +            option.equals("-html4") ||
                                  +            option.equals("-html5") ||
                                               option.equals("-xdoclint") ||
                                               option.startsWith("-xdoclint:")) {
                                               return 1;
                                  @@ -470,6 +482,20 @@ public class ConfigurationImpl extends Configuration {
                                           return true;
                                       }
                                   
                                  +    /**
                                  +     * Return true if the generated output is HTML5.
                                  +     */
                                  +    public boolean isOutputHtml5() {
                                  +        return htmlVersion == HtmlVersion.HTML5;
                                  +    }
                                  +
                                  +    /**
                                  +     * Return true if the tag is allowed for this specific version of HTML.
                                  +     */
                                  +    public boolean allowTag(HtmlTag htmlTag) {
                                  +        return htmlTag.allowTag(this.htmlVersion);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
                                  index 21f0c215038..10abd4b6cfd 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -62,6 +62,16 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                   
                                       private final String[] constantsTableHeader;
                                   
                                  +    /**
                                  +     * The HTML tree for main tag.
                                  +     */
                                  +    private HtmlTree mainTree = HtmlTree.MAIN();
                                  +
                                  +    /**
                                  +     * The HTML tree for constant values summary.
                                  +     */
                                  +    private HtmlTree summaryTree;
                                  +
                                       /**
                                        * Construct a ConstantsSummaryWriter.
                                        * @param configuration the configuration used in this run
                                  @@ -85,9 +95,15 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                        */
                                       public Content getHeader() {
                                           String label = configuration.getText("doclet.Constants_Summary");
                                  -        Content bodyTree = getBody(true, getWindowTitle(label));
                                  -        addTop(bodyTree);
                                  -        addNavLinks(true, bodyTree);
                                  +        HtmlTree bodyTree = getBody(true, getWindowTitle(label));
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
                                  +                ? HtmlTree.HEADER()
                                  +                : bodyTree;
                                  +        addTop(htmlTree);
                                  +        addNavLinks(true, htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.HEADER)) {
                                  +            bodyTree.addContent(htmlTree);
                                  +        }
                                           return bodyTree;
                                       }
                                   
                                  @@ -123,7 +139,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                       /**
                                        * {@inheritDoc}
                                        */
                                  -    public Content getContentsList(Content contentListTree) {
                                  +    public void addContentsList(Content contentTree, Content contentListTree) {
                                           Content titleContent = getResource(
                                                   "doclet.Constants_Summary");
                                           Content pHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
                                  @@ -131,10 +147,18 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                           Content div = HtmlTree.DIV(HtmlStyle.header, pHeading);
                                           Content headingContent = getResource(
                                                   "doclet.Contents");
                                  -        div.addContent(HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
                                  -                headingContent));
                                  -        div.addContent(contentListTree);
                                  -        return div;
                                  +        Content heading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
                                  +                headingContent);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            HtmlTree section = HtmlTree.SECTION(heading);
                                  +            section.addContent(contentListTree);
                                  +            div.addContent(section);
                                  +            mainTree.addContent(div);
                                  +        } else {
                                  +            div.addContent(heading);
                                  +            div.addContent(contentListTree);
                                  +            contentTree.addContent(div);
                                  +        }
                                       }
                                   
                                       /**
                                  @@ -149,9 +173,11 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                       /**
                                        * {@inheritDoc}
                                        */
                                  -    public void addPackageName(PackageDoc pkg, String parsedPackageName,
                                  -            Content summariesTree) {
                                  +    public void addPackageName(String parsedPackageName, Content summariesTree, boolean first) {
                                           Content pkgNameContent;
                                  +        if (!first && configuration.allowTag(HtmlTag.SECTION)) {
                                  +            summariesTree.addContent(summaryTree);
                                  +        }
                                           if (parsedPackageName.length() == 0) {
                                               summariesTree.addContent(getMarkerAnchor(
                                                       SectionName.UNNAMED_PACKAGE_ANCHOR));
                                  @@ -165,7 +191,11 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                           Content heading = HtmlTree.HEADING(HtmlConstants.PACKAGE_HEADING, true,
                                                   pkgNameContent);
                                           heading.addContent(headingContent);
                                  -        summariesTree.addContent(heading);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            summaryTree = HtmlTree.SECTION(heading);
                                  +        } else {
                                  +            summariesTree.addContent(heading);
                                  +        }
                                       }
                                   
                                       /**
                                  @@ -177,6 +207,17 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                           return ul;
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addClassConstant(Content summariesTree, Content classConstantTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            summaryTree.addContent(classConstantTree);
                                  +        } else {
                                  +            summariesTree.addContent(classConstantTree);
                                  +        }
                                  +    }
                                  +
                                       /**
                                        * Get the table caption and header for the constant summary table
                                        *
                                  @@ -208,8 +249,10 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                        * @return the table caption and header
                                        */
                                       protected Content getClassName(Content classStr) {
                                  -        Content table = HtmlTree.TABLE(HtmlStyle.constantsSummary, 0, 3, 0, constantsTableSummary,
                                  -                getTableCaption(classStr));
                                  +        Content caption = getTableCaption(classStr);
                                  +        Content table = (configuration.isOutputHtml5())
                                  +                ? HtmlTree.TABLE(HtmlStyle.constantsSummary, caption)
                                  +                : HtmlTree.TABLE(HtmlStyle.constantsSummary, constantsTableSummary, caption);
                                           table.addContent(getSummaryTableHeader(constantsTableHeader, "col"));
                                           return table;
                                       }
                                  @@ -297,12 +340,33 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter
                                           return HtmlTree.TD(HtmlStyle.colLast, code);
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addConstantSummaries(Content contentTree, Content summariesTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION) && summaryTree != null) {
                                  +            summariesTree.addContent(summaryTree);
                                  +        }
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(summariesTree);
                                  +            contentTree.addContent(mainTree);
                                  +        } else {
                                  +            contentTree.addContent(summariesTree);
                                  +        }
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                       public void addFooter(Content contentTree) {
                                  -        addNavLinks(false, contentTree);
                                  -        addBottom(contentTree);
                                  +        Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
                                  +                ? HtmlTree.FOOTER()
                                  +                : contentTree;
                                  +        addNavLinks(false, htmlTree);
                                  +        addBottom(htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            contentTree.addContent(htmlTree);
                                  +        }
                                       }
                                   
                                       /**
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
                                  index 989aaf95e44..d8d07632cd6 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -89,6 +89,13 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
                                           return memberTree;
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addMemberTree(Content memberSummaryTree, Content memberTree) {
                                  +        writer.addMemberTree(memberSummaryTree, memberTree);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  @@ -177,6 +184,10 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
                                        * {@inheritDoc}
                                        */
                                       public Content getConstructorDetails(Content constructorDetailsTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(constructorDetailsTree));
                                  +            return htmlTree;
                                  +        }
                                           return getMemberTree(constructorDetailsTree);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java
                                  index 63c81438956..85c6dc8ec59 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -138,8 +138,11 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
                                        */
                                       protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprapi)
                                               throws IOException {
                                  -        Content body = getHeader();
                                  -        body.addContent(getContentsList(deprapi));
                                  +        HtmlTree body = getHeader();
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
                                  +                ? HtmlTree.MAIN()
                                  +                : body;
                                  +        htmlTree.addContent(getContentsList(deprapi));
                                           String memberTableSummary;
                                           String[] memberTableHeader = new String[1];
                                           HtmlTree div = new HtmlTree(HtmlTag.DIV);
                                  @@ -164,9 +167,20 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
                                                               HEADING_KEYS[i], memberTableSummary, memberTableHeader, div);
                                               }
                                           }
                                  -        body.addContent(div);
                                  -        addNavLinks(false, body);
                                  -        addBottom(body);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            htmlTree.addContent(div);
                                  +            body.addContent(htmlTree);
                                  +        } else {
                                  +            body.addContent(div);
                                  +        }
                                  +        htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
                                  +                ? HtmlTree.FOOTER()
                                  +                : body;
                                  +        addNavLinks(false, htmlTree);
                                  +        addBottom(htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            body.addContent(htmlTree);
                                  +        }
                                           printHtmlDocument(null, true, body);
                                       }
                                   
                                  @@ -226,11 +240,17 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
                                        *
                                        * @return a content tree for the header
                                        */
                                  -    public Content getHeader() {
                                  +    public HtmlTree getHeader() {
                                           String title = configuration.getText("doclet.Window_Deprecated_List");
                                  -        Content bodyTree = getBody(true, getWindowTitle(title));
                                  -        addTop(bodyTree);
                                  -        addNavLinks(true, bodyTree);
                                  +        HtmlTree bodyTree = getBody(true, getWindowTitle(title));
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
                                  +                ? HtmlTree.HEADER()
                                  +                : bodyTree;
                                  +        addTop(htmlTree);
                                  +        addNavLinks(true, htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.HEADER)) {
                                  +            bodyTree.addContent(htmlTree);
                                  +        }
                                           return bodyTree;
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
                                  index 34a3a5027aa..82ac9748ba1 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -66,6 +66,13 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
                                           return memberTree;
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addMemberTree(Content memberSummaryTree, Content memberTree) {
                                  +        writer.addMemberTree(memberSummaryTree, memberTree);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  @@ -140,6 +147,10 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
                                        * {@inheritDoc}
                                        */
                                       public Content getEnumConstantsDetails(Content enumConstantsDetailsTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(enumConstantsDetailsTree));
                                  +            return htmlTree;
                                  +        }
                                           return getMemberTree(enumConstantsDetailsTree);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
                                  index 9ae2501efb9..7d1455bfad0 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -67,6 +67,13 @@ public class FieldWriterImpl extends AbstractMemberWriter
                                           return memberTree;
                                       }
                                   
                                  +    /**
                                  +     * {@inheritDoc}
                                  +     */
                                  +    public void addMemberTree(Content memberSummaryTree, Content memberTree) {
                                  +        writer.addMemberTree(memberSummaryTree, memberTree);
                                  +    }
                                  +
                                       /**
                                        * {@inheritDoc}
                                        */
                                  @@ -161,6 +168,10 @@ public class FieldWriterImpl extends AbstractMemberWriter
                                        * {@inheritDoc}
                                        */
                                       public Content getFieldDetails(Content fieldDetailsTree) {
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(fieldDetailsTree));
                                  +            return htmlTree;
                                  +        }
                                           return getMemberTree(fieldDetailsTree);
                                       }
                                   
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
                                  index 706f0d7b6c7..037d7fa77eb 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
                                  @@ -96,7 +96,12 @@ public class FrameOutputWriter extends HtmlDocletWriter {
                                       protected void generateFrameFile() throws IOException {
                                           Content frame = getFrameDetails();
                                           HtmlTree body = new HtmlTree(HtmlTag.BODY);
                                  -        body.addContent(frame);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            HtmlTree main = HtmlTree.MAIN(frame);
                                  +            body.addContent(main);
                                  +        } else {
                                  +            body.addContent(frame);
                                  +        }
                                           if (configuration.windowtitle.length() > 0) {
                                               printFramesDocument(configuration.windowtitle, configuration,
                                                       body);
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
                                  index e1111faf9e9..d5b7c0f1b13 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -44,6 +44,8 @@ import com.sun.tools.doclets.internal.toolkit.util.*;
                                    */
                                   public class HelpWriter extends HtmlDocletWriter {
                                   
                                  +    HtmlTree mainTree = HtmlTree.MAIN();
                                  +
                                       /**
                                        * Constructor to construct HelpWriter object.
                                        * @param filename File to be generated.
                                  @@ -81,12 +83,24 @@ public class HelpWriter extends HtmlDocletWriter {
                                        */
                                       protected void generateHelpFile() throws IOException {
                                           String title = configuration.getText("doclet.Window_Help_title");
                                  -        Content body = getBody(true, getWindowTitle(title));
                                  -        addTop(body);
                                  -        addNavLinks(true, body);
                                  +        HtmlTree body = getBody(true, getWindowTitle(title));
                                  +        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
                                  +                ? HtmlTree.HEADER()
                                  +                : body;
                                  +        addTop(htmlTree);
                                  +        addNavLinks(true, htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.HEADER)) {
                                  +            body.addContent(htmlTree);
                                  +        }
                                           addHelpFileContents(body);
                                  -        addNavLinks(false, body);
                                  -        addBottom(body);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            htmlTree = HtmlTree.FOOTER();
                                  +        }
                                  +        addNavLinks(false, htmlTree);
                                  +        addBottom(htmlTree);
                                  +        if (configuration.allowTag(HtmlTag.FOOTER)) {
                                  +            body.addContent(htmlTree);
                                  +        }
                                           printHtmlDocument(null, true, body);
                                       }
                                   
                                  @@ -105,26 +119,39 @@ public class HelpWriter extends HtmlDocletWriter {
                                           Content line2 = HtmlTree.DIV(HtmlStyle.subTitle,
                                                   getResource("doclet.Help_line_2"));
                                           div.addContent(line2);
                                  -        contentTree.addContent(div);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(div);
                                  +        } else {
                                  +            contentTree.addContent(div);
                                  +        }
                                  +        HtmlTree htmlTree;
                                           HtmlTree ul = new HtmlTree(HtmlTag.UL);
                                           ul.addStyle(HtmlStyle.blockList);
                                           if (configuration.createoverview) {
                                               Content overviewHeading = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Overview"));
                                  -            Content liOverview = HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
                                  +            htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                    ? HtmlTree.SECTION(overviewHeading)
                                  +                    : HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
                                               Content line3 = getResource("doclet.Help_line_3",
                                                       getHyperLink(DocPaths.OVERVIEW_SUMMARY,
                                                       configuration.getText("doclet.Overview")));
                                               Content overviewPara = HtmlTree.P(line3);
                                  -            liOverview.addContent(overviewPara);
                                  -            ul.addContent(liOverview);
                                  +            htmlTree.addContent(overviewPara);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +            } else {
                                  +                ul.addContent(htmlTree);
                                  +            }
                                           }
                                           Content packageHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Package"));
                                  -        Content liPackage = HtmlTree.LI(HtmlStyle.blockList, packageHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(packageHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, packageHead);
                                           Content line4 = getResource("doclet.Help_line_4");
                                           Content packagePara = HtmlTree.P(line4);
                                  -        liPackage.addContent(packagePara);
                                  +        htmlTree.addContent(packagePara);
                                           HtmlTree ulPackage = new HtmlTree(HtmlTag.UL);
                                           ulPackage.addContent(HtmlTree.LI(
                                                   getResource("doclet.Interfaces_Italic")));
                                  @@ -138,14 +165,20 @@ public class HelpWriter extends HtmlDocletWriter {
                                                   getResource("doclet.Errors")));
                                           ulPackage.addContent(HtmlTree.LI(
                                                   getResource("doclet.AnnotationTypes")));
                                  -        liPackage.addContent(ulPackage);
                                  -        ul.addContent(liPackage);
                                  +        htmlTree.addContent(ulPackage);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           Content classHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Help_line_5"));
                                  -        Content liClass = HtmlTree.LI(HtmlStyle.blockList, classHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(classHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, classHead);
                                           Content line6 = getResource("doclet.Help_line_6");
                                           Content classPara = HtmlTree.P(line6);
                                  -        liClass.addContent(classPara);
                                  +        htmlTree.addContent(classPara);
                                           HtmlTree ul1 = new HtmlTree(HtmlTag.UL);
                                           ul1.addContent(HtmlTree.LI(
                                                   getResource("doclet.Help_line_7")));
                                  @@ -159,7 +192,7 @@ public class HelpWriter extends HtmlDocletWriter {
                                                   getResource("doclet.Help_line_11")));
                                           ul1.addContent(HtmlTree.LI(
                                                   getResource("doclet.Help_line_12")));
                                  -        liClass.addContent(ul1);
                                  +        htmlTree.addContent(ul1);
                                           HtmlTree ul2 = new HtmlTree(HtmlTag.UL);
                                           ul2.addContent(HtmlTree.LI(
                                                   getResource("doclet.Nested_Class_Summary")));
                                  @@ -169,7 +202,7 @@ public class HelpWriter extends HtmlDocletWriter {
                                                   getResource("doclet.Constructor_Summary")));
                                           ul2.addContent(HtmlTree.LI(
                                                   getResource("doclet.Method_Summary")));
                                  -        liClass.addContent(ul2);
                                  +        htmlTree.addContent(ul2);
                                           HtmlTree ul3 = new HtmlTree(HtmlTag.UL);
                                           ul3.addContent(HtmlTree.LI(
                                                   getResource("doclet.Field_Detail")));
                                  @@ -177,18 +210,24 @@ public class HelpWriter extends HtmlDocletWriter {
                                                   getResource("doclet.Constructor_Detail")));
                                           ul3.addContent(HtmlTree.LI(
                                                   getResource("doclet.Method_Detail")));
                                  -        liClass.addContent(ul3);
                                  +        htmlTree.addContent(ul3);
                                           Content line13 = getResource("doclet.Help_line_13");
                                           Content para = HtmlTree.P(line13);
                                  -        liClass.addContent(para);
                                  -        ul.addContent(liClass);
                                  +        htmlTree.addContent(para);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           //Annotation Types
                                           Content aHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.AnnotationType"));
                                  -        Content liAnnotation = HtmlTree.LI(HtmlStyle.blockList, aHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(aHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, aHead);
                                           Content aline1 = getResource("doclet.Help_annotation_type_line_1");
                                           Content aPara = HtmlTree.P(aline1);
                                  -        liAnnotation.addContent(aPara);
                                  +        htmlTree.addContent(aPara);
                                           HtmlTree aul = new HtmlTree(HtmlTag.UL);
                                           aul.addContent(HtmlTree.LI(
                                                   getResource("doclet.Help_annotation_type_line_2")));
                                  @@ -200,15 +239,21 @@ public class HelpWriter extends HtmlDocletWriter {
                                                   getResource("doclet.Annotation_Type_Optional_Member_Summary")));
                                           aul.addContent(HtmlTree.LI(
                                                   getResource("doclet.Annotation_Type_Member_Detail")));
                                  -        liAnnotation.addContent(aul);
                                  -        ul.addContent(liAnnotation);
                                  +        htmlTree.addContent(aul);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           //Enums
                                           Content enumHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Enum"));
                                  -        Content liEnum = HtmlTree.LI(HtmlStyle.blockList, enumHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(enumHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, enumHead);
                                           Content eline1 = getResource("doclet.Help_enum_line_1");
                                           Content enumPara = HtmlTree.P(eline1);
                                  -        liEnum.addContent(enumPara);
                                  +        htmlTree.addContent(enumPara);
                                           HtmlTree eul = new HtmlTree(HtmlTag.UL);
                                           eul.addContent(HtmlTree.LI(
                                                   getResource("doclet.Help_enum_line_2")));
                                  @@ -218,46 +263,68 @@ public class HelpWriter extends HtmlDocletWriter {
                                                   getResource("doclet.Enum_Constant_Summary")));
                                           eul.addContent(HtmlTree.LI(
                                                   getResource("doclet.Enum_Constant_Detail")));
                                  -        liEnum.addContent(eul);
                                  -        ul.addContent(liEnum);
                                  +        htmlTree.addContent(eul);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           if (configuration.classuse) {
                                               Content useHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                       getResource("doclet.Help_line_14"));
                                  -            Content liUse = HtmlTree.LI(HtmlStyle.blockList, useHead);
                                  +            htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                    ? HtmlTree.SECTION(useHead)
                                  +                    : HtmlTree.LI(HtmlStyle.blockList, useHead);
                                               Content line15 = getResource("doclet.Help_line_15");
                                               Content usePara = HtmlTree.P(line15);
                                  -            liUse.addContent(usePara);
                                  -            ul.addContent(liUse);
                                  +            htmlTree.addContent(usePara);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +            } else {
                                  +                ul.addContent(htmlTree);
                                  +            }
                                           }
                                           if (configuration.createtree) {
                                               Content treeHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                       getResource("doclet.Help_line_16"));
                                  -            Content liTree = HtmlTree.LI(HtmlStyle.blockList, treeHead);
                                  +            htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                    ? HtmlTree.SECTION(treeHead)
                                  +                    : HtmlTree.LI(HtmlStyle.blockList, treeHead);
                                               Content line17 = getResource("doclet.Help_line_17_with_tree_link",
                                                       getHyperLink(DocPaths.OVERVIEW_TREE,
                                                       configuration.getText("doclet.Class_Hierarchy")),
                                                       HtmlTree.CODE(new StringContent("java.lang.Object")));
                                               Content treePara = HtmlTree.P(line17);
                                  -            liTree.addContent(treePara);
                                  +            htmlTree.addContent(treePara);
                                               HtmlTree tul = new HtmlTree(HtmlTag.UL);
                                               tul.addContent(HtmlTree.LI(
                                                       getResource("doclet.Help_line_18")));
                                               tul.addContent(HtmlTree.LI(
                                                       getResource("doclet.Help_line_19")));
                                  -            liTree.addContent(tul);
                                  -            ul.addContent(liTree);
                                  +            htmlTree.addContent(tul);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +            } else {
                                  +                ul.addContent(htmlTree);
                                  +            }
                                           }
                                           if (!(configuration.nodeprecatedlist ||
                                                     configuration.nodeprecated)) {
                                               Content dHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                       getResource("doclet.Deprecated_API"));
                                  -            Content liDeprecated = HtmlTree.LI(HtmlStyle.blockList, dHead);
                                  +            htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                    ? HtmlTree.SECTION(dHead)
                                  +                    : HtmlTree.LI(HtmlStyle.blockList, dHead);
                                               Content line20 = getResource("doclet.Help_line_20_with_deprecated_api_link",
                                                       getHyperLink(DocPaths.DEPRECATED_LIST,
                                                       configuration.getText("doclet.Deprecated_API")));
                                               Content dPara = HtmlTree.P(line20);
                                  -            liDeprecated.addContent(dPara);
                                  -            ul.addContent(liDeprecated);
                                  +            htmlTree.addContent(dPara);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +            } else {
                                  +                ul.addContent(htmlTree);
                                  +            }
                                           }
                                           if (configuration.createindex) {
                                               Content indexlink;
                                  @@ -270,55 +337,96 @@ public class HelpWriter extends HtmlDocletWriter {
                                               }
                                               Content indexHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                       getResource("doclet.Help_line_21"));
                                  -            Content liIndex = HtmlTree.LI(HtmlStyle.blockList, indexHead);
                                  +            htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                    ? HtmlTree.SECTION(indexHead)
                                  +                    : HtmlTree.LI(HtmlStyle.blockList, indexHead);
                                               Content line22 = getResource("doclet.Help_line_22", indexlink);
                                               Content indexPara = HtmlTree.P(line22);
                                  -            liIndex.addContent(indexPara);
                                  -            ul.addContent(liIndex);
                                  +            htmlTree.addContent(indexPara);
                                  +            if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +                ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +            } else {
                                  +                ul.addContent(htmlTree);
                                  +            }
                                           }
                                           Content prevHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Help_line_23"));
                                  -        Content liPrev = HtmlTree.LI(HtmlStyle.blockList, prevHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(prevHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, prevHead);
                                           Content line24 = getResource("doclet.Help_line_24");
                                           Content prevPara = HtmlTree.P(line24);
                                  -        liPrev.addContent(prevPara);
                                  -        ul.addContent(liPrev);
                                  +        htmlTree.addContent(prevPara);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           Content frameHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Help_line_25"));
                                  -        Content liFrame = HtmlTree.LI(HtmlStyle.blockList, frameHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(frameHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, frameHead);
                                           Content line26 = getResource("doclet.Help_line_26");
                                           Content framePara = HtmlTree.P(line26);
                                  -        liFrame.addContent(framePara);
                                  -        ul.addContent(liFrame);
                                  +        htmlTree.addContent(framePara);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           Content allclassesHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.All_Classes"));
                                  -        Content liAllClasses = HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(allclassesHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
                                           Content line27 = getResource("doclet.Help_line_27",
                                                   getHyperLink(DocPaths.ALLCLASSES_NOFRAME,
                                                   configuration.getText("doclet.All_Classes")));
                                           Content allclassesPara = HtmlTree.P(line27);
                                  -        liAllClasses.addContent(allclassesPara);
                                  -        ul.addContent(liAllClasses);
                                  +        htmlTree.addContent(allclassesPara);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           Content sHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Serialized_Form"));
                                  -        Content liSerial = HtmlTree.LI(HtmlStyle.blockList, sHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(sHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, sHead);
                                           Content line28 = getResource("doclet.Help_line_28");
                                           Content serialPara = HtmlTree.P(line28);
                                  -        liSerial.addContent(serialPara);
                                  -        ul.addContent(liSerial);
                                  +        htmlTree.addContent(serialPara);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           Content constHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
                                                   getResource("doclet.Constants_Summary"));
                                  -        Content liConst = HtmlTree.LI(HtmlStyle.blockList, constHead);
                                  +        htmlTree = (configuration.allowTag(HtmlTag.SECTION))
                                  +                ? HtmlTree.SECTION(constHead)
                                  +                : HtmlTree.LI(HtmlStyle.blockList, constHead);
                                           Content line29 = getResource("doclet.Help_line_29",
                                                   getHyperLink(DocPaths.CONSTANT_VALUES,
                                                   configuration.getText("doclet.Constants_Summary")));
                                           Content constPara = HtmlTree.P(line29);
                                  -        liConst.addContent(constPara);
                                  -        ul.addContent(liConst);
                                  +        htmlTree.addContent(constPara);
                                  +        if (configuration.allowTag(HtmlTag.SECTION)) {
                                  +            ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
                                  +        } else {
                                  +            ul.addContent(htmlTree);
                                  +        }
                                           Content divContent = HtmlTree.DIV(HtmlStyle.contentContainer, ul);
                                           Content line30 = HtmlTree.SPAN(HtmlStyle.emphasizedPhrase, getResource("doclet.Help_line_30"));
                                           divContent.addContent(line30);
                                  -        contentTree.addContent(divContent);
                                  +        if (configuration.allowTag(HtmlTag.MAIN)) {
                                  +            mainTree.addContent(divContent);
                                  +            contentTree.addContent(mainTree);
                                  +        } else {
                                  +            contentTree.addContent(divContent);
                                  +        }
                                       }
                                   
                                       /**
                                  diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
                                  index 0d8300b8a7b..9f1a0d5defa 100644
                                  --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
                                  +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -183,8 +183,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
                                        * @return a content tree for the script
                                        */
                                       public Content getAllClassesLinkScript(String id) {
                                  -        HtmlTree script = new HtmlTree(HtmlTag.SCRIPT);
                                  -        script.addAttr(HtmlAttr.TYPE, "text/javascript");
                                  +        HtmlTree script = HtmlTree.SCRIPT();
                                           String scriptCode = "\n"
                                                   + "",
                                                   // Bottom navbar 
                                                   "Skip navigation links",
                                  -                // Bottom navbar 
                                  -                "\n"
                                  +                // Bottom navbar 
                                  +                "\n"
                                                   + "\n"
                                                   + "");
                                   
                                  diff --git a/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java b/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java
                                  index f0c4a138e34..fcd5196e998 100644
                                  --- a/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java
                                  +++ b/langtools/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -53,15 +53,15 @@ public class TestAnchorNames extends JavadocTester {
                                   
                                           // Test some section markers and links to these markers
                                           checkOutput("pkg1/RegClass.html", true,
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           // Test some members and link to these members
                                  @@ -72,59 +72,59 @@ public class TestAnchorNames extends JavadocTester {
                                   
                                           // Test some fields
                                           checkOutput("pkg1/RegClass.html", true,
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           checkOutput("pkg1/DeprMemClass.html", true,
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           // Test constructor
                                           checkOutput("pkg1/RegClass.html", true,
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           // Test some methods
                                           checkOutput("pkg1/RegClass.html", true,
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "",
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           checkOutput("pkg1/DeprMemClass.html", true,
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           // Test enum
                                           checkOutput("pkg1/RegClass.Te$t_Enum.html", true,
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           // Test nested class
                                           checkOutput("pkg1/RegClass._NestedClas$.html", true,
                                  -                "",
                                  +                "",
                                                   "");
                                   
                                           // Test class use page
                                  @@ -143,11 +143,11 @@ public class TestAnchorNames extends JavadocTester {
                                           // Test serialized form page
                                           checkOutput("serialized-form.html", true,
                                                   //This is the marker for the link that appears in the pkg1.RegClass.html page
                                  -                "");
                                  +                "");
                                   
                                           // Test member name index page
                                           checkOutput("index-all.html", true,
                                  -                "",
                                  +                "",
                                                   "$",
                                                   "_");
                                   
                                  diff --git a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java
                                  index 18e8c93d0a5..6b723d0d9a4 100644
                                  --- a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java
                                  +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -47,6 +47,6 @@ public class TestAnnotationOptional extends JavadocTester {
                                           checkExit(Exit.OK);
                                   
                                           checkOutput("pkg/AnnotationOptional.html", true,
                                  -            "");
                                  +            "");
                                       }
                                   }
                                  diff --git a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java
                                  index 22070488d77..90d6b405aea 100644
                                  --- a/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java
                                  +++ b/langtools/test/com/sun/javadoc/testClassTree/TestClassTree.java
                                  @@ -1,5 +1,5 @@
                                   /*
                                  - * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
                                  + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
                                    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
                                    *
                                    * This code is free software; you can redistribute it and/or modify it
                                  @@ -50,22 +50,22 @@ public class TestClassTree extends JavadocTester {
                                   
                                           checkOutput("pkg/package-tree.html", true,
                                                   "

                              • ", - "
                                ", - "
                                ", - "
                                "); checkOutput("pkg1/package-summary.html", true, - "
                                "); checkOutput("pkg1/class-use/TestTable.html", true, - "
                                "); + "
                                "); checkOutput("overview-summary.html", true, - "
                                "); + "
                                "); checkOutput("deprecated-list.html", true, - "
                                "); checkOutput("constant-values.html", true, - "
                                "); } } diff --git a/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java b/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java index 13c9214e4d4..bd0ad241056 100644 --- a/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java +++ b/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,111 +63,85 @@ public class TestHtmlTableTags extends JavadocTester { void checkHtmlTableSummaries() { //Package summary checkOutput("pkg1/package-summary.html", true, - "
                                ", - "
                                "); checkOutput("pkg2/package-summary.html", true, - "
                                ", - "
                                "); // Class documentation checkOutput("pkg1/C1.html", true, - "
                                ", - "
                                "); checkOutput("pkg2/C2.html", true, - "
                                ", - "
                                "); checkOutput("pkg2/C2.ModalExclusionType.html", true, - "
                                "); checkOutput("pkg2/C3.html", true, - "
                                "); checkOutput("pkg2/C4.html", true, - "
                                "); // Class use documentation checkOutput("pkg1/class-use/I1.html", true, - "
                                "); + "
                                "); checkOutput("pkg1/class-use/C1.html", true, - "
                                ", - "
                                "); + "
                                ", + "
                                "); checkOutput("pkg2/class-use/C2.html", true, - "
                                ", - "
                                "); + "
                                ", + "
                                "); checkOutput("pkg2/class-use/C2.ModalExclusionType.html", true, - "
                                "); + "
                                "); checkOutput("pkg2/class-use/C2.ModalExclusionType.html", true, - "
                                "); + "
                                "); // Package use documentation checkOutput("pkg1/package-use.html", true, - "
                                ", - "
                                "); + "
                                ", + "
                                "); checkOutput("pkg2/package-use.html", true, - "
                                ", - "
                                "); + "
                                ", + "
                                "); // Deprecated checkOutput("deprecated-list.html", true, - "
                                ", - "
                                "); // Constant values checkOutput("constant-values.html", true, - "
                                "); // Overview Summary checkOutput("overview-summary.html", true, - "
                                "); + "
                                "); } /* diff --git a/langtools/test/com/sun/javadoc/testHtmlVersion/TestHtmlVersion.java b/langtools/test/com/sun/javadoc/testHtmlVersion/TestHtmlVersion.java new file mode 100644 index 00000000000..970ac00bd31 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testHtmlVersion/TestHtmlVersion.java @@ -0,0 +1,2158 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8072945 + * @summary Test the version of HTML generated by the javadoc tool. + * @author bpatel + * @library ../lib + * @build JavadocTester + * @run main TestHtmlVersion + */ + +public class TestHtmlVersion extends JavadocTester { + + public static void main(String... args) throws Exception { + TestHtmlVersion tester = new TestHtmlVersion(); + tester.runTests(); + } + + @Test + void test1() { + javadoc("-d", "out-1", "-private", "-linksource", "-html5", + "-Xprofilespath", testSrc("profile-rtjar-includes.txt"), + "-sourcepath", testSrc, + "-use", + "pkg", "pkg1", "pkg2", "pkg3"); + checkExit(Exit.OK); + + html5Output(); + html5NegatedOutput(); + } + + @Test + void test2() { + javadoc("-d", "out-2", "-private", "-linksource", "-html4", + "-Xprofilespath", testSrc("profile-rtjar-includes.txt"), + "-sourcepath", testSrc, + "-use", + "pkg", "pkg1", "pkg2", "pkg3"); + checkExit(Exit.OK); + + html4Output(); + html4NegatedOutput(); + } + + @Test + void test3() { + javadoc("-d", "out-3", "-private", "-linksource", + "-Xprofilespath", testSrc("profile-rtjar-includes.txt"), + "-sourcepath", testSrc, + "-use", + "pkg", "pkg1", "pkg2", "pkg3"); + checkExit(Exit.OK); + + html4Output(); + html4NegatedOutput(); + } + + @Test + void test4() { + javadoc("-d", "out-4", "-private", "-linksource", "-html5", + "-sourcepath", testSrc, + "-use", + "pkg3"); + checkExit(Exit.OK); + } + + void html5Output() { + // Test for overview-frame page + checkOutput("overview-frame.html", true, + "", + "\n" + + "
                                  \n" + + "
                                • All Classes
                                • ", + "
                                  \n" + + "

                                  Packages

                                  "); + + // Test for allclasses-frame page + checkOutput("allclasses-frame.html", true, + "", + "\n" + + "
                                    \n" + + "
                                  • "); + + // Test for allclasses-noframe page + checkOutput("allclasses-noframe.html", true, + "", + "\n" + + "
                                      \n" + + "
                                    • "); + + // Test for profile-overview-frame page + checkOutput("profile-overview-frame.html", true, + "", + "\n" + + "
                                        \n" + + "
                                      • All Classes
                                      • ", + "
                                        \n" + + "

                                        Profiles

                                        "); + + // Test for -frame page + checkOutput("compact1-frame.html", true, + "", + "\n" + + "
                                          \n" + + "
                                        • All Classes
                                        • ", + "
                                          \n" + + "

                                          compact1 Packages

                                          "); + + // Test for overview-summary page + checkOutput("overview-summary.html", true, + "", + "\n" + + "\n" + + "", + "
                                \n" + + "
                                ", + "
                                \n" + + "