mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-13 23:19:36 +00:00
Merge
This commit is contained in:
commit
b56e8054a3
1
.hgtags
1
.hgtags
@ -378,3 +378,4 @@ e613affb88d178dc7c589f1679db113d589bddb4 jdk-9+130
|
||||
e17429a7e843c4a4ed3651458d0f950970edcbcc jdk-9+133
|
||||
a71210c0d9800eb6925b61ecd6198abd554f90ee jdk-9+134
|
||||
e384420383a5b79fa0012ebcb25d8f83cff7f777 jdk-9+135
|
||||
1b4b5d01aa11edf24b6fadbe3d2f3e411e3b02cd jdk-9+136
|
||||
|
||||
@ -378,3 +378,4 @@ a24702d4d5ab0015a5c553ed57f66fce7d85155e jdk-9+132
|
||||
be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
|
||||
065724348690eda41fc69112278d8da6dcde548c jdk-9+134
|
||||
82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135
|
||||
3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136
|
||||
|
||||
@ -378,3 +378,4 @@ f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
|
||||
2021bfedf1c478a4808a7711a6090682a12f4c0e jdk-9+133
|
||||
1a497f5ca0cfd88115cc7daa8af8a62b8741caf2 jdk-9+134
|
||||
094d0db606db976045f594dba47d4593b715cc81 jdk-9+135
|
||||
aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136
|
||||
|
||||
@ -538,3 +538,4 @@ e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
|
||||
a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133
|
||||
b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
|
||||
3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
|
||||
a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
|
||||
|
||||
@ -378,3 +378,4 @@ e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
|
||||
9490ba2e5e41685c858a0ca2a6ec87611eb011c6 jdk-9+133
|
||||
1c6c21d87aa459d82425e1fddc9ce8647aebde34 jdk-9+134
|
||||
f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135
|
||||
f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136
|
||||
|
||||
@ -61,9 +61,19 @@ import com.sun.org.apache.xml.internal.resolver.readers.SAXCatalogReader;
|
||||
* catalog resolution outside of a parsing context. It may be shared
|
||||
* between several parsers and the application.</p>
|
||||
*
|
||||
* @deprecated This class and the JDK internal Catalog API in package
|
||||
* {@code com.sun.org.apache.xml.internal.resolver}
|
||||
* is encapsulated in JDK 9. The entire implementation under the package is now
|
||||
* deprecated and subject to removal in a future release. Users of the API should
|
||||
* migrate to the {@linkplain javax.xml.catalog new public API}.
|
||||
* <p>
|
||||
* The new Catalog API is supported throughout the JDK XML Processors, which allows
|
||||
* the use of Catalog by simply setting a path to a Catalog file as a property.
|
||||
*
|
||||
* @author Michael Glavassevich, IBM
|
||||
*
|
||||
*/
|
||||
@Deprecated(since="9", forRemoval=true)
|
||||
public class XMLCatalogResolver
|
||||
implements XMLEntityResolver, EntityResolver2, LSResourceResolver {
|
||||
|
||||
|
||||
@ -178,6 +178,14 @@ import javax.xml.parsers.SAXParserFactory;
|
||||
*
|
||||
* @see CatalogReader
|
||||
* @see CatalogEntry
|
||||
* @deprecated The JDK internal Catalog API in package
|
||||
* {@code com.sun.org.apache.xml.internal.resolver}
|
||||
* is encapsulated in JDK 9. The entire implementation under the package is now
|
||||
* deprecated and subject to removal in a future release. Users of the API
|
||||
* should migrate to the {@linkplain javax.xml.catalog new public API}.
|
||||
* <p>
|
||||
* The new Catalog API is supported throughout the JDK XML Processors, which allows
|
||||
* the use of Catalog by simply setting a path to a Catalog file as a property.
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
@ -187,6 +195,7 @@ import javax.xml.parsers.SAXParserFactory;
|
||||
* <p>Derived from public domain code originally published by Arbortext,
|
||||
* Inc.</p>
|
||||
*/
|
||||
@Deprecated(since="9", forRemoval=true)
|
||||
public class Catalog {
|
||||
/** The BASE Catalog Entry type. */
|
||||
public static final int BASE = CatalogEntry.addEntryType("BASE", 1);
|
||||
|
||||
@ -110,13 +110,21 @@ import sun.reflect.misc.ReflectUtil;
|
||||
* </table>
|
||||
*
|
||||
* @see Catalog
|
||||
* @deprecated The JDK internal Catalog API in package
|
||||
* {@code com.sun.org.apache.xml.internal.resolver}
|
||||
* is encapsulated in JDK 9. The entire implementation under the package is now
|
||||
* deprecated and subject to removal in a future release. Users of the API
|
||||
* should migrate to the {@linkplain javax.xml.catalog new public API}.
|
||||
* <p>
|
||||
* The new Catalog API is supported throughout the JDK XML Processors, which allows
|
||||
* the use of Catalog by simply setting a path to a Catalog file as a property.
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@Deprecated(since="9", forRemoval=true)
|
||||
public class CatalogManager {
|
||||
private static final String pFiles = "xml.catalog.files";
|
||||
private static final String pVerbosity = "xml.catalog.verbosity";
|
||||
|
||||
@ -37,12 +37,21 @@ import com.sun.org.apache.xml.internal.resolver.readers.TR9401CatalogReader;
|
||||
* suffix-based matching and an external RFC2483 resolver.
|
||||
*
|
||||
* @see Catalog
|
||||
* @deprecated The JDK internal Catalog API in package
|
||||
* {@code com.sun.org.apache.xml.internal.resolver}
|
||||
* is encapsulated in JDK 9. The entire implementation under the package is now
|
||||
* deprecated and subject to removal in a future release. Users of the API
|
||||
* should migrate to the {@linkplain javax.xml.catalog new public API}.
|
||||
* <p>
|
||||
* The new Catalog API is supported throughout the JDK XML Processors, which allows
|
||||
* the use of Catalog by simply setting a path to a Catalog file as a property.
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
@Deprecated(since="9", forRemoval=true)
|
||||
public class Resolver extends Catalog {
|
||||
/**
|
||||
* The URISUFFIX Catalog Entry type.
|
||||
|
||||
@ -52,12 +52,21 @@ import com.sun.org.apache.xml.internal.resolver.helpers.FileURL;
|
||||
* @see Catalog
|
||||
* @see org.xml.sax.EntityResolver
|
||||
* @see javax.xml.transform.URIResolver
|
||||
* @deprecated The JDK internal Catalog API in package
|
||||
* {@code com.sun.org.apache.xml.internal.resolver}
|
||||
* is encapsulated in JDK 9. The entire implementation under the package is now
|
||||
* deprecated and subject to removal in a future release. Users of the API
|
||||
* should migrate to the {@linkplain javax.xml.catalog new public API}.
|
||||
* <p>
|
||||
* The new Catalog API is supported throughout the JDK XML Processors, which allows
|
||||
* the use of Catalog by simply setting a path to a Catalog file as a property.
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
@Deprecated(since="9", forRemoval=true)
|
||||
public class CatalogResolver implements EntityResolver, URIResolver {
|
||||
/** Make the parser Namespace aware? */
|
||||
public boolean namespaceAware = true;
|
||||
|
||||
@ -25,7 +25,7 @@ package catalog;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
@ -42,7 +42,7 @@ import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8158084 8162438 8162442
|
||||
* @bug 8158084 8162438 8162442 8166220
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport
|
||||
* @run testng/othervm catalog.CatalogSupport
|
||||
@ -113,6 +113,15 @@ public class CatalogSupport extends CatalogSupportBase {
|
||||
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on XMLStreamReader.
|
||||
*/
|
||||
@Test(dataProvider = "data_StAXA")
|
||||
public void testStAXA(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -212,6 +221,20 @@ public class CatalogSupport extends CatalogSupportBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing the StAX parser
|
||||
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
|
||||
*/
|
||||
@DataProvider(name = "data_StAXA")
|
||||
public Object[][] getDataStAX() {
|
||||
|
||||
return new Object[][]{
|
||||
{false, true, xml_catalog, xml_system, null, expectedWCatalog},
|
||||
{false, true, xml_catalog, xml_system, null, expectedWResolver},
|
||||
{true, true, xml_catalog, xml_system, null, expectedWResolver}
|
||||
};
|
||||
}
|
||||
|
||||
MyEntityHandler getMyEntityHandler(String elementName, String[] systemIds, InputSource... returnValues) {
|
||||
return new MyEntityHandler(systemIds, returnValues, elementName);
|
||||
}
|
||||
@ -262,8 +285,8 @@ public class CatalogSupport extends CatalogSupportBase {
|
||||
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
|
||||
ss.setSystemId(xml_val_test_id);
|
||||
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
StreamSource source = new StreamSource(new File(xml_val_test));
|
||||
|
||||
@ -271,8 +294,7 @@ public class CatalogSupport extends CatalogSupportBase {
|
||||
XmlInput[] returnValues = {new XmlInput(null, dtd_system, null), new XmlInput(null, xsd_val_test, null)};
|
||||
LSResourceResolver resolver = new SourceResolver(null, systemIds, returnValues);
|
||||
|
||||
StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax3 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
return new Object[][]{
|
||||
// use catalog
|
||||
|
||||
@ -30,6 +30,7 @@ import java.io.File;
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.catalog.CatalogFeatures.Feature;
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
@ -47,7 +48,7 @@ import org.xml.sax.InputSource;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8158084 8162438 8162442
|
||||
* @bug 8158084 8162438 8162442 8166220
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport1
|
||||
* @run testng/othervm catalog.CatalogSupport1
|
||||
@ -109,6 +110,15 @@ public class CatalogSupport1 extends CatalogSupportBase {
|
||||
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on XMLStreamReader.
|
||||
*/
|
||||
@Test(dataProvider = "data_StAXC")
|
||||
public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -189,6 +199,18 @@ public class CatalogSupport1 extends CatalogSupportBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing the StAX parser
|
||||
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
|
||||
*/
|
||||
@DataProvider(name = "data_StAXC")
|
||||
public Object[][] getDataStAX() {
|
||||
|
||||
return new Object[][]{
|
||||
{false, true, null, xml_system, null, expectedWCatalog},
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing Schema validation
|
||||
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
|
||||
@ -218,8 +240,8 @@ public class CatalogSupport1 extends CatalogSupportBase {
|
||||
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
|
||||
ss.setSystemId(xml_val_test_id);
|
||||
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
StreamSource source = new StreamSource(new File(xml_val_test));
|
||||
|
||||
@ -227,8 +249,7 @@ public class CatalogSupport1 extends CatalogSupportBase {
|
||||
XmlInput[] returnValues = {new XmlInput(null, dtd_system, null), new XmlInput(null, xsd_val_test, null)};
|
||||
LSResourceResolver resolver = new SourceResolver(null, systemIds, returnValues);
|
||||
|
||||
StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax3 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax2 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
return new Object[][]{
|
||||
// use catalog
|
||||
|
||||
@ -30,6 +30,8 @@ import static jaxp.library.JAXPTestUtilities.setSystemProperty;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
@ -50,7 +52,7 @@ import org.xml.sax.SAXParseException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8158084 8162438 8162442 8163535
|
||||
* @bug 8158084 8162438 8162442 8163535 8166220
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport2
|
||||
* @run testng/othervm catalog.CatalogSupport2
|
||||
@ -128,6 +130,15 @@ public class CatalogSupport2 extends CatalogSupportBase {
|
||||
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on XMLStreamReader.
|
||||
*/
|
||||
@Test(dataProvider = "data_StAXC")
|
||||
public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
testStAXNegative(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -204,6 +215,17 @@ public class CatalogSupport2 extends CatalogSupportBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing the StAX parser
|
||||
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
|
||||
*/
|
||||
@DataProvider(name = "data_StAXC")
|
||||
public Object[][] getDataStAX() {
|
||||
return new Object[][]{
|
||||
{false, true, xml_catalog, xml_system, null, "null"},
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing Schema validation
|
||||
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
|
||||
@ -233,8 +255,8 @@ public class CatalogSupport2 extends CatalogSupportBase {
|
||||
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
|
||||
ss.setSystemId(xml_val_test_id);
|
||||
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
StreamSource source = new StreamSource(new File(xml_val_test));
|
||||
|
||||
|
||||
@ -29,6 +29,8 @@ import static jaxp.library.JAXPTestUtilities.setSystemProperty;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
@ -49,7 +51,7 @@ import org.xml.sax.SAXParseException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8158084 8162438 8162442 8163535
|
||||
* @bug 8158084 8162438 8162442 8163535 8166220
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport3
|
||||
* @run testng/othervm catalog.CatalogSupport3
|
||||
@ -124,6 +126,15 @@ public class CatalogSupport3 extends CatalogSupportBase {
|
||||
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on XMLStreamReader.
|
||||
*/
|
||||
@Test(dataProvider = "data_StAXC")
|
||||
public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
testStAXNegative(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -205,6 +216,17 @@ public class CatalogSupport3 extends CatalogSupportBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing the StAX parser
|
||||
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
|
||||
*/
|
||||
@DataProvider(name = "data_StAXC")
|
||||
public Object[][] getDataStAX() {
|
||||
return new Object[][]{
|
||||
{true, false, xml_catalog, xml_system, null, "null"},
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing Schema validation
|
||||
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
|
||||
@ -234,8 +256,8 @@ public class CatalogSupport3 extends CatalogSupportBase {
|
||||
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
|
||||
ss.setSystemId(xml_val_test_id);
|
||||
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
StreamSource source = new StreamSource(new File(xml_val_test));
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ import static jaxp.library.JAXPTestUtilities.setSystemProperty;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
@ -46,7 +46,7 @@ import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8158084 8162438 8162442
|
||||
* @bug 8158084 8162438 8162442 8166220
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport4
|
||||
* @run testng/othervm catalog.CatalogSupport4
|
||||
@ -117,6 +117,15 @@ public class CatalogSupport4 extends CatalogSupportBase {
|
||||
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on XMLStreamReader.
|
||||
*/
|
||||
@Test(dataProvider = "data_StAXA")
|
||||
public void testStAXA(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -199,6 +208,18 @@ public class CatalogSupport4 extends CatalogSupportBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing the StAX parser
|
||||
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
|
||||
*/
|
||||
@DataProvider(name = "data_StAXA")
|
||||
public Object[][] getDataStAX() {
|
||||
|
||||
return new Object[][]{
|
||||
{true, true, xml_catalog, xml_system, null, expectedWCatalog},
|
||||
};
|
||||
}
|
||||
|
||||
MyEntityHandler getMyEntityHandler(String elementName, String[] systemIds, InputSource... returnValues) {
|
||||
return new MyEntityHandler(systemIds, returnValues, elementName);
|
||||
}
|
||||
@ -230,8 +251,8 @@ public class CatalogSupport4 extends CatalogSupportBase {
|
||||
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
|
||||
ss.setSystemId(xml_val_test_id);
|
||||
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, true, true, xml_catalog);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, true, true, xml_catalog);
|
||||
|
||||
StreamSource source = new StreamSource(new File(xml_val_test));
|
||||
|
||||
@ -241,8 +262,8 @@ public class CatalogSupport4 extends CatalogSupportBase {
|
||||
{false, true, true, ds, null, null, null, xml_catalog},
|
||||
{true, false, true, ss, null, null, xml_catalog, null},
|
||||
{false, true, true, ss, null, null, null, xml_catalog},
|
||||
{true, false, true, stax, null, null, xml_catalog, null},
|
||||
{false, true, true, stax1, null, null, null, xml_catalog},
|
||||
{true, false, true, stax, null, null, xml_catalog, xml_catalog},
|
||||
{false, true, true, stax1, null, null, xml_catalog, xml_catalog},
|
||||
{true, false, true, source, null, null, xml_catalog, null},
|
||||
{false, true, true, source, null, null, null, xml_catalog},
|
||||
};
|
||||
|
||||
@ -25,6 +25,8 @@ package catalog;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringReader;
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
@ -43,7 +45,7 @@ import org.xml.sax.SAXException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8158084 8163232
|
||||
* @bug 8158084 8163232 8166220
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport5
|
||||
* @run testng/othervm catalog.CatalogSupport5
|
||||
@ -106,6 +108,15 @@ public class CatalogSupport5 extends CatalogSupportBase {
|
||||
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on XMLStreamReader.
|
||||
*/
|
||||
@Test(dataProvider = "data_StAXC", expectedExceptions = XMLStreamException.class)
|
||||
public void testStAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
testStAX(setUseCatalog, useCatalog, catalog, xml, resolver, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -182,6 +193,18 @@ public class CatalogSupport5 extends CatalogSupportBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing the StAX parser
|
||||
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
|
||||
*/
|
||||
@DataProvider(name = "data_StAXC")
|
||||
public Object[][] getDataStAX() {
|
||||
|
||||
return new Object[][]{
|
||||
{false, true, xml_bogus_catalog, xml_system, null, expectedWCatalog},
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
DataProvider: for testing Schema validation
|
||||
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
|
||||
@ -211,8 +234,8 @@ public class CatalogSupport5 extends CatalogSupportBase {
|
||||
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
|
||||
ss.setSystemId(xml_val_test_id);
|
||||
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
|
||||
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id, false, true, xml_catalog);
|
||||
|
||||
StreamSource source = new StreamSource(new File(xml_val_test));
|
||||
|
||||
|
||||
@ -318,6 +318,31 @@ public class CatalogSupportBase {
|
||||
assertEquals(expected, result.trim(), "Catalog support for DOM");
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on StAX parser.
|
||||
*/
|
||||
public void testStAX(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
|
||||
XMLStreamReader streamReader = getStreamReader(
|
||||
setUseCatalog, useCatalog, catalog, xml, resolver);
|
||||
String text = getText(streamReader, XMLStreamConstants.CHARACTERS);
|
||||
assertEquals(expected, text.trim(), "Catalog support for StAX");
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies that the Catalog support for StAX parser is disabled when
|
||||
USE_CATALOG == false.
|
||||
*/
|
||||
public void testStAXNegative(boolean setUseCatalog, boolean useCatalog, String catalog,
|
||||
String xml, XMLResolver resolver, String expected) throws Exception {
|
||||
|
||||
XMLStreamReader streamReader = getStreamReader(
|
||||
setUseCatalog, useCatalog, catalog, xml, resolver);
|
||||
String text = getText(streamReader, XMLStreamConstants.ENTITY_REFERENCE);
|
||||
assertEquals(expected, text.trim(), "Catalog support for StAX");
|
||||
}
|
||||
|
||||
/*
|
||||
Verifies the Catalog support on resolving DTD, xsd import and include in
|
||||
Schema files.
|
||||
@ -514,15 +539,24 @@ public class CatalogSupportBase {
|
||||
*
|
||||
* @param xmlFile the XML source file
|
||||
* @param xmlFileId the systemId of the source
|
||||
* @param setUseCatalog a flag indicates whether USE_CATALOG shall be set
|
||||
* through the factory
|
||||
* @param useCatalog the value of USE_CATALOG
|
||||
* @param catalog a catalog
|
||||
* @return a StAXSource
|
||||
* @throws XMLStreamException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
StAXSource getStaxSource(String xmlFile, String xmlFileId) {
|
||||
StAXSource getStaxSource(String xmlFile, String xmlFileId, boolean setUseCatalog,
|
||||
boolean useCatalog, String catalog) {
|
||||
StAXSource ss = null;
|
||||
try {
|
||||
ss = new StAXSource(
|
||||
XMLInputFactory.newFactory().createXMLEventReader(
|
||||
XMLInputFactory xif = XMLInputFactory.newFactory();
|
||||
if (setUseCatalog) {
|
||||
xif.setProperty(XMLConstants.USE_CATALOG, useCatalog);
|
||||
}
|
||||
xif.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
|
||||
ss = new StAXSource(xif.createXMLEventReader(
|
||||
xmlFileId, new FileInputStream(xmlFile)));
|
||||
} catch (Exception e) {}
|
||||
|
||||
@ -531,6 +565,10 @@ public class CatalogSupportBase {
|
||||
|
||||
/**
|
||||
* Creates an XMLStreamReader.
|
||||
*
|
||||
* @param setUseCatalog a flag indicates whether USE_CATALOG shall be set
|
||||
* through the factory
|
||||
* @param useCatalog the value of USE_CATALOG
|
||||
* @param catalog the path to a catalog
|
||||
* @param xml the xml to be parsed
|
||||
* @param resolver a resolver to be set on the reader
|
||||
@ -542,9 +580,17 @@ public class CatalogSupportBase {
|
||||
String catalog, String xml, XMLResolver resolver)
|
||||
throws FileNotFoundException, XMLStreamException {
|
||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||
factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
|
||||
if (catalog != null) {
|
||||
factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
|
||||
}
|
||||
|
||||
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
|
||||
factory.setProperty(XMLInputFactory.IS_COALESCING, true);
|
||||
factory.setProperty(XMLInputFactory.RESOLVER, resolver);
|
||||
|
||||
if (resolver != null) {
|
||||
factory.setProperty(XMLInputFactory.RESOLVER, resolver);
|
||||
}
|
||||
|
||||
if (setUseCatalog) {
|
||||
factory.setProperty(XMLConstants.USE_CATALOG, useCatalog);
|
||||
}
|
||||
@ -560,17 +606,28 @@ public class CatalogSupportBase {
|
||||
* @return the text of the first element
|
||||
* @throws XMLStreamException
|
||||
*/
|
||||
String getText(XMLStreamReader streamReader) throws XMLStreamException {
|
||||
String getText(XMLStreamReader streamReader, int type) throws XMLStreamException {
|
||||
StringBuilder text = new StringBuilder();
|
||||
StringBuilder entityRef = new StringBuilder();
|
||||
|
||||
while(streamReader.hasNext()){
|
||||
int eventType = streamReader.next() ;
|
||||
if(eventType == XMLStreamConstants.START_ELEMENT){
|
||||
eventType = streamReader.next() ;
|
||||
if(eventType == XMLStreamConstants.CHARACTERS){
|
||||
return streamReader.getText() ;
|
||||
}
|
||||
int eventType = streamReader.next();
|
||||
switch (eventType) {
|
||||
case XMLStreamConstants.START_ELEMENT:
|
||||
break;
|
||||
case XMLStreamConstants.CHARACTERS:
|
||||
text.append(streamReader.getText());
|
||||
break;
|
||||
case XMLStreamConstants.ENTITY_REFERENCE:
|
||||
entityRef.append(streamReader.getText());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (type == XMLStreamConstants.CHARACTERS) {
|
||||
return text.toString();
|
||||
} else {
|
||||
return entityRef.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -381,3 +381,4 @@ fe4e11bd2423635dc0f5f5cb9a64eb2f2cce7f4c jdk-9+128
|
||||
05e99eefda2b58d1ed176e411302d9d6b35dca16 jdk-9+133
|
||||
ab1d78d395d4cb8be426ff181211da1a4085cf01 jdk-9+134
|
||||
22631824f55128a7ab6605493b3001a37af6a168 jdk-9+135
|
||||
09ec13a99f50a4a346180d1e3b0fd8bc1ee399ce jdk-9+136
|
||||
|
||||
@ -378,3 +378,4 @@ d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
|
||||
3cdae27c90b5e41afe75eab904fda19fac076330 jdk-9+133
|
||||
803adcd526d74ae0b64948d1f8260c2dbe514779 jdk-9+134
|
||||
021369229cfd0b5feb76834b2ea498f47f43c0f3 jdk-9+135
|
||||
54c5931849a33a363e03fdffa141503f5cc4779d jdk-9+136
|
||||
|
||||
@ -32,14 +32,14 @@ formatVersion=3
|
||||
# Version of the currency code information in this class.
|
||||
# It is a serial number that accompanies with each amendment.
|
||||
|
||||
dataVersion=160
|
||||
dataVersion=162
|
||||
|
||||
# List of all valid ISO 4217 currency codes.
|
||||
# To ensure compatibility, do not remove codes.
|
||||
|
||||
all=ADP020-AED784-AFA004-AFN971-ALL008-AMD051-ANG532-AOA973-ARS032-ATS040-AUD036-\
|
||||
AWG533-AYM945-AZM031-AZN944-BAM977-BBD052-BDT050-BEF056-BGL100-BGN975-BHD048-BIF108-\
|
||||
BMD060-BND096-BOB068-BOV984-BRL986-BSD044-BTN064-BWP072-BYB112-BYR974-\
|
||||
BMD060-BND096-BOB068-BOV984-BRL986-BSD044-BTN064-BWP072-BYB112-BYR974-BYN933-\
|
||||
BZD084-CAD124-CDF976-CHE947-CHF756-CHW948-CLF990-CLP152-CNY156-COP170-COU970-CRC188-CSD891-CUP192-CUC931-\
|
||||
CVE132-CYP196-CZK203-DEM276-DJF262-DKK208-DOP214-DZD012-EEK233-EGP818-\
|
||||
ERN232-ESP724-ETB230-EUR978-FIM246-FJD242-FKP238-FRF250-GBP826-GEL981-\
|
||||
@ -119,7 +119,7 @@ BD=BDT
|
||||
# BARBADOS
|
||||
BB=BBD
|
||||
# BELARUS
|
||||
BY=BYR
|
||||
BY=BYN
|
||||
# BELGIUM
|
||||
BE=EUR
|
||||
# BELIZE
|
||||
|
||||
@ -30,8 +30,6 @@ SUNWprivate_1.1 {
|
||||
Java_sun_tools_attach_VirtualMachineImpl_checkPermissions;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_close;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_connect;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_getLinuxThreadsManager;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_isLinuxThreads;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_open;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_sendQuitTo;
|
||||
Java_sun_tools_attach_VirtualMachineImpl_sendQuitToChildrenOf;
|
||||
|
||||
@ -176,6 +176,9 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_ProcessHandleImpl_00024Info_info0;
|
||||
Java_java_lang_ProcessImpl_init;
|
||||
Java_java_lang_ProcessImpl_forkAndExec;
|
||||
Java_java_lang_ref_Reference_getAndClearReferencePendingList;
|
||||
Java_java_lang_ref_Reference_hasReferencePendingList;
|
||||
Java_java_lang_ref_Reference_waitForReferencePendingList;
|
||||
Java_java_lang_reflect_Array_get;
|
||||
Java_java_lang_reflect_Array_getBoolean;
|
||||
Java_java_lang_reflect_Array_getByte;
|
||||
|
||||
@ -42,6 +42,7 @@ SUNWprivate_1.1 {
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetReader;
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_disposeReader;
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetLibraryState;
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_clearNativeReadAbortFlag;
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initWriterIDs;
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter;
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest;
|
||||
|
||||
@ -410,6 +410,10 @@ int NET_Read(int s, void* buf, size_t len) {
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
|
||||
}
|
||||
|
||||
int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, MSG_NONBLOCK));
|
||||
}
|
||||
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count) {
|
||||
BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
|
||||
}
|
||||
@ -503,8 +507,8 @@ int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
||||
* Auto restarts with adjusted timeout if interrupted by
|
||||
* signal other than our wakeup signal.
|
||||
*/
|
||||
int NET_Timeout(int s, long timeout) {
|
||||
long prevtime = 0, newtime;
|
||||
int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
long prevtime = currentTime, newtime;
|
||||
struct timeval t;
|
||||
fdEntry_t *fdEntry = getFdEntry(s);
|
||||
|
||||
@ -516,14 +520,6 @@ int NET_Timeout(int s, long timeout) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick up current time as may need to adjust timeout
|
||||
*/
|
||||
if (timeout > 0) {
|
||||
gettimeofday(&t, NULL);
|
||||
prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
struct pollfd pfd;
|
||||
int rv;
|
||||
|
||||
@ -367,6 +367,10 @@ int NET_Read(int s, void* buf, size_t len) {
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
|
||||
}
|
||||
|
||||
int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT) );
|
||||
}
|
||||
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count) {
|
||||
BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
|
||||
}
|
||||
@ -406,8 +410,8 @@ int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
||||
* Auto restarts with adjusted timeout if interrupted by
|
||||
* signal other than our wakeup signal.
|
||||
*/
|
||||
int NET_Timeout(int s, long timeout) {
|
||||
long prevtime = 0, newtime;
|
||||
int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
long prevtime = currentTime, newtime;
|
||||
struct timeval t;
|
||||
fdEntry_t *fdEntry = getFdEntry(s);
|
||||
|
||||
@ -419,14 +423,6 @@ int NET_Timeout(int s, long timeout) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick up current time as may need to adjust timeout
|
||||
*/
|
||||
if (timeout > 0) {
|
||||
gettimeofday(&t, NULL);
|
||||
prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
struct pollfd pfd;
|
||||
int rv;
|
||||
|
||||
@ -371,6 +371,10 @@ int NET_Read(int s, void* buf, size_t len) {
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
|
||||
}
|
||||
|
||||
int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT));
|
||||
}
|
||||
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count) {
|
||||
BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
|
||||
}
|
||||
@ -410,8 +414,8 @@ int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
||||
* Auto restarts with adjusted timeout if interrupted by
|
||||
* signal other than our wakeup signal.
|
||||
*/
|
||||
int NET_Timeout(int s, long timeout) {
|
||||
long prevtime = 0, newtime;
|
||||
int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
long prevtime = currentTime, newtime;
|
||||
struct timeval t, *tp = &t;
|
||||
fd_set fds;
|
||||
fd_set* fdsp = NULL;
|
||||
@ -432,9 +436,6 @@ int NET_Timeout(int s, long timeout) {
|
||||
*/
|
||||
if (timeout > 0) {
|
||||
/* Timed */
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
prevtime = now.tv_sec * 1000 + now.tv_usec / 1000;
|
||||
t.tv_sec = timeout / 1000;
|
||||
t.tv_usec = (timeout % 1000) * 1000;
|
||||
} else if (timeout < 0) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
||||
@ -110,22 +110,6 @@ public abstract class Reference<T> {
|
||||
private transient Reference<T> discovered; /* used by VM */
|
||||
|
||||
|
||||
/* Object used to synchronize with the garbage collector. The collector
|
||||
* must acquire this lock at the beginning of each collection cycle. It is
|
||||
* therefore critical that any code holding this lock complete as quickly
|
||||
* as possible, allocate no new objects, and avoid calling user code.
|
||||
*/
|
||||
private static class Lock { }
|
||||
private static Lock lock = new Lock();
|
||||
|
||||
|
||||
/* List of References waiting to be enqueued. The collector adds
|
||||
* References to this list, while the Reference-handler thread removes
|
||||
* them. This list is protected by the above lock object. The
|
||||
* list uses the discovered field to link its elements.
|
||||
*/
|
||||
private static Reference<Object> pending = null;
|
||||
|
||||
/* High-priority thread to enqueue pending References
|
||||
*/
|
||||
private static class ReferenceHandler extends Thread {
|
||||
@ -139,10 +123,9 @@ public abstract class Reference<T> {
|
||||
}
|
||||
|
||||
static {
|
||||
// pre-load and initialize InterruptedException and Cleaner classes
|
||||
// so that we don't get into trouble later in the run loop if there's
|
||||
// memory shortage while loading/initializing them lazily.
|
||||
ensureClassInitialized(InterruptedException.class);
|
||||
// pre-load and initialize Cleaner class so that we don't
|
||||
// get into trouble later in the run loop if there's
|
||||
// memory shortage while loading/initializing it lazily.
|
||||
ensureClassInitialized(Cleaner.class);
|
||||
}
|
||||
|
||||
@ -152,72 +135,80 @@ public abstract class Reference<T> {
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
tryHandlePending(true);
|
||||
processPendingReferences();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try handle pending {@link Reference} if there is one.<p>
|
||||
* Return {@code true} as a hint that there might be another
|
||||
* {@link Reference} pending or {@code false} when there are no more pending
|
||||
* {@link Reference}s at the moment and the program can do some other
|
||||
* useful work instead of looping.
|
||||
*
|
||||
* @param waitForNotify if {@code true} and there was no pending
|
||||
* {@link Reference}, wait until notified from VM
|
||||
* or interrupted; if {@code false}, return immediately
|
||||
* when there is no pending {@link Reference}.
|
||||
* @return {@code true} if there was a {@link Reference} pending and it
|
||||
* was processed, or we waited for notification and either got it
|
||||
* or thread was interrupted before being notified;
|
||||
* {@code false} otherwise.
|
||||
/* Atomically get and clear (set to null) the VM's pending list.
|
||||
*/
|
||||
static boolean tryHandlePending(boolean waitForNotify) {
|
||||
Reference<Object> r;
|
||||
Cleaner c;
|
||||
try {
|
||||
synchronized (lock) {
|
||||
if (pending != null) {
|
||||
r = pending;
|
||||
// 'instanceof' might throw OutOfMemoryError sometimes
|
||||
// so do this before un-linking 'r' from the 'pending' chain...
|
||||
c = r instanceof Cleaner ? (Cleaner) r : null;
|
||||
// unlink 'r' from 'pending' chain
|
||||
pending = r.discovered;
|
||||
r.discovered = null;
|
||||
} else {
|
||||
// The waiting on the lock may cause an OutOfMemoryError
|
||||
// because it may try to allocate exception objects.
|
||||
if (waitForNotify) {
|
||||
lock.wait();
|
||||
}
|
||||
// retry if waited
|
||||
return waitForNotify;
|
||||
private static native Reference<Object> getAndClearReferencePendingList();
|
||||
|
||||
/* Test whether the VM's pending list contains any entries.
|
||||
*/
|
||||
private static native boolean hasReferencePendingList();
|
||||
|
||||
/* Wait until the VM's pending list may be non-null.
|
||||
*/
|
||||
private static native void waitForReferencePendingList();
|
||||
|
||||
private static final Object processPendingLock = new Object();
|
||||
private static boolean processPendingActive = false;
|
||||
|
||||
private static void processPendingReferences() {
|
||||
// Only the singleton reference processing thread calls
|
||||
// waitForReferencePendingList() and getAndClearReferencePendingList().
|
||||
// These are separate operations to avoid a race with other threads
|
||||
// that are calling waitForReferenceProcessing().
|
||||
waitForReferencePendingList();
|
||||
Reference<Object> pendingList;
|
||||
synchronized (processPendingLock) {
|
||||
pendingList = getAndClearReferencePendingList();
|
||||
processPendingActive = true;
|
||||
}
|
||||
while (pendingList != null) {
|
||||
Reference<Object> ref = pendingList;
|
||||
pendingList = ref.discovered;
|
||||
ref.discovered = null;
|
||||
|
||||
if (ref instanceof Cleaner) {
|
||||
((Cleaner)ref).clean();
|
||||
// Notify any waiters that progress has been made.
|
||||
// This improves latency for nio.Bits waiters, which
|
||||
// are the only important ones.
|
||||
synchronized (processPendingLock) {
|
||||
processPendingLock.notifyAll();
|
||||
}
|
||||
} else {
|
||||
ReferenceQueue<? super Object> q = ref.queue;
|
||||
if (q != ReferenceQueue.NULL) q.enqueue(ref);
|
||||
}
|
||||
} catch (OutOfMemoryError x) {
|
||||
// Give other threads CPU time so they hopefully drop some live references
|
||||
// and GC reclaims some space.
|
||||
// Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above
|
||||
// persistently throws OOME for some time...
|
||||
Thread.yield();
|
||||
// retry
|
||||
return true;
|
||||
} catch (InterruptedException x) {
|
||||
// retry
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fast path for cleaners
|
||||
if (c != null) {
|
||||
c.clean();
|
||||
return true;
|
||||
// Notify any waiters of completion of current round.
|
||||
synchronized (processPendingLock) {
|
||||
processPendingActive = false;
|
||||
processPendingLock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceQueue<? super Object> q = r.queue;
|
||||
if (q != ReferenceQueue.NULL) q.enqueue(r);
|
||||
return true;
|
||||
// Wait for progress in reference processing.
|
||||
//
|
||||
// Returns true after waiting (for notification from the reference
|
||||
// processing thread) if either (1) the VM has any pending
|
||||
// references, or (2) the reference processing thread is
|
||||
// processing references. Otherwise, returns false immediately.
|
||||
private static boolean waitForReferenceProcessing()
|
||||
throws InterruptedException
|
||||
{
|
||||
synchronized (processPendingLock) {
|
||||
if (processPendingActive || hasReferencePendingList()) {
|
||||
// Wait for progress, not necessarily completion.
|
||||
processPendingLock.wait();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
@ -236,8 +227,10 @@ public abstract class Reference<T> {
|
||||
// provide access in SharedSecrets
|
||||
SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
|
||||
@Override
|
||||
public boolean tryHandlePendingReference() {
|
||||
return tryHandlePending(false);
|
||||
public boolean waitForReferenceProcessing()
|
||||
throws InterruptedException
|
||||
{
|
||||
return Reference.waitForReferenceProcessing();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -131,23 +131,38 @@ class Bits { // package-private
|
||||
}
|
||||
|
||||
final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
|
||||
|
||||
// retry while helping enqueue pending Reference objects
|
||||
// which includes executing pending Cleaner(s) which includes
|
||||
// Cleaner(s) that free direct buffer memory
|
||||
while (jlra.tryHandlePendingReference()) {
|
||||
if (tryReserveMemory(size, cap)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// trigger VM's Reference processing
|
||||
System.gc();
|
||||
|
||||
// a retry loop with exponential back-off delays
|
||||
// (this gives VM some time to do it's job)
|
||||
boolean interrupted = false;
|
||||
try {
|
||||
|
||||
// Retry allocation until success or there are no more
|
||||
// references (including Cleaners that might free direct
|
||||
// buffer memory) to process and allocation still fails.
|
||||
boolean refprocActive;
|
||||
do {
|
||||
try {
|
||||
refprocActive = jlra.waitForReferenceProcessing();
|
||||
} catch (InterruptedException e) {
|
||||
// Defer interrupts and keep trying.
|
||||
interrupted = true;
|
||||
refprocActive = true;
|
||||
}
|
||||
if (tryReserveMemory(size, cap)) {
|
||||
return;
|
||||
}
|
||||
} while (refprocActive);
|
||||
|
||||
// trigger VM's Reference processing
|
||||
System.gc();
|
||||
|
||||
// A retry loop with exponential back-off delays.
|
||||
// Sometimes it would suffice to give up once reference
|
||||
// processing is complete. But if there are many threads
|
||||
// competing for memory, this gives more opportunities for
|
||||
// any given thread to make progress. In particular, this
|
||||
// seems to be enough for a stress test like
|
||||
// DirectBufferAllocTest to (usually) succeed, while
|
||||
// without it that test likely fails. Since failure here
|
||||
// ends in OOME, there's no need to hurry.
|
||||
long sleepTime = 1;
|
||||
int sleeps = 0;
|
||||
while (true) {
|
||||
@ -157,14 +172,14 @@ class Bits { // package-private
|
||||
if (sleeps >= MAX_SLEEPS) {
|
||||
break;
|
||||
}
|
||||
if (!jlra.tryHandlePendingReference()) {
|
||||
try {
|
||||
try {
|
||||
if (!jlra.waitForReferenceProcessing()) {
|
||||
Thread.sleep(sleepTime);
|
||||
sleepTime <<= 1;
|
||||
sleeps++;
|
||||
} catch (InterruptedException e) {
|
||||
interrupted = true;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
interrupted = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2016, 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
|
||||
@ -206,5 +206,5 @@ public abstract class ListResourceBundle extends ResourceBundle {
|
||||
lookup = temp;
|
||||
}
|
||||
|
||||
private Map<String,Object> lookup = null;
|
||||
private volatile Map<String,Object> lookup = null;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2016, 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
|
||||
@ -46,8 +46,6 @@ import java.io.IOException;
|
||||
import java.nio.charset.MalformedInputException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.charset.UnmappableCharacterException;
|
||||
import java.security.AccessController;
|
||||
import java.util.Locale;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.util.PropertyResourceBundleCharset;
|
||||
import sun.util.ResourceBundleEnumeration;
|
||||
@ -236,5 +234,5 @@ public class PropertyResourceBundle extends ResourceBundle {
|
||||
|
||||
// ==================privates====================
|
||||
|
||||
private Map<String,Object> lookup;
|
||||
private final Map<String,Object> lookup;
|
||||
}
|
||||
|
||||
@ -536,19 +536,6 @@ class JarFile extends ZipFile {
|
||||
* @return an ordered {@code Stream} of entries in this jar file
|
||||
* @throws IllegalStateException if the jar file has been closed
|
||||
* @since 1.8
|
||||
*
|
||||
* @apiNote A versioned view of the stream obtained from a {@code JarFile}
|
||||
* configured to process a multi-release jar file can be created with code
|
||||
* similar to the following:
|
||||
* <pre>
|
||||
* {@code
|
||||
* Stream<JarEntry> versionedStream(JarFile jf) {
|
||||
* return jf.stream().map(JarEntry::getName)
|
||||
* .filter(name -> !name.startsWith("META-INF/versions/"))
|
||||
* .map(jf::getJarEntry);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public Stream<JarEntry> stream() {
|
||||
return StreamSupport.stream(Spliterators.spliterator(
|
||||
@ -571,7 +558,7 @@ class JarFile extends ZipFile {
|
||||
|
||||
private ZipEntry getVersionedEntry(ZipEntry ze) {
|
||||
ZipEntry vze = null;
|
||||
if (BASE_VERSION_MAJOR < versionMajor && !ze.isDirectory()) {
|
||||
if (BASE_VERSION_MAJOR < versionMajor) {
|
||||
String name = ze.getName();
|
||||
if (!name.startsWith(META_INF)) {
|
||||
vze = searchForVersionedEntry(versionMajor, name);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2016, 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
|
||||
@ -28,12 +28,12 @@ package jdk.internal.misc;
|
||||
public interface JavaLangRefAccess {
|
||||
|
||||
/**
|
||||
* Help ReferenceHandler thread process next pending
|
||||
* {@link java.lang.ref.Reference}
|
||||
* Wait for progress in {@link java.lang.ref.Reference}
|
||||
* processing. If there aren't any pending {@link
|
||||
* java.lang.ref.Reference}s, return immediately.
|
||||
*
|
||||
* @return {@code true} if there was a pending reference and it
|
||||
* was enqueue-ed or {@code false} if there was no
|
||||
* pending reference
|
||||
* @return {@code true} if there were any pending
|
||||
* {@link java.lang.ref.Reference}s, {@code false} otherwise.
|
||||
*/
|
||||
boolean tryHandlePendingReference();
|
||||
boolean waitForReferenceProcessing() throws InterruptedException;
|
||||
}
|
||||
|
||||
@ -1197,6 +1197,9 @@ public final class Unsafe {
|
||||
if (hostClass == null || data == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (hostClass.isArray() || hostClass.isPrimitive()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
return defineAnonymousClass0(hostClass, data, cpPatches);
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 jdk.internal.util.jar;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class VersionedStream {
|
||||
private static final String META_INF_VERSIONS = "META-INF/versions/";
|
||||
|
||||
/**
|
||||
* Returns a stream of versioned entries, derived from the base names of
|
||||
* all entries in a multi-release {@code JarFile} that are present either in
|
||||
* the base directory or in any versioned directory with a version number
|
||||
* less than or equal to the {@code Runtime.Version::major} that the
|
||||
* {@code JarFile} was opened with. These versioned entries are aliases
|
||||
* for the real entries -- i.e. the names are base names and the content
|
||||
* may come from a versioned directory entry. If the {@code jarFile} is not
|
||||
* a multi-release jar, a stream of all entries is returned.
|
||||
*
|
||||
* @param jf the input JarFile
|
||||
* @return stream of entries
|
||||
* @since 9
|
||||
*/
|
||||
public static Stream<JarEntry> stream(JarFile jf) {
|
||||
if (jf.isMultiRelease()) {
|
||||
int version = jf.getVersion().major();
|
||||
return jf.stream()
|
||||
.map(je -> getBaseSuffix(je, version))
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.map(jf::getJarEntry);
|
||||
}
|
||||
return jf.stream();
|
||||
}
|
||||
|
||||
private static String getBaseSuffix(JarEntry je, int version) {
|
||||
String name = je.getName();
|
||||
if (name.startsWith(META_INF_VERSIONS)) {
|
||||
int len = META_INF_VERSIONS.length();
|
||||
int index = name.indexOf('/', len);
|
||||
if (index == -1 || index == (name.length() - 1)) {
|
||||
// filter out META-INF/versions/* and META-INF/versions/*/
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (Integer.parseInt(name, len, index, 10) > version) {
|
||||
// not an integer
|
||||
return null;
|
||||
}
|
||||
} catch (NumberFormatException x) {
|
||||
// silently remove malformed entries
|
||||
return null;
|
||||
}
|
||||
// We know name looks like META-INF/versions/*/*
|
||||
return name.substring(index + 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@ -143,7 +143,8 @@ module java.base {
|
||||
exports jdk.internal.org.objectweb.asm.signature to
|
||||
jdk.scripting.nashorn;
|
||||
exports jdk.internal.loader to
|
||||
java.instrument;
|
||||
java.instrument,
|
||||
java.logging;
|
||||
exports jdk.internal.math to
|
||||
java.desktop;
|
||||
exports jdk.internal.module to
|
||||
|
||||
@ -103,34 +103,42 @@ See http://www.oracle.com/technetwork/java/javase/documentation/index.html for m
|
||||
|
||||
# Translators please note do not translate the options themselves
|
||||
java.launcher.X.usage=\
|
||||
\ -Xmixed mixed mode execution (default)\n\
|
||||
\ -Xint interpreted mode execution only\n\
|
||||
\ -Xbatch disable background compilation\n\
|
||||
\ -Xbootclasspath/a:<directories and zip/jar files separated by {0}>\n\
|
||||
\ append to end of bootstrap class path\n\
|
||||
\ -Xcheck:jni perform additional checks for JNI functions\n\
|
||||
\ -Xcomp forces compilation of methods on first invocation\n\
|
||||
\ -Xdebug provided for backward compatibility\n\
|
||||
\ -Xdiag show additional diagnostic messages\n\
|
||||
\ -Xdiag:resolver show resolver diagnostic messages\n\
|
||||
\ -Xnoclassgc disable class garbage collection\n\
|
||||
\ -Xdisable-@files disable further argument file expansion\n\
|
||||
\ -Xfuture enable strictest checks, anticipating future default\n\
|
||||
\ -Xint interpreted mode execution only\n\
|
||||
\ -Xinternalversion\n\
|
||||
\ displays more detailed JVM version information than the\n\
|
||||
\ -version option\n\
|
||||
\ -Xloggc:<file> log GC status to a file with time stamps\n\
|
||||
\ -Xbatch disable background compilation\n\
|
||||
\ -Xmixed mixed mode execution (default)\n\
|
||||
\ -Xmn<size> sets the initial and maximum size (in bytes) of the heap\n\
|
||||
\ for the young generation (nursery)\n\
|
||||
\ -Xms<size> set initial Java heap size\n\
|
||||
\ -Xmx<size> set maximum Java heap size\n\
|
||||
\ -Xss<size> set java thread stack size\n\
|
||||
\ -Xnoclassgc disable class garbage collection\n\
|
||||
\ -Xprof output cpu profiling data\n\
|
||||
\ -Xfuture enable strictest checks, anticipating future default\n\
|
||||
\ -Xrs reduce use of OS signals by Java/VM (see documentation)\n\
|
||||
\ -Xcheck:jni perform additional checks for JNI functions\n\
|
||||
\ -Xshare:off do not attempt to use shared class data\n\
|
||||
\ -Xshare:auto use shared class data if possible (default)\n\
|
||||
\ -Xshare:off do not attempt to use shared class data\n\
|
||||
\ -Xshare:on require using shared class data, otherwise fail.\n\
|
||||
\ -XshowSettings show all settings and continue\n\
|
||||
\ -XshowSettings:all\n\
|
||||
\ show all settings and continue\n\
|
||||
\ -XshowSettings:vm show all vm related settings and continue\n\
|
||||
\ -XshowSettings:properties\n\
|
||||
\ show all property settings and continue\n\
|
||||
\ -XshowSettings:locale\n\
|
||||
\ show all locale related settings and continue\n\
|
||||
\ -Xdisable-@files disable further argument file expansion\n\
|
||||
\ -XshowSettings:properties\n\
|
||||
\ show all property settings and continue\n\
|
||||
\ -XshowSettings:vm show all vm related settings and continue\n\
|
||||
\ -Xss<size> set java thread stack size\n\
|
||||
\ -Xverify sets the mode of the bytecode verifier\n\
|
||||
\ --add-reads <module>=<target-module>(,<target-module>)*\n\
|
||||
\ updates <module> to read <target-module>, regardless\n\
|
||||
\ of module declaration. \n\
|
||||
|
||||
@ -125,7 +125,9 @@ public class JarURLConnection extends java.net.JarURLConnection {
|
||||
* to get the jarFile, and set it as our permission.
|
||||
*/
|
||||
if (getUseCaches()) {
|
||||
boolean oldUseCaches = jarFileURLConnection.getUseCaches();
|
||||
jarFileURLConnection = factory.getConnection(jarFile);
|
||||
jarFileURLConnection.setUseCaches(oldUseCaches);
|
||||
}
|
||||
|
||||
if ((entryName != null)) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2016, 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
|
||||
@ -125,7 +125,7 @@ public final class OCSP {
|
||||
("Exception while encoding OCSPRequest", e);
|
||||
}
|
||||
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
|
||||
responderURI, issuerCert, null, null,
|
||||
responderURI, new OCSPResponse.IssuerInfo(issuerCert), null, null,
|
||||
Collections.<Extension>emptyList());
|
||||
return (RevocationStatus)ocspResponse.getSingleResponse(certId);
|
||||
}
|
||||
@ -173,7 +173,8 @@ public final class OCSP {
|
||||
("Exception while encoding OCSPRequest", e);
|
||||
}
|
||||
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
|
||||
responderURI, issuerCert, responderCert, date, extensions);
|
||||
responderURI, new OCSPResponse.IssuerInfo(issuerCert),
|
||||
responderCert, date, extensions);
|
||||
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
|
||||
}
|
||||
|
||||
@ -182,7 +183,7 @@ public final class OCSP {
|
||||
*
|
||||
* @param certIds the CertIds to be checked
|
||||
* @param responderURI the URI of the OCSP responder
|
||||
* @param issuerCert the issuer's certificate
|
||||
* @param issuerInfo the issuer's certificate and/or subject and public key
|
||||
* @param responderCert the OCSP responder's certificate
|
||||
* @param date the time the validity of the OCSP responder's certificate
|
||||
* should be checked against. If null, the current time is used.
|
||||
@ -195,8 +196,8 @@ public final class OCSP {
|
||||
* @throws CertPathValidatorException if an exception occurs while
|
||||
* encoding the OCSP Request or validating the OCSP Response
|
||||
*/
|
||||
static OCSPResponse check(List<CertId> certIds, URI responderURI,
|
||||
X509Certificate issuerCert,
|
||||
static OCSPResponse check(List<CertId> certIds, URI responderURI,
|
||||
OCSPResponse.IssuerInfo issuerInfo,
|
||||
X509Certificate responderCert, Date date,
|
||||
List<Extension> extensions)
|
||||
throws IOException, CertPathValidatorException
|
||||
@ -214,7 +215,7 @@ public final class OCSP {
|
||||
ocspResponse = new OCSPResponse(response);
|
||||
|
||||
// verify the response
|
||||
ocspResponse.verify(certIds, issuerCert, responderCert, date,
|
||||
ocspResponse.verify(certIds, issuerInfo, responderCert, date,
|
||||
nonce);
|
||||
} catch (IOException ioe) {
|
||||
throw new CertPathValidatorException(
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, 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,6 +41,7 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
@ -373,8 +374,8 @@ public final class OCSPResponse {
|
||||
}
|
||||
}
|
||||
|
||||
void verify(List<CertId> certIds, X509Certificate issuerCert,
|
||||
X509Certificate responderCert, Date date, byte[] nonce)
|
||||
void verify(List<CertId> certIds, IssuerInfo issuerInfo,
|
||||
X509Certificate responderCert, Date date, byte[] nonce)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
switch (responseStatus) {
|
||||
@ -414,7 +415,9 @@ public final class OCSPResponse {
|
||||
// Add the Issuing CA cert and/or Trusted Responder cert to the list
|
||||
// of certs from the OCSP response
|
||||
try {
|
||||
certs.add(X509CertImpl.toImpl(issuerCert));
|
||||
if (issuerInfo.getCertificate() != null) {
|
||||
certs.add(X509CertImpl.toImpl(issuerInfo.getCertificate()));
|
||||
}
|
||||
if (responderCert != null) {
|
||||
certs.add(X509CertImpl.toImpl(responderCert));
|
||||
}
|
||||
@ -464,7 +467,10 @@ public final class OCSPResponse {
|
||||
// Check whether the signer cert returned by the responder is trusted
|
||||
if (signerCert != null) {
|
||||
// Check if the response is signed by the issuing CA
|
||||
if (signerCert.equals(issuerCert)) {
|
||||
if (signerCert.getSubjectX500Principal().equals(
|
||||
issuerInfo.getName()) &&
|
||||
signerCert.getPublicKey().equals(
|
||||
issuerInfo.getPublicKey())) {
|
||||
if (debug != null) {
|
||||
debug.println("OCSP response is signed by the target's " +
|
||||
"Issuing CA");
|
||||
@ -481,7 +487,7 @@ public final class OCSPResponse {
|
||||
|
||||
// Check if the response is signed by an authorized responder
|
||||
} else if (signerCert.getIssuerX500Principal().equals(
|
||||
issuerCert.getSubjectX500Principal())) {
|
||||
issuerInfo.getName())) {
|
||||
|
||||
// Check for the OCSPSigning key purpose
|
||||
try {
|
||||
@ -502,7 +508,8 @@ public final class OCSPResponse {
|
||||
// Check algorithm constraints specified in security property
|
||||
// "jdk.certpath.disabledAlgorithms".
|
||||
AlgorithmChecker algChecker = new AlgorithmChecker(
|
||||
new TrustAnchor(issuerCert, null));
|
||||
new TrustAnchor(issuerInfo.getName(),
|
||||
issuerInfo.getPublicKey(), null));
|
||||
algChecker.init(false);
|
||||
algChecker.check(signerCert, Collections.<String>emptySet());
|
||||
|
||||
@ -540,7 +547,7 @@ public final class OCSPResponse {
|
||||
|
||||
// verify the signature
|
||||
try {
|
||||
signerCert.verify(issuerCert.getPublicKey());
|
||||
signerCert.verify(issuerInfo.getPublicKey());
|
||||
if (debug != null) {
|
||||
debug.println("OCSP response is signed by an " +
|
||||
"Authorized Responder");
|
||||
@ -971,4 +978,86 @@ public final class OCSPResponse {
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class that allows consumers to pass in issuer information. This
|
||||
* will always consist of the issuer's name and public key, but may also
|
||||
* contain a certificate if the originating data is in that form.
|
||||
*/
|
||||
static final class IssuerInfo {
|
||||
private final X509Certificate certificate;
|
||||
private final X500Principal name;
|
||||
private final PublicKey pubKey;
|
||||
|
||||
IssuerInfo(X509Certificate issuerCert) {
|
||||
certificate = Objects.requireNonNull(issuerCert,
|
||||
"Constructor requires non-null certificate");
|
||||
name = certificate.getSubjectX500Principal();
|
||||
pubKey = certificate.getPublicKey();
|
||||
}
|
||||
|
||||
IssuerInfo(X500Principal subjectName, PublicKey key) {
|
||||
certificate = null;
|
||||
name = Objects.requireNonNull(subjectName,
|
||||
"Constructor requires non-null subject");
|
||||
pubKey = Objects.requireNonNull(key,
|
||||
"Constructor requires non-null public key");
|
||||
}
|
||||
|
||||
IssuerInfo(TrustAnchor anchor) {
|
||||
certificate = anchor.getTrustedCert();
|
||||
if (certificate != null) {
|
||||
name = certificate.getSubjectX500Principal();
|
||||
pubKey = certificate.getPublicKey();
|
||||
} else {
|
||||
name = anchor.getCA();
|
||||
pubKey = anchor.getCAPublicKey();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the certificate in this IssuerInfo if present.
|
||||
*
|
||||
* @return the {@code X509Certificate} used to create this IssuerInfo
|
||||
* object, or {@code null} if a certificate was not used in its
|
||||
* creation.
|
||||
*/
|
||||
X509Certificate getCertificate() {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this issuer.
|
||||
*
|
||||
* @return an {@code X500Principal} corresponding to this issuer's
|
||||
* name. If derived from an issuer's {@code X509Certificate} this
|
||||
* would be equivalent to the certificate subject name.
|
||||
*/
|
||||
X500Principal getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the public key for this issuer.
|
||||
*
|
||||
* @return a {@code PublicKey} for this issuer.
|
||||
*/
|
||||
PublicKey getPublicKey() {
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string representation of this IssuerInfo.
|
||||
*
|
||||
* @return a {@code String} form of this IssuerInfo object.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Issuer Info:\n");
|
||||
sb.append("Name: ").append(name.toString()).append("\n");
|
||||
sb.append("Public Key:\n").append(pubKey.toString()).append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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,12 +61,12 @@ class RevocationChecker extends PKIXRevocationChecker {
|
||||
private List<CertStore> certStores;
|
||||
private Map<X509Certificate, byte[]> ocspResponses;
|
||||
private List<Extension> ocspExtensions;
|
||||
private boolean legacy;
|
||||
private final boolean legacy;
|
||||
private LinkedList<CertPathValidatorException> softFailExceptions =
|
||||
new LinkedList<>();
|
||||
|
||||
// state variables
|
||||
private X509Certificate issuerCert;
|
||||
private OCSPResponse.IssuerInfo issuerInfo;
|
||||
private PublicKey prevPubKey;
|
||||
private boolean crlSignFlag;
|
||||
private int certIndex;
|
||||
@ -301,9 +301,9 @@ class RevocationChecker extends PKIXRevocationChecker {
|
||||
CertPathValidatorException("forward checking not supported");
|
||||
}
|
||||
if (anchor != null) {
|
||||
issuerCert = anchor.getTrustedCert();
|
||||
prevPubKey = (issuerCert != null) ? issuerCert.getPublicKey()
|
||||
: anchor.getCAPublicKey();
|
||||
issuerInfo = new OCSPResponse.IssuerInfo(anchor);
|
||||
prevPubKey = issuerInfo.getPublicKey();
|
||||
|
||||
}
|
||||
crlSignFlag = true;
|
||||
if (params != null && params.certPath() != null) {
|
||||
@ -437,7 +437,7 @@ class RevocationChecker extends PKIXRevocationChecker {
|
||||
private void updateState(X509Certificate cert)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
issuerCert = cert;
|
||||
issuerInfo = new OCSPResponse.IssuerInfo(cert);
|
||||
|
||||
// Make new public key if parameters are missing
|
||||
PublicKey pubKey = cert.getPublicKey();
|
||||
@ -708,14 +708,8 @@ class RevocationChecker extends PKIXRevocationChecker {
|
||||
OCSPResponse response = null;
|
||||
CertId certId = null;
|
||||
try {
|
||||
if (issuerCert != null) {
|
||||
certId = new CertId(issuerCert,
|
||||
currCert.getSerialNumberObject());
|
||||
} else {
|
||||
// must be an anchor name and key
|
||||
certId = new CertId(anchor.getCA(), anchor.getCAPublicKey(),
|
||||
currCert.getSerialNumberObject());
|
||||
}
|
||||
certId = new CertId(issuerInfo.getName(), issuerInfo.getPublicKey(),
|
||||
currCert.getSerialNumberObject());
|
||||
|
||||
// check if there is a cached OCSP response available
|
||||
byte[] responseBytes = ocspResponses.get(cert);
|
||||
@ -732,8 +726,8 @@ class RevocationChecker extends PKIXRevocationChecker {
|
||||
nonce = ext.getValue();
|
||||
}
|
||||
}
|
||||
response.verify(Collections.singletonList(certId), issuerCert,
|
||||
responderCert, params.date(), nonce);
|
||||
response.verify(Collections.singletonList(certId), issuerInfo,
|
||||
responderCert, params.date(), nonce);
|
||||
|
||||
} else {
|
||||
URI responderURI = (this.responderURI != null)
|
||||
@ -746,8 +740,8 @@ class RevocationChecker extends PKIXRevocationChecker {
|
||||
}
|
||||
|
||||
response = OCSP.check(Collections.singletonList(certId),
|
||||
responderURI, issuerCert, responderCert,
|
||||
null, ocspExtensions);
|
||||
responderURI, issuerInfo,
|
||||
responderCert, null, ocspExtensions);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CertPathValidatorException(
|
||||
|
||||
@ -92,6 +92,7 @@ BSD=BSD
|
||||
BTN=BTN
|
||||
BWP=BWP
|
||||
BYB=BYB
|
||||
BYN=BYN
|
||||
BYR=BYR
|
||||
BZD=BZD
|
||||
CAD=CAD
|
||||
@ -310,8 +311,9 @@ brl=Brazilian Real
|
||||
bsd=Bahamian Dollar
|
||||
btn=Bhutanese Ngultrum
|
||||
bwp=Botswanan Pula
|
||||
byb=Belarusian New Ruble (1994-1999)
|
||||
byr=Belarusian Ruble
|
||||
byb=Belarusian Ruble (1994-1999)
|
||||
byn=Belarusian Ruble
|
||||
byr=Belarusian Ruble (2000-2016)
|
||||
bzd=Belize Dollar
|
||||
cad=Canadian Dollar
|
||||
cdf=Congolese Franc
|
||||
@ -399,7 +401,7 @@ mro=Mauritanian Ouguiya
|
||||
mtl=Maltese Lira
|
||||
mur=Mauritian Rupee
|
||||
mvr=Maldivian Rufiyaa
|
||||
mwk=Malawian Kwacha
|
||||
mwk=Malawian Malawi Kwacha
|
||||
mxn=Mexican Peso
|
||||
mxv=Mexican Investment Unit
|
||||
myr=Malaysian Ringgit
|
||||
@ -414,7 +416,7 @@ npr=Nepalese Rupee
|
||||
nzd=New Zealand Dollar
|
||||
omr=Omani Rial
|
||||
pab=Panamanian Balboa
|
||||
pen=Peruvian Nuevo Sol
|
||||
pen=Peruvian Sol
|
||||
pgk=Papua New Guinean Kina
|
||||
php=Philippine Peso
|
||||
pkr=Pakistani Rupee
|
||||
|
||||
@ -281,6 +281,18 @@ JVM_GetSystemPackage(JNIEnv *env, jstring name);
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
JVM_GetSystemPackages(JNIEnv *env);
|
||||
|
||||
/*
|
||||
* java.lang.ref.Reference
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL
|
||||
JVM_GetAndClearReferencePendingList(JNIEnv *env);
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
JVM_HasReferencePendingList(JNIEnv *env);
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_WaitForReferencePendingList(JNIEnv *env);
|
||||
|
||||
/*
|
||||
* java.io.ObjectInputStream
|
||||
*/
|
||||
|
||||
45
jdk/src/java.base/share/native/libjava/Reference.c
Normal file
45
jdk/src/java.base/share/native/libjava/Reference.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 "jvm.h"
|
||||
#include "java_lang_ref_Reference.h"
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_java_lang_ref_Reference_getAndClearReferencePendingList(JNIEnv *env, jclass ignore)
|
||||
{
|
||||
return JVM_GetAndClearReferencePendingList(env);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_java_lang_ref_Reference_hasReferencePendingList(JNIEnv *env, jclass ignore)
|
||||
{
|
||||
return JVM_HasReferencePendingList(env);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_java_lang_ref_Reference_waitForReferencePendingList(JNIEnv *env, jclass ignore)
|
||||
{
|
||||
JVM_WaitForReferencePendingList(env);
|
||||
}
|
||||
@ -112,6 +112,9 @@ GetXUsagePath(char *buf, jint bufsize);
|
||||
jboolean
|
||||
GetApplicationHome(char *buf, jint bufsize);
|
||||
|
||||
jboolean
|
||||
GetApplicationHomeFromDll(char *buf, jint bufsize);
|
||||
|
||||
#define GetArch() GetArchPath(CURRENT_DATA_MODEL)
|
||||
|
||||
/*
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
if (1) { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
return _result; \
|
||||
} \
|
||||
} while(0)
|
||||
@ -44,6 +44,10 @@ int NET_Read(int s, void* buf, size_t len) {
|
||||
RESTARTABLE_RETURN_INT(recv(s, buf, len, 0));
|
||||
}
|
||||
|
||||
int NET_NonBlockingRead(int s, void* buf, size_t len) {
|
||||
RESTARTABLE_RETURN_INT(recv(s, buf, len, MSG_DONTWAIT));
|
||||
}
|
||||
|
||||
int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen) {
|
||||
RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen));
|
||||
@ -86,19 +90,14 @@ int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
||||
RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout));
|
||||
}
|
||||
|
||||
int NET_Timeout(int s, long timeout) {
|
||||
int NET_Timeout0(int s, long timeout, long currentTime) {
|
||||
int result;
|
||||
struct timeval t;
|
||||
long prevtime, newtime;
|
||||
long prevtime = currentTime, newtime;
|
||||
struct pollfd pfd;
|
||||
pfd.fd = s;
|
||||
pfd.events = POLLIN;
|
||||
|
||||
if (timeout > 0) {
|
||||
gettimeofday(&t, NULL);
|
||||
prevtime = (t.tv_sec * 1000) + t.tv_usec / 1000;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
result = poll(&pfd, 1, timeout);
|
||||
if (result < 0 && errno == EINTR) {
|
||||
|
||||
@ -128,13 +128,20 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
|
||||
char *dbuf = NULL;
|
||||
char *tz = NULL;
|
||||
int res;
|
||||
long name_max = 0;
|
||||
|
||||
dirp = opendir(dir);
|
||||
if (dirp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = (struct dirent64 *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
|
||||
name_max = pathconf(dir, _PC_NAME_MAX);
|
||||
// If pathconf did not work, fall back to a mimimum buffer size.
|
||||
if (name_max < 1024) {
|
||||
name_max = 1024;
|
||||
}
|
||||
|
||||
entry = (struct dirent64 *)malloc(offsetof(struct dirent64, d_name) + name_max + 1);
|
||||
if (entry == NULL) {
|
||||
(void) closedir(dirp);
|
||||
return NULL;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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,8 +25,49 @@
|
||||
#include "java.h"
|
||||
|
||||
/*
|
||||
* If app is "/foo/bin/javac", or "/foo/bin/sparcv9/javac" then put
|
||||
* "/foo" into buf.
|
||||
* Find the last occurrence of a string
|
||||
*/
|
||||
char* findLastPathComponent(char *buffer, const char *comp) {
|
||||
char* t = buffer;
|
||||
char* p = NULL;
|
||||
size_t l = JLI_StrLen(comp);
|
||||
t = JLI_StrStr(t, comp);
|
||||
|
||||
while (t != NULL) {
|
||||
p = t;
|
||||
t += l;
|
||||
t = JLI_StrStr(t, comp);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes the trailing file name and any intermediate platform
|
||||
* directories, if any, and its enclosing directory.
|
||||
* Ex: if a buffer contains "/foo/bin/javac" or "/foo/bin/x64/javac", the
|
||||
* truncated resulting buffer will contain "/foo".
|
||||
*/
|
||||
jboolean
|
||||
TruncatePath(char *buf)
|
||||
{
|
||||
// try bin directory, maybe an executable
|
||||
char *p = findLastPathComponent(buf, "/bin/");
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
return JNI_TRUE;
|
||||
}
|
||||
// try lib directory, maybe a library
|
||||
p = findLastPathComponent(buf, "/lib/");
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
return JNI_TRUE;
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the path to the JRE home by locating the executable file
|
||||
* of the current process and then truncating the path to the executable
|
||||
*/
|
||||
jboolean
|
||||
GetApplicationHome(char *buf, jint bufsize)
|
||||
@ -38,26 +79,27 @@ GetApplicationHome(char *buf, jint bufsize)
|
||||
} else {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if (JLI_StrRChr(buf, '/') == 0) {
|
||||
buf[0] = '\0';
|
||||
return JNI_FALSE;
|
||||
}
|
||||
*(JLI_StrRChr(buf, '/')) = '\0'; /* executable file */
|
||||
if (JLI_StrLen(buf) < 4 || JLI_StrRChr(buf, '/') == 0) {
|
||||
buf[0] = '\0';
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (JLI_StrCmp("/bin", buf + JLI_StrLen(buf) - 4) != 0)
|
||||
*(JLI_StrRChr(buf, '/')) = '\0'; /* sparcv9 or amd64 */
|
||||
if (JLI_StrLen(buf) < 4 || JLI_StrCmp("/bin", buf + JLI_StrLen(buf) - 4) != 0) {
|
||||
buf[0] = '\0';
|
||||
return JNI_FALSE;
|
||||
}
|
||||
*(JLI_StrRChr(buf, '/')) = '\0'; /* bin */
|
||||
|
||||
return JNI_TRUE;
|
||||
return TruncatePath(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the path to the JRE home by locating the
|
||||
* shared library and then truncating the path to it.
|
||||
*/
|
||||
jboolean
|
||||
GetApplicationHomeFromDll(char *buf, jint bufsize)
|
||||
{
|
||||
/* try to find ourselves instead */
|
||||
Dl_info info;
|
||||
if (dladdr((void*)&GetApplicationHomeFromDll, &info) != 0) {
|
||||
char *path = realpath(info.dli_fname, buf);
|
||||
if (path == buf) {
|
||||
return TruncatePath(buf);
|
||||
}
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the named program exists
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2016, 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
|
||||
@ -666,6 +666,7 @@ static jboolean
|
||||
GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
|
||||
{
|
||||
char libjava[MAXPATHLEN];
|
||||
struct stat s;
|
||||
|
||||
if (GetApplicationHome(path, pathsize)) {
|
||||
/* Is JRE co-located with the application? */
|
||||
@ -688,6 +689,14 @@ GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
|
||||
}
|
||||
}
|
||||
|
||||
if (GetApplicationHomeFromDll(path, pathsize)) {
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/%s/" JAVA_DLL, path, arch);
|
||||
if (stat(libjava, &s) == 0) {
|
||||
JLI_TraceLauncher("JRE path is %s\n", path);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!speculative)
|
||||
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
|
||||
return JNI_FALSE;
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
|
||||
#include "java_net_SocketInputStream.h"
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* SocketInputStream
|
||||
*/
|
||||
@ -52,6 +51,40 @@ Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) {
|
||||
IO_fd_fdID = NET_GetFileDescriptorID(env);
|
||||
}
|
||||
|
||||
static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
|
||||
int result = 0;
|
||||
long prevtime = NET_GetCurrentTime(), newtime;
|
||||
while (timeout > 0) {
|
||||
result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime);
|
||||
if (result <= 0) {
|
||||
if (result == 0) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "Read timed out");
|
||||
} else if (result == -1) {
|
||||
if (errno == EBADF) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
|
||||
} else if (errno == ENOMEM) {
|
||||
JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
|
||||
} else {
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
(env, JNU_JAVANETPKG "SocketException", "select/poll failed");
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
result = NET_NonBlockingRead(fd, bufP, len);
|
||||
if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
|
||||
newtime = NET_GetCurrentTime();
|
||||
timeout -= newtime - prevtime;
|
||||
if (timeout > 0) {
|
||||
prevtime = newtime;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: java_net_SocketInputStream
|
||||
* Method: socketRead0
|
||||
@ -98,32 +131,18 @@ Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
|
||||
} else {
|
||||
bufP = BUF;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
nread = NET_Timeout(fd, timeout);
|
||||
if (nread <= 0) {
|
||||
if (nread == 0) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
|
||||
"Read timed out");
|
||||
} else if (nread == -1) {
|
||||
if (errno == EBADF) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
|
||||
} else if (errno == ENOMEM) {
|
||||
JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
|
||||
} else {
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
(env, JNU_JAVANETPKG "SocketException", "select/poll failed");
|
||||
}
|
||||
}
|
||||
nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
if (bufP != BUF) {
|
||||
free(bufP);
|
||||
}
|
||||
return -1;
|
||||
return nread;
|
||||
}
|
||||
} else {
|
||||
nread = NET_Read(fd, bufP, len);
|
||||
}
|
||||
|
||||
nread = NET_Read(fd, bufP, len);
|
||||
|
||||
if (nread <= 0) {
|
||||
if (nread < 0) {
|
||||
|
||||
@ -143,7 +162,6 @@ Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,
|
||||
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
|
||||
"Operation interrupted");
|
||||
break;
|
||||
|
||||
default:
|
||||
JNU_ThrowByNameWithMessageAndLastError
|
||||
(env, JNU_JAVANETPKG "SocketException", "Read failed");
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef _ALLBSD_SOURCE
|
||||
#include <values.h>
|
||||
@ -1669,3 +1670,18 @@ NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout)
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
long NET_GetCurrentTime() {
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
return (time.tv_sec * 1000 + time.tv_usec / 1000);
|
||||
}
|
||||
|
||||
int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) {
|
||||
return NET_Timeout0(s, timeout, currentTime);
|
||||
}
|
||||
|
||||
int NET_Timeout(int s, long timeout) {
|
||||
long currentTime = (timeout > 0) ? NET_GetCurrentTime() : 0;
|
||||
return NET_Timeout0(s, timeout, currentTime);
|
||||
}
|
||||
|
||||
@ -35,7 +35,11 @@
|
||||
#include <sys/poll.h>
|
||||
|
||||
int NET_Timeout(int s, long timeout);
|
||||
int NET_Timeout0(int s, long timeout, long currentTime);
|
||||
int NET_Read(int s, void* buf, size_t len);
|
||||
int NET_NonBlockingRead(int s, void* buf, size_t len);
|
||||
int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime);
|
||||
long NET_GetCurrentTime();
|
||||
int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen);
|
||||
int NET_ReadV(int s, const struct iovec * vector, int count);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
||||
@ -348,7 +348,6 @@ GetJREPath(char *path, jint pathsize)
|
||||
|
||||
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
|
||||
return JNI_FALSE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -423,11 +422,11 @@ TruncatePath(char *buf)
|
||||
*JLI_StrRChr(buf, '\\') = '\0'; /* remove .exe file name */
|
||||
if ((cp = JLI_StrRChr(buf, '\\')) == 0) {
|
||||
/* This happens if the application is in a drive root, and
|
||||
* there is no bin directory. */
|
||||
* there is no bin directory. */
|
||||
buf[0] = '\0';
|
||||
return JNI_FALSE;
|
||||
}
|
||||
*cp = '\0'; /* remove the bin\ part */
|
||||
*cp = '\0'; /* remove the bin\ part */
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
@ -449,16 +448,16 @@ GetApplicationHome(char *buf, jint bufsize)
|
||||
jboolean
|
||||
GetApplicationHomeFromDll(char *buf, jint bufsize)
|
||||
{
|
||||
HMODULE hModule;
|
||||
DWORD dwFlags =
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
|
||||
HMODULE module;
|
||||
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
|
||||
|
||||
if (GetModuleHandleEx(dwFlags, (LPCSTR)&GetJREPath, &hModule) == 0) {
|
||||
return JNI_FALSE;
|
||||
};
|
||||
GetModuleFileName(hModule, buf, bufsize);
|
||||
return TruncatePath(buf);
|
||||
if (GetModuleHandleEx(flags, (LPCSTR)&GetJREPath, &module) != 0) {
|
||||
if (GetModuleFileName(module, buf, bufsize) != 0) {
|
||||
return TruncatePath(buf);
|
||||
}
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2016, 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
|
||||
@ -54,7 +54,4 @@ extern jlong Counter2Micros(jlong counts);
|
||||
|
||||
int UnsetEnv(char *name);
|
||||
|
||||
jboolean
|
||||
GetApplicationHomeFromDll(char *buf, jint bufsize);
|
||||
|
||||
#endif /* JAVA_MD_H */
|
||||
|
||||
@ -187,6 +187,7 @@ public class LWWindowPeer
|
||||
|
||||
updateAlwaysOnTopState();
|
||||
updateMinimumSize();
|
||||
updateFocusableWindowState();
|
||||
|
||||
final Shape shape = getTarget().getShape();
|
||||
if (shape != null) {
|
||||
|
||||
@ -63,6 +63,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
|
||||
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
|
||||
private static native void nativeSynthesizeMouseEnteredExitedEvents();
|
||||
private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr, int eventType);
|
||||
private static native void nativeDispose(long nsWindowPtr);
|
||||
private static native void nativeEnterFullScreenMode(long nsWindowPtr);
|
||||
private static native void nativeExitFullScreenMode(long nsWindowPtr);
|
||||
@ -825,6 +826,13 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
return;
|
||||
}
|
||||
|
||||
if (blocked) {
|
||||
// We are going to show a modal window. Previously displayed window will be
|
||||
// blocked/disabled. So we have to send mouse exited event to it now, since
|
||||
// all mouse events are discarded for blocked/disabled windows.
|
||||
nativeSynthesizeMouseEnteredExitedEvents(getNSWindowPtr(), CocoaConstants.NSMouseExited);
|
||||
}
|
||||
|
||||
nativeSetEnabled(getNSWindowPtr(), !blocked);
|
||||
checkBlockingAndOrder();
|
||||
}
|
||||
|
||||
@ -1333,9 +1333,9 @@ JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnde
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CPlatformWindow
|
||||
* Method: nativeSynthesizeMouseEnteredExitedEvents
|
||||
* Signature: (J)V
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__
|
||||
(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
@ -1347,6 +1347,29 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMou
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CPlatformWindow
|
||||
* Method: nativeSynthesizeMouseEnteredExitedEvents
|
||||
* Signature: (JI)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__JI
|
||||
(JNIEnv *env, jclass clazz, jlong windowPtr, jint eventType)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
if (eventType == NSMouseEntered || eventType == NSMouseExited) {
|
||||
NSWindow *nsWindow = OBJC(windowPtr);
|
||||
|
||||
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
|
||||
[AWTWindow synthesizeMouseEnteredExitedEvents:nsWindow withType:eventType];
|
||||
}];
|
||||
} else {
|
||||
[JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];
|
||||
}
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CPlatformWindow
|
||||
* Method: _toggleFullScreenMode
|
||||
|
||||
@ -447,6 +447,7 @@ public final class AWTUtilities {
|
||||
* @param shape the new 'mixing-cutout' shape
|
||||
* @throws NullPointerException if the component argument is {@code null}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
public static void setComponentMixingCutoutShape(Component component,
|
||||
Shape shape)
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, 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
|
||||
@ -749,6 +749,10 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
checkIndex(imageIndex);
|
||||
clearAbortRequest();
|
||||
processImageStarted(imageIndex);
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return bi;
|
||||
}
|
||||
|
||||
if (param == null)
|
||||
param = getDefaultReadParam();
|
||||
@ -1005,9 +1009,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
int j = isBottomUp ? (height -1)*bytesPerScanline : 0;
|
||||
|
||||
for (int i=0; i<height; i++) {
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
iis.readFully(bdata, j, bytesPerScanline);
|
||||
iis.skipBytes(padding);
|
||||
j += isBottomUp ? -bytesPerScanline : bytesPerScanline;
|
||||
@ -1015,6 +1016,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F * i/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
byte[] buf = new byte[lineLength];
|
||||
@ -1051,9 +1055,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
|
||||
for (int j = 0, y = sourceRegion.y;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.read(buf, 0, lineLength);
|
||||
for (int i = 0; i < destinationRegion.width; i++) {
|
||||
//get the bit and assign to the data buffer of the raster
|
||||
@ -1067,6 +1068,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1087,9 +1091,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
int j = isBottomUp ? (height -1) * bytesPerScanline : 0;
|
||||
|
||||
for (int i=0; i<height; i++) {
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
iis.readFully(bdata, j, bytesPerScanline);
|
||||
iis.skipBytes(padding);
|
||||
j += isBottomUp ? -bytesPerScanline : bytesPerScanline;
|
||||
@ -1097,6 +1098,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F * i/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
byte[] buf = new byte[lineLength];
|
||||
@ -1133,9 +1137,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
|
||||
for (int j = 0, y = sourceRegion.y;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.read(buf, 0, lineLength);
|
||||
for (int i = 0; i < destinationRegion.width; i++) {
|
||||
//get the bit and assign to the data buffer of the raster
|
||||
@ -1149,6 +1150,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1168,9 +1172,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
int j = isBottomUp ? (height -1) * width : 0;
|
||||
|
||||
for (int i=0; i<height; i++) {
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
iis.readFully(bdata, j, width);
|
||||
iis.skipBytes(padding);
|
||||
j += isBottomUp ? -width : width;
|
||||
@ -1178,6 +1179,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F * i/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
byte[] buf = new byte[lineLength];
|
||||
@ -1200,9 +1204,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
|
||||
for (int j = 0, y = sourceRegion.y;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.read(buf, 0, lineLength);
|
||||
for (int i = 0, m = sourceRegion.x;
|
||||
i < destinationRegion.width; i++, m += scaleX) {
|
||||
@ -1216,6 +1217,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1235,9 +1239,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
int j = isBottomUp ? (height -1) * width * 3 : 0;
|
||||
|
||||
for (int i=0; i<height; i++) {
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
iis.readFully(bdata, j, lineStride);
|
||||
iis.skipBytes(padding);
|
||||
j += isBottomUp ? -lineStride : lineStride;
|
||||
@ -1245,6 +1246,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F * i/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
byte[] buf = new byte[lineLength];
|
||||
@ -1267,9 +1271,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
|
||||
for (int j = 0, y = sourceRegion.y;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.read(buf, 0, lineLength);
|
||||
for (int i = 0, m = 3 * sourceRegion.x;
|
||||
i < destinationRegion.width; i++, m += 3 * scaleX) {
|
||||
@ -1285,6 +1286,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1302,10 +1306,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
if (noTransform) {
|
||||
int j = isBottomUp ? (height -1) * width : 0;
|
||||
for (int i=0; i<height; i++) {
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
|
||||
iis.readFully(sdata, j, width);
|
||||
iis.skipBytes(padding);
|
||||
|
||||
@ -1314,6 +1314,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F * i/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
short[] buf = new short[lineLength];
|
||||
@ -1336,9 +1339,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
|
||||
for (int j = 0, y = sourceRegion.y;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.readFully(buf, 0, lineLength);
|
||||
for (int i = 0, m = sourceRegion.x;
|
||||
i < destinationRegion.width; i++, m += scaleX) {
|
||||
@ -1352,6 +1352,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1361,15 +1364,15 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
int j = isBottomUp ? (height -1) * width : 0;
|
||||
|
||||
for (int i=0; i<height; i++) {
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
iis.readFully(idata, j, width);
|
||||
j += isBottomUp ? -width : width;
|
||||
processImageUpdate(bi, 0, i,
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F * i/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int[] buf = new int[width];
|
||||
@ -1392,9 +1395,6 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
|
||||
for (int j = 0, y = sourceRegion.y;
|
||||
j < destinationRegion.height; j++, y+=scaleY) {
|
||||
|
||||
if (abortRequested())
|
||||
break;
|
||||
iis.readFully(buf, 0, width);
|
||||
for (int i = 0, m = sourceRegion.x;
|
||||
i < destinationRegion.width; i++, m += scaleX) {
|
||||
@ -1408,6 +1408,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
|
||||
destinationRegion.width, 1, 1, 1,
|
||||
new int[]{0});
|
||||
processImageProgress(100.0F*j/destinationRegion.height);
|
||||
if (abortRequested()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -456,6 +456,9 @@ public class GIFImageReader extends ImageReader {
|
||||
// Update IIOReadProgressListeners
|
||||
++rowsDone;
|
||||
processImageProgress(100.0F*rowsDone/height);
|
||||
if (abortRequested()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (decodeThisRow) {
|
||||
outputRow();
|
||||
@ -860,7 +863,6 @@ public class GIFImageReader extends ImageReader {
|
||||
throw new IndexOutOfBoundsException("imageIndex out of bounds!");
|
||||
}
|
||||
|
||||
clearAbortRequest();
|
||||
readMetadata();
|
||||
|
||||
// A null ImageReadParam means we use the default
|
||||
@ -903,8 +905,13 @@ public class GIFImageReader extends ImageReader {
|
||||
(streamY - sourceRegion.y)/sourceYSubsampling;
|
||||
computeDecodeThisRow();
|
||||
|
||||
clearAbortRequest();
|
||||
// Inform IIOReadProgressListeners of start of image
|
||||
processImageStarted(imageIndex);
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return theImage;
|
||||
}
|
||||
startPass(0);
|
||||
|
||||
this.rowBuf = new byte[width];
|
||||
@ -947,7 +954,7 @@ public class GIFImageReader extends ImageReader {
|
||||
int codeSize = initCodeSize + 1;
|
||||
int codeMask = (1 << codeSize) - 1;
|
||||
|
||||
while (!abortRequested()) {
|
||||
do {
|
||||
code = getCode(codeSize, codeMask);
|
||||
|
||||
if (code == clearCode) {
|
||||
@ -1005,7 +1012,7 @@ public class GIFImageReader extends ImageReader {
|
||||
|
||||
outputPixels(string, len);
|
||||
oldCode = code;
|
||||
}
|
||||
} while (!abortRequested());
|
||||
|
||||
processReadAborted();
|
||||
return theImage;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -1327,28 +1327,32 @@ public class JPEGImageReader extends ImageReader {
|
||||
System.out.println("callbackUpdates is " + callbackUpdates);
|
||||
}
|
||||
|
||||
// Finally, we are ready to read
|
||||
|
||||
/*
|
||||
* All the Jpeg processing happens in native, we should clear
|
||||
* abortFlag of imageIODataStruct in imageioJPEG.c. And we need to
|
||||
* clear abortFlag because if in previous read() if we had called
|
||||
* reader.abort() that will continue to be valid for present call also.
|
||||
*/
|
||||
clearNativeReadAbortFlag(structPointer);
|
||||
processImageStarted(currentImage);
|
||||
|
||||
boolean aborted = false;
|
||||
|
||||
// Note that getData disables acceleration on buffer, but it is
|
||||
// just a 1-line intermediate data transfer buffer that will not
|
||||
// affect the acceleration of the resulting image.
|
||||
aborted = readImage(structPointer,
|
||||
buffer.getData(),
|
||||
numRasterBands,
|
||||
srcBands,
|
||||
bandSizes,
|
||||
srcROI.x, srcROI.y,
|
||||
srcROI.width, srcROI.height,
|
||||
periodX, periodY,
|
||||
abbrevQTables,
|
||||
abbrevDCHuffmanTables,
|
||||
abbrevACHuffmanTables,
|
||||
minProgressivePass, maxProgressivePass,
|
||||
callbackUpdates);
|
||||
/*
|
||||
* Note that getData disables acceleration on buffer, but it is
|
||||
* just a 1-line intermediate data transfer buffer that will not
|
||||
* affect the acceleration of the resulting image.
|
||||
*/
|
||||
boolean aborted = readImage(structPointer,
|
||||
buffer.getData(),
|
||||
numRasterBands,
|
||||
srcBands,
|
||||
bandSizes,
|
||||
srcROI.x, srcROI.y,
|
||||
srcROI.width, srcROI.height,
|
||||
periodX, periodY,
|
||||
abbrevQTables,
|
||||
abbrevDCHuffmanTables,
|
||||
abbrevACHuffmanTables,
|
||||
minProgressivePass, maxProgressivePass,
|
||||
callbackUpdates);
|
||||
|
||||
if (aborted) {
|
||||
processReadAborted();
|
||||
@ -1513,6 +1517,12 @@ public class JPEGImageReader extends ImageReader {
|
||||
int maxProgressivePass,
|
||||
boolean wantUpdates);
|
||||
|
||||
/*
|
||||
* We should call clearNativeReadAbortFlag() before we start reading
|
||||
* jpeg image as image processing happens at native side.
|
||||
*/
|
||||
private native void clearNativeReadAbortFlag(long structPointer);
|
||||
|
||||
public void abort() {
|
||||
setThreadLock();
|
||||
try {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -937,12 +937,6 @@ public class PNGImageReader extends ImageReader {
|
||||
for (int srcY = 0; srcY < passHeight; srcY++) {
|
||||
// Skip filter byte and the remaining row bytes
|
||||
pixelStream.skipBytes(1 + bytesPerRow);
|
||||
|
||||
// If read has been aborted, just return
|
||||
// processReadAborted will be called later
|
||||
if (abortRequested()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -996,6 +990,13 @@ public class PNGImageReader extends ImageReader {
|
||||
for (int srcY = 0; srcY < passHeight; srcY++) {
|
||||
// Update count of pixels read
|
||||
updateImageProgress(passWidth);
|
||||
/*
|
||||
* If read has been aborted, just return
|
||||
* processReadAborted will be called later
|
||||
*/
|
||||
if (abortRequested()) {
|
||||
return;
|
||||
}
|
||||
// Skip filter byte and the remaining row bytes
|
||||
pixelStream.skipBytes(1 + bytesPerRow);
|
||||
}
|
||||
@ -1105,7 +1106,13 @@ public class PNGImageReader extends ImageReader {
|
||||
for (int srcY = 0; srcY < passHeight; srcY++) {
|
||||
// Update count of pixels read
|
||||
updateImageProgress(passWidth);
|
||||
|
||||
/*
|
||||
* If read has been aborted, just return
|
||||
* processReadAborted will be called later
|
||||
*/
|
||||
if (abortRequested()) {
|
||||
return;
|
||||
}
|
||||
// Read the filter type byte and a row of data
|
||||
int filter = pixelStream.read();
|
||||
try {
|
||||
@ -1195,12 +1202,6 @@ public class PNGImageReader extends ImageReader {
|
||||
updateWidth, 1,
|
||||
updateXStep, updateYStep,
|
||||
destinationBands);
|
||||
|
||||
// If read has been aborted, just return
|
||||
// processReadAborted will be called later
|
||||
if (abortRequested()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1215,8 +1216,6 @@ public class PNGImageReader extends ImageReader {
|
||||
this.pixelsDone = 0;
|
||||
this.totalPixels = width*height;
|
||||
|
||||
clearAbortRequest();
|
||||
|
||||
if (metadata.IHDR_interlaceMethod == 0) {
|
||||
decodePass(0, 0, 0, 1, 1, width, height);
|
||||
} else {
|
||||
@ -1241,8 +1240,10 @@ public class PNGImageReader extends ImageReader {
|
||||
(height + ybump)/YSubsampling);
|
||||
}
|
||||
|
||||
// If read has been aborted, just return
|
||||
// processReadAborted will be called later
|
||||
/*
|
||||
* If read has been aborted, just return
|
||||
* processReadAborted will be called later
|
||||
*/
|
||||
if (abortRequested()) {
|
||||
return;
|
||||
}
|
||||
@ -1332,13 +1333,19 @@ public class PNGImageReader extends ImageReader {
|
||||
inputBandsForColorType[colorType],
|
||||
theImage.getSampleModel().getNumBands());
|
||||
|
||||
clearAbortRequest();
|
||||
processImageStarted(0);
|
||||
decodeImage();
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
} else {
|
||||
processImageComplete();
|
||||
decodeImage();
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
} else {
|
||||
processImageComplete();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new IIOException("Error reading PNG image data", e);
|
||||
} finally {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2016, 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
|
||||
@ -101,13 +101,17 @@ public class TIFFDeflateDecompressor extends TIFFDecompressor {
|
||||
|
||||
if (predictor ==
|
||||
BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
|
||||
int step = planar || samplesPerPixel == 1 ? 1 : samplesPerPixel;
|
||||
int samplesPerRow = step * srcWidth;
|
||||
|
||||
int off = bufOffset + step;
|
||||
for (int j = 0; j < srcHeight; j++) {
|
||||
int count = bufOffset + samplesPerPixel * (j * srcWidth + 1);
|
||||
for (int i=samplesPerPixel; i<srcWidth*samplesPerPixel; i++) {
|
||||
buf[count] += buf[count - samplesPerPixel];
|
||||
int count = off;
|
||||
for (int i = step; i < samplesPerRow; i++) {
|
||||
buf[count] += buf[count - step];
|
||||
count++;
|
||||
}
|
||||
off += samplesPerRow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1131,8 +1131,12 @@ public class TIFFImageReader extends ImageReader {
|
||||
pixelsToRead = destRegion.width * destRegion.height;
|
||||
pixelsRead = 0;
|
||||
|
||||
clearAbortRequest();
|
||||
processImageStarted(imageIndex);
|
||||
processImageProgress(0.0f);
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return theImage;
|
||||
}
|
||||
|
||||
tilesAcross = (width + tileOrStripWidth - 1) / tileOrStripWidth;
|
||||
tilesDown = (height + tileOrStripHeight - 1) / tileOrStripHeight;
|
||||
@ -1286,6 +1290,10 @@ public class TIFFImageReader extends ImageReader {
|
||||
}
|
||||
|
||||
reportProgress();
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return theImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1294,16 +1302,14 @@ public class TIFFImageReader extends ImageReader {
|
||||
decodeTile(ti, tj, -1);
|
||||
|
||||
reportProgress();
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return theImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
} else {
|
||||
processImageComplete();
|
||||
}
|
||||
|
||||
processImageComplete();
|
||||
return theImage;
|
||||
}
|
||||
|
||||
|
||||
@ -162,16 +162,18 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
|
||||
|
||||
if (predictor ==
|
||||
BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
|
||||
int step = planar || samplesPerPixel == 1 ? 1 : samplesPerPixel;
|
||||
|
||||
int samplesPerRow = step * srcWidth;
|
||||
|
||||
int off = dstOffset + step;
|
||||
for (int j = 0; j < srcHeight; j++) {
|
||||
|
||||
int count = dstOffset + samplesPerPixel * (j * srcWidth + 1);
|
||||
|
||||
for (int i = samplesPerPixel; i < srcWidth * samplesPerPixel; i++) {
|
||||
|
||||
dstData[count] += dstData[count - samplesPerPixel];
|
||||
int count = off;
|
||||
for (int i = step; i < samplesPerRow; i++) {
|
||||
dstData[count] += dstData[count - step];
|
||||
count++;
|
||||
}
|
||||
off += samplesPerRow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -504,7 +504,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
|
||||
public Object createValue(UIDefaults table) {
|
||||
GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
|
||||
GTKStyle style = (GTKStyle)factory.getStyle(null, region);
|
||||
return style.getFontForState(null);
|
||||
return style.getDefaultFont();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -282,7 +282,17 @@ class GTKStyle extends SynthStyle implements GTKConstants {
|
||||
return getColorForState(context, type);
|
||||
}
|
||||
|
||||
Font getDefaultFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
protected Font getFontForState(SynthContext context) {
|
||||
Font propFont = UIManager
|
||||
.getFont(context.getRegion().getName() + ".font");
|
||||
if (propFont != null) {
|
||||
// if font property got a value then return it
|
||||
return propFont;
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
|
||||
@ -843,32 +843,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
return new Rectangle(comp.x, comp.y, comp.width, comp.height);
|
||||
}
|
||||
public void setMixingCutoutShape(Component comp, Shape shape) {
|
||||
Region region = shape == null ? null :
|
||||
Region.getInstance(shape, null);
|
||||
|
||||
synchronized (comp.getTreeLock()) {
|
||||
boolean needShowing = false;
|
||||
boolean needHiding = false;
|
||||
|
||||
if (!comp.isNonOpaqueForMixing()) {
|
||||
needHiding = true;
|
||||
}
|
||||
|
||||
comp.mixingCutoutRegion = region;
|
||||
|
||||
if (!comp.isNonOpaqueForMixing()) {
|
||||
needShowing = true;
|
||||
}
|
||||
|
||||
if (comp.isMixingNeeded()) {
|
||||
if (needHiding) {
|
||||
comp.mixOnHiding(comp.isLightweight());
|
||||
}
|
||||
if (needShowing) {
|
||||
comp.mixOnShowing();
|
||||
}
|
||||
}
|
||||
}
|
||||
comp.setMixingCutoutShape(shape);
|
||||
}
|
||||
|
||||
public void setGraphicsConfiguration(Component comp,
|
||||
@ -10238,6 +10213,71 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a 'mixing-cutout' shape for the given component.
|
||||
*
|
||||
* By default a lightweight component is treated as an opaque rectangle for
|
||||
* the purposes of the Heavyweight/Lightweight Components Mixing feature.
|
||||
* This method enables developers to set an arbitrary shape to be cut out
|
||||
* from heavyweight components positioned underneath the lightweight
|
||||
* component in the z-order.
|
||||
* <p>
|
||||
* The {@code shape} argument may have the following values:
|
||||
* <ul>
|
||||
* <li>{@code null} - reverts the default cutout shape (the rectangle equal
|
||||
* to the component's {@code getBounds()})
|
||||
* <li><i>empty-shape</i> - does not cut out anything from heavyweight
|
||||
* components. This makes the given lightweight component effectively
|
||||
* transparent. Note that descendants of the lightweight component still
|
||||
* affect the shapes of heavyweight components. An example of an
|
||||
* <i>empty-shape</i> is {@code new Rectangle()}.
|
||||
* <li><i>non-empty-shape</i> - the given shape will be cut out from
|
||||
* heavyweight components.
|
||||
* </ul>
|
||||
* <p>
|
||||
* The most common example when the 'mixing-cutout' shape is needed is a
|
||||
* glass pane component. The {@link JRootPane#setGlassPane()} method
|
||||
* automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
|
||||
* for the given glass pane component. If a developer needs some other
|
||||
* 'mixing-cutout' shape for the glass pane (which is rare), this must be
|
||||
* changed manually after installing the glass pane to the root pane.
|
||||
* <p>
|
||||
* Note that the 'mixing-cutout' shape neither affects painting, nor the
|
||||
* mouse events handling for the given component. It is used exclusively
|
||||
* for the purposes of the Heavyweight/Lightweight Components Mixing
|
||||
* feature.
|
||||
*
|
||||
* @param shape the new 'mixing-cutout' shape
|
||||
* @since 9
|
||||
*/
|
||||
void setMixingCutoutShape(Shape shape) {
|
||||
Region region = shape == null ? null : Region.getInstance(shape, null);
|
||||
|
||||
synchronized (getTreeLock()) {
|
||||
boolean needShowing = false;
|
||||
boolean needHiding = false;
|
||||
|
||||
if (!isNonOpaqueForMixing()) {
|
||||
needHiding = true;
|
||||
}
|
||||
|
||||
mixingCutoutRegion = region;
|
||||
|
||||
if (!isNonOpaqueForMixing()) {
|
||||
needShowing = true;
|
||||
}
|
||||
|
||||
if (isMixingNeeded()) {
|
||||
if (needHiding) {
|
||||
mixOnHiding(isLightweight());
|
||||
}
|
||||
if (needShowing) {
|
||||
mixOnShowing();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ****************** END OF MIXING CODE ********************************
|
||||
|
||||
// Note that the method is overriden in the Window class,
|
||||
|
||||
@ -273,9 +273,7 @@ public class Taskbar {
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests user attention to the specified window until it is activated.
|
||||
*
|
||||
* On an already active window requesting attention does nothing.
|
||||
* Requests user attention to the specified window.
|
||||
*
|
||||
* @param w window
|
||||
* @throws SecurityException if a security manager exists and it denies the
|
||||
|
||||
@ -208,7 +208,7 @@ public abstract class Toolkit {
|
||||
|
||||
/**
|
||||
* Returns whether dynamic layout of Containers on resize is currently
|
||||
* enabled on the underlying operating system and/or window manager). If the
|
||||
* enabled on the underlying operating system and/or window manager. If the
|
||||
* platform supports it, {@code setDynamicLayout(boolean)} may be used to
|
||||
* programmatically enable or disable platform dynamic layout. Regardless of
|
||||
* whether that toggling is supported, or whether {@code true} or {@code
|
||||
|
||||
@ -49,9 +49,7 @@ public interface TaskbarPeer {
|
||||
default void requestUserAttention(boolean enabled, final boolean critical) {}
|
||||
|
||||
/**
|
||||
* Requests user attention to the specified window until it is activated.
|
||||
*
|
||||
* On an already active window requesting attention does nothing.
|
||||
* Requests user attention to the specified window.
|
||||
*
|
||||
* @param w window
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -26,15 +26,11 @@ package javax.swing;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Window;
|
||||
import java.util.*;
|
||||
import java.awt.FocusTraversalPolicy;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* A FocusTraversalPolicy that determines traversal order by sorting the
|
||||
@ -100,27 +96,10 @@ public class SortingFocusTraversalPolicy
|
||||
* See: JDK-8048887
|
||||
*/
|
||||
private static final boolean legacySortingFTPEnabled;
|
||||
private static final Method legacyMergeSortMethod;
|
||||
|
||||
static {
|
||||
legacySortingFTPEnabled = "true".equals(AccessController.doPrivileged(
|
||||
new GetPropertyAction("swing.legacySortingFTPEnabled", "true")));
|
||||
legacyMergeSortMethod = legacySortingFTPEnabled ?
|
||||
AccessController.doPrivileged(new PrivilegedAction<Method>() {
|
||||
public Method run() {
|
||||
try {
|
||||
Method m = java.util.Arrays.class.getDeclaredMethod("legacyMergeSort",
|
||||
new Class<?>[]{Object[].class,
|
||||
Comparator.class});
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
} catch (NoSuchMethodException e) {
|
||||
// using default sorting algo
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}) :
|
||||
null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -169,30 +148,25 @@ public class SortingFocusTraversalPolicy
|
||||
private void enumerateAndSortCycle(Container focusCycleRoot, List<Component> cycle) {
|
||||
if (focusCycleRoot.isShowing()) {
|
||||
enumerateCycle(focusCycleRoot, cycle);
|
||||
if (!legacySortingFTPEnabled ||
|
||||
!legacySort(cycle, comparator))
|
||||
{
|
||||
Collections.sort(cycle, comparator);
|
||||
if (legacySortingFTPEnabled) {
|
||||
legacySort(cycle, comparator);
|
||||
} else {
|
||||
cycle.sort(comparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean legacySort(List<Component> l, Comparator<? super Component> c) {
|
||||
if (legacyMergeSortMethod == null)
|
||||
return false;
|
||||
|
||||
Object[] a = l.toArray();
|
||||
try {
|
||||
legacyMergeSortMethod.invoke(null, a, c);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
return false;
|
||||
private void legacySort(List<Component> l,
|
||||
Comparator<? super Component> c) {
|
||||
if (c != null && l.size() > 1) {
|
||||
Component[] a = l.toArray(new Component[l.size()]);
|
||||
mergeSort(a.clone(), a, 0, a.length, 0, c);
|
||||
ListIterator<Component> i = l.listIterator();
|
||||
for (Component e : a) {
|
||||
i.next();
|
||||
i.set(e);
|
||||
}
|
||||
}
|
||||
ListIterator<Component> i = l.listIterator();
|
||||
for (Object e : a) {
|
||||
i.next();
|
||||
i.set((Component)e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@ -665,6 +639,48 @@ public class SortingFocusTraversalPolicy
|
||||
protected boolean accept(Component aComponent) {
|
||||
return fitnessTestPolicy.accept(aComponent);
|
||||
}
|
||||
|
||||
// merge sort implementation copied from java.utils.Arrays
|
||||
private <T> void mergeSort(T[] src, T[] dest,
|
||||
int low, int high, int off,
|
||||
Comparator<? super T> c) {
|
||||
int length = high - low;
|
||||
|
||||
// Insertion sort on smallest arrays
|
||||
if (length < 7) {
|
||||
for (int i=low; i<high; i++)
|
||||
for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--) {
|
||||
T t = dest[j];
|
||||
dest[j] = dest[j-1];
|
||||
dest[j-1] = t;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Recursively sort halves of dest into src
|
||||
int destLow = low;
|
||||
int destHigh = high;
|
||||
low += off;
|
||||
high += off;
|
||||
int mid = (low + high) >>> 1;
|
||||
mergeSort(dest, src, low, mid, -off, c);
|
||||
mergeSort(dest, src, mid, high, -off, c);
|
||||
|
||||
// If list is already sorted, just copy from src to dest. This is an
|
||||
// optimization that results in faster sorts for nearly ordered lists.
|
||||
if (c.compare(src[mid-1], src[mid]) <= 0) {
|
||||
System.arraycopy(src, low, dest, destLow, length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Merge sorted halves (now in src) into dest
|
||||
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
|
||||
if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
|
||||
dest[i] = src[p++];
|
||||
else
|
||||
dest[i] = src[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create our own subclass and change accept to public so that we can call
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
||||
@ -1603,13 +1603,18 @@ public class BasicSliderUI extends SliderUI{
|
||||
blockIncrement = 1;
|
||||
}
|
||||
|
||||
int tickSpacing = getTickSpacing();
|
||||
if (slider.getSnapToTicks()) {
|
||||
int tickSpacing = getTickSpacing();
|
||||
|
||||
if (blockIncrement < tickSpacing) {
|
||||
blockIncrement = tickSpacing;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tickSpacing > 0) {
|
||||
blockIncrement = tickSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL);
|
||||
slider.setValue(slider.getValue() + delta);
|
||||
|
||||
@ -391,21 +391,8 @@ public class SynthButtonUI extends BasicButtonUI implements
|
||||
}
|
||||
|
||||
private Icon getRolloverIcon(AbstractButton b, Icon defaultIcon) {
|
||||
ButtonModel model = b.getModel();
|
||||
Icon icon = null;
|
||||
if (model.isSelected()) {
|
||||
icon = getIcon(b, b.getRolloverSelectedIcon(), null,
|
||||
SynthConstants.MOUSE_OVER | SynthConstants.SELECTED);
|
||||
if (icon == null) {
|
||||
icon = getIcon(b, b.getSelectedIcon(), null,
|
||||
SynthConstants.SELECTED);
|
||||
}
|
||||
}
|
||||
if (icon == null) {
|
||||
icon = getIcon(b, b.getRolloverIcon(), defaultIcon,
|
||||
SynthConstants.MOUSE_OVER);
|
||||
}
|
||||
return icon;
|
||||
return getSpecificIcon(b, b.getRolloverSelectedIcon(), b.getRolloverIcon(),
|
||||
defaultIcon, SynthConstants.MOUSE_OVER);
|
||||
}
|
||||
|
||||
private Icon getPressedIcon(AbstractButton b, Icon defaultIcon) {
|
||||
@ -414,21 +401,44 @@ public class SynthButtonUI extends BasicButtonUI implements
|
||||
}
|
||||
|
||||
private Icon getSynthDisabledIcon(AbstractButton b, Icon defaultIcon) {
|
||||
ButtonModel model = b.getModel();
|
||||
return getSpecificIcon(b, b.getDisabledSelectedIcon(), b.getDisabledIcon(),
|
||||
defaultIcon, SynthConstants.DISABLED);
|
||||
}
|
||||
|
||||
private Icon getSpecificIcon(AbstractButton b, Icon specificSelectedIcon,
|
||||
Icon specificIcon, Icon defaultIcon,
|
||||
int state) {
|
||||
boolean selected = b.getModel().isSelected();
|
||||
Icon icon = null;
|
||||
if (model.isSelected()) {
|
||||
icon = getIcon(b, b.getDisabledSelectedIcon(), null,
|
||||
SynthConstants.DISABLED | SynthConstants.SELECTED);
|
||||
|
||||
if (selected) {
|
||||
icon = specificSelectedIcon;
|
||||
if (icon == null) {
|
||||
icon = getIcon(b, b.getSelectedIcon(), null,
|
||||
SynthConstants.SELECTED);
|
||||
icon = b.getSelectedIcon();
|
||||
}
|
||||
}
|
||||
|
||||
if (icon == null) {
|
||||
icon = getIcon(b, b.getDisabledIcon(), defaultIcon,
|
||||
SynthConstants.DISABLED);
|
||||
icon = specificIcon;
|
||||
}
|
||||
return icon;
|
||||
|
||||
if (icon != null) {
|
||||
return icon;
|
||||
}
|
||||
|
||||
if (defaultIcon == null || defaultIcon instanceof UIResource) {
|
||||
if (selected) {
|
||||
icon = getSynthIcon(b, state | SynthConstants.SELECTED);
|
||||
if (icon == null) {
|
||||
icon = getSynthIcon(b, SynthConstants.SELECTED);
|
||||
}
|
||||
}
|
||||
if (icon == null) {
|
||||
icon = getSynthIcon(b, state);
|
||||
}
|
||||
}
|
||||
|
||||
return icon != null ? icon : defaultIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -550,13 +550,16 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
return charinfo;
|
||||
}
|
||||
|
||||
private static final boolean DEBUG = FontUtilities.debugFonts();
|
||||
/*
|
||||
* This takes the glyph info record obtained from the glyph vector and converts it into a similar record
|
||||
* adjusted to represent character data instead. For economy we don't use glyph info records in this processing.
|
||||
*
|
||||
* Here are some constraints:
|
||||
* - there can be more glyphs than characters (glyph insertion, perhaps based on normalization, has taken place)
|
||||
* - there can not be fewer glyphs than characters (0xffff glyphs are inserted for characters ligaturized away)
|
||||
* - there can be fewer glyphs than characters
|
||||
* Some layout engines may insert 0xffff glyphs for characters ligaturized away, but
|
||||
* not all do, and it cannot be relied upon.
|
||||
* - each glyph maps to a single character, when multiple glyphs exist for a character they all map to it, but
|
||||
* no two characters map to the same glyph
|
||||
* - multiple glyphs mapping to the same character need not be in sequence (thai, tamil have split characters)
|
||||
@ -578,7 +581,8 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
*
|
||||
* The algorithm works in the following way:
|
||||
* 1) we scan the glyphs ltr or rtl based on the bidi run direction
|
||||
* 2) we can work in place, since we always consume a glyph for each char we write
|
||||
* 2) Since the may be fewer glyphs than chars we cannot work in place.
|
||||
* A new array is allocated for output.
|
||||
* a) if the line is ltr, we start writing at position 0 until we finish, there may be leftver space
|
||||
* b) if the line is rtl and 1-1, we start writing at position numChars/glyphs - 1 until we finish at 0
|
||||
* c) otherwise if we don't finish at 0, we have to copy the data down
|
||||
@ -594,7 +598,7 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
* iii) the x advance is the distance to the maximum x + adv of all glyphs whose advance is not zero
|
||||
* iv) the y advance is the baseline
|
||||
* v) vis x,y,w,h tightly encloses the vis x,y,w,h of all the glyphs with nonzero w and h
|
||||
* 4) we can make some simple optimizations if we know some things:
|
||||
* 4) In the future, we can make some simple optimizations to avoid copying if we know some things:
|
||||
* a) if the mapping is 1-1, unidirectional, and there are no zero-adv glyphs, we just return the glyphinfo
|
||||
* b) if the mapping is 1-1, unidirectional, we just adjust the remaining glyphs to originate at right/left of the base
|
||||
* c) if the mapping is 1-1, we compute the base position and advance as we go, then go back to adjust the remaining glyphs
|
||||
@ -625,23 +629,20 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
System.out.println(source);
|
||||
}
|
||||
|
||||
/*
|
||||
if ((gv.getDescriptionFlags() & 0x7) == 0) {
|
||||
return glyphinfo;
|
||||
}
|
||||
*/
|
||||
|
||||
int numGlyphs = gv.getNumGlyphs();
|
||||
if (numGlyphs == 0) {
|
||||
return glyphinfo;
|
||||
}
|
||||
int[] indices = gv.getGlyphCharIndices(0, numGlyphs, null);
|
||||
float[] charInfo = new float[source.getLength() * numvals];
|
||||
|
||||
boolean DEBUG = false;
|
||||
if (DEBUG) {
|
||||
System.err.println("number of glyphs: " + numGlyphs);
|
||||
System.err.println("glyphinfo.len: " + glyphinfo.length);
|
||||
System.err.println("indices.len: " + indices.length);
|
||||
for (int i = 0; i < numGlyphs; ++i) {
|
||||
System.err.println("g: " + i +
|
||||
" v: " + gv.getGlyphCode(i) +
|
||||
", x: " + glyphinfo[i*numvals+posx] +
|
||||
", a: " + glyphinfo[i*numvals+advx] +
|
||||
", n: " + indices[i]);
|
||||
@ -650,22 +651,19 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
|
||||
int minIndex = indices[0]; // smallest index seen this cluster
|
||||
int maxIndex = minIndex; // largest index seen this cluster
|
||||
int nextMin = 0; // expected smallest index for this cluster
|
||||
int cp = 0; // character position
|
||||
int cx = 0; // character index (logical)
|
||||
int cc = 0;
|
||||
int gp = 0; // glyph position
|
||||
int gx = 0; // glyph index (visual)
|
||||
int gxlimit = numGlyphs; // limit of gx, when we reach this we're done
|
||||
int pdelta = numvals; // delta for incrementing positions
|
||||
int xdelta = 1; // delta for incrementing indices
|
||||
|
||||
boolean ltr = (source.getLayoutFlags() & 0x1) == 0;
|
||||
if (!ltr) {
|
||||
boolean rtl = (source.getLayoutFlags() & 0x1) == 1;
|
||||
if (rtl) {
|
||||
minIndex = indices[numGlyphs - 1];
|
||||
maxIndex = minIndex;
|
||||
nextMin = 0; // still logical
|
||||
cp = glyphinfo.length - numvals;
|
||||
cx = 0; // still logical
|
||||
cp = charInfo.length - numvals;
|
||||
gp = glyphinfo.length - numvals;
|
||||
gx = numGlyphs - 1;
|
||||
gxlimit = -1;
|
||||
@ -693,47 +691,36 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
float cposl = 0, cposr = 0, cvisl = 0, cvist = 0, cvisr = 0, cvisb = 0;
|
||||
float baseline = 0;
|
||||
|
||||
// record if we have to copy data even when no cluster
|
||||
boolean mustCopy = false;
|
||||
|
||||
while (gx != gxlimit) {
|
||||
// start of new cluster
|
||||
boolean haveCopy = false;
|
||||
int clusterExtraGlyphs = 0;
|
||||
|
||||
minIndex = indices[gx];
|
||||
maxIndex = minIndex;
|
||||
|
||||
cposl = glyphinfo[gp + posx];
|
||||
cposr = cposl + glyphinfo[gp + advx];
|
||||
cvisl = glyphinfo[gp + visx];
|
||||
cvist = glyphinfo[gp + visy];
|
||||
cvisr = cvisl + glyphinfo[gp + visw];
|
||||
cvisb = cvist + glyphinfo[gp + vish];
|
||||
|
||||
// advance to next glyph
|
||||
gx += xdelta;
|
||||
gp += pdelta;
|
||||
|
||||
/*
|
||||
while (gx != gxlimit && (glyphinfo[gp + advx] == 0 ||
|
||||
minIndex != nextMin || indices[gx] <= maxIndex)) {
|
||||
*/
|
||||
while (gx != gxlimit &&
|
||||
((glyphinfo[gp + advx] == 0) ||
|
||||
(minIndex != nextMin) ||
|
||||
(indices[gx] <= maxIndex) ||
|
||||
(maxIndex - minIndex > clusterExtraGlyphs))) {
|
||||
// initialize base data first time through, using base glyph
|
||||
if (!haveCopy) {
|
||||
int gps = gp - pdelta;
|
||||
|
||||
cposl = glyphinfo[gps + posx];
|
||||
cposr = cposl + glyphinfo[gps + advx];
|
||||
cvisl = glyphinfo[gps + visx];
|
||||
cvist = glyphinfo[gps + visy];
|
||||
cvisr = cvisl + glyphinfo[gps + visw];
|
||||
cvisb = cvist + glyphinfo[gps + vish];
|
||||
|
||||
haveCopy = true;
|
||||
++clusterExtraGlyphs; // have an extra glyph in this cluster
|
||||
if (DEBUG) {
|
||||
System.err.println("gp=" +gp +" adv=" + glyphinfo[gp + advx] +
|
||||
" gx="+ gx+ " i[gx]="+indices[gx] +
|
||||
" clusterExtraGlyphs="+clusterExtraGlyphs);
|
||||
}
|
||||
|
||||
// have an extra glyph in this cluster
|
||||
++clusterExtraGlyphs;
|
||||
|
||||
// adjust advance only if new glyph has non-zero advance
|
||||
float radvx = glyphinfo[gp + advx];
|
||||
if (radvx != 0) {
|
||||
@ -764,110 +751,90 @@ class ExtendedTextSourceLabel extends ExtendedTextLabel implements Decoration.La
|
||||
// done with cluster, gx and gp are set for next glyph
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("minIndex = " + minIndex + ", maxIndex = " + maxIndex);
|
||||
System.err.println("minIndex = " + minIndex + ", maxIndex = " + maxIndex);
|
||||
}
|
||||
|
||||
nextMin = maxIndex + 1;
|
||||
// save adjustments to the base character and do common adjustments.
|
||||
charInfo[cp + posx] = cposl;
|
||||
charInfo[cp + posy] = baseline;
|
||||
charInfo[cp + advx] = cposr - cposl;
|
||||
charInfo[cp + advy] = 0;
|
||||
charInfo[cp + visx] = cvisl;
|
||||
charInfo[cp + visy] = cvist;
|
||||
charInfo[cp + visw] = cvisr - cvisl;
|
||||
charInfo[cp + vish] = cvisb - cvist;
|
||||
cc++;
|
||||
|
||||
// do common character adjustments
|
||||
glyphinfo[cp + posy] = baseline;
|
||||
glyphinfo[cp + advy] = 0;
|
||||
|
||||
if (haveCopy) {
|
||||
// save adjustments to the base character
|
||||
glyphinfo[cp + posx] = cposl;
|
||||
glyphinfo[cp + advx] = cposr - cposl;
|
||||
glyphinfo[cp + visx] = cvisl;
|
||||
glyphinfo[cp + visy] = cvist;
|
||||
glyphinfo[cp + visw] = cvisr - cvisl;
|
||||
glyphinfo[cp + vish] = cvisb - cvist;
|
||||
|
||||
// compare number of chars read with number of glyphs read.
|
||||
// if more glyphs than chars, set mustCopy to true, as we'll always have
|
||||
// to copy the data from here on out.
|
||||
if (maxIndex - minIndex < clusterExtraGlyphs) {
|
||||
mustCopy = true;
|
||||
}
|
||||
|
||||
// Fix the characters that follow the base character.
|
||||
// New values are all the same. Note we fix the number of characters
|
||||
// we saw, not the number of glyphs we saw.
|
||||
if (minIndex < maxIndex) {
|
||||
if (!ltr) {
|
||||
// if rtl, characters to left of base, else to right. reuse cposr.
|
||||
cposr = cposl;
|
||||
}
|
||||
cvisr -= cvisl; // reuse, convert to deltas.
|
||||
cvisb -= cvist;
|
||||
|
||||
int iMinIndex = minIndex, icp = cp / 8;
|
||||
|
||||
while (minIndex < maxIndex) {
|
||||
++minIndex;
|
||||
cx += xdelta;
|
||||
cp += pdelta;
|
||||
|
||||
if (cp < 0 || cp >= glyphinfo.length) {
|
||||
if (DEBUG) System.out.println("minIndex = " + iMinIndex + ", maxIndex = " + maxIndex + ", cp = " + icp);
|
||||
}
|
||||
|
||||
glyphinfo[cp + posx] = cposr;
|
||||
glyphinfo[cp + posy] = baseline;
|
||||
glyphinfo[cp + advx] = 0;
|
||||
glyphinfo[cp + advy] = 0;
|
||||
glyphinfo[cp + visx] = cvisl;
|
||||
glyphinfo[cp + visy] = cvist;
|
||||
glyphinfo[cp + visw] = cvisr;
|
||||
glyphinfo[cp + vish] = cvisb;
|
||||
}
|
||||
}
|
||||
|
||||
// no longer using this copy
|
||||
haveCopy = false;
|
||||
} else if (mustCopy) {
|
||||
// out of synch, so we have to copy all the time now
|
||||
int gpr = gp - pdelta;
|
||||
|
||||
glyphinfo[cp + posx] = glyphinfo[gpr + posx];
|
||||
glyphinfo[cp + advx] = glyphinfo[gpr + advx];
|
||||
glyphinfo[cp + visx] = glyphinfo[gpr + visx];
|
||||
glyphinfo[cp + visy] = glyphinfo[gpr + visy];
|
||||
glyphinfo[cp + visw] = glyphinfo[gpr + visw];
|
||||
glyphinfo[cp + vish] = glyphinfo[gpr + vish];
|
||||
/* We may have consumed multiple glyphs for this char position.
|
||||
* Map those extra consumed glyphs to char positions that would follow
|
||||
* up to the index prior to that which begins the next cluster.
|
||||
* If we have reached the last glyph (reached gxlimit) then we need to
|
||||
* map remaining unmapped chars to the same location as the last one.
|
||||
*/
|
||||
int tgt;
|
||||
if (gx == gxlimit) {
|
||||
tgt = charInfo.length / numvals;
|
||||
} else {
|
||||
tgt = indices[gx]-1;
|
||||
}
|
||||
// else glyphinfo is already at the correct character position, and is unchanged, so just leave it
|
||||
if (DEBUG) {
|
||||
System.err.println("gx=" + gx + " gxlimit=" + gxlimit +
|
||||
" charInfo.len=" + charInfo.length +
|
||||
" tgt=" + tgt + " cc=" + cc + " cp=" + cp);
|
||||
}
|
||||
while (cc < tgt) {
|
||||
if (rtl) {
|
||||
// if rtl, characters to left of base, else to right. reuse cposr.
|
||||
cposr = cposl;
|
||||
}
|
||||
cvisr -= cvisl; // reuse, convert to deltas.
|
||||
cvisb -= cvist;
|
||||
|
||||
// reset for new cluster
|
||||
cp += pdelta;
|
||||
cx += xdelta;
|
||||
}
|
||||
cp += pdelta;
|
||||
|
||||
if (mustCopy && !ltr) {
|
||||
// data written to wrong end of array, need to shift down
|
||||
if (cp < 0 || cp >= charInfo.length) {
|
||||
if (DEBUG) {
|
||||
System.err.println("Error : cp=" + cp +
|
||||
" charInfo.length=" + charInfo.length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cp -= pdelta; // undo last increment, get start of valid character data in array
|
||||
System.arraycopy(glyphinfo, cp, glyphinfo, 0, glyphinfo.length - cp);
|
||||
if (DEBUG) {
|
||||
System.err.println("Insert charIndex " + cc + " at pos="+cp);
|
||||
}
|
||||
charInfo[cp + posx] = cposr;
|
||||
charInfo[cp + posy] = baseline;
|
||||
charInfo[cp + advx] = 0;
|
||||
charInfo[cp + advy] = 0;
|
||||
charInfo[cp + visx] = cvisl;
|
||||
charInfo[cp + visy] = cvist;
|
||||
charInfo[cp + visw] = cvisr;
|
||||
charInfo[cp + vish] = cvisb;
|
||||
cc++;
|
||||
}
|
||||
cp += pdelta; // reset for new cluster
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
char[] chars = source.getChars();
|
||||
int start = source.getStart();
|
||||
int length = source.getLength();
|
||||
System.out.println("char info for " + length + " characters");
|
||||
for(int i = 0; i < length * numvals;) {
|
||||
System.out.println(" ch: " + Integer.toHexString(chars[start + v2l(i / numvals)]) +
|
||||
" x: " + glyphinfo[i++] +
|
||||
" y: " + glyphinfo[i++] +
|
||||
" xa: " + glyphinfo[i++] +
|
||||
" ya: " + glyphinfo[i++] +
|
||||
" l: " + glyphinfo[i++] +
|
||||
" t: " + glyphinfo[i++] +
|
||||
" w: " + glyphinfo[i++] +
|
||||
" h: " + glyphinfo[i++]);
|
||||
char[] chars = source.getChars();
|
||||
int start = source.getStart();
|
||||
int length = source.getLength();
|
||||
System.err.println("char info for " + length + " characters");
|
||||
|
||||
for (int i = 0; i < length * numvals;) {
|
||||
System.err.println(" ch: " + Integer.toHexString(chars[start + v2l(i / numvals)]) +
|
||||
" x: " + charInfo[i++] +
|
||||
" y: " + charInfo[i++] +
|
||||
" xa: " + charInfo[i++] +
|
||||
" ya: " + charInfo[i++] +
|
||||
" l: " + charInfo[i++] +
|
||||
" t: " + charInfo[i++] +
|
||||
" w: " + charInfo[i++] +
|
||||
" h: " + charInfo[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
return glyphinfo;
|
||||
return charInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -25,9 +25,11 @@
|
||||
|
||||
package sun.print;
|
||||
|
||||
import java.awt.Dialog;
|
||||
import javax.print.attribute.Attribute;
|
||||
import javax.print.attribute.PrintRequestAttribute;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Window;
|
||||
|
||||
/**
|
||||
* Class DialogOwner is a printing attribute class that identifies
|
||||
@ -42,7 +44,7 @@ import java.awt.Frame;
|
||||
public final class DialogOwner
|
||||
implements PrintRequestAttribute {
|
||||
|
||||
private Frame dlgOwner;
|
||||
private Window dlgOwner;
|
||||
|
||||
/**
|
||||
* Construct a new dialog owner attribute with the given frame.
|
||||
@ -53,11 +55,19 @@ public final class DialogOwner
|
||||
dlgOwner = frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new dialog owner attribute with the given dialog.
|
||||
*
|
||||
* @param dialog the dialog that owns the print dialog
|
||||
*/
|
||||
public DialogOwner(Dialog dialog) {
|
||||
dlgOwner = dialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string table for class DialogOwner.
|
||||
*/
|
||||
public Frame getOwner() {
|
||||
public Window getOwner() {
|
||||
return dlgOwner;
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,6 @@ import java.io.FilePermission;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
@ -39,7 +38,6 @@ import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
@ -55,7 +53,6 @@ import java.awt.Window;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
import sun.awt.image.ByteInterleavedRaster;
|
||||
|
||||
@ -74,7 +71,6 @@ import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.ResolutionSyntax;
|
||||
import javax.print.attribute.Size2DSyntax;
|
||||
import javax.print.attribute.standard.Chromaticity;
|
||||
import javax.print.attribute.standard.Copies;
|
||||
import javax.print.attribute.standard.Destination;
|
||||
import javax.print.attribute.standard.DialogTypeSelection;
|
||||
@ -96,11 +92,6 @@ import javax.print.attribute.standard.RequestingUserName;
|
||||
import javax.print.attribute.standard.SheetCollate;
|
||||
import javax.print.attribute.standard.Sides;
|
||||
|
||||
import sun.print.PageableDoc;
|
||||
import sun.print.ServiceDialog;
|
||||
import sun.print.SunPrinterJobService;
|
||||
import sun.print.SunPageSelection;
|
||||
|
||||
/**
|
||||
* A class which rasterizes a printer job.
|
||||
*
|
||||
@ -836,9 +827,16 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
Rectangle gcBounds = gc.getBounds();
|
||||
int x = gcBounds.x+50;
|
||||
int y = gcBounds.y+50;
|
||||
ServiceDialog pageDialog = new ServiceDialog(gc, x, y, service,
|
||||
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
|
||||
attributes, (Frame)null);
|
||||
ServiceDialog pageDialog;
|
||||
if (w instanceof Frame) {
|
||||
pageDialog = new ServiceDialog(gc, x, y, service,
|
||||
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
|
||||
attributes,(Frame)w);
|
||||
} else {
|
||||
pageDialog = new ServiceDialog(gc, x, y, service,
|
||||
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
|
||||
attributes, (Dialog)w);
|
||||
}
|
||||
Rectangle dlgBounds = pageDialog.getBounds();
|
||||
|
||||
// if portion of dialog is not within the gc boundary
|
||||
@ -944,6 +942,14 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
||||
if (w != null) {
|
||||
grCfg = w.getGraphicsConfiguration();
|
||||
/* Add DialogOwner attribute to set the owner of this print dialog
|
||||
* only if it is not set already
|
||||
* (it might be set in java.awt.PrintJob.printDialog)
|
||||
*/
|
||||
if (attributes.get(DialogOwner.class) == null) {
|
||||
attributes.add(w instanceof Frame ? new DialogOwner((Frame)w) :
|
||||
new DialogOwner((Dialog)w));
|
||||
}
|
||||
} else {
|
||||
grCfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
|
||||
getDefaultScreenDevice().getDefaultConfiguration();
|
||||
@ -1001,6 +1007,10 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
// temporarily add an attribute pointing back to this job.
|
||||
PrinterJobWrapper jobWrapper = new PrinterJobWrapper(this);
|
||||
attributes.add(jobWrapper);
|
||||
PageRanges pgRng = (PageRanges)attributes.get(PageRanges.class);
|
||||
if (pgRng == null && mDocument.getNumberOfPages() > 1) {
|
||||
attributes.add(new PageRanges(1, mDocument.getNumberOfPages()));
|
||||
}
|
||||
try {
|
||||
newService =
|
||||
ServiceUI.printDialog(gc, x, y,
|
||||
@ -1014,6 +1024,7 @@ public abstract class RasterPrinterJob extends PrinterJob {
|
||||
attributes);
|
||||
}
|
||||
attributes.remove(PrinterJobWrapper.class);
|
||||
attributes.remove(DialogOwner.class);
|
||||
|
||||
if (newService == null) {
|
||||
return false;
|
||||
|
||||
@ -107,13 +107,16 @@ public abstract class CachedPainter {
|
||||
ImageCache cache = getCache(key);
|
||||
Image image = cache.getImage(key, config, w, h, args);
|
||||
int attempts = 0;
|
||||
VolatileImage volatileImage = (image instanceof VolatileImage)
|
||||
? (VolatileImage) image
|
||||
: null;
|
||||
do {
|
||||
boolean draw = false;
|
||||
if (image instanceof VolatileImage) {
|
||||
if (volatileImage != null) {
|
||||
// See if we need to recreate the image
|
||||
switch (((VolatileImage)image).validate(config)) {
|
||||
switch (volatileImage.validate(config)) {
|
||||
case VolatileImage.IMAGE_INCOMPATIBLE:
|
||||
((VolatileImage)image).flush();
|
||||
volatileImage.flush();
|
||||
image = null;
|
||||
break;
|
||||
case VolatileImage.IMAGE_RESTORED:
|
||||
@ -126,11 +129,14 @@ public abstract class CachedPainter {
|
||||
image = createImage(c, w, h, config, args);
|
||||
cache.setImage(key, config, w, h, args, image);
|
||||
draw = true;
|
||||
volatileImage = (image instanceof VolatileImage)
|
||||
? (VolatileImage) image
|
||||
: null;
|
||||
}
|
||||
if (draw) {
|
||||
// Render to the Image
|
||||
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||
if (w != baseWidth || h != baseHeight) {
|
||||
if (volatileImage == null && (w != baseWidth || h != baseHeight)) {
|
||||
g2.scale((double) w / baseWidth, (double) h / baseHeight);
|
||||
}
|
||||
paintToImage(c, image, g2, baseWidth, baseHeight, args);
|
||||
@ -140,8 +146,8 @@ public abstract class CachedPainter {
|
||||
// If we did this 3 times and the contents are still lost
|
||||
// assume we're painting to a VolatileImage that is bogus and
|
||||
// give up. Presumably we'll be called again to paint.
|
||||
} while ((image instanceof VolatileImage) &&
|
||||
((VolatileImage)image).contentsLost() && ++attempts < 3);
|
||||
} while ((volatileImage != null) &&
|
||||
volatileImage.contentsLost() && ++attempts < 3);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ static jfieldID gvdFlagsFID = 0;
|
||||
static jfieldID gvdGlyphsFID = 0;
|
||||
static jfieldID gvdPositionsFID = 0;
|
||||
static jfieldID gvdIndicesFID = 0;
|
||||
static jmethodID gvdGrowMID = 0;
|
||||
static int jniInited = 0;
|
||||
|
||||
static void getFloat(JNIEnv* env, jobject pt, jfloat *x, jfloat *y) {
|
||||
@ -63,73 +64,88 @@ static int init_JNI_IDs(JNIEnv *env) {
|
||||
CHECK_NULL_RETURN(gvdGlyphsFID = (*env)->GetFieldID(env, gvdClass, "_glyphs", "[I"), 0);
|
||||
CHECK_NULL_RETURN(gvdPositionsFID = (*env)->GetFieldID(env, gvdClass, "_positions", "[F"), 0);
|
||||
CHECK_NULL_RETURN(gvdIndicesFID = (*env)->GetFieldID(env, gvdClass, "_indices", "[I"), 0);
|
||||
CHECK_NULL_RETURN(gvdGrowMID = (*env)->GetMethodID(env, gvdClass, "grow", "()V"), 0);
|
||||
jniInited = 1;
|
||||
return jniInited;
|
||||
}
|
||||
|
||||
// gmask is the composite font slot mask
|
||||
// baseindex is to be added to the character (code point) index.
|
||||
int storeGVData(JNIEnv* env,
|
||||
jobject gvdata, jint slot, jint baseIndex, jobject startPt,
|
||||
int glyphCount, hb_glyph_info_t *glyphInfo,
|
||||
hb_glyph_position_t *glyphPos, hb_direction_t direction,
|
||||
float devScale) {
|
||||
jboolean storeGVData(JNIEnv* env,
|
||||
jobject gvdata, jint slot,
|
||||
jint baseIndex, int offset, jobject startPt,
|
||||
int charCount, int glyphCount, hb_glyph_info_t *glyphInfo,
|
||||
hb_glyph_position_t *glyphPos, float devScale) {
|
||||
|
||||
int i;
|
||||
int i, needToGrow;
|
||||
float x=0, y=0;
|
||||
float startX, startY;
|
||||
float scale = 1.0f/64.0f/devScale;
|
||||
float startX, startY, advX, advY;
|
||||
float scale = 1.0f / HBFloatToFixedScale / devScale;
|
||||
unsigned int* glyphs;
|
||||
float* positions;
|
||||
int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv;
|
||||
int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv, maxStore;
|
||||
unsigned int* indices;
|
||||
jarray glyphArray, posArray, inxArray;
|
||||
|
||||
if (!init_JNI_IDs(env)) {
|
||||
return 0;
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
|
||||
glyphArray =
|
||||
(jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
|
||||
posArray =
|
||||
(jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
|
||||
|
||||
if (glyphArray == NULL || posArray == NULL)
|
||||
{
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The Java code catches the IIOBE and expands the storage
|
||||
// and re-invokes layout. I suppose this is expected to be rare
|
||||
// because at least in a single threaded case there should be
|
||||
// re-use of the same container, but it is a little wasteful/distateful.
|
||||
glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
|
||||
posArrayLen = (*env)->GetArrayLength(env, posArray);
|
||||
maxGlyphs = glyphCount + initialCount;
|
||||
if ((maxGlyphs > glyphArrayLen) ||
|
||||
(maxGlyphs * 2 + 2 > posArrayLen))
|
||||
{
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "");
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
glyphArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
|
||||
posArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
|
||||
inxArray = (jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
|
||||
if (glyphArray == NULL || posArray == NULL || inxArray == NULL) {
|
||||
JNU_ThrowArrayIndexOutOfBoundsException(env, "");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
|
||||
posArrayLen = (*env)->GetArrayLength(env, posArray);
|
||||
maxGlyphs = (charCount > glyphCount) ? charCount : glyphCount;
|
||||
maxStore = maxGlyphs + initialCount;
|
||||
needToGrow = (maxStore > glyphArrayLen) ||
|
||||
(maxStore * 2 + 2 > posArrayLen);
|
||||
if (needToGrow) {
|
||||
(*env)->CallVoidMethod(env, gvdata, gvdGrowMID);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
}
|
||||
} while (needToGrow);
|
||||
|
||||
getFloat(env, startPt, &startX, &startY);
|
||||
|
||||
glyphs =
|
||||
(unsigned int*)(*env)->GetPrimitiveArrayCritical(env, glyphArray, NULL);
|
||||
if (glyphs == NULL) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
positions = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
|
||||
if (positions == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
indices =
|
||||
(unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
|
||||
if (indices == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < glyphCount; i++) {
|
||||
int storei = i + initialCount;
|
||||
int index = glyphInfo[i].codepoint | slot;
|
||||
if (i<glyphCount)glyphs[storei] = (unsigned int)index;
|
||||
positions[(storei*2)] = startX + x + glyphPos[i].x_offset * scale;
|
||||
positions[(storei*2)+1] = startY + y - glyphPos[i].y_offset * scale;
|
||||
int cluster = glyphInfo[i].cluster - offset;
|
||||
indices[storei] = baseIndex + cluster;
|
||||
glyphs[storei] = (unsigned int)(glyphInfo[i].codepoint | slot);
|
||||
positions[storei*2] = startX + x + glyphPos[i].x_offset * scale;
|
||||
positions[(storei*2)+1] = startY + y + glyphPos[i].y_offset * scale;
|
||||
x += glyphPos[i].x_advance * scale;
|
||||
y += glyphPos[i].y_advance * scale;
|
||||
storei++;
|
||||
}
|
||||
storeadv = initialCount+glyphCount;
|
||||
storeadv = initialCount + glyphCount;
|
||||
// The final slot in the positions array is important
|
||||
// because when the GlyphVector is created from this
|
||||
// data it determines the overall advance of the glyphvector
|
||||
@ -137,30 +153,17 @@ int storeGVData(JNIEnv* env,
|
||||
// during rendering where text is broken into runs.
|
||||
// We also need to report it back into "pt", so layout can
|
||||
// pass it back down for that next run in this code.
|
||||
positions[(storeadv*2)] = startX + x;
|
||||
positions[(storeadv*2)+1] = startY + y;
|
||||
advX = startX + x;
|
||||
advY = startY + y;
|
||||
positions[(storeadv*2)] = advX;
|
||||
positions[(storeadv*2)+1] = advY;
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
|
||||
putFloat(env, startPt,positions[(storeadv*2)],positions[(storeadv*2)+1] );
|
||||
inxArray =
|
||||
(jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
|
||||
indices =
|
||||
(unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
|
||||
for (i = 0; i < glyphCount; i++) {
|
||||
int cluster = glyphInfo[i].cluster;
|
||||
if (direction == HB_DIRECTION_LTR) {
|
||||
// I need to understand what hb does when processing a substring
|
||||
// I expected the cluster index to be from the start of the text
|
||||
// to process.
|
||||
// Instead it appears to be from the start of the whole thing.
|
||||
indices[i+initialCount] = cluster;
|
||||
} else {
|
||||
indices[i+initialCount] = baseIndex + glyphCount -1 -i;
|
||||
}
|
||||
}
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, inxArray, indices, 0);
|
||||
(*env)->SetIntField(env, gvdata, gvdCountFID, initialCount+glyphCount);
|
||||
return initialCount+glyphCount;
|
||||
putFloat(env, startPt, advX, advY);
|
||||
(*env)->SetIntField(env, gvdata, gvdCountFID, storeadv);
|
||||
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
static float euclidianDistance(float a, float b)
|
||||
@ -226,7 +229,9 @@ JDKFontInfo*
|
||||
}
|
||||
|
||||
|
||||
#define TYPO_RTL 0x80000000
|
||||
#define TYPO_KERN 0x00000001
|
||||
#define TYPO_LIGA 0x00000002
|
||||
#define TYPO_RTL 0x80000000
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
|
||||
(JNIEnv *env, jclass cls,
|
||||
@ -255,10 +260,11 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
|
||||
hb_glyph_info_t *glyphInfo;
|
||||
hb_glyph_position_t *glyphPos;
|
||||
hb_direction_t direction = HB_DIRECTION_LTR;
|
||||
hb_feature_t *features = NULL;
|
||||
hb_feature_t *features = NULL;
|
||||
int featureCount = 0;
|
||||
|
||||
int i;
|
||||
char* kern = (flags & TYPO_KERN) ? "kern" : "-kern";
|
||||
char* liga = (flags & TYPO_LIGA) ? "liga" : "-liga";
|
||||
jboolean ret;
|
||||
unsigned int buflen;
|
||||
|
||||
JDKFontInfo *jdkFontInfo =
|
||||
@ -281,6 +287,8 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
|
||||
direction = HB_DIRECTION_RTL;
|
||||
}
|
||||
hb_buffer_set_direction(buffer, direction);
|
||||
hb_buffer_set_cluster_level(buffer,
|
||||
HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
|
||||
|
||||
chars = (*env)->GetCharArrayElements(env, text, NULL);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
@ -293,36 +301,26 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
|
||||
|
||||
hb_buffer_add_utf16(buffer, chars, len, offset, limit-offset);
|
||||
|
||||
features = calloc(2, sizeof(hb_feature_t));
|
||||
if (features) {
|
||||
hb_feature_from_string(kern, -1, &features[featureCount++]);
|
||||
hb_feature_from_string(liga, -1, &features[featureCount++]);
|
||||
}
|
||||
|
||||
hb_shape_full(hbfont, buffer, features, featureCount, 0);
|
||||
glyphCount = hb_buffer_get_length(buffer);
|
||||
glyphInfo = hb_buffer_get_glyph_infos(buffer, 0);
|
||||
glyphPos = hb_buffer_get_glyph_positions(buffer, &buflen);
|
||||
for (i = 0; i < glyphCount; i++) {
|
||||
int index = glyphInfo[i].codepoint;
|
||||
int xadv = (glyphPos[i].x_advance);
|
||||
int yadv = (glyphPos[i].y_advance);
|
||||
}
|
||||
// On "input" HB assigns a cluster index to each character in UTF-16.
|
||||
// On output where a sequence of characters have been mapped to
|
||||
// a glyph they are all mapped to the cluster index of the first character.
|
||||
// The next cluster index will be that of the first character in the
|
||||
// next cluster. So cluster indexes may 'skip' on output.
|
||||
// This can also happen if there are supplementary code-points
|
||||
// such that two UTF-16 characters are needed to make one codepoint.
|
||||
// In RTL text you need to count down.
|
||||
// So the following code tries to build the reverse map as expected
|
||||
// by calling code.
|
||||
|
||||
storeGVData(env, gvdata, slot, baseIndex, startPt,
|
||||
glyphCount, glyphInfo, glyphPos, direction,
|
||||
jdkFontInfo->devScale);
|
||||
ret = storeGVData(env, gvdata, slot, baseIndex, offset, startPt,
|
||||
limit - offset, glyphCount, glyphInfo, glyphPos,
|
||||
jdkFontInfo->devScale);
|
||||
|
||||
hb_buffer_destroy (buffer);
|
||||
hb_font_destroy(hbfont);
|
||||
free((void*)jdkFontInfo);
|
||||
if (features != NULL) free(features);
|
||||
(*env)->ReleaseCharArrayElements(env, text, chars, JNI_ABORT);
|
||||
|
||||
return JNI_TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -55,10 +55,6 @@ hb_jdk_get_glyph (hb_font_t *font HB_UNUSED,
|
||||
return (*glyph != 0);
|
||||
}
|
||||
|
||||
// This is also define in freetypescaler.c and similar macros are
|
||||
// in fontscalerdefs.h. Consider tidying this up.
|
||||
#define FloatToF26Dot6(x) ((unsigned int) ((x)*64))
|
||||
|
||||
static hb_position_t
|
||||
hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
@ -84,7 +80,7 @@ hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
||||
fadv *= jdkFontInfo->devScale;
|
||||
env->DeleteLocalRef(pt);
|
||||
|
||||
return FloatToF26Dot6(fadv); // should this round ?
|
||||
return HBFloatToFixed(fadv);
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
@ -111,7 +107,7 @@ hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
||||
fadv = env->GetFloatField(pt, sunFontIDs.yFID);
|
||||
env->DeleteLocalRef(pt);
|
||||
|
||||
return FloatToF26Dot6(fadv); // should this round ?
|
||||
return HBFloatToFixed(fadv);
|
||||
|
||||
}
|
||||
|
||||
@ -205,8 +201,8 @@ hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
|
||||
*x = 0; *y = 0;
|
||||
return true;
|
||||
}
|
||||
*x = FloatToF26Dot6(env->GetFloatField(pt, sunFontIDs.xFID));
|
||||
*y = FloatToF26Dot6(env->GetFloatField(pt, sunFontIDs.yFID));
|
||||
*x = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.xFID));
|
||||
*y = HBFloatToFixed(env->GetFloatField(pt, sunFontIDs.yFID));
|
||||
env->DeleteLocalRef(pt);
|
||||
|
||||
return true;
|
||||
@ -325,8 +321,8 @@ static hb_font_t* _hb_jdk_font_create(JDKFontInfo *jdkFontInfo,
|
||||
_hb_jdk_get_font_funcs (),
|
||||
jdkFontInfo, (hb_destroy_func_t) _do_nothing);
|
||||
hb_font_set_scale (font,
|
||||
FloatToF26Dot6(jdkFontInfo->ptSize*jdkFontInfo->devScale),
|
||||
FloatToF26Dot6(jdkFontInfo->ptSize*jdkFontInfo->devScale));
|
||||
HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale),
|
||||
HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale));
|
||||
return font;
|
||||
}
|
||||
|
||||
@ -343,8 +339,8 @@ static hb_font_t* _hb_jdk_ct_font_create(JDKFontInfo *jdkFontInfo) {
|
||||
hb_face_destroy(face);
|
||||
|
||||
hb_font_set_scale(font,
|
||||
FloatToF26Dot6(jdkFontInfo->ptSize),
|
||||
FloatToF26Dot6(jdkFontInfo->ptSize));
|
||||
HBFloatToFixed(jdkFontInfo->ptSize),
|
||||
HBFloatToFixed(jdkFontInfo->ptSize));
|
||||
return font;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -48,6 +48,10 @@ typedef struct JDKFontInfo_Struct {
|
||||
} JDKFontInfo;
|
||||
|
||||
|
||||
// Use 16.16 for better precision than 26.6
|
||||
#define HBFloatToFixedScale ((float)(1 << 16))
|
||||
#define HBFloatToFixed(f) ((unsigned int)((f) * HBFloatToFixedScale))
|
||||
|
||||
/*
|
||||
* Note:
|
||||
*
|
||||
|
||||
@ -2161,6 +2161,25 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage
|
||||
return data->abortFlag;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_clearNativeReadAbortFlag
|
||||
(JNIEnv *env,
|
||||
jobject this,
|
||||
jlong ptr) {
|
||||
|
||||
imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
|
||||
|
||||
if (data == NULL) {
|
||||
JNU_ThrowByName(env,
|
||||
"java/lang/IllegalStateException",
|
||||
"Attempting to use reader after dispose()");
|
||||
return;
|
||||
}
|
||||
|
||||
data->abortFlag = JNI_FALSE;
|
||||
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abortRead
|
||||
(JNIEnv *env,
|
||||
|
||||
@ -1570,6 +1570,10 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
|
||||
Integer.valueOf(getMultiClickTime()));
|
||||
desktopProperties.put("awt.mouse.numButtons",
|
||||
Integer.valueOf(getNumberOfButtons()));
|
||||
if(SunGraphicsEnvironment.isUIScaleEnabled()) {
|
||||
addPropertyChangeListener("gnome.Xft/DPI", evt ->
|
||||
localEnv.displayChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
private SunDisplayChanger topLevels = new SunDisplayChanger();
|
||||
private DisplayMode origDisplayMode;
|
||||
private boolean shutdownHookRegistered;
|
||||
private final int scale;
|
||||
private int scale;
|
||||
|
||||
public X11GraphicsDevice(int screennum) {
|
||||
this.screen = screennum;
|
||||
@ -488,6 +488,7 @@ public final class X11GraphicsDevice extends GraphicsDevice
|
||||
* X11GraphicsEnvironment when the display mode has been changed.
|
||||
*/
|
||||
public synchronized void displayChanged() {
|
||||
scale = initScaleFactor();
|
||||
// On X11 the visuals do not change, and therefore we don't need
|
||||
// to reset the defaultConfig, config, doubleBufferVisuals,
|
||||
// neither do we need to reset the native data.
|
||||
|
||||
@ -148,7 +148,7 @@ static double getDesktopScale(char *output_name) {
|
||||
void *scale = fp_g_variant_get_child_value(entry, 1);
|
||||
if (screen && scale) {
|
||||
char *name = fp_g_variant_get_string(screen, NULL);
|
||||
if (name && strcmp(name, output_name)) {
|
||||
if (name && !strcmp(name, output_name)) {
|
||||
result = fp_g_variant_get_int32(scale) / 8.;
|
||||
}
|
||||
fp_g_variant_unref(screen);
|
||||
|
||||
@ -2181,7 +2181,8 @@ static char *get_output_screen_name(JNIEnv *env, int screen) {
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
|
||||
(JNIEnv *env, jobject this, jint screen) {
|
||||
char *name = get_output_screen_name(env, screen);
|
||||
// in case of Xinerama individual screen scales are not supported
|
||||
char *name = get_output_screen_name(env, usingXinerama ? 0 : screen);
|
||||
double scale = getNativeScaleFactor(name);
|
||||
if (name) {
|
||||
free(name);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2016, 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
|
||||
@ -303,10 +303,10 @@ abstract class TranslucentWindowPainter {
|
||||
if (bb instanceof DestSurfaceProvider) {
|
||||
Surface s = ((DestSurfaceProvider)bb).getDestSurface();
|
||||
if (s instanceof AccelSurface) {
|
||||
final int w = bb.getWidth(null);
|
||||
final int h = bb.getHeight(null);
|
||||
final boolean arr[] = { false };
|
||||
final AccelSurface as = (AccelSurface)s;
|
||||
final int w = as.getBounds().width;
|
||||
final int h = as.getBounds().height;
|
||||
RenderQueue rq = as.getContext().getRenderQueue();
|
||||
rq.lock();
|
||||
try {
|
||||
|
||||
@ -478,9 +478,12 @@ public final class WPrinterJob extends RasterPrinterJob
|
||||
}
|
||||
|
||||
DialogOwner dlgOwner = (DialogOwner)attributes.get(DialogOwner.class);
|
||||
Frame ownerFrame = (dlgOwner != null) ? dlgOwner.getOwner() : null;
|
||||
Window owner = (dlgOwner != null) ? dlgOwner.getOwner() : null;
|
||||
|
||||
WPrintDialog dialog = (owner instanceof Frame) ?
|
||||
new WPrintDialog((Frame)owner, this) :
|
||||
new WPrintDialog((Dialog)owner, this);
|
||||
|
||||
WPrintDialog dialog = new WPrintDialog(ownerFrame, this);
|
||||
dialog.setRetVal(false);
|
||||
dialog.setVisible(true);
|
||||
boolean prv = dialog.getRetVal();
|
||||
@ -498,8 +501,9 @@ public final class WPrinterJob extends RasterPrinterJob
|
||||
title = rb.getString("dialog.printtofile");
|
||||
} catch (MissingResourceException e) {
|
||||
}
|
||||
FileDialog fileDialog = new FileDialog(ownerFrame, title,
|
||||
FileDialog.SAVE);
|
||||
FileDialog fileDialog = (owner instanceof Frame) ?
|
||||
new FileDialog((Frame)owner, title, FileDialog.SAVE) :
|
||||
new FileDialog((Dialog)owner, title, FileDialog.SAVE);
|
||||
|
||||
URI destURI = dest.getURI();
|
||||
// Old code destURI.getPath() would return null for "file:out.prn"
|
||||
@ -531,10 +535,17 @@ public final class WPrinterJob extends RasterPrinterJob
|
||||
((pFile != null) &&
|
||||
(!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) {
|
||||
|
||||
(new PrintToFileErrorDialog(ownerFrame,
|
||||
if (owner instanceof Frame) {
|
||||
(new PrintToFileErrorDialog((Frame)owner,
|
||||
ServiceDialog.getMsg("dialog.owtitle"),
|
||||
ServiceDialog.getMsg("dialog.writeerror")+" "+fullName,
|
||||
ServiceDialog.getMsg("button.ok"))).setVisible(true);
|
||||
} else {
|
||||
(new PrintToFileErrorDialog((Dialog)owner,
|
||||
ServiceDialog.getMsg("dialog.owtitle"),
|
||||
ServiceDialog.getMsg("dialog.writeerror")+" "+fullName,
|
||||
ServiceDialog.getMsg("button.ok"))).setVisible(true);
|
||||
}
|
||||
|
||||
fileDialog.setVisible(true);
|
||||
fileName = fileDialog.getFile();
|
||||
|
||||
@ -753,10 +753,15 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition
|
||||
}
|
||||
|
||||
void rescale(SIZE *size) {
|
||||
HWND hWnd = ::GetDesktopWindow();
|
||||
HDC hDC = ::GetDC(hWnd);
|
||||
int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||
int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
static int dpiX = -1;
|
||||
static int dpiY = -1;
|
||||
if (dpiX == -1 || dpiY == -1) {
|
||||
HWND hWnd = ::GetDesktopWindow();
|
||||
HDC hDC = ::GetDC(hWnd);
|
||||
dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||
dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
::ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
|
||||
if (dpiX !=0 && dpiX != 96) {
|
||||
float invScaleX = 96.0f / dpiX;
|
||||
@ -766,7 +771,6 @@ void rescale(SIZE *size) {
|
||||
float invScaleY = 96.0f / dpiY;
|
||||
size->cy = ROUND_TO_INT(size->cy * invScaleY);
|
||||
}
|
||||
::ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -88,11 +88,16 @@ void AwtDesktopProperties::GetWindowsParameters() {
|
||||
}
|
||||
|
||||
void getInvScale(float &invScaleX, float &invScaleY) {
|
||||
HWND hWnd = ::GetDesktopWindow();
|
||||
HDC hDC = ::GetDC(hWnd);
|
||||
int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||
int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
::ReleaseDC(hWnd, hDC);
|
||||
static int dpiX = -1;
|
||||
static int dpiY = -1;
|
||||
if (dpiX == -1 || dpiY == -1) {
|
||||
HWND hWnd = ::GetDesktopWindow();
|
||||
HDC hDC = ::GetDC(hWnd);
|
||||
dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||
dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
::ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
|
||||
invScaleX = (dpiX == 0.0f) ? 1.0f : 96.0f / dpiX;
|
||||
invScaleY = (dpiY == 0.0f) ? 1.0f : 96.0f / dpiY;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setProgressState
|
||||
JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_flashWindow
|
||||
(JNIEnv *, jobject, jlong window)
|
||||
{
|
||||
AwtWindow::FlashWindowEx((HWND) window, 3, 0, FLASHW_TIMERNOFG);
|
||||
::FlashWindow((HWND) window, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -24,13 +24,22 @@
|
||||
*/
|
||||
|
||||
package java.util.logging;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Module;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.function.Function;
|
||||
import jdk.internal.loader.ClassLoaderValue;
|
||||
|
||||
/**
|
||||
* The Level class defines a set of standard logging levels that
|
||||
@ -177,6 +186,10 @@ public class Level implements java.io.Serializable {
|
||||
*/
|
||||
public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
|
||||
|
||||
private static final Level[] standardLevels = {
|
||||
OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a named Level with a given integer value.
|
||||
* <p>
|
||||
@ -267,7 +280,8 @@ public class Level implements java.io.Serializable {
|
||||
// or its defining class loader, if it's unnamed module,
|
||||
// of this Level instance that can be a custom Level subclass;
|
||||
Module module = this.getClass().getModule();
|
||||
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale, module);
|
||||
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName,
|
||||
newLocale, module);
|
||||
|
||||
final String localizedName = rb.getString(name);
|
||||
final boolean isDefaultBundle = defaultBundle.equals(resourceBundleName);
|
||||
@ -350,12 +364,12 @@ public class Level implements java.io.Serializable {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
KnownLevel level;
|
||||
Optional<Level> level;
|
||||
|
||||
// Look for a known Level with the given non-localized name.
|
||||
level = KnownLevel.findByName(name);
|
||||
if (level != null) {
|
||||
return level.mirroredLevel;
|
||||
level = KnownLevel.findByName(name, KnownLevel::mirrored);
|
||||
if (level.isPresent()) {
|
||||
return level.get();
|
||||
}
|
||||
|
||||
// Now, check if the given name is an integer. If so,
|
||||
@ -363,21 +377,24 @@ public class Level implements java.io.Serializable {
|
||||
// if necessary create one.
|
||||
try {
|
||||
int x = Integer.parseInt(name);
|
||||
level = KnownLevel.findByValue(x);
|
||||
if (level == null) {
|
||||
level = KnownLevel.findByValue(x, KnownLevel::mirrored);
|
||||
if (!level.isPresent()) {
|
||||
// add new Level
|
||||
Level levelObject = new Level(name, x);
|
||||
level = KnownLevel.findByValue(x);
|
||||
// There's no need to use a reachability fence here because
|
||||
// KnownLevel keeps a strong reference on the level when
|
||||
// level.getClass() == Level.class.
|
||||
return KnownLevel.findByValue(x, KnownLevel::mirrored).get();
|
||||
}
|
||||
return level.mirroredLevel;
|
||||
} catch (NumberFormatException ex) {
|
||||
// Not an integer.
|
||||
// Drop through.
|
||||
}
|
||||
|
||||
level = KnownLevel.findByLocalizedLevelName(name);
|
||||
if (level != null) {
|
||||
return level.mirroredLevel;
|
||||
level = KnownLevel.findByLocalizedLevelName(name,
|
||||
KnownLevel::mirrored);
|
||||
if (level.isPresent()) {
|
||||
return level.get();
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -408,15 +425,13 @@ public class Level implements java.io.Serializable {
|
||||
// Serialization magic to prevent "doppelgangers".
|
||||
// This is a performance optimization.
|
||||
private Object readResolve() {
|
||||
KnownLevel o = KnownLevel.matches(this);
|
||||
if (o != null) {
|
||||
return o.levelObject;
|
||||
Optional<Level> level = KnownLevel.matches(this);
|
||||
if (level.isPresent()) {
|
||||
return level.get();
|
||||
}
|
||||
|
||||
// Woops. Whoever sent us this object knows
|
||||
// about a new log level. Add it to our list.
|
||||
Level level = new Level(this.name, this.value, this.resourceBundleName);
|
||||
return level;
|
||||
return new Level(this.name, this.value, this.resourceBundleName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -450,12 +465,12 @@ public class Level implements java.io.Serializable {
|
||||
// Check that name is not null.
|
||||
name.length();
|
||||
|
||||
KnownLevel level;
|
||||
Optional<Level> level;
|
||||
|
||||
// Look for a known Level with the given non-localized name.
|
||||
level = KnownLevel.findByName(name);
|
||||
if (level != null) {
|
||||
return level.levelObject;
|
||||
level = KnownLevel.findByName(name, KnownLevel::referent);
|
||||
if (level.isPresent()) {
|
||||
return level.get();
|
||||
}
|
||||
|
||||
// Now, check if the given name is an integer. If so,
|
||||
@ -463,13 +478,16 @@ public class Level implements java.io.Serializable {
|
||||
// if necessary create one.
|
||||
try {
|
||||
int x = Integer.parseInt(name);
|
||||
level = KnownLevel.findByValue(x);
|
||||
if (level == null) {
|
||||
// add new Level
|
||||
Level levelObject = new Level(name, x);
|
||||
level = KnownLevel.findByValue(x);
|
||||
level = KnownLevel.findByValue(x, KnownLevel::referent);
|
||||
if (level.isPresent()) {
|
||||
return level.get();
|
||||
}
|
||||
return level.levelObject;
|
||||
// add new Level.
|
||||
Level levelObject = new Level(name, x);
|
||||
// There's no need to use a reachability fence here because
|
||||
// KnownLevel keeps a strong reference on the level when
|
||||
// level.getClass() == Level.class.
|
||||
return KnownLevel.findByValue(x, KnownLevel::referent).get();
|
||||
} catch (NumberFormatException ex) {
|
||||
// Not an integer.
|
||||
// Drop through.
|
||||
@ -478,9 +496,9 @@ public class Level implements java.io.Serializable {
|
||||
// Finally, look for a known level with the given localized name,
|
||||
// in the current default locale.
|
||||
// This is relatively expensive, but not excessively so.
|
||||
level = KnownLevel.findByLocalizedLevelName(name);
|
||||
if (level != null) {
|
||||
return level.levelObject;
|
||||
level = KnownLevel.findByLocalizedLevelName(name, KnownLevel::referent);
|
||||
if (level .isPresent()) {
|
||||
return level.get();
|
||||
}
|
||||
|
||||
// OK, we've tried everything and failed
|
||||
@ -530,22 +548,67 @@ public class Level implements java.io.Serializable {
|
||||
// If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
|
||||
// were final, the following KnownLevel implementation can be removed.
|
||||
// Future API change should take this into consideration.
|
||||
static final class KnownLevel {
|
||||
static final class KnownLevel extends WeakReference<Level> {
|
||||
private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
|
||||
private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
|
||||
final Level levelObject; // instance of Level class or Level subclass
|
||||
private static final ReferenceQueue<Level> QUEUE = new ReferenceQueue<>();
|
||||
|
||||
// CUSTOM_LEVEL_CLV is used to register custom level instances with
|
||||
// their defining class loader, so that they are garbage collected
|
||||
// if and only if their class loader is no longer strongly
|
||||
// referenced.
|
||||
private static final ClassLoaderValue<List<Level>> CUSTOM_LEVEL_CLV =
|
||||
new ClassLoaderValue<>();
|
||||
|
||||
final Level mirroredLevel; // mirror of the custom Level
|
||||
KnownLevel(Level l) {
|
||||
this.levelObject = l;
|
||||
super(l, QUEUE);
|
||||
if (l.getClass() == Level.class) {
|
||||
this.mirroredLevel = l;
|
||||
} else {
|
||||
// this mirrored level object is hidden
|
||||
this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName, false);
|
||||
this.mirroredLevel = new Level(l.name, l.value,
|
||||
l.resourceBundleName, false);
|
||||
}
|
||||
}
|
||||
|
||||
Optional<Level> mirrored() {
|
||||
return Optional.of(mirroredLevel);
|
||||
}
|
||||
|
||||
Optional<Level> referent() {
|
||||
return Optional.ofNullable(get());
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
Optional.ofNullable(nameToLevels.get(mirroredLevel.name))
|
||||
.ifPresent((x) -> x.remove(this));
|
||||
Optional.ofNullable(intToLevels.get(mirroredLevel.value))
|
||||
.ifPresent((x) -> x.remove(this));
|
||||
}
|
||||
|
||||
// Remove all stale KnownLevel instances
|
||||
static synchronized void purge() {
|
||||
Reference<? extends Level> ref;
|
||||
while ((ref = QUEUE.poll()) != null) {
|
||||
if (ref instanceof KnownLevel) {
|
||||
((KnownLevel)ref).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void registerWithClassLoader(Level customLevel) {
|
||||
PrivilegedAction<ClassLoader> pa =
|
||||
() -> customLevel.getClass().getClassLoader();
|
||||
PrivilegedAction<String> pn = customLevel.getClass()::getName;
|
||||
final String name = AccessController.doPrivileged(pn);
|
||||
final ClassLoader cl = AccessController.doPrivileged(pa);
|
||||
CUSTOM_LEVEL_CLV.computeIfAbsent(cl, (c, v) -> new ArrayList<>())
|
||||
.add(customLevel);
|
||||
}
|
||||
|
||||
static synchronized void add(Level l) {
|
||||
purge();
|
||||
// the mirroredLevel object is always added to the list
|
||||
// before the custom Level instance
|
||||
KnownLevel o = new KnownLevel(l);
|
||||
@ -562,24 +625,36 @@ public class Level implements java.io.Serializable {
|
||||
intToLevels.put(l.value, list);
|
||||
}
|
||||
list.add(o);
|
||||
|
||||
// keep the custom level reachable from its class loader
|
||||
// This will ensure that custom level values are not GC'ed
|
||||
// until there class loader is GC'ed.
|
||||
if (o.mirroredLevel != l) {
|
||||
registerWithClassLoader(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Returns a KnownLevel with the given non-localized name.
|
||||
static synchronized KnownLevel findByName(String name) {
|
||||
List<KnownLevel> list = nameToLevels.get(name);
|
||||
if (list != null) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
static synchronized Optional<Level> findByName(String name,
|
||||
Function<KnownLevel, Optional<Level>> selector) {
|
||||
purge();
|
||||
return nameToLevels.getOrDefault(name, Collections.emptyList())
|
||||
.stream()
|
||||
.map(selector)
|
||||
.flatMap(Optional::stream)
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
// Returns a KnownLevel with the given value.
|
||||
static synchronized KnownLevel findByValue(int value) {
|
||||
List<KnownLevel> list = intToLevels.get(value);
|
||||
if (list != null) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
static synchronized Optional<Level> findByValue(int value,
|
||||
Function<KnownLevel, Optional<Level>> selector) {
|
||||
purge();
|
||||
return intToLevels.getOrDefault(value, Collections.emptyList())
|
||||
.stream()
|
||||
.map(selector)
|
||||
.flatMap(Optional::stream)
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
// Returns a KnownLevel with the given localized name matching
|
||||
@ -587,32 +662,34 @@ public class Level implements java.io.Serializable {
|
||||
// from the resourceBundle associated with the Level object).
|
||||
// This method does not call Level.getLocalizedName() that may
|
||||
// be overridden in a subclass implementation
|
||||
static synchronized KnownLevel findByLocalizedLevelName(String name) {
|
||||
for (List<KnownLevel> levels : nameToLevels.values()) {
|
||||
for (KnownLevel l : levels) {
|
||||
String lname = l.levelObject.getLocalizedLevelName();
|
||||
if (name.equals(lname)) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
static synchronized Optional<Level> findByLocalizedLevelName(String name,
|
||||
Function<KnownLevel, Optional<Level>> selector) {
|
||||
purge();
|
||||
return nameToLevels.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.map(selector)
|
||||
.flatMap(Optional::stream)
|
||||
.filter(l -> name.equals(l.getLocalizedLevelName()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
static synchronized KnownLevel matches(Level l) {
|
||||
static synchronized Optional<Level> matches(Level l) {
|
||||
purge();
|
||||
List<KnownLevel> list = nameToLevels.get(l.name);
|
||||
if (list != null) {
|
||||
for (KnownLevel level : list) {
|
||||
Level other = level.mirroredLevel;
|
||||
for (KnownLevel ref : list) {
|
||||
Level levelObject = ref.get();
|
||||
if (levelObject == null) continue;
|
||||
Level other = ref.mirroredLevel;
|
||||
if (l.value == other.value &&
|
||||
(l.resourceBundleName == other.resourceBundleName ||
|
||||
(l.resourceBundleName != null &&
|
||||
l.resourceBundleName.equals(other.resourceBundleName)))) {
|
||||
return level;
|
||||
return Optional.of(levelObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2016, 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
|
||||
@ -1707,25 +1707,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public ObjectInputStream deserialize(ObjectName name, byte[] data) throws InstanceNotFoundException,
|
||||
OperationsException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public ObjectInputStream deserialize(String className, byte[] data) throws OperationsException,
|
||||
ReflectionException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public ObjectInputStream deserialize(String className, ObjectName loaderName,
|
||||
byte[] data) throws InstanceNotFoundException, OperationsException,
|
||||
ReflectionException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public ClassLoaderRepository getClassLoaderRepository() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2016, 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
|
||||
@ -94,32 +94,6 @@ public interface MBeanServerInterceptor extends MBeanServer {
|
||||
throws ReflectionException, MBeanException,
|
||||
InstanceNotFoundException;
|
||||
|
||||
/**
|
||||
* This method should never be called.
|
||||
* Usually throws UnsupportedOperationException.
|
||||
*/
|
||||
@Deprecated
|
||||
public ObjectInputStream deserialize(ObjectName name, byte[] data)
|
||||
throws InstanceNotFoundException, OperationsException;
|
||||
|
||||
/**
|
||||
* This method should never be called.
|
||||
* Usually throws UnsupportedOperationException.
|
||||
*/
|
||||
@Deprecated
|
||||
public ObjectInputStream deserialize(String className, byte[] data)
|
||||
throws OperationsException, ReflectionException;
|
||||
|
||||
/**
|
||||
* This method should never be called.
|
||||
* Usually hrows UnsupportedOperationException.
|
||||
*/
|
||||
@Deprecated
|
||||
public ObjectInputStream deserialize(String className,
|
||||
ObjectName loaderName, byte[] data)
|
||||
throws InstanceNotFoundException, OperationsException,
|
||||
ReflectionException;
|
||||
|
||||
/**
|
||||
* This method should never be called.
|
||||
* Usually throws UnsupportedOperationException.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2016, 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
|
||||
@ -655,6 +655,8 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
* used for the de-serialization.
|
||||
* @param data The byte array to be de-sererialized.
|
||||
*
|
||||
* @implSpec This method throws {@link UnsupportedOperationException} by default.
|
||||
*
|
||||
* @return The de-serialized object stream.
|
||||
*
|
||||
* @exception InstanceNotFoundException The MBean specified is not
|
||||
@ -665,10 +667,11 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
* @deprecated Use {@link #getClassLoaderFor getClassLoaderFor} to
|
||||
* obtain the appropriate class loader for deserialization.
|
||||
*/
|
||||
@Deprecated
|
||||
public ObjectInputStream deserialize(ObjectName name, byte[] data)
|
||||
throws InstanceNotFoundException, OperationsException;
|
||||
|
||||
@Deprecated(since="1.5")
|
||||
default public ObjectInputStream deserialize(ObjectName name, byte[] data)
|
||||
throws InstanceNotFoundException, OperationsException {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>De-serializes a byte array in the context of a given MBean
|
||||
@ -682,6 +685,8 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
* used for the de-serialization.
|
||||
* @param data The byte array to be de-sererialized.
|
||||
*
|
||||
* @implSpec This method throws {@link UnsupportedOperationException} by default.
|
||||
*
|
||||
* @return The de-serialized object stream.
|
||||
*
|
||||
* @exception OperationsException Any of the usual Input/Output
|
||||
@ -692,9 +697,11 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
* @deprecated Use {@link #getClassLoaderRepository} to obtain the
|
||||
* class loader repository and use it to deserialize.
|
||||
*/
|
||||
@Deprecated
|
||||
public ObjectInputStream deserialize(String className, byte[] data)
|
||||
throws OperationsException, ReflectionException;
|
||||
@Deprecated(since="1.5")
|
||||
default public ObjectInputStream deserialize(String className, byte[] data)
|
||||
throws OperationsException, ReflectionException {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -711,6 +718,8 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
* loading the specified class. If null, the MBean Server's class
|
||||
* loader will be used.
|
||||
*
|
||||
* @implSpec This method throws {@link UnsupportedOperationException} by default.
|
||||
*
|
||||
* @return The de-serialized object stream.
|
||||
*
|
||||
* @exception InstanceNotFoundException The specified class loader
|
||||
@ -723,12 +732,14 @@ public interface MBeanServer extends MBeanServerConnection {
|
||||
* @deprecated Use {@link #getClassLoader getClassLoader} to obtain
|
||||
* the class loader for deserialization.
|
||||
*/
|
||||
@Deprecated
|
||||
public ObjectInputStream deserialize(String className,
|
||||
@Deprecated(since="1.5")
|
||||
default public ObjectInputStream deserialize(String className,
|
||||
ObjectName loaderName,
|
||||
byte[] data)
|
||||
throws InstanceNotFoundException, OperationsException,
|
||||
ReflectionException;
|
||||
ReflectionException {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the {@link java.lang.ClassLoader} that was used for
|
||||
|
||||
@ -308,10 +308,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||
|
||||
//-- native methods
|
||||
|
||||
static native boolean isLinuxThreads();
|
||||
|
||||
static native int getLinuxThreadsManager(int pid) throws IOException;
|
||||
|
||||
static native void sendQuitToChildrenOf(int pid) throws IOException;
|
||||
|
||||
static native void sendQuitTo(int pid) throws IOException;
|
||||
|
||||
@ -194,113 +194,6 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: isLinuxThreads
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_sun_tools_attach_VirtualMachineImpl_isLinuxThreads
|
||||
(JNIEnv *env, jclass cls)
|
||||
{
|
||||
# ifndef _CS_GNU_LIBPTHREAD_VERSION
|
||||
# define _CS_GNU_LIBPTHREAD_VERSION 3
|
||||
# endif
|
||||
size_t n;
|
||||
char* s;
|
||||
jboolean res;
|
||||
|
||||
n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
|
||||
if (n <= 0) {
|
||||
/* glibc before 2.3.2 only has LinuxThreads */
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
s = (char *)malloc(n);
|
||||
if (s == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, "malloc failed");
|
||||
return JNI_TRUE;
|
||||
}
|
||||
confstr(_CS_GNU_LIBPTHREAD_VERSION, s, n);
|
||||
|
||||
/*
|
||||
* If the LIBPTHREAD version include "NPTL" then we know we
|
||||
* have the new threads library and not LinuxThreads
|
||||
*/
|
||||
res = (jboolean)(strstr(s, "NPTL") == NULL);
|
||||
free(s);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure and callback function used to count the children of
|
||||
* a given process, and record the pid of the "manager thread".
|
||||
*/
|
||||
typedef struct {
|
||||
pid_t ppid;
|
||||
int count;
|
||||
pid_t mpid;
|
||||
} ChildCountContext;
|
||||
|
||||
static void ChildCountCallback(const pid_t pid, void* user_data) {
|
||||
ChildCountContext* context = (ChildCountContext*)user_data;
|
||||
if (getParent(pid) == context->ppid) {
|
||||
context->count++;
|
||||
/*
|
||||
* Remember the pid of the first child. If the final count is
|
||||
* one then this is the pid of the LinuxThreads manager.
|
||||
*/
|
||||
if (context->count == 1) {
|
||||
context->mpid = pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_VirtualMachineImpl
|
||||
* Method: getLinuxThreadsManager
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_getLinuxThreadsManager
|
||||
(JNIEnv *env, jclass cls, jint pid)
|
||||
{
|
||||
ChildCountContext context;
|
||||
|
||||
/*
|
||||
* Iterate over all processes to find how many children 'pid' has
|
||||
*/
|
||||
context.ppid = pid;
|
||||
context.count = 0;
|
||||
context.mpid = (pid_t)0;
|
||||
forEachProcess(ChildCountCallback, (void*)&context);
|
||||
|
||||
/*
|
||||
* If there's no children then this is likely the pid of the primordial
|
||||
* created by the launcher - in that case the LinuxThreads manager is the
|
||||
* parent of this process.
|
||||
*/
|
||||
if (context.count == 0) {
|
||||
pid_t parent = getParent(pid);
|
||||
if ((int)parent > 0) {
|
||||
return (jint)parent;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There's one child so this is likely the embedded VM case where the
|
||||
* the primordial thread == LinuxThreads initial thread. The LinuxThreads
|
||||
* manager in that case is the child.
|
||||
*/
|
||||
if (context.count == 1) {
|
||||
return (jint)context.mpid;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here it's most likely we were given the wrong pid
|
||||
*/
|
||||
JNU_ThrowIOException(env, "Unable to get pid of LinuxThreads manager thread");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure and callback function used to send a QUIT signal to all
|
||||
* children of a given process
|
||||
|
||||
@ -993,32 +993,39 @@ implements ReferenceType {
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
private void getConstantPoolInfo() {
|
||||
private byte[] getConstantPoolInfo() {
|
||||
JDWP.ReferenceType.ConstantPool jdwpCPool;
|
||||
if (!vm.canGetConstantPool()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
if (constantPoolInfoGotten) {
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
jdwpCPool = JDWP.ReferenceType.ConstantPool.process(vm, this);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
|
||||
constanPoolCount = 0;
|
||||
constantPoolBytesRef = null;
|
||||
constantPoolInfoGotten = true;
|
||||
return;
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
if (constantPoolBytesRef == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] cpbytes = constantPoolBytesRef.get();
|
||||
if (cpbytes != null) {
|
||||
return cpbytes;
|
||||
}
|
||||
byte[] cpbytes;
|
||||
constanPoolCount = jdwpCPool.count;
|
||||
cpbytes = jdwpCPool.bytes;
|
||||
constantPoolBytesRef = new SoftReference<byte[]>(cpbytes);
|
||||
constantPoolInfoGotten = true;
|
||||
}
|
||||
|
||||
try {
|
||||
jdwpCPool = JDWP.ReferenceType.ConstantPool.process(vm, this);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
|
||||
constanPoolCount = 0;
|
||||
constantPoolBytesRef = null;
|
||||
constantPoolInfoGotten = true;
|
||||
return null;
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
byte[] cpbytes;
|
||||
constanPoolCount = jdwpCPool.count;
|
||||
cpbytes = jdwpCPool.bytes;
|
||||
constantPoolBytesRef = new SoftReference<byte[]>(cpbytes);
|
||||
constantPoolInfoGotten = true;
|
||||
return cpbytes;
|
||||
}
|
||||
|
||||
public int constantPoolCount() {
|
||||
@ -1031,13 +1038,13 @@ implements ReferenceType {
|
||||
}
|
||||
|
||||
public byte[] constantPool() {
|
||||
byte[] cpbytes;
|
||||
try {
|
||||
getConstantPoolInfo();
|
||||
cpbytes = getConstantPoolInfo();
|
||||
} catch (RuntimeException exc) {
|
||||
throw exc;
|
||||
}
|
||||
if (constantPoolBytesRef != null) {
|
||||
byte[] cpbytes = constantPoolBytesRef.get();
|
||||
if (cpbytes != null) {
|
||||
/*
|
||||
* Arrays are always modifiable, so it is a little unsafe
|
||||
* to return the cached bytecodes directly; instead, we
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
module jdk.jdi {
|
||||
requires jdk.attach;
|
||||
requires jdk.jdwp.agent;
|
||||
|
||||
exports com.sun.jdi;
|
||||
exports com.sun.jdi.connect;
|
||||
|
||||
@ -55,6 +55,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.tools.jlink.internal.BasicImageWriter;
|
||||
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
|
||||
import jdk.tools.jlink.internal.ExecutableImage;
|
||||
@ -159,7 +160,7 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
props.setProperty("MODULES", builder.toString());
|
||||
props.setProperty("MODULES", quote(builder.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -188,7 +189,8 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
|
||||
storeFiles(modules, release);
|
||||
|
||||
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
|
||||
if (root.getFileSystem().supportedFileAttributeViews()
|
||||
.contains("posix")) {
|
||||
// launchers in the bin directory need execute permission.
|
||||
// On Windows, "bin" also subdirectories containing jvm.dll.
|
||||
if (Files.isDirectory(bin)) {
|
||||
@ -217,19 +219,38 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse version string and return a string that includes only version part
|
||||
// leaving "pre", "build" information. See also: java.lang.Runtime.Version.
|
||||
private static String parseVersion(String str) {
|
||||
return Runtime.Version.parse(str).
|
||||
version().
|
||||
stream().
|
||||
map(Object::toString).
|
||||
collect(Collectors.joining("."));
|
||||
}
|
||||
|
||||
private static String quote(String str) {
|
||||
return "\"" + str + "\"";
|
||||
}
|
||||
|
||||
private Properties releaseProperties(ResourcePool pool) throws IOException {
|
||||
Properties props = new Properties();
|
||||
Optional<ResourcePoolModule> javaBase = pool.moduleView().findModule("java.base");
|
||||
javaBase.ifPresent(mod -> {
|
||||
// fill release information available from transformed "java.base" module!
|
||||
ModuleDescriptor desc = mod.descriptor();
|
||||
desc.osName().ifPresent(s -> props.setProperty("OS_NAME", s));
|
||||
desc.osVersion().ifPresent(s -> props.setProperty("OS_VERSION", s));
|
||||
desc.osArch().ifPresent(s -> props.setProperty("OS_ARCH", s));
|
||||
props.setProperty("JAVA_VERSION", System.getProperty("java.version"));
|
||||
desc.osName().ifPresent(s -> {
|
||||
props.setProperty("OS_NAME", quote(s));
|
||||
this.targetOsName = s;
|
||||
});
|
||||
desc.osVersion().ifPresent(s -> props.setProperty("OS_VERSION", quote(s)));
|
||||
desc.osArch().ifPresent(s -> props.setProperty("OS_ARCH", quote(s)));
|
||||
desc.version().ifPresent(s -> props.setProperty("JAVA_VERSION",
|
||||
quote(parseVersion(s.toString()))));
|
||||
desc.version().ifPresent(s -> props.setProperty("JAVA_FULL_VERSION",
|
||||
quote(s.toString())));
|
||||
});
|
||||
|
||||
this.targetOsName = props.getProperty("OS_NAME");
|
||||
if (this.targetOsName == null) {
|
||||
throw new PluginException("TargetPlatform attribute is missing for java.base module");
|
||||
}
|
||||
@ -282,8 +303,8 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
StandardOpenOption.CREATE_NEW)) {
|
||||
writer.write(sb.toString());
|
||||
}
|
||||
if (Files.getFileStore(root.resolve("bin"))
|
||||
.supportsFileAttributeView(PosixFileAttributeView.class)) {
|
||||
if (root.resolve("bin").getFileSystem()
|
||||
.supportedFileAttributeViews().contains("posix")) {
|
||||
setExecutable(cmd);
|
||||
}
|
||||
// generate .bat file for Windows
|
||||
|
||||
@ -35,4 +35,5 @@
|
||||
# This notice and attribution to Taligent may not be removed.
|
||||
# Taligent is a registered trademark of Taligent, Inc.
|
||||
|
||||
BYN=\u0420\u0443\u0431
|
||||
BYR=\u0420\u0443\u0431
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user