--- a/.hgtags Tue Dec 07 13:27:02 2010 +0000
+++ b/.hgtags Tue Dec 07 13:29:20 2010 +0000
@@ -93,3 +93,4 @@
a4e6aa1f45ad23a6f083ed98d970b5006ea4d292 jdk7-b116
228e73f288c543a8c34e2a54227103ae5649e6af jdk7-b117
2e876e59938a853934aa738c811b26c452bd9fe8 jdk7-b118
+4951967a61b4dbbf514828879f57bd1a0d4b420b jdk7-b119
--- a/.hgtags-top-repo Tue Dec 07 13:27:02 2010 +0000
+++ b/.hgtags-top-repo Tue Dec 07 13:29:20 2010 +0000
@@ -93,3 +93,4 @@
94e9a1bfba8b8d1fe0bfd43b88629b1f27b02a76 jdk7-b116
7220e60b097fa027e922f1aeecdd330f3e37409f jdk7-b117
a12a9e78df8a9d534da0b4a244ed68f0de0bd58e jdk7-b118
+661360bef6ccad6c119f067f5829b207de80c936 jdk7-b119
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/ClientRequestInfoImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -74,6 +74,7 @@
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
+import com.sun.corba.se.spi.protocol.RetryType;
import com.sun.corba.se.spi.transport.CorbaContactInfo;
import com.sun.corba.se.spi.transport.CorbaContactInfoList;
import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
@@ -110,7 +111,7 @@
// The current retry request status. True if this request is being
// retried and this info object is to be reused, or false otherwise.
- private boolean retryRequest;
+ private RetryType retryRequest;
// The number of times this info object has been (re)used. This is
// incremented every time a request is retried, and decremented every
@@ -163,7 +164,8 @@
// Please keep these in the same order that they're declared above.
- retryRequest = false;
+ // 6763340
+ retryRequest = RetryType.NONE;
// Do not reset entryCount because we need to know when to pop this
// from the stack.
@@ -824,14 +826,15 @@
/**
* Set or reset the retry request flag.
*/
- void setRetryRequest( boolean retryRequest ) {
+ void setRetryRequest( RetryType retryRequest ) {
this.retryRequest = retryRequest;
}
/**
* Retrieve the current retry request status.
*/
- boolean getRetryRequest() {
+ RetryType getRetryRequest() {
+ // 6763340
return this.retryRequest;
}
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -70,6 +70,7 @@
import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
import com.sun.corba.se.spi.protocol.ForwardException;
import com.sun.corba.se.spi.protocol.PIHandler;
+import com.sun.corba.se.spi.protocol.RetryType;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.impl.logging.InterceptorsSystemException;
@@ -372,9 +373,24 @@
}
}
- public Exception invokeClientPIEndingPoint(
- int replyStatus, Exception exception )
- {
+ // Needed when an error forces a retry AFTER initiateClientPIRequest
+ // but BEFORE invokeClientPIStartingPoint.
+ public Exception makeCompletedClientRequest( int replyStatus,
+ Exception exception ) {
+
+ // 6763340
+ return handleClientPIEndingPoint( replyStatus, exception, false ) ;
+ }
+
+ public Exception invokeClientPIEndingPoint( int replyStatus,
+ Exception exception ) {
+
+ // 6763340
+ return handleClientPIEndingPoint( replyStatus, exception, true ) ;
+ }
+
+ public Exception handleClientPIEndingPoint(
+ int replyStatus, Exception exception, boolean invokeEndingPoint ) {
if( !hasClientInterceptors ) return exception;
if( !isClientPIEnabledForThisThread() ) return exception;
@@ -388,24 +404,31 @@
ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
info.setReplyStatus( piReplyStatus );
info.setException( exception );
- interceptorInvoker.invokeClientInterceptorEndingPoint( info );
- piReplyStatus = info.getReplyStatus();
+
+ if (invokeEndingPoint) {
+ // 6763340
+ interceptorInvoker.invokeClientInterceptorEndingPoint( info );
+ piReplyStatus = info.getReplyStatus();
+ }
// Check reply status:
if( (piReplyStatus == LOCATION_FORWARD.value) ||
- (piReplyStatus == TRANSPORT_RETRY.value) )
- {
+ (piReplyStatus == TRANSPORT_RETRY.value) ) {
// If this is a forward or a retry, reset and reuse
// info object:
info.reset();
- info.setRetryRequest( true );
+
+ // fix for 6763340:
+ if (invokeEndingPoint) {
+ info.setRetryRequest( RetryType.AFTER_RESPONSE ) ;
+ } else {
+ info.setRetryRequest( RetryType.BEFORE_RESPONSE ) ;
+ }
// ... and return a RemarshalException so the orb internals know
exception = new RemarshalException();
- }
- else if( (piReplyStatus == SYSTEM_EXCEPTION.value) ||
- (piReplyStatus == USER_EXCEPTION.value) )
- {
+ } else if( (piReplyStatus == SYSTEM_EXCEPTION.value) ||
+ (piReplyStatus == USER_EXCEPTION.value) ) {
exception = info.getException();
}
@@ -421,18 +444,21 @@
RequestInfoStack infoStack =
(RequestInfoStack)threadLocalClientRequestInfoStack.get();
ClientRequestInfoImpl info = null;
- if( !infoStack.empty() ) info =
- (ClientRequestInfoImpl)infoStack.peek();
- if( !diiRequest && (info != null) && info.isDIIInitiate() ) {
+ if (!infoStack.empty() ) {
+ info = (ClientRequestInfoImpl)infoStack.peek();
+ }
+
+ if (!diiRequest && (info != null) && info.isDIIInitiate() ) {
// In RequestImpl.doInvocation we already called
// initiateClientPIRequest( true ), so ignore this initiate.
info.setDIIInitiate( false );
- }
- else {
+ } else {
// If there is no info object or if we are not retrying a request,
// push a new ClientRequestInfoImpl on the stack:
- if( (info == null) || !info.getRetryRequest() ) {
+
+ // 6763340: don't push unless this is not a retry
+ if( (info == null) || !info.getRetryRequest().isRetry() ) {
info = new ClientRequestInfoImpl( orb );
infoStack.push( info );
printPush();
@@ -442,9 +468,15 @@
// Reset the retry request flag so that recursive calls will
// push a new info object, and bump up entry count so we know
// when to pop this info object:
- info.setRetryRequest( false );
+ info.setRetryRequest( RetryType.NONE );
info.incrementEntryCount();
+ // KMC 6763340: I don't know why this wasn't set earlier,
+ // but we do not want a retry to pick up the previous
+ // reply status, so clear it here. Most likely a new
+ // info was pushed before, so that this was not a problem.
+ info.setReplyStatus( RequestInfoImpl.UNINITIALIZED ) ;
+
// If this is a DII request, make sure we ignore the next initiate.
if( diiRequest ) {
info.setDIIInitiate( true );
@@ -457,25 +489,34 @@
if( !isClientPIEnabledForThisThread() ) return;
ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
+ RetryType rt = info.getRetryRequest() ;
- // If the replyStatus has not yet been set, this is an indication
- // that the ORB threw an exception before we had a chance to
- // invoke the client interceptor ending points.
- //
- // _REVISIT_ We cannot handle any exceptions or ForwardRequests
- // flagged by the ending points here because there is no way
- // to gracefully handle this in any of the calling code.
- // This is a rare corner case, so we will ignore this for now.
- short replyStatus = info.getReplyStatus();
- if( replyStatus == info.UNINITIALIZED ) {
- invokeClientPIEndingPoint( ReplyMessage.SYSTEM_EXCEPTION,
- wrapper.unknownRequestInvoke(
- CompletionStatus.COMPLETED_MAYBE ) ) ;
+ // fix for 6763340
+ if (!rt.equals( RetryType.BEFORE_RESPONSE )) {
+
+ // If the replyStatus has not yet been set, this is an indication
+ // that the ORB threw an exception before we had a chance to
+ // invoke the client interceptor ending points.
+ //
+ // _REVISIT_ We cannot handle any exceptions or ForwardRequests
+ // flagged by the ending points here because there is no way
+ // to gracefully handle this in any of the calling code.
+ // This is a rare corner case, so we will ignore this for now.
+ short replyStatus = info.getReplyStatus();
+ if (replyStatus == info.UNINITIALIZED ) {
+ invokeClientPIEndingPoint( ReplyMessage.SYSTEM_EXCEPTION,
+ wrapper.unknownRequestInvoke(
+ CompletionStatus.COMPLETED_MAYBE ) ) ;
+ }
}
// Decrement entry count, and if it is zero, pop it from the stack.
info.decrementEntryCount();
- if( info.getEntryCount() == 0 ) {
+
+ // fix for 6763340, and probably other cases (non-recursive retry)
+ if (info.getEntryCount() == 0 && !info.getRetryRequest().isRetry()) {
+ // RequestInfoStack<ClientRequestInfoImpl> infoStack =
+ // threadLocalClientRequestInfoStack.get();
RequestInfoStack infoStack =
(RequestInfoStack)threadLocalClientRequestInfoStack.get();
infoStack.pop();
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PINoOpHandlerImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -107,6 +107,11 @@
return null;
}
+ public Exception makeCompletedClientRequest(
+ int replyStatus, Exception exception ) {
+ return null;
+ }
+
public void initiateClientPIRequest( boolean diiRequest ) {
}
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -187,7 +187,8 @@
startingPointCall = 0;
intermediatePointCall = 0;
endingPointCall = 0;
- replyStatus = UNINITIALIZED;
+ // 6763340
+ setReplyStatus( UNINITIALIZED ) ;
currentExecutionPoint = EXECUTION_POINT_STARTING;
alreadyExecuted = false;
connection = null;
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Tue Dec 07 13:29:20 2010 +0000
@@ -1012,7 +1012,11 @@
* else,
* Handle it as a serializable class.
*/
- if (currentClassDesc.isExternalizable()) {
+ if (Enum.class.isAssignableFrom( clz )) {
+ int ordinal = orbStream.read_long() ;
+ String value = (String)orbStream.read_value( String.class ) ;
+ return Enum.valueOf( clz, value ) ;
+ } else if (currentClassDesc.isExternalizable()) {
try {
currentObject = (currentClass == null) ?
null : currentClassDesc.newInstance();
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -1672,6 +1672,7 @@
{
StackImpl invocationInfoStack =
(StackImpl)clientInvocationInfoStack.get();
+ int entryCount = -1;
ClientInvocationInfo clientInvocationInfo = null;
if (!invocationInfoStack.empty()) {
clientInvocationInfo =
@@ -1680,8 +1681,12 @@
throw wrapper.invocationInfoStackEmpty() ;
}
clientInvocationInfo.decrementEntryCount();
+ entryCount = clientInvocationInfo.getEntryCount();
if (clientInvocationInfo.getEntryCount() == 0) {
- invocationInfoStack.pop();
+ // 6763340: don't pop if this is a retry!
+ if (!clientInvocationInfo.isRetryInvocation()) {
+ invocationInfoStack.pop();
+ }
finishedDispatch();
}
}
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaClientRequestDispatcherImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaClientRequestDispatcherImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -185,6 +185,7 @@
if(getContactInfoListIterator(orb).hasNext()) {
contactInfo = (ContactInfo)
getContactInfoListIterator(orb).next();
+ unregisterWaiter(orb);
return beginRequest(self, opName,
isOneWay, contactInfo);
} else {
@@ -292,10 +293,22 @@
// ContactInfoList outside of subcontract.
// Want to move that update to here.
if (getContactInfoListIterator(orb).hasNext()) {
- contactInfo = (ContactInfo)
- getContactInfoListIterator(orb).next();
+ contactInfo = (ContactInfo)getContactInfoListIterator(orb).next();
+ if (orb.subcontractDebugFlag) {
+ dprint( "RemarshalException: hasNext true\ncontact info " + contactInfo );
+ }
+
+ // Fix for 6763340: Complete the first attempt before starting another.
+ orb.getPIHandler().makeCompletedClientRequest(
+ ReplyMessage.LOCATION_FORWARD, null ) ;
+ unregisterWaiter(orb);
+ orb.getPIHandler().cleanupClientPIRequest() ;
+
return beginRequest(self, opName, isOneWay, contactInfo);
} else {
+ if (orb.subcontractDebugFlag) {
+ dprint( "RemarshalException: hasNext false" );
+ }
ORBUtilSystemException wrapper =
ORBUtilSystemException.get(orb,
CORBALogDomains.RPC_PROTOCOL);
--- a/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java Tue Dec 07 13:27:02 2010 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/spi/protocol/PIHandler.java Tue Dec 07 13:29:20 2010 +0000
@@ -142,6 +142,27 @@
int replyStatus, Exception exception ) ;
/**
+ * Called when a retry is needed after initiateClientPIRequest but
+ * before invokeClientPIRequest. In this case, we need to properly
+ * balance initiateClientPIRequest/cleanupClientPIRequest calls,
+ * but WITHOUT extraneous calls to invokeClientPIEndingPoint
+ * (see bug 6763340).
+ *
+ * @param replyStatus One of the constants in iiop.messages.ReplyMessage
+ * indicating which reply status to set.
+ * @param exception The exception before ending interception points have
+ * been invoked, or null if no exception at the moment.
+ * @return The exception to be thrown, after having gone through
+ * all ending points, or null if there is no exception to be
+ * thrown. Note that this exception can be either the same or
+ * different from the exception set using setClientPIException.
+ * There are four possible return types: null (no exception),
+ * SystemException, UserException, or RemarshalException.
+ */
+ Exception makeCompletedClientRequest(
+ int replyStatus, Exception exception ) ;
+
+ /**
* Invoked when a request is about to be created. Must be called before
* any of the setClientPI* methods so that a new info object can be
* prepared for information collection.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/share/classes/com/sun/corba/se/spi/protocol/RetryType.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.protocol ;
+
+// Introduce more information about WHY we are re-trying a request
+// so we can properly handle the two cases:
+// - BEFORE_RESPONSE means that the retry is caused by
+// something that happened BEFORE the message was sent: either
+// an exception from the SocketFactory, or one from the
+// Client side send_request interceptor point.
+// - AFTER_RESPONSE means that the retry is a result either of the
+// request sent to the server (from the response), or from the
+// Client side receive_xxx interceptor point.
+public enum RetryType {
+ NONE( false ),
+ BEFORE_RESPONSE( true ),
+ AFTER_RESPONSE( true ) ;
+
+ private final boolean isRetry ;
+
+ RetryType( boolean isRetry ) {
+ this.isRetry = isRetry ;
+ }
+
+ public boolean isRetry() {
+ return this.isRetry ;
+ }
+} ;
+
--- a/jaxp/.hgtags Tue Dec 07 13:27:02 2010 +0000
+++ b/jaxp/.hgtags Tue Dec 07 13:29:20 2010 +0000
@@ -93,3 +93,4 @@
f8d4e6c6cfce1cda23fcbd144628a9791a9e1a63 jdk7-b116
9ee4d96e893436a48607924227dadd2d93b9b00d jdk7-b117
b2f6d9c4f12ffd307a5de40455b2b61b31a5cb79 jdk7-b118
+9ee900f01c5872551c06f33ae909662ffd8463ac jdk7-b119
--- a/jaxws/.hgtags Tue Dec 07 13:27:02 2010 +0000
+++ b/jaxws/.hgtags Tue Dec 07 13:29:20 2010 +0000
@@ -93,3 +93,4 @@
376ac153078dd3b5f6d4a0981feee092c1492c96 jdk7-b116
1320fb3bb588298c79716bd2d10b5b4afacb9370 jdk7-b117
19a2fab3f91a275f90791c15d1c21a24e820ff2d jdk7-b118
+41fa02b3663795ddf529690df7aa6714210093ec jdk7-b119
--- a/jdk/.hgtags Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/.hgtags Tue Dec 07 13:29:20 2010 +0000
@@ -93,3 +93,5 @@
1657ed4e1d86c8aa2028ab5a41f9da1ac4a369f8 jdk7-b116
3e6726bbf80a4254ecd01051c8ed77ee19325e46 jdk7-b117
b357910aa04aead2a16b6d6ff395a8df4b51d1dd jdk7-b118
+ecab7eefb8f2326fd90fb632f47f1b6f81e928f8 jdk7-b119
+37d74e29687cf07c2bf9411af58c7e42440855c3 jdk7-b120
--- a/jdk/make/common/shared/Defs-linux.gmk Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/common/shared/Defs-linux.gmk Tue Dec 07 13:29:20 2010 +0000
@@ -123,7 +123,7 @@
# GCC29_COMPILER_PATH: is the path to where the gcc 2.9 compiler is installed
# NOTE: Must end with / so that it could be empty, allowing PATH usage.
-ifneq "$(origin ALT_GCC29_COMPILER_PATH)" "undefined"
+ifdef ALT_GCC29_COMPILER_PATH
GCC29_COMPILER_PATH :=$(call PrefixPath,$(ALT_GCC29_COMPILER_PATH))
else
GCC29_COMPILER_PATH = $(JDK_DEVTOOLS_DIR)/$(PLATFORM)/gcc29/usr/
--- a/jdk/make/common/shared/Defs-versions.gmk Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/common/shared/Defs-versions.gmk Tue Dec 07 13:29:20 2010 +0000
@@ -65,7 +65,7 @@
# If we are using freetype, the freetype version expected.
#
# REQUIRED_GCC_VER
-# Solaris and Linux only. The required version of gcc/g++ for the plugin.
+# Solaris and Linux only. The required version of gcc/g++ for the legacy OJI plugin.
#
# REQUIRED_LINK_VER
# Windows only: The version of link.exe expected.
--- a/jdk/make/common/shared/Sanity.gmk Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/common/shared/Sanity.gmk Tue Dec 07 13:29:20 2010 +0000
@@ -99,12 +99,16 @@
echo "RedHat"; \
elif [ -f /etc/SuSE-release ] ; then \
echo "SuSE"; \
+ elif [ -f /etc/lsb-release ] ; then \
+ $(EGREP) DISTRIB_ID /etc/lsb-release | $(SED) -e 's@.*DISTRIB_ID=\(.*\)@\1@'; \
else \
echo "Unknown"; \
fi)
OS_VARIANT_VERSION := $(shell \
if [ "$(OS_VARIANT_NAME)" = "Fedora" ] ; then \
$(CAT) /etc/fedora-release | $(HEAD) -1 | $(NAWK) '{ print $$3; }' ; \
+ elif [ -f /etc/lsb-release ] ; then \
+ $(EGREP) DISTRIB_RELEASE /etc/lsb-release | $(SED) -e 's@.*DISTRIB_RELEASE=\(.*\)@\1@'; \
fi)
ALSA_INCLUDE=/usr/include/alsa/version.h
ALSA_LIBRARY=/usr/lib/libasound.so
@@ -279,7 +283,7 @@
fi
######################################################
-# Check the OS version (windows and linus have release name checks)
+# Check the OS version (windows and linux have release name checks)
# NOTE: OPENJDK explicitly does not check for OS release information.
# Unless we know for sure that it will not build somewhere, we cannot
# generate a fatal sanity error, and a warning about the official
@@ -1476,20 +1480,20 @@
endif
######################################################
-# Check the Solaris GNU c++ compiler for solaris plugin
+# Check the GNU C++ compiler for OJI plugin
######################################################
sane-gcc-compiler:
-ifeq ($(PLATFORM), solaris)
- ifndef OPENJDK
- @if [ -r $(GCC_COMPILER_PATH) ]; then \
- if [ ! "$(GCC_VER)" = $(REQUIRED_GCC_VERSION) ]; then \
- $(ECHO) "ERROR: The Solaris GCC compiler version must be $(REQUIRED_GCC_VERSION). \n" \
+ifndef OPENJDK
+ ifeq ($(PLATFORM), solaris)
+ @if [ -r $(GCC_COMPILER_PATH) ]; then \
+ if [ ! "$(GCC_VER)" = $(REQUIRED_GCC_VER) ]; then \
+ $(ECHO) "ERROR: The Solaris GCC compiler version must be $(REQUIRED_GCC_VER). \n" \
" You are using the following compiler version: $(GCC_VER) \n" \
" The compiler was obtained from the following location: \n" \
" $(GCC_COMPILER_PATH) \n" \
" Please change your compiler. \n" \
"" >> $(ERROR_FILE) ; \
- fi \
+ fi \
else \
$(ECHO) "ERROR: You do not have a valid GCC_COMPILER_PATH setting. \n" \
" Please check your access to \n" \
@@ -1501,15 +1505,16 @@
endif
ifeq ($(PLATFORM), linux)
+ ifeq ($(ARCH_DATA_MODEL), 32)
ifdef ALT_GCC29_COMPILER_PATH
@if [ ! -x $(ALT_GCC29_COMPILER_PATH)/bin/gcc ]; then \
- $(ECHO) "ERROR: You do not have a valid ALT_GCC29_COMPILER_PATH setting. \n" \
+ $(ECHO) "ERROR: You do not have a valid ALT_GCC29_COMPILER_PATH setting. \n" \
" Please check your access to \n" \
" $(ALT_GCC29_COMPILER_PATH)/bin/gcc \n" \
" This will affect you if you build the plugin target. \n" \
"" >> $(ERROR_FILE) ; \
fi
- endif
+ else
ifdef ALT_GCC29_PLUGIN_LIB_PATH
@if [ ! -r $(ALT_GCC29_PLUGIN_LIB_PATH)/libjavaplugin_oji.so ]; then \
$(ECHO) "Error: You do not have a valid ALT_GCC29_PLUGIN_LIB_PATH setting. \n" \
@@ -1523,13 +1528,15 @@
$(ECHO) "ERROR: You do not have a valid GCC29_COMPILER_PATH setting. \n" \
" Please check your access to \n" \
" $(GCC29_COMPILER_PATH) \n" \
- " and/or check your value of ALT_GCC29_COMPILER_PATH. \n" \
+ " and/or check your value of ALT_GCC29_COMPILER_PATH or ALT_GCC29_PLUGIN_LIB_PATH \n" \
" This will affect you if you build the plugin target. \n" \
"" >> $(ERROR_FILE) ; \
fi
- endif
- endif
-endif
+ endif # ALT_GCC29_PLUGIN_LIB_PATH
+ endif # ALT_GCC29_COMPILER_PATH
+ endif # ARCH_DATA_MODEL, 32
+ endif # LINUX
+endif # OPEN_JDK
######################################################
--- a/jdk/make/docs/Makefile Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/docs/Makefile Tue Dec 07 13:29:20 2010 +0000
@@ -190,7 +190,6 @@
# Common javadoc options used by all
COMMON_JAVADOCFLAGS = \
$(NO_PROPRIETARY_API_WARNINGS) \
- -source 1.5 \
-quiet \
-use \
-keywords \
--- a/jdk/make/mkdemo/nio/zipfs/Makefile Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/mkdemo/nio/zipfs/Makefile Tue Dec 07 13:29:20 2010 +0000
@@ -33,8 +33,8 @@
include $(BUILDDIR)/common/Defs.gmk
DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME)
-DEMO_TOPFILES = ./README.txt
-DEMO_SRCDIR = $(DEMO_ROOT)
+DEMO_TOPFILES = README.txt Demo.java
+DEMO_SRCDIR = $(DEMO_ROOT)/src
DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME)
#
@@ -42,10 +42,10 @@
#
include $(BUILDDIR)/common/Demo.gmk
-#EXTJAR = $(EXTDIR)/$(DEMONAME).jar
-#
-#all : build $(EXTJAR)
-#
-#$(EXTJAR) : $(DEMO_JAR)
-# $(prep-target)
-# $(CP) $(DEMO_JAR) $(EXTJAR)
+EXTJAR = $(EXTDIR)/$(DEMONAME).jar
+
+all : build $(EXTJAR)
+
+$(EXTJAR) : $(DEMO_JAR)
+ $(prep-target)
+ $(CP) $(DEMO_JAR) $(EXTJAR)
--- a/jdk/make/sun/xawt/mapfile-vers Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/sun/xawt/mapfile-vers Tue Dec 07 13:29:20 2010 +0000
@@ -429,6 +429,7 @@
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue;
Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName;
+ Java_sun_awt_X11_GtkFileDialogPeer_initIDs;
Java_sun_awt_X11_GtkFileDialogPeer_run;
Java_sun_awt_X11_GtkFileDialogPeer_quit;
--- a/jdk/make/tools/CharsetMapping/extsbcs Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/make/tools/CharsetMapping/extsbcs Tue Dec 07 13:29:20 2010 +0000
@@ -32,7 +32,7 @@
IBM420 IBM420 Cp420 false sun.nio.cs.ext
IBM424 IBM424 Cp424 false sun.nio.cs.ext
IBM500 IBM500 Cp500 false sun.nio.cs.ext
-IBM833 IBM833 Cp833 false sun.nio.cs.ext
+IBM833 x-IBM833 Cp833 false sun.nio.cs.ext
IBM838 IBM-Thai Cp838 false sun.nio.cs.ext
IBM856 x-IBM856 Cp856 false sun.nio.cs.ext
IBM860 IBM860 Cp860 false sun.nio.cs.ext
--- a/jdk/src/share/bin/java.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/bin/java.c Tue Dec 07 13:29:20 2010 +0000
@@ -65,6 +65,7 @@
static jboolean showVersion = JNI_FALSE; /* print but continue */
static jboolean printUsage = JNI_FALSE; /* print and exit*/
static jboolean printXUsage = JNI_FALSE; /* print and exit*/
+static char *showSettings = NULL; /* print but continue */
static const char *_program_name;
static const char *_launcher_name;
@@ -109,6 +110,7 @@
static void PrintJavaVersion(JNIEnv *env, jboolean extraLF);
static void PrintUsage(JNIEnv* env, jboolean doXUsage);
+static void ShowSettings(JNIEnv* env, char *optString);
static void SetPaths(int argc, char **argv);
@@ -157,6 +159,7 @@
* create a new thread to invoke JVM. See 6316197 for more information.
*/
static jlong threadStackSize = 0; /* stack size of the new thread */
+static jlong heapSize = 0; /* heap size */
int JNICALL JavaMain(void * args); /* entry point */
@@ -376,6 +379,10 @@
}
}
+ if (showSettings != NULL) {
+ ShowSettings(env, showSettings);
+ CHECK_EXCEPTION_LEAVE(0);
+ }
/* If the user specified neither a class name nor a JAR file */
if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
PrintUsage(env, printXUsage);
@@ -611,7 +618,7 @@
/* copied from HotSpot function "atomll()" */
static int
-parse_stack_size(const char *s, jlong *result) {
+parse_size(const char *s, jlong *result) {
jlong n = 0;
int args_read = sscanf(s, jlong_format_specifier(), &n);
if (args_read != 1) {
@@ -673,10 +680,17 @@
options[numOptions++].extraInfo = info;
if (JLI_StrCCmp(str, "-Xss") == 0) {
- jlong tmp;
- if (parse_stack_size(str + 4, &tmp)) {
- threadStackSize = tmp;
- }
+ jlong tmp;
+ if (parse_size(str + 4, &tmp)) {
+ threadStackSize = tmp;
+ }
+ }
+
+ if (JLI_StrCCmp(str, "-Xmx") == 0) {
+ jlong tmp;
+ if (parse_size(str + 4, &tmp)) {
+ heapSize = tmp;
+ }
}
}
@@ -1015,6 +1029,13 @@
printXUsage = JNI_TRUE;
return JNI_TRUE;
/*
+ * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT.
+ * In the latter case, any SUBOPT value not recognized will default to "all"
+ */
+ } else if (JLI_StrCmp(arg, "-XshowSettings") == 0 ||
+ JLI_StrCCmp(arg, "-XshowSettings:") == 0) {
+ showSettings = arg;
+/*
* The following case provide backward compatibility with old-style
* command line options.
*/
@@ -1475,6 +1496,27 @@
}
/*
+ * Prints all the Java settings, see the java implementation for more details.
+ */
+static void
+ShowSettings(JNIEnv *env, char *optString)
+{
+ jclass cls;
+ jmethodID showSettingsID;
+ jstring joptString;
+ NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper"));
+ NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls,
+ "showSettings", "(ZLjava/lang/String;JJZ)V"));
+ joptString = (*env)->NewStringUTF(env, optString);
+ (*env)->CallStaticVoidMethod(env, cls, showSettingsID,
+ JNI_TRUE,
+ joptString,
+ (jlong)heapSize,
+ (jlong)threadStackSize,
+ ServerClassMachine());
+}
+
+/*
* Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java
*/
static void
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/AdaptiveCoding.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/AdaptiveCoding.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,8 +25,10 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
/**
* Adaptive coding.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,9 +25,17 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import com.sun.java.util.jar.pack.ConstantPool.Index;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Represents an attribute in a class-file.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,12 +25,28 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-import com.sun.java.util.jar.pack.Package.Class;
-import com.sun.java.util.jar.pack.Package.InnerClass;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import com.sun.java.util.jar.pack.ConstantPool.Index;
+import com.sun.java.util.jar.pack.Package.Class.Field;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.jar.Pack200;
/**
* Define the structure and ordering of "bands" in a packed file.
@@ -1629,7 +1645,7 @@
}
}
- protected void setConstantValueIndex(Class.Field f) {
+ protected void setConstantValueIndex(com.sun.java.util.jar.pack.Package.Class.Field f) {
Index ix = null;
if (f != null) {
byte tag = f.getLiteralTag();
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,11 +25,19 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
import com.sun.java.util.jar.pack.Package.Class;
import com.sun.java.util.jar.pack.Package.InnerClass;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import java.io.DataInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Map;
/**
* Reader for a class file that is being incorporated into a package.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassWriter.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,11 +25,19 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
+
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import com.sun.java.util.jar.pack.ConstantPool.Index;
+import com.sun.java.util.jar.pack.ConstantPool.NumberEntry;
import com.sun.java.util.jar.pack.Package.Class;
import com.sun.java.util.jar.pack.Package.InnerClass;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
/**
* Writer for a class file that is incorporated into a package.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Code.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,10 +25,10 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
import com.sun.java.util.jar.pack.Package.Class;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
/**
* Represents a chunk of bytecodes.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Coding.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Coding.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,8 +25,10 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
/**
* Define the conversions between sequences of small integers and raw bytes.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/CodingChooser.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/CodingChooser.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,9 +25,17 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
/**
* Heuristic chooser of basic encodings.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/CodingMethod.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/CodingMethod.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,7 +25,9 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
/**
* Interface for encoding and decoding int arrays using bytewise codes.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,7 +25,14 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
/**
* Representation of constant pool entries and indexes.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Constants.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,7 +25,8 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
+import java.util.Arrays;
+import java.util.List;
/**
* Shared constants
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,11 +25,32 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
import java.text.MessageFormat;
-import java.util.*;
-import java.util.jar.*;
-import java.util.zip.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Pack200;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
/** Command line interface for Pack200.
*/
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Fixups.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,9 +25,11 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
/**
* Collection of relocatable constant pool references.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Histogram.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Histogram.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,8 +25,10 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
/**
* Histogram derived from an integer array of events (int[]).
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java Tue Dec 07 13:29:20 2010 +0000
@@ -26,10 +26,18 @@
package com.sun.java.util.jar.pack;
-import java.nio.*;
-import java.io.*;
-import java.util.jar.*;
-import java.util.zip.*;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Pack200;
+import java.util.zip.CRC32;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
class NativeUnpack {
// Pointer to the native unpacker obj
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Package.java Tue Dec 07 13:29:20 2010 +0000
@@ -26,11 +26,32 @@
package com.sun.java.util.jar.pack;
import com.sun.java.util.jar.pack.Attribute.Layout;
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Index;
+import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.SequenceInputStream;
import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.jar.*;
-import java.io.*;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarFile;
/**
* Define the main data structure transmitted by pack/unpack.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,12 +25,18 @@
package com.sun.java.util.jar.pack;
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import com.sun.java.util.jar.pack.ConstantPool.Index;
+import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
import java.io.*;
import java.util.*;
import com.sun.java.util.jar.pack.Package.Class;
import com.sun.java.util.jar.pack.Package.File;
import com.sun.java.util.jar.pack.Package.InnerClass;
-import com.sun.java.util.jar.pack.ConstantPool.*;
/**
* Reader for a package file.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,12 +25,30 @@
package com.sun.java.util.jar.pack;
-import java.io.*;
-import java.util.*;
+import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
+import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
+import com.sun.java.util.jar.pack.ConstantPool.Entry;
+import com.sun.java.util.jar.pack.ConstantPool.Index;
+import com.sun.java.util.jar.pack.ConstantPool.IndexGroup;
+import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.NumberEntry;
+import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
+import com.sun.java.util.jar.pack.ConstantPool.StringEntry;
import com.sun.java.util.jar.pack.Package.Class;
import com.sun.java.util.jar.pack.Package.File;
import com.sun.java.util.jar.pack.Package.InnerClass;
-import com.sun.java.util.jar.pack.ConstantPool.*;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
/**
* Writer for a package file.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -26,10 +26,27 @@
package com.sun.java.util.jar.pack;
import com.sun.java.util.jar.pack.Attribute.Layout;
-import java.util.*;
-import java.util.jar.*;
-import java.io.*;
import java.beans.PropertyChangeListener;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TimeZone;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.Pack200;
/*
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PopulationCoding.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PopulationCoding.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,8 +25,12 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.HashSet;
/**
* Population-based coding.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,13 +25,24 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
-import java.util.jar.*;
-import java.util.jar.Pack200;
-import java.util.zip.*;
-import java.io.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.jar.Pack200;
/**
* Control block for publishing Pack200 options to the other classes.
*/
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,11 +25,25 @@
package com.sun.java.util.jar.pack;
-import java.util.*;
-import java.util.jar.*;
-import java.util.zip.*;
-import java.io.*;
import java.beans.PropertyChangeListener;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.SortedMap;
+import java.util.TimeZone;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Pack200;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.ZipEntry;
/*
* Implementation of the Pack provider.
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,18 +25,27 @@
package com.sun.java.util.jar.pack;
-import com.sun.java.util.jar.pack.Attribute.Layout;
import com.sun.java.util.jar.pack.ConstantPool.ClassEntry;
import com.sun.java.util.jar.pack.ConstantPool.DescriptorEntry;
import com.sun.java.util.jar.pack.ConstantPool.LiteralEntry;
import com.sun.java.util.jar.pack.ConstantPool.MemberEntry;
import com.sun.java.util.jar.pack.ConstantPool.SignatureEntry;
import com.sun.java.util.jar.pack.ConstantPool.Utf8Entry;
-import java.util.*;
-import java.util.jar.*;
-import java.util.zip.*;
-import java.io.*;
-
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
import sun.util.logging.PlatformLogger;
class Utils {
--- a/jdk/src/share/classes/com/sun/jndi/ldap/BasicControl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/BasicControl.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -113,6 +113,6 @@
* ASN.1 BER encoded value.
*/
public byte[] getEncodedValue() {
- return value;
+ return value == null ? null : value.clone();
}
}
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Filter.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Filter.java Tue Dec 07 13:29:20 2010 +0000
@@ -427,7 +427,10 @@
}
} else {
// descriptor
- if (filter[i] != '-' &&
+ // The underscore ("_") character is not allowed by
+ // the LDAP specification. We allow it here to
+ // tolerate the incorrect use in practice.
+ if (filter[i] != '-' && filter[i] != '_' &&
!(filter[i] >= '0' && filter[i] <= '9') &&
!(filter[i] >= 'A' && filter[i] <= 'Z') &&
!(filter[i] >= 'a' && filter[i] <= 'z')) {
@@ -467,7 +470,10 @@
break;
}
- if (filter[i] != '-' &&
+ // The underscore ("_") character is not allowed by
+ // the LDAP specification. We allow it here to
+ // tolerate the incorrect use in practice.
+ if (filter[i] != '-' && filter[i] != '_' &&
!(filter[i] >= '0' && filter[i] <= '9') &&
!(filter[i] >= 'A' && filter[i] <= 'Z') &&
!(filter[i] >= 'a' && filter[i] <= 'z')) {
@@ -515,7 +521,10 @@
}
} else {
// descriptor
- if (filter[j] != '-' &&
+ // The underscore ("_") character is not allowed by
+ // the LDAP specification. We allow it here to
+ // tolerate the incorrect use in practice.
+ if (filter[j] != '-' && filter[j] != '_' &&
!(filter[j] >= '0' && filter[j] <= '9') &&
!(filter[j] >= 'A' && filter[j] <= 'Z') &&
!(filter[j] >= 'a' && filter[j] <= 'z')) {
--- a/jdk/src/share/classes/com/sun/security/auth/module/NTSystem.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/security/auth/module/NTSystem.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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,6 @@
package com.sun.security.auth.module;
-import javax.security.auth.login.LoginException;
-
/**
* <p> This class implementation retrieves and makes available NT
* security information for the current user.
@@ -124,7 +122,7 @@
* @return the group SIDs for the current NT user.
*/
public String[] getGroupIDs() {
- return groupIDs;
+ return groupIDs == null ? null : groupIDs.clone();
}
/**
--- a/jdk/src/share/classes/com/sun/security/auth/module/SolarisSystem.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/security/auth/module/SolarisSystem.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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,9 +25,6 @@
package com.sun.security.auth.module;
-import javax.security.auth.*;
-import javax.security.auth.login.*;
-
/**
* <p> This class implementation retrieves and makes available Solaris
* UID/GID/groups information for the current user.
@@ -92,6 +89,6 @@
* @return the supplementary groups for the current Solaris user.
*/
public long[] getGroups() {
- return groups;
+ return groups == null ? null : groups.clone();
}
}
--- a/jdk/src/share/classes/com/sun/security/auth/module/UnixSystem.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/com/sun/security/auth/module/UnixSystem.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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,9 +25,6 @@
package com.sun.security.auth.module;
-import javax.security.auth.*;
-import javax.security.auth.login.*;
-
/**
* <p> This class implementation retrieves and makes available Unix
* UID/GID/groups information for the current user.
@@ -92,6 +89,6 @@
* @return the supplementary groups for the current Unix user.
*/
public long[] getGroups() {
- return groups;
+ return groups == null ? null : groups.clone();
}
}
--- a/jdk/src/share/classes/java/awt/Component.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/awt/Component.java Tue Dec 07 13:29:20 2010 +0000
@@ -2154,6 +2154,7 @@
*
* @param d the dimension specifying the new size
* of this component
+ * @throws NullPointerException if {@code d} is {@code null}
* @see #setSize
* @see #setBounds
* @see #invalidate
@@ -2351,6 +2352,7 @@
* invalidates the component hierarchy.
*
* @param r the new bounding rectangle for this component
+ * @throws NullPointerException if {@code r} is {@code null}
* @see #getBounds
* @see #setLocation(int, int)
* @see #setLocation(Point)
@@ -4545,6 +4547,7 @@
* where the point's <i>x</i> and <i>y</i> coordinates are defined
* to be relative to the coordinate system of this component.
* @param p the point
+ * @throws NullPointerException if {@code p} is {@code null}
* @see #getComponentAt(Point)
* @since JDK1.1
*/
@@ -5879,7 +5882,7 @@
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
- *
+ * @throws NullPointerException if {@code listenerType} is {@code null}
* @see #getComponentListeners
* @see #getFocusListeners
* @see #getHierarchyListeners
@@ -8038,6 +8041,7 @@
* Prints a listing of this component to the specified output
* stream.
* @param out a print stream
+ * @throws NullPointerException if {@code out} is {@code null}
* @since JDK1.0
*/
public void list(PrintStream out) {
@@ -8050,6 +8054,7 @@
* @param out a print stream
* @param indent number of spaces to indent
* @see java.io.PrintStream#println(java.lang.Object)
+ * @throws NullPointerException if {@code out} is {@code null}
* @since JDK1.0
*/
public void list(PrintStream out, int indent) {
@@ -8062,6 +8067,7 @@
/**
* Prints a listing to the specified print writer.
* @param out the print writer to print to
+ * @throws NullPointerException if {@code out} is {@code null}
* @since JDK1.1
*/
public void list(PrintWriter out) {
@@ -8073,6 +8079,7 @@
* the specified print writer.
* @param out the print writer to print to
* @param indent the number of spaces to indent
+ * @throws NullPointerException if {@code out} is {@code null}
* @see java.io.PrintStream#println(java.lang.Object)
* @since JDK1.1
*/
--- a/jdk/src/share/classes/java/awt/Container.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/awt/Container.java Tue Dec 07 13:29:20 2010 +0000
@@ -1231,6 +1231,7 @@
* reflect the changes.
*
* @param comp the component to be removed
+ * @throws NullPointerException if {@code comp} is {@code null}
* @see #add
* @see #invalidate
* @see #validate
@@ -2154,6 +2155,7 @@
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
+ * @exception NullPointerException if {@code listenerType} is {@code null}
*
* @see #getContainerListeners
*
@@ -2705,6 +2707,7 @@
* If there is no child component at the requested point and the
* point is within the bounds of the container the container itself
* is returned.
+ * @throws NullPointerException if {@code p} is {@code null}
* @see Component#contains
* @see #getComponentAt
* @since 1.2
@@ -2969,6 +2972,7 @@
*
* @param out a print stream
* @param indent the number of spaces to indent
+ * @throws NullPointerException if {@code out} is {@code null}
* @see Component#list(java.io.PrintStream, int)
* @since JDK1.0
*/
@@ -2995,6 +2999,7 @@
*
* @param out a print writer
* @param indent the number of spaces to indent
+ * @throws NullPointerException if {@code out} is {@code null}
* @see Component#list(java.io.PrintWriter, int)
* @since JDK1.1
*/
--- a/jdk/src/share/classes/java/awt/ScrollPane.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/awt/ScrollPane.java Tue Dec 07 13:29:20 2010 +0000
@@ -377,6 +377,7 @@
* This is a convenience method which interfaces with the Adjustable
* objects which represent the state of the scrollbars.
* @param p the Point representing the position to scroll to
+ * @throws NullPointerException if {@code p} is {@code null}
*/
public void setScrollPosition(Point p) {
setScrollPosition(p.x, p.y);
--- a/jdk/src/share/classes/java/awt/Window.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/awt/Window.java Tue Dec 07 13:29:20 2010 +0000
@@ -1888,6 +1888,7 @@
* @exception ClassCastException if <code>listenerType</code>
* doesn't specify a class or interface that implements
* <code>java.util.EventListener</code>
+ * @exception NullPointerException if {@code listenerType} is {@code null}
*
* @see #getWindowListeners
* @since 1.3
--- a/jdk/src/share/classes/java/io/FileOutputStream.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java Tue Dec 07 13:29:20 2010 +0000
@@ -56,7 +56,15 @@
*/
private final FileDescriptor fd;
- private FileChannel channel= null;
+ /**
+ * True if the file is opened for append.
+ */
+ private final boolean append;
+
+ /**
+ * The associated channel, initalized lazily.
+ */
+ private FileChannel channel;
private final Object closeLock = new Object();
private volatile boolean closed = false;
@@ -196,7 +204,9 @@
if (name == null) {
throw new NullPointerException();
}
- fd = new FileDescriptor();
+ this.fd = new FileDescriptor();
+ this.append = append;
+
fd.incrementAndGetUseCount();
open(name, append);
}
@@ -232,7 +242,8 @@
if (security != null) {
security.checkWrite(fdObj);
}
- fd = fdObj;
+ this.fd = fdObj;
+ this.append = false;
/*
* FileDescriptor is being shared by streams.
@@ -251,22 +262,36 @@
throws FileNotFoundException;
/**
+ * Writes the specified byte to this file output stream.
+ *
+ * @param b the byte to be written.
+ * @param append {@code true} if the write operation first
+ * advances the position to the end of file
+ */
+ private native void write(int b, boolean append) throws IOException;
+
+ /**
* Writes the specified byte to this file output stream. Implements
* the <code>write</code> method of <code>OutputStream</code>.
*
* @param b the byte to be written.
* @exception IOException if an I/O error occurs.
*/
- public native void write(int b) throws IOException;
+ public void write(int b) throws IOException {
+ write(b, append);
+ }
/**
* Writes a sub array as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
+ * @param append {@code true} to first advance the position to the
+ * end of file
* @exception IOException If an I/O error has occurred.
*/
- private native void writeBytes(byte b[], int off, int len) throws IOException;
+ private native void writeBytes(byte b[], int off, int len, boolean append)
+ throws IOException;
/**
* Writes <code>b.length</code> bytes from the specified byte array
@@ -276,7 +301,7 @@
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[]) throws IOException {
- writeBytes(b, 0, b.length);
+ writeBytes(b, 0, b.length, append);
}
/**
@@ -289,7 +314,7 @@
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
- writeBytes(b, off, len);
+ writeBytes(b, off, len, append);
}
/**
@@ -372,7 +397,7 @@
public FileChannel getChannel() {
synchronized (this) {
if (channel == null) {
- channel = FileChannelImpl.open(fd, false, true, this);
+ channel = FileChannelImpl.open(fd, false, true, append, this);
/*
* Increment fd's use count. Invoking the channel's close()
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java Tue Dec 07 13:29:20 2010 +0000
@@ -3498,8 +3498,8 @@
return ((int[]) array).clone();
} else if (array instanceof long[]) {
return ((long[]) array).clone();
- } else if (array instanceof double[]) {
- return ((double[]) array).clone();
+ } else if (array instanceof short[]) {
+ return ((short[]) array).clone();
} else {
throw new AssertionError();
}
--- a/jdk/src/share/classes/java/lang/Double.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/lang/Double.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2010, 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
@@ -973,7 +973,8 @@
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
- long thisBits = Double.doubleToLongBits(d1);
+ // Cannot use doubleToRawLongBits because of possibility of NaNs.
+ long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
--- a/jdk/src/share/classes/java/lang/Float.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/lang/Float.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2010, 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
@@ -872,12 +872,13 @@
* @since 1.4
*/
public static int compare(float f1, float f2) {
- if (f1 < f2)
+ if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger
- int thisBits = Float.floatToIntBits(f1);
+ // Cannot use floatToRawIntBits because of possibility of NaNs.
+ int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
--- a/jdk/src/share/classes/java/lang/ProcessBuilder.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java Tue Dec 07 13:29:20 2010 +0000
@@ -537,7 +537,11 @@
*/
public File file() { return null; }
- FileOutputStream toFileOutputStream() throws IOException {
+ /**
+ * When redirected to a destination file, indicates if the output
+ * is to be written to the end of the file.
+ */
+ boolean append() {
throw new UnsupportedOperationException();
}
@@ -588,9 +592,7 @@
public String toString() {
return "redirect to write to file \"" + file + "\"";
}
- FileOutputStream toFileOutputStream() throws IOException {
- return new FileOutputStream(file, false);
- }
+ boolean append() { return false; }
};
}
@@ -620,9 +622,7 @@
public String toString() {
return "redirect to append to file \"" + file + "\"";
}
- FileOutputStream toFileOutputStream() throws IOException {
- return new FileOutputStream(file, true);
- }
+ boolean append() { return true; }
};
}
--- a/jdk/src/share/classes/java/lang/StrictMath.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/lang/StrictMath.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -801,8 +801,9 @@
return (a >= b) ? a : b;
}
- private static long negativeZeroFloatBits = Float.floatToIntBits(-0.0f);
- private static long negativeZeroDoubleBits = Double.doubleToLongBits(-0.0d);
+ // Use raw bit-wise conversions on guaranteed non-NaN arguments.
+ private static long negativeZeroFloatBits = Float.floatToRawIntBits(-0.0f);
+ private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
/**
* Returns the greater of two {@code float} values. That is,
@@ -819,9 +820,12 @@
* @return the larger of {@code a} and {@code b}.
*/
public static float max(float a, float b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0f) && (b == 0.0f)
- && (Float.floatToIntBits(a) == negativeZeroFloatBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0f) &&
+ (b == 0.0f) &&
+ (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a >= b) ? a : b;
@@ -842,9 +846,12 @@
* @return the larger of {@code a} and {@code b}.
*/
public static double max(double a, double b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0d) && (b == 0.0d)
- && (Double.doubleToLongBits(a) == negativeZeroDoubleBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0d) &&
+ (b == 0.0d) &&
+ (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a >= b) ? a : b;
@@ -893,9 +900,12 @@
* @return the smaller of {@code a} and {@code b.}
*/
public static float min(float a, float b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0f) && (b == 0.0f)
- && (Float.floatToIntBits(b) == negativeZeroFloatBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0f) &&
+ (b == 0.0f) &&
+ (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a <= b) ? a : b;
@@ -916,9 +926,12 @@
* @return the smaller of {@code a} and {@code b}.
*/
public static double min(double a, double b) {
- if (a != a) return a; // a is NaN
- if ((a == 0.0d) && (b == 0.0d)
- && (Double.doubleToLongBits(b) == negativeZeroDoubleBits)) {
+ if (a != a)
+ return a; // a is NaN
+ if ((a == 0.0d) &&
+ (b == 0.0d) &&
+ (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
+ // Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a <= b) ? a : b;
--- a/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java Tue Dec 07 13:29:20 2010 +0000
@@ -110,7 +110,8 @@
* state of the {@link ByteBuffer}, or the sequence of buffers, for the I/O
* operation is not defined. Buffers should be discarded or at least care must
* be taken to ensure that the buffers are not accessed while the channel remains
- * open.
+ * open. All methods that accept timeout parameters treat values less than or
+ * equal to zero to mean that the I/O operation does not timeout.
*
* @since 1.7
*/
@@ -367,7 +368,7 @@
* @param dst
* The buffer into which bytes are to be transferred
* @param timeout
- * The timeout, or {@code 0L} for no timeout
+ * The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
@@ -376,8 +377,7 @@
* The handler for consuming the result
*
* @throws IllegalArgumentException
- * If the {@code timeout} parameter is negative or the buffer is
- * read-only
+ * If the buffer is read-only
* @throws ReadPendingException
* If a read operation is already in progress on this channel
* @throws NotYetConnectedException
@@ -471,7 +471,7 @@
* The maximum number of buffers to be accessed; must be non-negative
* and no larger than {@code dsts.length - offset}
* @param timeout
- * The timeout, or {@code 0L} for no timeout
+ * The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
@@ -483,8 +483,7 @@
* If the pre-conditions for the {@code offset} and {@code length}
* parameter aren't met
* @throws IllegalArgumentException
- * If the {@code timeout} parameter is negative, or a buffer is
- * read-only
+ * If the buffer is read-only
* @throws ReadPendingException
* If a read operation is already in progress on this channel
* @throws NotYetConnectedException
@@ -524,7 +523,7 @@
* @param src
* The buffer from which bytes are to be retrieved
* @param timeout
- * The timeout, or {@code 0L} for no timeout
+ * The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
@@ -532,8 +531,6 @@
* @param handler
* The handler for consuming the result
*
- * @throws IllegalArgumentException
- * If the {@code timeout} parameter is negative
* @throws WritePendingException
* If a write operation is already in progress on this channel
* @throws NotYetConnectedException
@@ -623,7 +620,7 @@
* The maximum number of buffers to be accessed; must be non-negative
* and no larger than {@code srcs.length - offset}
* @param timeout
- * The timeout, or {@code 0L} for no timeout
+ * The maximum time for the I/O operation to complete
* @param unit
* The time unit of the {@code timeout} argument
* @param attachment
@@ -634,8 +631,6 @@
* @throws IndexOutOfBoundsException
* If the pre-conditions for the {@code offset} and {@code length}
* parameter aren't met
- * @throws IllegalArgumentException
- * If the {@code timeout} parameter is negative
* @throws WritePendingException
* If a write operation is already in progress on this channel
* @throws NotYetConnectedException
--- a/jdk/src/share/classes/java/security/Timestamp.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/security/Timestamp.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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,9 +26,11 @@
package java.security;
import java.io.Serializable;
+import java.security.cert.Certificate;
import java.security.cert.CertPath;
import java.security.cert.X509Extension;
import java.util.Date;
+import java.util.List;
/**
* This class encapsulates information about a signed timestamp.
@@ -142,7 +144,12 @@
StringBuffer sb = new StringBuffer();
sb.append("(");
sb.append("timestamp: " + timestamp);
- sb.append("TSA: " + signerCertPath.getCertificates().get(0));
+ List<? extends Certificate> certs = signerCertPath.getCertificates();
+ if (!certs.isEmpty()) {
+ sb.append("TSA: " + certs.get(0));
+ } else {
+ sb.append("TSA: <empty>");
+ }
sb.append(")");
return sb.toString();
}
--- a/jdk/src/share/classes/java/util/AbstractCollection.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/AbstractCollection.java Tue Dec 07 13:29:20 2010 +0000
@@ -96,14 +96,14 @@
* @throws NullPointerException {@inheritDoc}
*/
public boolean contains(Object o) {
- Iterator<E> e = iterator();
+ Iterator<E> it = iterator();
if (o==null) {
- while (e.hasNext())
- if (e.next()==null)
+ while (it.hasNext())
+ if (it.next()==null)
return true;
} else {
- while (e.hasNext())
- if (o.equals(e.next()))
+ while (it.hasNext())
+ if (o.equals(it.next()))
return true;
}
return false;
@@ -269,18 +269,18 @@
* @throws NullPointerException {@inheritDoc}
*/
public boolean remove(Object o) {
- Iterator<E> e = iterator();
+ Iterator<E> it = iterator();
if (o==null) {
- while (e.hasNext()) {
- if (e.next()==null) {
- e.remove();
+ while (it.hasNext()) {
+ if (it.next()==null) {
+ it.remove();
return true;
}
}
} else {
- while (e.hasNext()) {
- if (o.equals(e.next())) {
- e.remove();
+ while (it.hasNext()) {
+ if (o.equals(it.next())) {
+ it.remove();
return true;
}
}
@@ -304,9 +304,8 @@
* @see #contains(Object)
*/
public boolean containsAll(Collection<?> c) {
- Iterator<?> e = c.iterator();
- while (e.hasNext())
- if (!contains(e.next()))
+ for (Object e : c)
+ if (!contains(e))
return false;
return true;
}
@@ -331,11 +330,9 @@
*/
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
- Iterator<? extends E> e = c.iterator();
- while (e.hasNext()) {
- if (add(e.next()))
+ for (E e : c)
+ if (add(e))
modified = true;
- }
return modified;
}
@@ -362,10 +359,10 @@
*/
public boolean removeAll(Collection<?> c) {
boolean modified = false;
- Iterator<?> e = iterator();
- while (e.hasNext()) {
- if (c.contains(e.next())) {
- e.remove();
+ Iterator<?> it = iterator();
+ while (it.hasNext()) {
+ if (c.contains(it.next())) {
+ it.remove();
modified = true;
}
}
@@ -395,10 +392,10 @@
*/
public boolean retainAll(Collection<?> c) {
boolean modified = false;
- Iterator<E> e = iterator();
- while (e.hasNext()) {
- if (!c.contains(e.next())) {
- e.remove();
+ Iterator<E> it = iterator();
+ while (it.hasNext()) {
+ if (!c.contains(it.next())) {
+ it.remove();
modified = true;
}
}
@@ -421,10 +418,10 @@
* @throws UnsupportedOperationException {@inheritDoc}
*/
public void clear() {
- Iterator<E> e = iterator();
- while (e.hasNext()) {
- e.next();
- e.remove();
+ Iterator<E> it = iterator();
+ while (it.hasNext()) {
+ it.next();
+ it.remove();
}
}
@@ -442,18 +439,18 @@
* @return a string representation of this collection
*/
public String toString() {
- Iterator<E> i = iterator();
- if (! i.hasNext())
+ Iterator<E> it = iterator();
+ if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
- E e = i.next();
+ E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
- if (! i.hasNext())
+ if (! it.hasNext())
return sb.append(']').toString();
- sb.append(", ");
+ sb.append(',').append(' ');
}
}
--- a/jdk/src/share/classes/java/util/AbstractList.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/AbstractList.java Tue Dec 07 13:29:20 2010 +0000
@@ -175,15 +175,15 @@
* @throws NullPointerException {@inheritDoc}
*/
public int indexOf(Object o) {
- ListIterator<E> e = listIterator();
+ ListIterator<E> it = listIterator();
if (o==null) {
- while (e.hasNext())
- if (e.next()==null)
- return e.previousIndex();
+ while (it.hasNext())
+ if (it.next()==null)
+ return it.previousIndex();
} else {
- while (e.hasNext())
- if (o.equals(e.next()))
- return e.previousIndex();
+ while (it.hasNext())
+ if (o.equals(it.next()))
+ return it.previousIndex();
}
return -1;
}
@@ -200,15 +200,15 @@
* @throws NullPointerException {@inheritDoc}
*/
public int lastIndexOf(Object o) {
- ListIterator<E> e = listIterator(size());
+ ListIterator<E> it = listIterator(size());
if (o==null) {
- while (e.hasPrevious())
- if (e.previous()==null)
- return e.nextIndex();
+ while (it.hasPrevious())
+ if (it.previous()==null)
+ return it.nextIndex();
} else {
- while (e.hasPrevious())
- if (o.equals(e.previous()))
- return e.nextIndex();
+ while (it.hasPrevious())
+ if (o.equals(it.previous()))
+ return it.nextIndex();
}
return -1;
}
@@ -517,7 +517,7 @@
ListIterator<E> e1 = listIterator();
ListIterator e2 = ((List) o).listIterator();
- while(e1.hasNext() && e2.hasNext()) {
+ while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
--- a/jdk/src/share/classes/java/util/AbstractMap.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/AbstractMap.java Tue Dec 07 13:29:20 2010 +0000
@@ -523,7 +523,7 @@
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
- sb.append(", ");
+ sb.append(',').append(' ');
}
}
--- a/jdk/src/share/classes/java/util/ArrayList.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/ArrayList.java Tue Dec 07 13:29:20 2010 +0000
@@ -120,9 +120,9 @@
/**
* Constructs an empty list with the specified initial capacity.
*
- * @param initialCapacity the initial capacity of the list
- * @exception IllegalArgumentException if the specified initial capacity
- * is negative
+ * @param initialCapacity the initial capacity of the list
+ * @throws IllegalArgumentException if the specified initial capacity
+ * is negative
*/
public ArrayList(int initialCapacity) {
super();
@@ -173,7 +173,7 @@
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
- * @param minCapacity the desired minimum capacity
+ * @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
if (minCapacity > 0)
--- a/jdk/src/share/classes/java/util/Collections.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/Collections.java Tue Dec 07 13:29:20 2010 +0000
@@ -124,7 +124,7 @@
*
* <p>The implementation takes equal advantage of ascending and
* descending order in its input array, and can take advantage of
- * ascending and descending order in different parts of the the same
+ * ascending and descending order in different parts of the same
* input array. It is well-suited to merging two or more sorted arrays:
* simply concatenate the arrays and sort the resulting array.
*
@@ -184,7 +184,7 @@
*
* <p>The implementation takes equal advantage of ascending and
* descending order in its input array, and can take advantage of
- * ascending and descending order in different parts of the the same
+ * ascending and descending order in different parts of the same
* input array. It is well-suited to merging two or more sorted arrays:
* simply concatenate the arrays and sort the resulting array.
*
@@ -823,7 +823,7 @@
i -= size;
displaced = list.set(i, displaced);
nMoved ++;
- } while(i != cycleStart);
+ } while (i != cycleStart);
}
}
@@ -1452,9 +1452,9 @@
* when o is a Map.Entry, and calls o.setValue.
*/
public boolean containsAll(Collection<?> coll) {
- Iterator<?> e = coll.iterator();
- while (e.hasNext())
- if (!contains(e.next())) // Invokes safe contains() above
+ Iterator<?> it = coll.iterator();
+ while (it.hasNext())
+ if (!contains(it.next())) // Invokes safe contains() above
return false;
return true;
}
@@ -1482,12 +1482,12 @@
UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;}
- public K getKey() {return e.getKey();}
- public V getValue() {return e.getValue();}
+ public K getKey() {return e.getKey();}
+ public V getValue() {return e.getValue();}
public V setValue(V value) {
throw new UnsupportedOperationException();
}
- public int hashCode() {return e.hashCode();}
+ public int hashCode() {return e.hashCode();}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
@@ -1495,7 +1495,7 @@
return eq(e.getKey(), t.getKey()) &&
eq(e.getValue(), t.getValue());
}
- public String toString() {return e.toString();}
+ public String toString() {return e.toString();}
}
}
}
@@ -1562,7 +1562,7 @@
* <pre>
* Collection c = Collections.synchronizedCollection(myCollection);
* ...
- * synchronized(c) {
+ * synchronized (c) {
* Iterator i = c.iterator(); // Must be in the synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -1611,19 +1611,19 @@
}
public int size() {
- synchronized(mutex) {return c.size();}
+ synchronized (mutex) {return c.size();}
}
public boolean isEmpty() {
- synchronized(mutex) {return c.isEmpty();}
+ synchronized (mutex) {return c.isEmpty();}
}
public boolean contains(Object o) {
- synchronized(mutex) {return c.contains(o);}
+ synchronized (mutex) {return c.contains(o);}
}
public Object[] toArray() {
- synchronized(mutex) {return c.toArray();}
+ synchronized (mutex) {return c.toArray();}
}
public <T> T[] toArray(T[] a) {
- synchronized(mutex) {return c.toArray(a);}
+ synchronized (mutex) {return c.toArray(a);}
}
public Iterator<E> iterator() {
@@ -1631,32 +1631,32 @@
}
public boolean add(E e) {
- synchronized(mutex) {return c.add(e);}
+ synchronized (mutex) {return c.add(e);}
}
public boolean remove(Object o) {
- synchronized(mutex) {return c.remove(o);}
+ synchronized (mutex) {return c.remove(o);}
}
public boolean containsAll(Collection<?> coll) {
- synchronized(mutex) {return c.containsAll(coll);}
+ synchronized (mutex) {return c.containsAll(coll);}
}
public boolean addAll(Collection<? extends E> coll) {
- synchronized(mutex) {return c.addAll(coll);}
+ synchronized (mutex) {return c.addAll(coll);}
}
public boolean removeAll(Collection<?> coll) {
- synchronized(mutex) {return c.removeAll(coll);}
+ synchronized (mutex) {return c.removeAll(coll);}
}
public boolean retainAll(Collection<?> coll) {
- synchronized(mutex) {return c.retainAll(coll);}
+ synchronized (mutex) {return c.retainAll(coll);}
}
public void clear() {
- synchronized(mutex) {c.clear();}
+ synchronized (mutex) {c.clear();}
}
public String toString() {
- synchronized(mutex) {return c.toString();}
+ synchronized (mutex) {return c.toString();}
}
private void writeObject(ObjectOutputStream s) throws IOException {
- synchronized(mutex) {s.defaultWriteObject();}
+ synchronized (mutex) {s.defaultWriteObject();}
}
}
@@ -1671,7 +1671,7 @@
* <pre>
* Set s = Collections.synchronizedSet(new HashSet());
* ...
- * synchronized(s) {
+ * synchronized (s) {
* Iterator i = s.iterator(); // Must be in the synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -1709,10 +1709,10 @@
}
public boolean equals(Object o) {
- synchronized(mutex) {return c.equals(o);}
+ synchronized (mutex) {return c.equals(o);}
}
public int hashCode() {
- synchronized(mutex) {return c.hashCode();}
+ synchronized (mutex) {return c.hashCode();}
}
}
@@ -1728,7 +1728,7 @@
* <pre>
* SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
* ...
- * synchronized(s) {
+ * synchronized (s) {
* Iterator i = s.iterator(); // Must be in the synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -1739,7 +1739,7 @@
* SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
* SortedSet s2 = s.headSet(foo);
* ...
- * synchronized(s) { // Note: s, not s2!!!
+ * synchronized (s) { // Note: s, not s2!!!
* Iterator i = s2.iterator(); // Must be in the synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -1766,7 +1766,7 @@
{
private static final long serialVersionUID = 8695801310862127406L;
- final private SortedSet<E> ss;
+ private final SortedSet<E> ss;
SynchronizedSortedSet(SortedSet<E> s) {
super(s);
@@ -1778,31 +1778,31 @@
}
public Comparator<? super E> comparator() {
- synchronized(mutex) {return ss.comparator();}
+ synchronized (mutex) {return ss.comparator();}
}
public SortedSet<E> subSet(E fromElement, E toElement) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedSortedSet<E>(
ss.subSet(fromElement, toElement), mutex);
}
}
public SortedSet<E> headSet(E toElement) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedSortedSet<E>(ss.headSet(toElement), mutex);
}
}
public SortedSet<E> tailSet(E fromElement) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedSortedSet<E>(ss.tailSet(fromElement),mutex);
}
}
public E first() {
- synchronized(mutex) {return ss.first();}
+ synchronized (mutex) {return ss.first();}
}
public E last() {
- synchronized(mutex) {return ss.last();}
+ synchronized (mutex) {return ss.last();}
}
}
@@ -1817,7 +1817,7 @@
* <pre>
* List list = Collections.synchronizedList(new ArrayList());
* ...
- * synchronized(list) {
+ * synchronized (list) {
* Iterator i = list.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -1863,34 +1863,34 @@
}
public boolean equals(Object o) {
- synchronized(mutex) {return list.equals(o);}
+ synchronized (mutex) {return list.equals(o);}
}
public int hashCode() {
- synchronized(mutex) {return list.hashCode();}
+ synchronized (mutex) {return list.hashCode();}
}
public E get(int index) {
- synchronized(mutex) {return list.get(index);}
+ synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
- synchronized(mutex) {return list.set(index, element);}
+ synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
- synchronized(mutex) {list.add(index, element);}
+ synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
- synchronized(mutex) {return list.remove(index);}
+ synchronized (mutex) {return list.remove(index);}
}
public int indexOf(Object o) {
- synchronized(mutex) {return list.indexOf(o);}
+ synchronized (mutex) {return list.indexOf(o);}
}
public int lastIndexOf(Object o) {
- synchronized(mutex) {return list.lastIndexOf(o);}
+ synchronized (mutex) {return list.lastIndexOf(o);}
}
public boolean addAll(int index, Collection<? extends E> c) {
- synchronized(mutex) {return list.addAll(index, c);}
+ synchronized (mutex) {return list.addAll(index, c);}
}
public ListIterator<E> listIterator() {
@@ -1902,7 +1902,7 @@
}
public List<E> subList(int fromIndex, int toIndex) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedList<E>(list.subList(fromIndex, toIndex),
mutex);
}
@@ -1943,7 +1943,7 @@
}
public List<E> subList(int fromIndex, int toIndex) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedRandomAccessList<E>(
list.subList(fromIndex, toIndex), mutex);
}
@@ -1975,7 +1975,7 @@
* ...
* Set s = m.keySet(); // Needn't be in synchronized block
* ...
- * synchronized(m) { // Synchronizing on m, not s!
+ * synchronized (m) { // Synchronizing on m, not s!
* Iterator i = s.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -2016,32 +2016,32 @@
}
public int size() {
- synchronized(mutex) {return m.size();}
+ synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
- synchronized(mutex) {return m.isEmpty();}
+ synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
- synchronized(mutex) {return m.containsKey(key);}
+ synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
- synchronized(mutex) {return m.containsValue(value);}
+ synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
- synchronized(mutex) {return m.get(key);}
+ synchronized (mutex) {return m.get(key);}
}
public V put(K key, V value) {
- synchronized(mutex) {return m.put(key, value);}
+ synchronized (mutex) {return m.put(key, value);}
}
public V remove(Object key) {
- synchronized(mutex) {return m.remove(key);}
+ synchronized (mutex) {return m.remove(key);}
}
public void putAll(Map<? extends K, ? extends V> map) {
- synchronized(mutex) {m.putAll(map);}
+ synchronized (mutex) {m.putAll(map);}
}
public void clear() {
- synchronized(mutex) {m.clear();}
+ synchronized (mutex) {m.clear();}
}
private transient Set<K> keySet = null;
@@ -2049,7 +2049,7 @@
private transient Collection<V> values = null;
public Set<K> keySet() {
- synchronized(mutex) {
+ synchronized (mutex) {
if (keySet==null)
keySet = new SynchronizedSet<K>(m.keySet(), mutex);
return keySet;
@@ -2057,7 +2057,7 @@
}
public Set<Map.Entry<K,V>> entrySet() {
- synchronized(mutex) {
+ synchronized (mutex) {
if (entrySet==null)
entrySet = new SynchronizedSet<Map.Entry<K,V>>(m.entrySet(), mutex);
return entrySet;
@@ -2065,7 +2065,7 @@
}
public Collection<V> values() {
- synchronized(mutex) {
+ synchronized (mutex) {
if (values==null)
values = new SynchronizedCollection<V>(m.values(), mutex);
return values;
@@ -2073,16 +2073,16 @@
}
public boolean equals(Object o) {
- synchronized(mutex) {return m.equals(o);}
+ synchronized (mutex) {return m.equals(o);}
}
public int hashCode() {
- synchronized(mutex) {return m.hashCode();}
+ synchronized (mutex) {return m.hashCode();}
}
public String toString() {
- synchronized(mutex) {return m.toString();}
+ synchronized (mutex) {return m.toString();}
}
private void writeObject(ObjectOutputStream s) throws IOException {
- synchronized(mutex) {s.defaultWriteObject();}
+ synchronized (mutex) {s.defaultWriteObject();}
}
}
@@ -2101,7 +2101,7 @@
* ...
* Set s = m.keySet(); // Needn't be in synchronized block
* ...
- * synchronized(m) { // Synchronizing on m, not s!
+ * synchronized (m) { // Synchronizing on m, not s!
* Iterator i = s.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -2114,7 +2114,7 @@
* ...
* Set s2 = m2.keySet(); // Needn't be in synchronized block
* ...
- * synchronized(m) { // Synchronizing on m, not m2 or s2!
+ * synchronized (m) { // Synchronizing on m, not m2 or s2!
* Iterator i = s.iterator(); // Must be in synchronized block
* while (i.hasNext())
* foo(i.next());
@@ -2154,31 +2154,31 @@
}
public Comparator<? super K> comparator() {
- synchronized(mutex) {return sm.comparator();}
+ synchronized (mutex) {return sm.comparator();}
}
public SortedMap<K,V> subMap(K fromKey, K toKey) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedSortedMap<K,V>(
sm.subMap(fromKey, toKey), mutex);
}
}
public SortedMap<K,V> headMap(K toKey) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedSortedMap<K,V>(sm.headMap(toKey), mutex);
}
}
public SortedMap<K,V> tailMap(K fromKey) {
- synchronized(mutex) {
+ synchronized (mutex) {
return new SynchronizedSortedMap<K,V>(sm.tailMap(fromKey),mutex);
}
}
public K firstKey() {
- synchronized(mutex) {return sm.firstKey();}
+ synchronized (mutex) {return sm.firstKey();}
}
public K lastKey() {
- synchronized(mutex) {return sm.lastKey();}
+ synchronized (mutex) {return sm.lastKey();}
}
}
@@ -3317,7 +3317,7 @@
{
private static final long serialVersionUID = 3193687207550431679L;
- final private E element;
+ private final E element;
SingletonSet(E e) {element = e;}
@@ -3448,7 +3448,7 @@
* @param o the element to appear repeatedly in the returned list.
* @return an immutable list consisting of <tt>n</tt> copies of the
* specified object.
- * @throws IllegalArgumentException if n < 0.
+ * @throws IllegalArgumentException if {@code n < 0}
* @see List#addAll(Collection)
* @see List#addAll(int, Collection)
*/
--- a/jdk/src/share/classes/java/util/ComparableTimSort.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/ComparableTimSort.java Tue Dec 07 13:29:20 2010 +0000
@@ -207,7 +207,7 @@
* @param lo the index of the first element in the range to be sorted
* @param hi the index after the last element in the range to be sorted
* @param start the index of the first element in the range that is
- * not already known to be sorted (@code lo <= start <= hi}
+ * not already known to be sorted ({@code lo <= start <= hi})
*/
@SuppressWarnings("fallthrough")
private static void binarySort(Object[] a, int lo, int hi, int start) {
@@ -245,7 +245,7 @@
*/
int n = start - left; // The number of elements to move
// Switch is just an optimization for arraycopy in default case
- switch(n) {
+ switch (n) {
case 2: a[left + 2] = a[left + 1];
case 1: a[left + 1] = a[left];
break;
@@ -275,7 +275,7 @@
* @param a the array in which a run is to be counted and possibly reversed
* @param lo index of the first element in the run
* @param hi index after the last element that may be contained in the run.
- It is required that @code{lo < hi}.
+ It is required that {@code lo < hi}.
* @return the length of the run beginning at the specified position in
* the specified array
*/
@@ -288,7 +288,7 @@
// Find end of run, and reverse range if descending
if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending
- while(runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0)
+ while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0)
runHi++;
reverseRange(a, lo, runHi);
} else { // Ascending
--- a/jdk/src/share/classes/java/util/Random.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/Random.java Tue Dec 07 13:29:20 2010 +0000
@@ -77,9 +77,9 @@
*/
private final AtomicLong seed;
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
/**
* Creates a new random number generator. This constructor sets
@@ -285,7 +285,7 @@
* @return the next pseudorandom, uniformly distributed {@code int}
* value between {@code 0} (inclusive) and {@code n} (exclusive)
* from this random number generator's sequence
- * @exception IllegalArgumentException if n is not positive
+ * @throws IllegalArgumentException if n is not positive
* @since 1.2
*/
--- a/jdk/src/share/classes/java/util/Stack.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/Stack.java Tue Dec 07 13:29:20 2010 +0000
@@ -73,9 +73,9 @@
* Removes the object at the top of this stack and returns that
* object as the value of this function.
*
- * @return The object at the top of this stack (the last item
- * of the <tt>Vector</tt> object).
- * @exception EmptyStackException if this stack is empty.
+ * @return The object at the top of this stack (the last item
+ * of the <tt>Vector</tt> object).
+ * @throws EmptyStackException if this stack is empty.
*/
public synchronized E pop() {
E obj;
@@ -91,9 +91,9 @@
* Looks at the object at the top of this stack without removing it
* from the stack.
*
- * @return the object at the top of this stack (the last item
- * of the <tt>Vector</tt> object).
- * @exception EmptyStackException if this stack is empty.
+ * @return the object at the top of this stack (the last item
+ * of the <tt>Vector</tt> object).
+ * @throws EmptyStackException if this stack is empty.
*/
public synchronized E peek() {
int len = size();
--- a/jdk/src/share/classes/java/util/TimSort.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/TimSort.java Tue Dec 07 13:29:20 2010 +0000
@@ -239,7 +239,7 @@
* @param lo the index of the first element in the range to be sorted
* @param hi the index after the last element in the range to be sorted
* @param start the index of the first element in the range that is
- * not already known to be sorted (@code lo <= start <= hi}
+ * not already known to be sorted ({@code lo <= start <= hi})
* @param c comparator to used for the sort
*/
@SuppressWarnings("fallthrough")
@@ -278,7 +278,7 @@
*/
int n = start - left; // The number of elements to move
// Switch is just an optimization for arraycopy in default case
- switch(n) {
+ switch (n) {
case 2: a[left + 2] = a[left + 1];
case 1: a[left + 1] = a[left];
break;
@@ -308,7 +308,7 @@
* @param a the array in which a run is to be counted and possibly reversed
* @param lo index of the first element in the run
* @param hi index after the last element that may be contained in the run.
- It is required that @code{lo < hi}.
+ It is required that {@code lo < hi}.
* @param c the comparator to used for the sort
* @return the length of the run beginning at the specified position in
* the specified array
@@ -322,7 +322,7 @@
// Find end of run, and reverse range if descending
if (c.compare(a[runHi++], a[lo]) < 0) { // Descending
- while(runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
+ while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
runHi++;
reverseRange(a, lo, runHi);
} else { // Ascending
--- a/jdk/src/share/classes/java/util/TreeMap.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/TreeMap.java Tue Dec 07 13:29:20 2010 +0000
@@ -1056,11 +1056,11 @@
public Comparator<? super E> comparator() { return m.comparator(); }
public E pollFirst() {
Map.Entry<E,Object> e = m.pollFirstEntry();
- return e == null? null : e.getKey();
+ return (e == null) ? null : e.getKey();
}
public E pollLast() {
Map.Entry<E,Object> e = m.pollLastEntry();
- return e == null? null : e.getKey();
+ return (e == null) ? null : e.getKey();
}
public boolean remove(Object o) {
int oldSize = size();
@@ -1196,7 +1196,7 @@
* Test two values for equality. Differs from o1.equals(o2) only in
* that it copes with {@code null} o1 properly.
*/
- final static boolean valEquals(Object o1, Object o2) {
+ static final boolean valEquals(Object o1, Object o2) {
return (o1==null ? o2==null : o1.equals(o2));
}
@@ -1204,7 +1204,7 @@
* Return SimpleImmutableEntry for entry, or null if null
*/
static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
- return e == null? null :
+ return (e == null) ? null :
new AbstractMap.SimpleImmutableEntry<K,V>(e);
}
@@ -1212,7 +1212,7 @@
* Return key for entry, or null if null
*/
static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
- return e == null? null : e.key;
+ return (e == null) ? null : e.key;
}
/**
@@ -1237,7 +1237,7 @@
/**
* @serial include
*/
- static abstract class NavigableSubMap<K,V> extends AbstractMap<K,V>
+ abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
implements NavigableMap<K,V>, java.io.Serializable {
/**
* The backing map.
@@ -1412,11 +1412,11 @@
}
public final V get(Object key) {
- return !inRange(key)? null : m.get(key);
+ return !inRange(key) ? null : m.get(key);
}
public final V remove(Object key) {
- return !inRange(key)? null : m.remove(key);
+ return !inRange(key) ? null : m.remove(key);
}
public final Map.Entry<K,V> ceilingEntry(K key) {
@@ -1559,7 +1559,8 @@
if (!inRange(key))
return false;
TreeMap.Entry<K,V> node = m.getEntry(key);
- if (node!=null && valEquals(node.getValue(),entry.getValue())){
+ if (node!=null && valEquals(node.getValue(),
+ entry.getValue())) {
m.deleteEntry(node);
return true;
}
@@ -1724,7 +1725,7 @@
false, toKey, inclusive);
}
- public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive){
+ public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
if (!inRange(fromKey, inclusive))
throw new IllegalArgumentException("fromKey out of range");
return new AscendingSubMap(m,
@@ -1805,7 +1806,7 @@
toEnd, hi, hiInclusive);
}
- public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive){
+ public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
if (!inRange(fromKey, inclusive))
throw new IllegalArgumentException("fromKey out of range");
return new DescendingSubMap(m,
@@ -2143,7 +2144,7 @@
// If strictly internal, copy successor's element to p and then make p
// point to successor.
if (p.left != null && p.right != null) {
- Entry<K,V> s = successor (p);
+ Entry<K,V> s = successor(p);
p.key = s.key;
p.value = s.value;
p = s;
--- a/jdk/src/share/classes/java/util/TreeSet.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/TreeSet.java Tue Dec 07 13:29:20 2010 +0000
@@ -452,7 +452,7 @@
*/
public E pollFirst() {
Map.Entry<E,?> e = m.pollFirstEntry();
- return (e == null)? null : e.getKey();
+ return (e == null) ? null : e.getKey();
}
/**
@@ -460,7 +460,7 @@
*/
public E pollLast() {
Map.Entry<E,?> e = m.pollLastEntry();
- return (e == null)? null : e.getKey();
+ return (e == null) ? null : e.getKey();
}
/**
--- a/jdk/src/share/classes/java/util/Vector.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/Vector.java Tue Dec 07 13:29:20 2010 +0000
@@ -919,7 +919,7 @@
* elements (optional), or if the specified collection is null
* @since 1.2
*/
- public synchronized boolean retainAll(Collection<?> c) {
+ public synchronized boolean retainAll(Collection<?> c) {
return super.retainAll(c);
}
--- a/jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java Tue Dec 07 13:29:20 2010 +0000
@@ -51,20 +51,20 @@
* <p> <b>Extension example</b>. Here is a sketch of a class
* that customizes {@link ThreadPoolExecutor} to use
* a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
- * <pre>
+ * <pre> {@code
* public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
*
- * static class CustomTask<V> implements RunnableFuture<V> {...}
+ * static class CustomTask<V> implements RunnableFuture<V> {...}
*
- * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
- * return new CustomTask<V>(c);
+ * protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
+ * return new CustomTask<V>(c);
* }
- * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
- * return new CustomTask<V>(r, v);
+ * protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
+ * return new CustomTask<V>(r, v);
* }
* // ... add constructors, etc.
- * }
- * </pre>
+ * }}</pre>
+ *
* @since 1.5
* @author Doug Lea
*/
@@ -106,7 +106,7 @@
*/
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
- RunnableFuture<Object> ftask = newTaskFor(task, null);
+ RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
@@ -158,7 +158,7 @@
// Record exceptions so that if we fail to obtain any
// result, we can throw the last exception we got.
ExecutionException ee = null;
- long lastTime = (timed)? System.nanoTime() : 0;
+ long lastTime = timed ? System.nanoTime() : 0;
Iterator<? extends Callable<T>> it = tasks.iterator();
// Start one task for sure; the rest incrementally
@@ -191,8 +191,6 @@
--active;
try {
return f.get();
- } catch (InterruptedException ie) {
- throw ie;
} catch (ExecutionException eex) {
ee = eex;
} catch (RuntimeException rex) {
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Dec 07 13:29:20 2010 +0000
@@ -1270,7 +1270,7 @@
* for each key-value mapping, followed by a null pair.
* The key-value mappings are emitted in no particular order.
*/
- private void writeObject(java.io.ObjectOutputStream s) throws IOException {
+ private void writeObject(java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
for (int k = 0; k < segments.length; ++k) {
@@ -1298,7 +1298,7 @@
* @param s the stream
*/
private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
+ throws IOException, ClassNotFoundException {
s.defaultReadObject();
// Initialize each segment to be minimally sized, and let grow.
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Dec 07 13:29:20 2010 +0000
@@ -38,7 +38,6 @@
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.ConcurrentModificationException;
import java.util.Deque;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -212,7 +211,7 @@
* The actual representation we use is that p.next == p means to
* goto the first node (which in turn is reached by following prev
* pointers from head), and p.next == null && p.prev == p means
- * that the iteration is at an end and that p is a (final static)
+ * that the iteration is at an end and that p is a (static final)
* dummy node, NEXT_TERMINATOR, and not the last active node.
* Finishing the iteration when encountering such a TERMINATOR is
* good enough for read-only traversals, so such traversals can use
@@ -271,7 +270,7 @@
*/
private transient volatile Node<E> tail;
- private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
+ private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
static {
PREV_TERMINATOR = new Node<Object>(null);
@@ -401,7 +400,7 @@
}
}
- private final static int HOPS = 2;
+ private static final int HOPS = 2;
/**
* Unlinks non-null node x.
@@ -871,7 +870,7 @@
/**
* Inserts the specified element at the front of this deque.
*
- * @throws NullPointerException {@inheritDoc}
+ * @throws NullPointerException if the specified element is null
*/
public void addFirst(E e) {
linkFirst(e);
@@ -882,7 +881,7 @@
*
* <p>This method is equivalent to {@link #add}.
*
- * @throws NullPointerException {@inheritDoc}
+ * @throws NullPointerException if the specified element is null
*/
public void addLast(E e) {
linkLast(e);
@@ -892,7 +891,7 @@
* Inserts the specified element at the front of this deque.
*
* @return {@code true} always
- * @throws NullPointerException {@inheritDoc}
+ * @throws NullPointerException if the specified element is null
*/
public boolean offerFirst(E e) {
linkFirst(e);
@@ -905,7 +904,7 @@
* <p>This method is equivalent to {@link #add}.
*
* @return {@code true} always
- * @throws NullPointerException {@inheritDoc}
+ * @throws NullPointerException if the specified element is null
*/
public boolean offerLast(E e) {
linkLast(e);
@@ -940,7 +939,7 @@
/**
* @throws NoSuchElementException {@inheritDoc}
*/
- public E getLast() {
+ public E getLast() {
return screenNullResult(peekLast());
}
@@ -1016,7 +1015,7 @@
*
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
- * @throws NullPointerException if the specified element is {@code null}
+ * @throws NullPointerException if the specified element is null
*/
public boolean removeFirstOccurrence(Object o) {
checkNotNull(o);
@@ -1037,7 +1036,7 @@
*
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
- * @throws NullPointerException if the specified element is {@code null}
+ * @throws NullPointerException if the specified element is null
*/
public boolean removeLastOccurrence(Object o) {
checkNotNull(o);
@@ -1110,7 +1109,7 @@
*
* @param o element to be removed from this deque, if present
* @return {@code true} if the deque contained the specified element
- * @throws NullPointerException if the specified element is {@code null}
+ * @throws NullPointerException if the specified element is null
*/
public boolean remove(Object o) {
return removeFirstOccurrence(o);
@@ -1165,7 +1164,7 @@
beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
if (p.casNext(null, beginningOfTheEnd)) {
// Successful CAS is the linearization point
- // for all elements to be added to this queue.
+ // for all elements to be added to this deque.
if (!casTail(t, last)) {
// Try a little harder to update tail,
// since we may be adding many elements.
@@ -1251,12 +1250,12 @@
* Returns an iterator over the elements in this deque in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+ * <p>The returned iterator is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*
* @return an iterator over the elements in this deque in proper sequence
*/
@@ -1269,12 +1268,12 @@
* sequential order. The elements will be returned in order from
* last (tail) to first (head).
*
- * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+ * <p>The returned iterator is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*
* @return an iterator over the elements in this deque in reverse order
*/
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Dec 07 13:29:20 2010 +0000
@@ -65,8 +65,8 @@
* <p>Iterators are <i>weakly consistent</i>, returning elements
* reflecting the state of the queue at some point at or since the
* creation of the iterator. They do <em>not</em> throw {@link
- * ConcurrentModificationException}, and may proceed concurrently with
- * other operations. Elements contained in the queue since the creation
+ * java.util.ConcurrentModificationException}, and may proceed concurrently
+ * with other operations. Elements contained in the queue since the creation
* of the iterator will be returned exactly once.
*
* <p>Beware that, unlike in most collections, the {@code size} method
@@ -634,12 +634,12 @@
* Returns an iterator over the elements in this queue in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
*
- * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+ * <p>The returned iterator is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*
* @return an iterator over the elements in this queue in proper sequence
*/
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Tue Dec 07 13:29:20 2010 +0000
@@ -362,12 +362,12 @@
public E pollFirst() {
Map.Entry<E,Object> e = m.pollFirstEntry();
- return e == null? null : e.getKey();
+ return (e == null) ? null : e.getKey();
}
public E pollLast() {
Map.Entry<E,Object> e = m.pollLastEntry();
- return e == null? null : e.getKey();
+ return (e == null) ? null : e.getKey();
}
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Tue Dec 07 13:29:20 2010 +0000
@@ -547,7 +547,7 @@
* @param fromIndex index of first element to be removed
* @param toIndex index after last element to be removed
* @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
- * (@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
+ * ({@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
*/
private void removeRange(int fromIndex, int toIndex) {
final ReentrantLock lock = this.lock;
@@ -989,7 +989,7 @@
}
private static class COWIterator<E> implements ListIterator<E> {
- /** Snapshot of the array **/
+ /** Snapshot of the array */
private final Object[] snapshot;
/** Index of element to be returned by subsequent call to next. */
private int cursor;
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Tue Dec 07 13:29:20 2010 +0000
@@ -59,24 +59,23 @@
* copy-on-write set to maintain a set of Handler objects that
* perform some action upon state updates.
*
- * <pre>
+ * <pre> {@code
* class Handler { void handle(); ... }
*
* class X {
- * private final CopyOnWriteArraySet<Handler> handlers
- * = new CopyOnWriteArraySet<Handler>();
- * public void addHandler(Handler h) { handlers.add(h); }
+ * private final CopyOnWriteArraySet<Handler> handlers
+ * = new CopyOnWriteArraySet<Handler>();
+ * public void addHandler(Handler h) { handlers.add(h); }
*
- * private long internalState;
- * private synchronized void changeState() { internalState = ...; }
+ * private long internalState;
+ * private synchronized void changeState() { internalState = ...; }
*
- * public void update() {
- * changeState();
- * for (Handler handler : handlers)
- * handler.handle();
- * }
- * }
- * </pre>
+ * public void update() {
+ * changeState();
+ * for (Handler handler : handlers)
+ * handler.handle();
+ * }
+ * }}</pre>
*
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
--- a/jdk/src/share/classes/java/util/concurrent/CountDownLatch.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/CountDownLatch.java Tue Dec 07 13:29:20 2010 +0000
@@ -175,7 +175,7 @@
}
protected int tryAcquireShared(int acquires) {
- return getState() == 0? 1 : -1;
+ return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
--- a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java Tue Dec 07 13:29:20 2010 +0000
@@ -482,12 +482,14 @@
/**
* Returns an iterator over all the elements (both expired and
* unexpired) in this queue. The iterator does not return the
- * elements in any particular order. The returned
- * <tt>Iterator</tt> is a "weakly consistent" iterator that will
- * never throw {@link ConcurrentModificationException}, and
- * guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed
- * to) reflect any modifications subsequent to construction.
+ * elements in any particular order.
+ *
+ * <p>The returned iterator is a "weakly consistent" iterator that
+ * will never throw {@link java.util.ConcurrentModificationException
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*
* @return an iterator over the elements in this queue
*/
--- a/jdk/src/share/classes/java/util/concurrent/Exchanger.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/Exchanger.java Tue Dec 07 13:29:20 2010 +0000
@@ -355,7 +355,9 @@
else if (y == null && // Try to occupy
slot.compareAndSet(null, me)) {
if (index == 0) // Blocking wait for slot 0
- return timed? awaitNanos(me, slot, nanos): await(me, slot);
+ return timed ?
+ awaitNanos(me, slot, nanos) :
+ await(me, slot);
Object v = spinWait(me, slot); // Spin wait for non-0
if (v != CANCEL)
return v;
@@ -597,8 +599,8 @@
* dormant until one of two things happens:
* <ul>
* <li>Some other thread enters the exchange; or
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current
- * thread.
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread.
* </ul>
* <p>If the current thread:
* <ul>
@@ -616,7 +618,7 @@
*/
public V exchange(V x) throws InterruptedException {
if (!Thread.interrupted()) {
- Object v = doExchange(x == null? NULL_ITEM : x, false, 0);
+ Object v = doExchange((x == null) ? NULL_ITEM : x, false, 0);
if (v == NULL_ITEM)
return null;
if (v != CANCEL)
@@ -671,7 +673,7 @@
public V exchange(V x, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
if (!Thread.interrupted()) {
- Object v = doExchange(x == null? NULL_ITEM : x,
+ Object v = doExchange((x == null) ? NULL_ITEM : x,
true, unit.toNanos(timeout));
if (v == NULL_ITEM)
return null;
--- a/jdk/src/share/classes/java/util/concurrent/Executor.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/Executor.java Tue Dec 07 13:29:20 2010 +0000
@@ -79,37 +79,37 @@
* serializes the submission of tasks to a second executor,
* illustrating a composite executor.
*
- * <pre>
+ * <pre> {@code
* class SerialExecutor implements Executor {
- * final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
- * final Executor executor;
- * Runnable active;
+ * final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
+ * final Executor executor;
+ * Runnable active;
*
- * SerialExecutor(Executor executor) {
- * this.executor = executor;
- * }
+ * SerialExecutor(Executor executor) {
+ * this.executor = executor;
+ * }
*
- * public synchronized void execute(final Runnable r) {
- * tasks.offer(new Runnable() {
- * public void run() {
- * try {
- * r.run();
- * } finally {
- * scheduleNext();
- * }
- * }
- * });
- * if (active == null) {
- * scheduleNext();
+ * public synchronized void execute(final Runnable r) {
+ * tasks.offer(new Runnable() {
+ * public void run() {
+ * try {
+ * r.run();
+ * } finally {
+ * scheduleNext();
* }
+ * }
+ * });
+ * if (active == null) {
+ * scheduleNext();
* }
+ * }
*
- * protected synchronized void scheduleNext() {
- * if ((active = tasks.poll()) != null) {
- * executor.execute(active);
- * }
+ * protected synchronized void scheduleNext() {
+ * if ((active = tasks.poll()) != null) {
+ * executor.execute(active);
* }
- * }</pre>
+ * }
+ * }}</pre>
*
* The <tt>Executor</tt> implementations provided in this package
* implement {@link ExecutorService}, which is a more extensive
--- a/jdk/src/share/classes/java/util/concurrent/ExecutorCompletionService.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ExecutorCompletionService.java Tue Dec 07 13:29:20 2010 +0000
@@ -197,7 +197,8 @@
return completionQueue.poll();
}
- public Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException {
+ public Future<V> poll(long timeout, TimeUnit unit)
+ throws InterruptedException {
return completionQueue.poll(timeout, unit);
}
--- a/jdk/src/share/classes/java/util/concurrent/Executors.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/Executors.java Tue Dec 07 13:29:20 2010 +0000
@@ -83,7 +83,7 @@
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
- * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>
+ * @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
@@ -108,7 +108,7 @@
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
* @throws NullPointerException if threadFactory is null
- * @throws IllegalArgumentException if <tt>nThreads <= 0</tt>
+ * @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
@@ -242,7 +242,7 @@
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle.
* @return a newly created scheduled thread pool
- * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt>
+ * @throws IllegalArgumentException if {@code corePoolSize < 0}
*/
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
@@ -256,7 +256,7 @@
* @param threadFactory the factory to use when the executor
* creates a new thread.
* @return a newly created scheduled thread pool
- * @throws IllegalArgumentException if <tt>corePoolSize < 0</tt>
+ * @throws IllegalArgumentException if {@code corePoolSize < 0}
* @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newScheduledThreadPool(
@@ -562,8 +562,8 @@
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
- group = (s != null)? s.getThreadGroup() :
- Thread.currentThread().getThreadGroup();
+ group = (s != null) ? s.getThreadGroup() :
+ Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
@@ -669,7 +669,7 @@
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
- protected void finalize() {
+ protected void finalize() {
super.shutdown();
}
}
--- a/jdk/src/share/classes/java/util/concurrent/Future.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/Future.java Tue Dec 07 13:29:20 2010 +0000
@@ -47,21 +47,21 @@
* computation has completed, the computation cannot be cancelled.
* If you would like to use a <tt>Future</tt> for the sake
* of cancellability but not provide a usable result, you can
- * declare types of the form <tt>Future<?></tt> and
+ * declare types of the form {@code Future<?>} and
* return <tt>null</tt> as a result of the underlying task.
*
* <p>
* <b>Sample Usage</b> (Note that the following classes are all
* made-up.) <p>
- * <pre>
+ * <pre> {@code
* interface ArchiveSearcher { String search(String target); }
* class App {
* ExecutorService executor = ...
* ArchiveSearcher searcher = ...
* void showSearch(final String target)
* throws InterruptedException {
- * Future<String> future
- * = executor.submit(new Callable<String>() {
+ * Future<String> future
+ * = executor.submit(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
@@ -70,20 +70,18 @@
* displayText(future.get()); // use future
* } catch (ExecutionException ex) { cleanup(); return; }
* }
- * }
- * </pre>
+ * }}</pre>
*
* The {@link FutureTask} class is an implementation of <tt>Future</tt> that
* implements <tt>Runnable</tt>, and so may be executed by an <tt>Executor</tt>.
* For example, the above construction with <tt>submit</tt> could be replaced by:
- * <pre>
- * FutureTask<String> future =
- * new FutureTask<String>(new Callable<String>() {
+ * <pre> {@code
+ * FutureTask<String> future =
+ * new FutureTask<String>(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
- * executor.execute(future);
- * </pre>
+ * executor.execute(future);}</pre>
*
* <p>Memory consistency effects: Actions taken by the asynchronous computation
* <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
--- a/jdk/src/share/classes/java/util/concurrent/FutureTask.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/FutureTask.java Tue Dec 07 13:29:20 2010 +0000
@@ -85,7 +85,7 @@
* @param result the result to return on successful completion. If
* you don't need a particular result, consider using
* constructions of the form:
- * <tt>Future<?> f = new FutureTask<Object>(runnable, null)</tt>
+ * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
* @throws NullPointerException if runnable is null
*/
public FutureTask(Runnable runnable, V result) {
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Tue Dec 07 13:29:20 2010 +0000
@@ -1004,12 +1004,13 @@
/**
* Returns an iterator over the elements in this deque in proper sequence.
* The elements will be returned in order from first (head) to last (tail).
- * The returned {@code Iterator} is a "weakly consistent" iterator that
+ *
+ * <p>The returned iterator is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*
* @return an iterator over the elements in this deque in proper sequence
*/
@@ -1021,12 +1022,13 @@
* Returns an iterator over the elements in this deque in reverse
* sequential order. The elements will be returned in order from
* last (tail) to first (head).
- * The returned {@code Iterator} is a "weakly consistent" iterator that
+ *
+ * <p>The returned iterator is a "weakly consistent" iterator that
* will never throw {@link java.util.ConcurrentModificationException
- * ConcurrentModificationException},
- * and guarantees to traverse elements as they existed upon
- * construction of the iterator, and may (but is not guaranteed to)
- * reflect any modifications subsequent to construction.
+ * ConcurrentModificationException}, and guarantees to traverse
+ * elements as they existed upon construction of the iterator, and
+ * may (but is not guaranteed to) reflect any modifications
+ * subsequent to construction.
*/
public Iterator<E> descendingIterator() {
return new DescendingItr();
--- a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Dec 07 13:29:20 2010 +0000
@@ -159,7 +159,9 @@
protected abstract void compute();
/**
- * Always returns null.
+ * Always returns {@code null}.
+ *
+ * @return {@code null} always
*/
public final Void getRawResult() { return null; }
--- a/jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Tue Dec 07 13:29:20 2010 +0000
@@ -72,24 +72,23 @@
* Here is a class with a method that sets up a ScheduledExecutorService
* to beep every ten seconds for an hour:
*
- * <pre>
+ * <pre> {@code
* import static java.util.concurrent.TimeUnit.*;
* class BeeperControl {
- * private final ScheduledExecutorService scheduler =
- * Executors.newScheduledThreadPool(1);
+ * private final ScheduledExecutorService scheduler =
+ * Executors.newScheduledThreadPool(1);
*
- * public void beepForAnHour() {
- * final Runnable beeper = new Runnable() {
- * public void run() { System.out.println("beep"); }
- * };
- * final ScheduledFuture<?> beeperHandle =
- * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
- * scheduler.schedule(new Runnable() {
- * public void run() { beeperHandle.cancel(true); }
- * }, 60 * 60, SECONDS);
- * }
- * }
- * </pre>
+ * public void beepForAnHour() {
+ * final Runnable beeper = new Runnable() {
+ * public void run() { System.out.println("beep"); }
+ * };
+ * final ScheduledFuture<?> beeperHandle =
+ * scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
+ * scheduler.schedule(new Runnable() {
+ * public void run() { beeperHandle.cancel(true); }
+ * }, 60 * 60, SECONDS);
+ * }
+ * }}</pre>
*
* @since 1.5
* @author Doug Lea
--- a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Tue Dec 07 13:29:20 2010 +0000
@@ -62,8 +62,8 @@
* time of cancellation.
*
* <p>Successive executions of a task scheduled via
- * <code>scheduleAtFixedRate</code> or
- * <code>scheduleWithFixedDelay</code> do not overlap. While different
+ * {@code scheduleAtFixedRate} or
+ * {@code scheduleWithFixedDelay} do not overlap. While different
* executions may be performed by different threads, the effects of
* prior executions <a
* href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
@@ -436,7 +436,7 @@
* @throws NullPointerException if {@code threadFactory} is null
*/
public ScheduledThreadPoolExecutor(int corePoolSize,
- ThreadFactory threadFactory) {
+ ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
@@ -453,7 +453,7 @@
* @throws NullPointerException if {@code handler} is null
*/
public ScheduledThreadPoolExecutor(int corePoolSize,
- RejectedExecutionHandler handler) {
+ RejectedExecutionHandler handler) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), handler);
}
@@ -473,8 +473,8 @@
* {@code handler} is null
*/
public ScheduledThreadPoolExecutor(int corePoolSize,
- ThreadFactory threadFactory,
- RejectedExecutionHandler handler) {
+ ThreadFactory threadFactory,
+ RejectedExecutionHandler handler) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory, handler);
}
--- a/jdk/src/share/classes/java/util/concurrent/Semaphore.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/Semaphore.java Tue Dec 07 13:29:20 2010 +0000
@@ -223,7 +223,7 @@
/**
* NonFair version
*/
- final static class NonfairSync extends Sync {
+ static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;
NonfairSync(int permits) {
@@ -238,7 +238,7 @@
/**
* Fair version
*/
- final static class FairSync extends Sync {
+ static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L;
FairSync(int permits) {
@@ -282,7 +282,7 @@
* else {@code false}
*/
public Semaphore(int permits, boolean fair) {
- sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
+ sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
/**
--- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Tue Dec 07 13:29:20 2010 +0000
@@ -63,9 +63,9 @@
*/
public class ThreadLocalRandom extends Random {
// same constants as Random, but must be redeclared because private
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
/**
* The random seed. We can't use super.seed.
--- a/jdk/src/share/classes/java/util/concurrent/TimeUnit.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/TimeUnit.java Tue Dec 07 13:29:20 2010 +0000
@@ -53,12 +53,12 @@
* java.util.concurrent.locks.Lock lock} is not available:
*
* <pre> Lock lock = ...;
- * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
+ * if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...
* </pre>
* while this code will timeout in 50 seconds:
* <pre>
* Lock lock = ...;
- * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
+ * if (lock.tryLock(50L, TimeUnit.SECONDS)) ...
* </pre>
*
* Note however, that there is no guarantee that a particular timeout
@@ -291,7 +291,8 @@
abstract int excessNanos(long d, long m);
/**
- * Performs a timed <tt>Object.wait</tt> using this time unit.
+ * Performs a timed {@link Object#wait(long, int) Object.wait}
+ * using this time unit.
* This is a convenience method that converts timeout arguments
* into the form required by the <tt>Object.wait</tt> method.
*
@@ -299,21 +300,22 @@
* method (see {@link BlockingQueue#poll BlockingQueue.poll})
* using:
*
- * <pre> public synchronized Object poll(long timeout, TimeUnit unit) throws InterruptedException {
- * while (empty) {
- * unit.timedWait(this, timeout);
- * ...
- * }
- * }</pre>
+ * <pre> {@code
+ * public synchronized Object poll(long timeout, TimeUnit unit)
+ * throws InterruptedException {
+ * while (empty) {
+ * unit.timedWait(this, timeout);
+ * ...
+ * }
+ * }}</pre>
*
* @param obj the object to wait on
* @param timeout the maximum time to wait. If less than
* or equal to zero, do not wait at all.
- * @throws InterruptedException if interrupted while waiting.
- * @see Object#wait(long, int)
+ * @throws InterruptedException if interrupted while waiting
*/
public void timedWait(Object obj, long timeout)
- throws InterruptedException {
+ throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
@@ -322,17 +324,18 @@
}
/**
- * Performs a timed <tt>Thread.join</tt> using this time unit.
+ * Performs a timed {@link Thread#join(long, int) Thread.join}
+ * using this time unit.
* This is a convenience method that converts time arguments into the
* form required by the <tt>Thread.join</tt> method.
+ *
* @param thread the thread to wait for
* @param timeout the maximum time to wait. If less than
* or equal to zero, do not wait at all.
- * @throws InterruptedException if interrupted while waiting.
- * @see Thread#join(long, int)
+ * @throws InterruptedException if interrupted while waiting
*/
public void timedJoin(Thread thread, long timeout)
- throws InterruptedException {
+ throws InterruptedException {
if (timeout > 0) {
long ms = toMillis(timeout);
int ns = excessNanos(timeout, ms);
@@ -341,13 +344,14 @@
}
/**
- * Performs a <tt>Thread.sleep</tt> using this unit.
+ * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
+ * this time unit.
* This is a convenience method that converts time arguments into the
* form required by the <tt>Thread.sleep</tt> method.
+ *
* @param timeout the minimum time to sleep. If less than
* or equal to zero, do not sleep at all.
- * @throws InterruptedException if interrupted while sleeping.
- * @see Thread#sleep
+ * @throws InterruptedException if interrupted while sleeping
*/
public void sleep(long timeout) throws InterruptedException {
if (timeout > 0) {
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Tue Dec 07 13:29:20 2010 +0000
@@ -55,7 +55,7 @@
* @author Doug Lea
* @param <T> The type of the object holding the updatable field
*/
-public abstract class AtomicIntegerFieldUpdater<T> {
+public abstract class AtomicIntegerFieldUpdater<T> {
/**
* Creates and returns an updater for objects with the given field.
* The Class argument is needed to check that reflective types and
@@ -279,7 +279,7 @@
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- } catch(Exception ex) {
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Tue Dec 07 13:29:20 2010 +0000
@@ -55,7 +55,7 @@
* @author Doug Lea
* @param <T> The type of the object holding the updatable field
*/
-public abstract class AtomicLongFieldUpdater<T> {
+public abstract class AtomicLongFieldUpdater<T> {
/**
* Creates and returns an updater for objects with the given field.
* The Class argument is needed to check that reflective types and
@@ -278,7 +278,7 @@
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- } catch(Exception ex) {
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -331,7 +331,7 @@
if (cclass.isInstance(obj)) {
return;
}
- throw new RuntimeException (
+ throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
@@ -361,7 +361,7 @@
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
- } catch(Exception ex) {
+ } catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -387,7 +387,7 @@
public boolean compareAndSet(T obj, long expect, long update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
- synchronized(this) {
+ synchronized (this) {
long v = unsafe.getLong(obj, offset);
if (v != expect)
return false;
@@ -402,7 +402,7 @@
public void set(T obj, long newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
- synchronized(this) {
+ synchronized (this) {
unsafe.putLong(obj, offset, newValue);
}
}
@@ -413,7 +413,7 @@
public long get(T obj) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
- synchronized(this) {
+ synchronized (this) {
return unsafe.getLong(obj, offset);
}
}
@@ -422,7 +422,7 @@
if (cclass.isInstance(obj)) {
return;
}
- throw new RuntimeException (
+ throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Dec 07 13:29:20 2010 +0000
@@ -45,13 +45,13 @@
* independently subject to atomic updates. For example, a tree node
* might be declared as
*
- * <pre>
+ * <pre> {@code
* class Node {
* private volatile Node left, right;
*
- * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
+ * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
* AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
- * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
+ * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
* AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
*
* Node getLeft() { return left; }
@@ -59,8 +59,7 @@
* return leftUpdater.compareAndSet(this, expect, update);
* }
* // ... and so on
- * }
- * </pre>
+ * }}</pre>
*
* <p>Note that the guarantees of the {@code compareAndSet}
* method in this class are weaker than in other atomic classes.
@@ -74,7 +73,7 @@
* @param <T> The type of the object holding the updatable field
* @param <V> The type of the field
*/
-public abstract class AtomicReferenceFieldUpdater<T, V> {
+public abstract class AtomicReferenceFieldUpdater<T, V> {
/**
* Creates and returns an updater for objects with the given field.
@@ -291,7 +290,7 @@
if (cclass.isInstance(obj)) {
return;
}
- throw new RuntimeException (
+ throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Tue Dec 07 13:29:20 2010 +0000
@@ -990,7 +990,8 @@
* can represent anything you like.
* @throws InterruptedException if the current thread is interrupted
*/
- public final void acquireInterruptibly(long arg) throws InterruptedException {
+ public final void acquireInterruptibly(long arg)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
@@ -1014,7 +1015,8 @@
* @return {@code true} if acquired; {@code false} if timed out
* @throws InterruptedException if the current thread is interrupted
*/
- public final boolean tryAcquireNanos(long arg, long nanosTimeout) throws InterruptedException {
+ public final boolean tryAcquireNanos(long arg, long nanosTimeout)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
@@ -1070,7 +1072,8 @@
* you like.
* @throws InterruptedException if the current thread is interrupted
*/
- public final void acquireSharedInterruptibly(long arg) throws InterruptedException {
+ public final void acquireSharedInterruptibly(long arg)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
@@ -1093,7 +1096,8 @@
* @return {@code true} if acquired; {@code false} if timed out
* @throws InterruptedException if the current thread is interrupted
*/
- public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout) throws InterruptedException {
+ public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquireShared(arg) >= 0 ||
@@ -1841,7 +1845,8 @@
* <li> If interrupted while blocked in step 4, throw InterruptedException.
* </ol>
*/
- public final long awaitNanos(long nanosTimeout) throws InterruptedException {
+ public final long awaitNanos(long nanosTimeout)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
@@ -1885,7 +1890,8 @@
* <li> If timed out while blocked in step 4, return false, else true.
* </ol>
*/
- public final boolean awaitUntil(Date deadline) throws InterruptedException {
+ public final boolean awaitUntil(Date deadline)
+ throws InterruptedException {
if (deadline == null)
throw new NullPointerException();
long abstime = deadline.getTime();
@@ -1928,7 +1934,8 @@
* <li> If timed out while blocked in step 4, return false, else true.
* </ol>
*/
- public final boolean await(long time, TimeUnit unit) throws InterruptedException {
+ public final boolean await(long time, TimeUnit unit)
+ throws InterruptedException {
if (unit == null)
throw new NullPointerException();
long nanosTimeout = unit.toNanos(time);
@@ -2084,7 +2091,7 @@
/**
* CAS waitStatus field of a node.
*/
- private final static boolean compareAndSetWaitStatus(Node node,
+ private static final boolean compareAndSetWaitStatus(Node node,
int expect,
int update) {
return unsafe.compareAndSwapInt(node, waitStatusOffset,
@@ -2094,7 +2101,7 @@
/**
* CAS next field of a node.
*/
- private final static boolean compareAndSetNext(Node node,
+ private static final boolean compareAndSetNext(Node node,
Node expect,
Node update) {
return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Dec 07 13:29:20 2010 +0000
@@ -265,7 +265,7 @@
* boolean isSignalled() { return getState() != 0; }
*
* protected int tryAcquireShared(int ignore) {
- * return isSignalled()? 1 : -1;
+ * return isSignalled() ? 1 : -1;
* }
*
* protected boolean tryReleaseShared(int ignore) {
@@ -1213,7 +1213,8 @@
* can represent anything you like.
* @throws InterruptedException if the current thread is interrupted
*/
- public final void acquireInterruptibly(int arg) throws InterruptedException {
+ public final void acquireInterruptibly(int arg)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
@@ -1237,7 +1238,8 @@
* @return {@code true} if acquired; {@code false} if timed out
* @throws InterruptedException if the current thread is interrupted
*/
- public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException {
+ public final boolean tryAcquireNanos(int arg, long nanosTimeout)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
@@ -1293,7 +1295,8 @@
* you like.
* @throws InterruptedException if the current thread is interrupted
*/
- public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
+ public final void acquireSharedInterruptibly(int arg)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
@@ -1316,7 +1319,8 @@
* @return {@code true} if acquired; {@code false} if timed out
* @throws InterruptedException if the current thread is interrupted
*/
- public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException {
+ public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquireShared(arg) >= 0 ||
@@ -2062,7 +2066,8 @@
* <li> If interrupted while blocked in step 4, throw InterruptedException.
* </ol>
*/
- public final long awaitNanos(long nanosTimeout) throws InterruptedException {
+ public final long awaitNanos(long nanosTimeout)
+ throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
@@ -2106,7 +2111,8 @@
* <li> If timed out while blocked in step 4, return false, else true.
* </ol>
*/
- public final boolean awaitUntil(Date deadline) throws InterruptedException {
+ public final boolean awaitUntil(Date deadline)
+ throws InterruptedException {
if (deadline == null)
throw new NullPointerException();
long abstime = deadline.getTime();
@@ -2149,7 +2155,8 @@
* <li> If timed out while blocked in step 4, return false, else true.
* </ol>
*/
- public final boolean await(long time, TimeUnit unit) throws InterruptedException {
+ public final boolean await(long time, TimeUnit unit)
+ throws InterruptedException {
if (unit == null)
throw new NullPointerException();
long nanosTimeout = unit.toNanos(time);
@@ -2305,7 +2312,7 @@
/**
* CAS waitStatus field of a node.
*/
- private final static boolean compareAndSetWaitStatus(Node node,
+ private static final boolean compareAndSetWaitStatus(Node node,
int expect,
int update) {
return unsafe.compareAndSwapInt(node, waitStatusOffset,
@@ -2315,7 +2322,7 @@
/**
* CAS next field of a node.
*/
- private final static boolean compareAndSetNext(Node node,
+ private static final boolean compareAndSetNext(Node node,
Node expect,
Node update) {
return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
--- a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java Tue Dec 07 13:29:20 2010 +0000
@@ -200,8 +200,8 @@
* <li>Some other thread invokes {@link #unpark unpark} with the
* current thread as the target; or
*
- * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current
- * thread; or
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
*
* <li>The specified waiting time elapses; or
*
--- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantLock.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantLock.java Tue Dec 07 13:29:20 2010 +0000
@@ -116,7 +116,7 @@
* into fair and nonfair versions below. Uses AQS state to
* represent the number of holds on the lock.
*/
- static abstract class Sync extends AbstractQueuedSynchronizer {
+ abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
@@ -200,7 +200,7 @@
/**
* Sync object for non-fair locks
*/
- final static class NonfairSync extends Sync {
+ static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
@@ -222,7 +222,7 @@
/**
* Sync object for fair locks
*/
- final static class FairSync extends Sync {
+ static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
@@ -269,7 +269,7 @@
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
- sync = (fair)? new FairSync() : new NonfairSync();
+ sync = fair ? new FairSync() : new NonfairSync();
}
/**
@@ -440,7 +440,8 @@
* @throws NullPointerException if the time unit is null
*
*/
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ public boolean tryLock(long timeout, TimeUnit unit)
+ throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
--- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Tue Dec 07 13:29:20 2010 +0000
@@ -155,7 +155,7 @@
* }
* // Downgrade by acquiring read lock before releasing write lock
* rwl.readLock().lock();
- * } finally {
+ * } finally {
* rwl.writeLock().unlock(); // Unlock write, still hold read
* }
* }
@@ -215,7 +215,8 @@
* @author Doug Lea
*
*/
-public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable {
+public class ReentrantReadWriteLock
+ implements ReadWriteLock, java.io.Serializable {
private static final long serialVersionUID = -6992448646407690164L;
/** Inner class providing readlock */
private final ReentrantReadWriteLock.ReadLock readerLock;
@@ -251,7 +252,7 @@
* Synchronization implementation for ReentrantReadWriteLock.
* Subclassed into fair and nonfair versions.
*/
- static abstract class Sync extends AbstractQueuedSynchronizer {
+ abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 6317671515068378041L;
/*
@@ -618,7 +619,7 @@
final Thread getOwner() {
// Must read state before owner to ensure memory consistency
- return ((exclusiveCount(getState()) == 0)?
+ return ((exclusiveCount(getState()) == 0) ?
null :
getExclusiveOwnerThread());
}
@@ -669,7 +670,7 @@
/**
* Nonfair version of Sync
*/
- final static class NonfairSync extends Sync {
+ static final class NonfairSync extends Sync {
private static final long serialVersionUID = -8159625535654395037L;
final boolean writerShouldBlock() {
return false; // writers can always barge
@@ -689,7 +690,7 @@
/**
* Fair version of Sync
*/
- final static class FairSync extends Sync {
+ static final class FairSync extends Sync {
private static final long serialVersionUID = -2274990926593161451L;
final boolean writerShouldBlock() {
return hasQueuedPredecessors();
@@ -702,7 +703,7 @@
/**
* The lock returned by method {@link ReentrantReadWriteLock#readLock}.
*/
- public static class ReadLock implements Lock, java.io.Serializable {
+ public static class ReadLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -5992448646407690164L;
private final Sync sync;
@@ -867,7 +868,8 @@
* @throws NullPointerException if the time unit is null
*
*/
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ public boolean tryLock(long timeout, TimeUnit unit)
+ throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
@@ -908,7 +910,7 @@
/**
* The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
*/
- public static class WriteLock implements Lock, java.io.Serializable {
+ public static class WriteLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = -4992448646407690164L;
private final Sync sync;
@@ -1108,7 +1110,8 @@
* @throws NullPointerException if the time unit is null
*
*/
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ public boolean tryLock(long timeout, TimeUnit unit)
+ throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
--- a/jdk/src/share/classes/javax/security/auth/Policy.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/javax/security/auth/Policy.java Tue Dec 07 13:29:20 2010 +0000
@@ -25,6 +25,9 @@
package javax.security.auth;
+import java.security.Security;
+import sun.security.util.Debug;
+
/**
* <p> This is an abstract class for representing the system policy for
* Subject-based authorization. A subclass implementation
@@ -159,6 +162,10 @@
private static Policy policy;
private static ClassLoader contextClassLoader;
+ // true if a custom (not com.sun.security.auth.PolicyFile) system-wide
+ // policy object is set
+ private static boolean isCustomPolicy;
+
static {
contextClassLoader = java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<ClassLoader>() {
@@ -234,6 +241,8 @@
contextClassLoader).newInstance();
}
});
+ isCustomPolicy =
+ !finalClass.equals("com.sun.security.auth.PolicyFile");
} catch (Exception e) {
throw new SecurityException
(sun.security.util.ResourcesMgr.getString
@@ -265,6 +274,46 @@
java.lang.SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(new AuthPermission("setPolicy"));
Policy.policy = policy;
+ // all non-null policy objects are assumed to be custom
+ isCustomPolicy = policy != null ? true : false;
+ }
+
+ /**
+ * Returns true if a custom (not com.sun.security.auth.PolicyFile)
+ * system-wide policy object has been set or installed. This method is
+ * called by SubjectDomainCombiner to provide backwards compatibility for
+ * developers that provide their own javax.security.auth.Policy
+ * implementations.
+ *
+ * @return true if a custom (not com.sun.security.auth.PolicyFile)
+ * system-wide policy object has been set; false otherwise
+ */
+ static boolean isCustomPolicySet(Debug debug) {
+ if (policy != null) {
+ if (debug != null && isCustomPolicy) {
+ debug.println("Providing backwards compatibility for " +
+ "javax.security.auth.policy implementation: " +
+ policy.toString());
+ }
+ return isCustomPolicy;
+ }
+ // check if custom policy has been set using auth.policy.provider prop
+ String policyClass = java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<String>() {
+ public String run() {
+ return Security.getProperty("auth.policy.provider");
+ }
+ });
+ if (policyClass != null
+ && !policyClass.equals("com.sun.security.auth.PolicyFile")) {
+ if (debug != null) {
+ debug.println("Providing backwards compatibility for " +
+ "javax.security.auth.policy implementation: " +
+ policyClass);
+ }
+ return true;
+ }
+ return false;
}
/**
--- a/jdk/src/share/classes/javax/security/auth/SubjectDomainCombiner.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/javax/security/auth/SubjectDomainCombiner.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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,8 +26,6 @@
package javax.security.auth;
import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.AllPermission;
import java.security.Permission;
import java.security.Permissions;
import java.security.PermissionCollection;
@@ -35,10 +33,8 @@
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
-import java.lang.ClassLoader;
import java.security.Security;
import java.util.Set;
-import java.util.Iterator;
import java.util.WeakHashMap;
import java.lang.ref.WeakReference;
@@ -61,7 +57,8 @@
"\t[SubjectDomainCombiner]");
// Note: check only at classloading time, not dynamically during combine()
- private static final boolean useJavaxPolicy = compatPolicy();
+ private static final boolean useJavaxPolicy =
+ javax.security.auth.Policy.isCustomPolicySet(debug);
// Relevant only when useJavaxPolicy is true
private static final boolean allowCaching =
@@ -202,8 +199,8 @@
return null;
}
- // maintain backwards compatibility for people who provide
- // their own javax.security.auth.Policy implementations
+ // maintain backwards compatibility for developers who provide
+ // their own custom javax.security.auth.Policy implementations
if (useJavaxPolicy) {
return combineJavaxPolicy(currentDomains, assignedDomains);
}
@@ -476,8 +473,7 @@
String s = AccessController.doPrivileged
(new PrivilegedAction<String>() {
public String run() {
- return java.security.Security.getProperty
- ("cache.auth.policy");
+ return Security.getProperty("cache.auth.policy");
}
});
if (s != null) {
@@ -488,29 +484,6 @@
return true;
}
- // maintain backwards compatibility for people who provide
- // their own javax.security.auth.Policy implementations
- private static boolean compatPolicy() {
- javax.security.auth.Policy javaxPolicy = AccessController.doPrivileged
- (new PrivilegedAction<javax.security.auth.Policy>() {
- public javax.security.auth.Policy run() {
- return javax.security.auth.Policy.getPolicy();
- }
- });
-
- if (!(javaxPolicy instanceof com.sun.security.auth.PolicyFile)) {
- if (debug != null) {
- debug.println("Providing backwards compatibility for " +
- "javax.security.auth.policy implementation: " +
- javaxPolicy.toString());
- }
-
- return true;
- } else {
- return false;
- }
- }
-
private static void printInputDomains(ProtectionDomain[] currentDomains,
ProtectionDomain[] assignedDomains) {
if (currentDomains == null || currentDomains.length == 0) {
--- a/jdk/src/share/classes/javax/swing/GroupLayout.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/javax/swing/GroupLayout.java Tue Dec 07 13:29:20 2010 +0000
@@ -653,6 +653,10 @@
*/
public ParallelGroup createParallelGroup(Alignment alignment,
boolean resizable){
+ if (alignment == null) {
+ throw new IllegalArgumentException("alignment must be non null");
+ }
+
if (alignment == Alignment.BASELINE) {
return new BaselineGroup(resizable);
}
--- a/jdk/src/share/classes/javax/swing/JComponent.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/javax/swing/JComponent.java Tue Dec 07 13:29:20 2010 +0000
@@ -4734,6 +4734,8 @@
* Notifies this component that it now has a parent component.
* When this method is invoked, the chain of parent components is
* set up with <code>KeyboardAction</code> event listeners.
+ * This method is called by the toolkit internally and should
+ * not be called directly by programs.
*
* @see #registerKeyboardAction
*/
@@ -4750,6 +4752,8 @@
* Notifies this component that it no longer has a parent component.
* When this method is invoked, any <code>KeyboardAction</code>s
* set up in the the chain of parent components are removed.
+ * This method is called by the toolkit internally and should
+ * not be called directly by programs.
*
* @see #registerKeyboardAction
*/
--- a/jdk/src/share/classes/javax/swing/Popup.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/javax/swing/Popup.java Tue Dec 07 13:29:20 2010 +0000
@@ -156,7 +156,8 @@
component.setLocation(ownerX, ownerY);
component.getContentPane().add(contents, BorderLayout.CENTER);
- contents.invalidate();
+ component.invalidate();
+ component.validate();
if(component.isVisible()) {
// Do not call pack() if window is not visible to
// avoid early native peer creation
--- a/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/javax/swing/text/DefaultHighlighter.java Tue Dec 07 13:29:20 2010 +0000
@@ -113,6 +113,14 @@
* @exception BadLocationException if the specified location is invalid
*/
public Object addHighlight(int p0, int p1, Highlighter.HighlightPainter p) throws BadLocationException {
+ if (p0 < 0) {
+ throw new BadLocationException("Invalid start offset", p0);
+ }
+
+ if (p1 < p0) {
+ throw new BadLocationException("Invalid end offset", p1);
+ }
+
Document doc = component.getDocument();
HighlightInfo i = (getDrawsLayeredHighlights() &&
(p instanceof LayeredHighlighter.LayerPainter)) ?
@@ -217,6 +225,14 @@
* @exception BadLocationException if the specified location is invalid
*/
public void changeHighlight(Object tag, int p0, int p1) throws BadLocationException {
+ if (p0 < 0) {
+ throw new BadLocationException("Invalid beginning of the range", p0);
+ }
+
+ if (p1 < p0) {
+ throw new BadLocationException("Invalid end of the range", p1);
+ }
+
Document doc = component.getDocument();
if (tag instanceof LayeredHighlightInfo) {
LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
--- a/jdk/src/share/classes/sun/awt/UngrabEvent.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/awt/UngrabEvent.java Tue Dec 07 13:29:20 2010 +0000
@@ -40,8 +40,10 @@
* <p>To listen for this event, install AWTEventListener with {@value sun.awt.SunToolkit#GRAB_EVENT_MASK}
*/
public class UngrabEvent extends AWTEvent {
+ private final static int UNGRAB_EVENT_ID = 1998;
+
public UngrabEvent(Component source) {
- super(source, 0xffff);
+ super(source, UNGRAB_EVENT_ID);
}
public String toString() {
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Tue Dec 07 13:29:20 2010 +0000
@@ -44,8 +44,16 @@
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
import java.util.ResourceBundle;
import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
@@ -59,6 +67,17 @@
private static StringBuilder outBuf = new StringBuilder();
private static ResourceBundle javarb = null;
+
+ private static final String INDENT = " ";
+ private static final String VM_SETTINGS = "VM settings:";
+ private static final String PROP_SETTINGS = "Property settings:";
+ private static final String LOCALE_SETTINGS = "Locale settings:";
+
+ private static final long K = 1024;
+ private static final long M = K * K;
+ private static final long G = M * K;
+ private static final long T = G * K;
+
private static synchronized ResourceBundle getLauncherResourceBundle() {
if (javarb == null) {
javarb = ResourceBundle.getBundle(defaultBundleName);
@@ -66,6 +85,184 @@
return javarb;
}
+ /*
+ * A method called by the launcher to print out the standard settings,
+ * by default -XshowSettings is equivalent to -XshowSettings:all,
+ * Specific information may be gotten by using suboptions with possible
+ * values vm, properties and locale.
+ *
+ * printToStderr: choose between stdout and stderr
+ *
+ * optionFlag: specifies which options to print default is all other
+ * possible values are vm, properties, locale.
+ *
+ * maxHeapSize: in bytes, as set by the launcher, a zero-value indicates
+ * this code should determine this value, using a suitable method.
+ *
+ * stackSize: in bytes, as set by the launcher, a zero-value indicates
+ * this code determine this value, using a suitable method.
+ */
+ static void showSettings(boolean printToStderr, String optionFlag,
+ long maxHeapSize, long stackSize, boolean isServer) {
+
+ PrintStream ostream = (printToStderr) ? System.err : System.out;
+ String opts[] = optionFlag.split(":");
+ String optStr = (opts.length > 1 && opts[1] != null)
+ ? opts[1].trim()
+ : "all";
+ switch (optStr) {
+ case "vm":
+ printVmSettings(ostream, maxHeapSize, stackSize, isServer);
+ break;
+ case "properties":
+ printProperties(ostream);
+ break;
+ case "locale":
+ printLocale(ostream);
+ break;
+ default:
+ printVmSettings(ostream, maxHeapSize, stackSize, isServer);
+ printProperties(ostream);
+ printLocale(ostream);
+ break;
+ }
+ }
+
+ /*
+ * prints the main vm settings subopt/section
+ */
+ private static void printVmSettings(PrintStream ostream, long maxHeapSize,
+ long stackSize, boolean isServer) {
+
+ ostream.println(VM_SETTINGS);
+ if (stackSize != 0L) {
+ ostream.println(INDENT + "Stack Size: " + scaleValue(stackSize));
+ }
+ if (maxHeapSize != 0L) {
+ ostream.println(INDENT + "Max. Heap Size: " + scaleValue(maxHeapSize));
+ } else {
+ ostream.println(INDENT + "Max. Heap Size (Estimated): "
+ + scaleValue(Runtime.getRuntime().maxMemory()));
+ }
+ ostream.println(INDENT + "Ergonomics Machine Class: "
+ + ((isServer) ? "server" : "client"));
+ ostream.println(INDENT + "Using VM: "
+ + System.getProperty("java.vm.name"));
+ ostream.println();
+ }
+
+ /*
+ * scale the incoming values to a human readable form, represented as
+ * K, M, G and T, see java.c parse_size for the scaled values and
+ * suffixes.
+ */
+
+ private static String scaleValue(double v) {
+ MathContext mc2 = new MathContext(3, RoundingMode.HALF_EVEN);
+
+ if (v >= K && v < M) {
+ return (new BigDecimal(v / K, mc2)).toPlainString() + "K";
+ } else if (v >= M && v < G) {
+ return (new BigDecimal(v / M, mc2)).toPlainString() + "M";
+ } else if (v >= G && v < T) {
+ return (new BigDecimal(v / G, mc2)).toPlainString() + "G";
+ } else if (v >= T) {
+ return (new BigDecimal(v / T, mc2)).toPlainString() + "T";
+ } else {
+ return String.format("%.0f", v);
+ }
+ }
+
+ /*
+ * prints the properties subopt/section
+ */
+ private static void printProperties(PrintStream ostream) {
+ Properties p = System.getProperties();
+ ostream.println(PROP_SETTINGS);
+ List<String> sortedPropertyKeys = new ArrayList<>();
+ sortedPropertyKeys.addAll(p.stringPropertyNames());
+ Collections.sort(sortedPropertyKeys);
+ for (String x : sortedPropertyKeys) {
+ printPropertyValue(ostream, x, p.getProperty(x));
+ }
+ ostream.println();
+ }
+
+ private static boolean isPath(String key) {
+ return key.endsWith(".dirs") || key.endsWith(".path");
+ }
+
+ private static void printPropertyValue(PrintStream ostream,
+ String key, String value) {
+ ostream.print(INDENT + key + " = ");
+ if (key.equals("line.separator")) {
+ byte[] bytes = value.getBytes();
+ for (byte b : bytes) {
+ switch (b) {
+ case 0xd:
+ ostream.print("CR ");
+ break;
+ case 0xa:
+ ostream.print("LF ");
+ break;
+ default:
+ ostream.printf("0x%02X", b & 0xff);
+ break;
+ }
+ }
+ ostream.println();
+ return;
+ }
+ if (!isPath(key)) {
+ ostream.println(value);
+ return;
+ }
+ // pretty print the path values as a list
+ String[] values = value.split(System.getProperty("path.separator"));
+ int len = values.length;
+ for (int i = 0 ; i < len ; i++) {
+ if (i == 0) { // first line treated specially
+ ostream.println(values[i]);
+ } else { // following lines prefix with indents
+ ostream.print(INDENT + INDENT);
+ ostream.println(values[i]);
+ }
+ }
+ }
+
+ /*
+ * prints the locale subopt/section
+ */
+ private static void printLocale(PrintStream ostream) {
+ Locale locale = Locale.getDefault();
+ ostream.println(LOCALE_SETTINGS);
+ ostream.println(INDENT + "default locale = " + locale.getDisplayLanguage());
+ printLocales(ostream);
+ ostream.println();
+ }
+
+ private static void printLocales(PrintStream ostream) {
+ Locale[] locales = Locale.getAvailableLocales();
+ final int len = locales == null ? 0 : locales.length;
+ if (len < 1 ) {
+ return;
+ }
+ ostream.print(INDENT + "available locales = ");
+ final int last = len - 1 ;
+ for (int i = 0; i < last ; i++) {
+ ostream.print(locales[i]);
+ if (i != last) {
+ ostream.print(", ");
+ }
+ // print columns of 8
+ if ((i + 1) % 8 == 0) {
+ ostream.println();
+ ostream.print(INDENT + INDENT);
+ }
+ }
+ ostream.println(locales[last]);
+ }
+
/**
* A private helper method to get a localized message and also
* apply any arguments that we might pass.
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, 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
@@ -97,7 +97,15 @@
\ -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:on require using shared class data, otherwise fail.\n\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\n\
The -X options are non-standard and subject to change without notice.\n
java.launcher.cls.error1=\
--- a/jdk/src/share/classes/sun/misc/FpUtils.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/misc/FpUtils.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,9 +29,9 @@
import sun.misc.DoubleConsts;
/**
- * The class <code>FpUtils</code> contains static utility methods for
- * manipulating and inspecting <code>float</code> and
- * <code>double</code> floating-point numbers. These methods include
+ * The class {@code FpUtils} contains static utility methods for
+ * manipulating and inspecting {@code float} and
+ * {@code double} floating-point numbers. These methods include
* functionality recommended or required by the IEEE 754
* floating-point standard.
*
@@ -136,7 +136,7 @@
// tests for exception cases.
/**
- * Returns unbiased exponent of a <code>double</code>.
+ * Returns unbiased exponent of a {@code double}.
*/
public static int getExponent(double d){
/*
@@ -149,7 +149,7 @@
}
/**
- * Returns unbiased exponent of a <code>float</code>.
+ * Returns unbiased exponent of a {@code float}.
*/
public static int getExponent(float f){
/*
@@ -185,15 +185,15 @@
* Returns the first floating-point argument with the sign of the
* second floating-point argument. Note that unlike the {@link
* FpUtils#copySign(double, double) copySign} method, this method
- * does not require NaN <code>sign</code> arguments to be treated
+ * does not require NaN {@code sign} arguments to be treated
* as positive values; implementations are permitted to treat some
* NaN arguments as positive and other NaN arguments as negative
* to allow greater performance.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
- * @return a value with the magnitude of <code>magnitude</code>
- * and the sign of <code>sign</code>.
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
* @author Joseph D. Darcy
*/
public static double rawCopySign(double magnitude, double sign) {
@@ -208,15 +208,15 @@
* Returns the first floating-point argument with the sign of the
* second floating-point argument. Note that unlike the {@link
* FpUtils#copySign(float, float) copySign} method, this method
- * does not require NaN <code>sign</code> arguments to be treated
+ * does not require NaN {@code sign} arguments to be treated
* as positive values; implementations are permitted to treat some
* NaN arguments as positive and other NaN arguments as negative
* to allow greater performance.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
- * @return a value with the magnitude of <code>magnitude</code>
- * and the sign of <code>sign</code>.
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
* @author Joseph D. Darcy
*/
public static float rawCopySign(float magnitude, float sign) {
@@ -230,129 +230,129 @@
/* ***************************************************************** */
/**
- * Returns <code>true</code> if the argument is a finite
- * floating-point value; returns <code>false</code> otherwise (for
+ * Returns {@code true} if the argument is a finite
+ * floating-point value; returns {@code false} otherwise (for
* NaN and infinity arguments).
*
- * @param d the <code>double</code> value to be tested
- * @return <code>true</code> if the argument is a finite
- * floating-point value, <code>false</code> otherwise.
+ * @param d the {@code double} value to be tested
+ * @return {@code true} if the argument is a finite
+ * floating-point value, {@code false} otherwise.
*/
public static boolean isFinite(double d) {
return Math.abs(d) <= DoubleConsts.MAX_VALUE;
}
/**
- * Returns <code>true</code> if the argument is a finite
- * floating-point value; returns <code>false</code> otherwise (for
+ * Returns {@code true} if the argument is a finite
+ * floating-point value; returns {@code false} otherwise (for
* NaN and infinity arguments).
*
- * @param f the <code>float</code> value to be tested
- * @return <code>true</code> if the argument is a finite
- * floating-point value, <code>false</code> otherwise.
+ * @param f the {@code float} value to be tested
+ * @return {@code true} if the argument is a finite
+ * floating-point value, {@code false} otherwise.
*/
public static boolean isFinite(float f) {
return Math.abs(f) <= FloatConsts.MAX_VALUE;
}
/**
- * Returns <code>true</code> if the specified number is infinitely
- * large in magnitude, <code>false</code> otherwise.
+ * Returns {@code true} if the specified number is infinitely
+ * large in magnitude, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Double#isInfinite(double) Double.isInfinite} method; the
* functionality is included in this class for convenience.
*
* @param d the value to be tested.
- * @return <code>true</code> if the value of the argument is positive
- * infinity or negative infinity; <code>false</code> otherwise.
+ * @return {@code true} if the value of the argument is positive
+ * infinity or negative infinity; {@code false} otherwise.
*/
public static boolean isInfinite(double d) {
return Double.isInfinite(d);
}
/**
- * Returns <code>true</code> if the specified number is infinitely
- * large in magnitude, <code>false</code> otherwise.
+ * Returns {@code true} if the specified number is infinitely
+ * large in magnitude, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Float#isInfinite(float) Float.isInfinite} method; the
* functionality is included in this class for convenience.
*
* @param f the value to be tested.
- * @return <code>true</code> if the argument is positive infinity or
- * negative infinity; <code>false</code> otherwise.
+ * @return {@code true} if the argument is positive infinity or
+ * negative infinity; {@code false} otherwise.
*/
public static boolean isInfinite(float f) {
return Float.isInfinite(f);
}
/**
- * Returns <code>true</code> if the specified number is a
- * Not-a-Number (NaN) value, <code>false</code> otherwise.
+ * Returns {@code true} if the specified number is a
+ * Not-a-Number (NaN) value, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Double#isNaN(double) Double.isNaN} method; the functionality is
* included in this class for convenience.
*
* @param d the value to be tested.
- * @return <code>true</code> if the value of the argument is NaN;
- * <code>false</code> otherwise.
+ * @return {@code true} if the value of the argument is NaN;
+ * {@code false} otherwise.
*/
public static boolean isNaN(double d) {
return Double.isNaN(d);
}
/**
- * Returns <code>true</code> if the specified number is a
- * Not-a-Number (NaN) value, <code>false</code> otherwise.
+ * Returns {@code true} if the specified number is a
+ * Not-a-Number (NaN) value, {@code false} otherwise.
*
* <p>Note that this method is equivalent to the {@link
* Float#isNaN(float) Float.isNaN} method; the functionality is
* included in this class for convenience.
*
* @param f the value to be tested.
- * @return <code>true</code> if the argument is NaN;
- * <code>false</code> otherwise.
+ * @return {@code true} if the argument is NaN;
+ * {@code false} otherwise.
*/
public static boolean isNaN(float f) {
return Float.isNaN(f);
}
/**
- * Returns <code>true</code> if the unordered relation holds
+ * Returns {@code true} if the unordered relation holds
* between the two arguments. When two floating-point values are
* unordered, one value is neither less than, equal to, nor
* greater than the other. For the unordered relation to be true,
- * at least one argument must be a <code>NaN</code>.
+ * at least one argument must be a {@code NaN}.
*
* @param arg1 the first argument
* @param arg2 the second argument
- * @return <code>true</code> if at least one argument is a NaN,
- * <code>false</code> otherwise.
+ * @return {@code true} if at least one argument is a NaN,
+ * {@code false} otherwise.
*/
public static boolean isUnordered(double arg1, double arg2) {
return isNaN(arg1) || isNaN(arg2);
}
/**
- * Returns <code>true</code> if the unordered relation holds
+ * Returns {@code true} if the unordered relation holds
* between the two arguments. When two floating-point values are
* unordered, one value is neither less than, equal to, nor
* greater than the other. For the unordered relation to be true,
- * at least one argument must be a <code>NaN</code>.
+ * at least one argument must be a {@code NaN}.
*
* @param arg1 the first argument
* @param arg2 the second argument
- * @return <code>true</code> if at least one argument is a NaN,
- * <code>false</code> otherwise.
+ * @return {@code true} if at least one argument is a NaN,
+ * {@code false} otherwise.
*/
public static boolean isUnordered(float arg1, float arg2) {
return isNaN(arg1) || isNaN(arg2);
}
/**
- * Returns unbiased exponent of a <code>double</code>; for
+ * Returns unbiased exponent of a {@code double}; for
* subnormal values, the number is treated as if it were
* normalized. That is for all finite, non-zero, positive numbers
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
@@ -378,7 +378,6 @@
return (1<<30); // 2^30
else // infinite value
return (1<<28); // 2^28
- // break;
case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal
if(d == 0.0) {
@@ -414,18 +413,16 @@
exponent < DoubleConsts.MIN_EXPONENT);
return exponent;
}
- // break;
default:
assert( exponent >= DoubleConsts.MIN_EXPONENT &&
exponent <= DoubleConsts.MAX_EXPONENT);
return exponent;
- // break;
}
}
/**
- * Returns unbiased exponent of a <code>float</code>; for
+ * Returns unbiased exponent of a {@code float}; for
* subnormal values, the number is treated as if it were
* normalized. That is for all finite, non-zero, positive numbers
* <i>x</i>, <code>scalb(<i>x</i>, -ilogb(<i>x</i>))</code> is
@@ -451,7 +448,6 @@
return (1<<30); // 2^30
else // infinite value
return (1<<28); // 2^28
- // break;
case FloatConsts.MIN_EXPONENT-1: // zero or subnormal
if(f == 0.0f) {
@@ -487,13 +483,11 @@
exponent < FloatConsts.MIN_EXPONENT);
return exponent;
}
- // break;
default:
assert( exponent >= FloatConsts.MIN_EXPONENT &&
exponent <= FloatConsts.MAX_EXPONENT);
return exponent;
- // break;
}
}
@@ -534,22 +528,22 @@
*/
/**
- * Return <code>d</code> ×
- * 2<sup><code>scale_factor</code></sup> rounded as if performed
+ * Return {@code d} ×
+ * 2<sup>{@code scale_factor}</sup> rounded as if performed
* by a single correctly rounded floating-point multiply to a
* member of the double value set. See <a
* href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#9208">§4.2.3</a>
* of the <a href="http://java.sun.com/docs/books/jls/html/">Java
* Language Specification</a> for a discussion of floating-point
* value sets. If the exponent of the result is between the
- * <code>double</code>'s minimum exponent and maximum exponent,
+ * {@code double}'s minimum exponent and maximum exponent,
* the answer is calculated exactly. If the exponent of the
- * result would be larger than <code>doubles</code>'s maximum
+ * result would be larger than {@code doubles}'s maximum
* exponent, an infinity is returned. Note that if the result is
- * subnormal, precision may be lost; that is, when <code>scalb(x,
- * n)</code> is subnormal, <code>scalb(scalb(x, n), -n)</code> may
+ * subnormal, precision may be lost; that is, when {@code scalb(x,
+ * n)} is subnormal, {@code scalb(scalb(x, n), -n)} may
* not equal <i>x</i>. When the result is non-NaN, the result has
- * the same sign as <code>d</code>.
+ * the same sign as {@code d}.
*
*<p>
* Special cases:
@@ -562,8 +556,8 @@
* </ul>
*
* @param d number to be scaled by a power of two.
- * @param scale_factor power of 2 used to scale <code>d</code>
- * @return <code>d * </code>2<sup><code>scale_factor</code></sup>
+ * @param scale_factor power of 2 used to scale {@code d}
+ * @return {@code d * }2<sup>{@code scale_factor}</sup>
* @author Joseph D. Darcy
*/
public static double scalb(double d, int scale_factor) {
@@ -644,22 +638,22 @@
}
/**
- * Return <code>f </code>×
- * 2<sup><code>scale_factor</code></sup> rounded as if performed
+ * Return {@code f} ×
+ * 2<sup>{@code scale_factor}</sup> rounded as if performed
* by a single correctly rounded floating-point multiply to a
* member of the float value set. See <a
* href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#9208">§4.2.3</a>
* of the <a href="http://java.sun.com/docs/books/jls/html/">Java
* Language Specification</a> for a discussion of floating-point
* value set. If the exponent of the result is between the
- * <code>float</code>'s minimum exponent and maximum exponent, the
+ * {@code float}'s minimum exponent and maximum exponent, the
* answer is calculated exactly. If the exponent of the result
- * would be larger than <code>float</code>'s maximum exponent, an
+ * would be larger than {@code float}'s maximum exponent, an
* infinity is returned. Note that if the result is subnormal,
- * precision may be lost; that is, when <code>scalb(x, n)</code>
- * is subnormal, <code>scalb(scalb(x, n), -n)</code> may not equal
+ * precision may be lost; that is, when {@code scalb(x, n)}
+ * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal
* <i>x</i>. When the result is non-NaN, the result has the same
- * sign as <code>f</code>.
+ * sign as {@code f}.
*
*<p>
* Special cases:
@@ -672,8 +666,8 @@
* </ul>
*
* @param f number to be scaled by a power of two.
- * @param scale_factor power of 2 used to scale <code>f</code>
- * @return <code>f * </code>2<sup><code>scale_factor</code></sup>
+ * @param scale_factor power of 2 used to scale {@code f}
+ * @return {@code f * }2<sup>{@code scale_factor}</sup>
* @author Joseph D. Darcy
*/
public static float scalb(float f, int scale_factor) {
@@ -709,34 +703,34 @@
* <ul>
* <li> If either argument is a NaN, then NaN is returned.
*
- * <li> If both arguments are signed zeros, <code>direction</code>
+ * <li> If both arguments are signed zeros, {@code direction}
* is returned unchanged (as implied by the requirement of
* returning the second argument if the arguments compare as
* equal).
*
- * <li> If <code>start</code> is
- * ±<code>Double.MIN_VALUE</code> and <code>direction</code>
+ * <li> If {@code start} is
+ * ±{@code Double.MIN_VALUE} and {@code direction}
* has a value such that the result should have a smaller
- * magnitude, then a zero with the same sign as <code>start</code>
+ * magnitude, then a zero with the same sign as {@code start}
* is returned.
*
- * <li> If <code>start</code> is infinite and
- * <code>direction</code> has a value such that the result should
- * have a smaller magnitude, <code>Double.MAX_VALUE</code> with the
- * same sign as <code>start</code> is returned.
+ * <li> If {@code start} is infinite and
+ * {@code direction} has a value such that the result should
+ * have a smaller magnitude, {@code Double.MAX_VALUE} with the
+ * same sign as {@code start} is returned.
*
- * <li> If <code>start</code> is equal to ±
- * <code>Double.MAX_VALUE</code> and <code>direction</code> has a
+ * <li> If {@code start} is equal to ±
+ * {@code Double.MAX_VALUE} and {@code direction} has a
* value such that the result should have a larger magnitude, an
- * infinity with same sign as <code>start</code> is returned.
+ * infinity with same sign as {@code start} is returned.
* </ul>
*
* @param start starting floating-point value
* @param direction value indicating which of
- * <code>start</code>'s neighbors or <code>start</code> should
+ * {@code start}'s neighbors or {@code start} should
* be returned
- * @return The floating-point number adjacent to <code>start</code> in the
- * direction of <code>direction</code>.
+ * @return The floating-point number adjacent to {@code start} in the
+ * direction of {@code direction}.
* @author Joseph D. Darcy
*/
public static double nextAfter(double start, double direction) {
@@ -809,34 +803,34 @@
* <ul>
* <li> If either argument is a NaN, then NaN is returned.
*
- * <li> If both arguments are signed zeros, a <code>float</code>
- * zero with the same sign as <code>direction</code> is returned
+ * <li> If both arguments are signed zeros, a {@code float}
+ * zero with the same sign as {@code direction} is returned
* (as implied by the requirement of returning the second argument
* if the arguments compare as equal).
*
- * <li> If <code>start</code> is
- * ±<code>Float.MIN_VALUE</code> and <code>direction</code>
+ * <li> If {@code start} is
+ * ±{@code Float.MIN_VALUE} and {@code direction}
* has a value such that the result should have a smaller
- * magnitude, then a zero with the same sign as <code>start</code>
+ * magnitude, then a zero with the same sign as {@code start}
* is returned.
*
- * <li> If <code>start</code> is infinite and
- * <code>direction</code> has a value such that the result should
- * have a smaller magnitude, <code>Float.MAX_VALUE</code> with the
- * same sign as <code>start</code> is returned.
+ * <li> If {@code start} is infinite and
+ * {@code direction} has a value such that the result should
+ * have a smaller magnitude, {@code Float.MAX_VALUE} with the
+ * same sign as {@code start} is returned.
*
- * <li> If <code>start</code> is equal to ±
- * <code>Float.MAX_VALUE</code> and <code>direction</code> has a
+ * <li> If {@code start} is equal to ±
+ * {@code Float.MAX_VALUE} and {@code direction} has a
* value such that the result should have a larger magnitude, an
- * infinity with same sign as <code>start</code> is returned.
+ * infinity with same sign as {@code start} is returned.
* </ul>
*
* @param start starting floating-point value
* @param direction value indicating which of
- * <code>start</code>'s neighbors or <code>start</code> should
+ * {@code start}'s neighbors or {@code start} should
* be returned
- * @return The floating-point number adjacent to <code>start</code> in the
- * direction of <code>direction</code>.
+ * @return The floating-point number adjacent to {@code start} in the
+ * direction of {@code direction}.
* @author Joseph D. Darcy
*/
public static float nextAfter(float start, double direction) {
@@ -900,12 +894,12 @@
}
/**
- * Returns the floating-point value adjacent to <code>d</code> in
+ * Returns the floating-point value adjacent to {@code d} in
* the direction of positive infinity. This method is
- * semantically equivalent to <code>nextAfter(d,
- * Double.POSITIVE_INFINITY)</code>; however, a <code>nextUp</code>
+ * semantically equivalent to {@code nextAfter(d,
+ * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
* implementation may run faster than its equivalent
- * <code>nextAfter</code> call.
+ * {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
@@ -915,7 +909,7 @@
* positive infinity.
*
* <li> If the argument is zero, the result is
- * <code>Double.MIN_VALUE</code>
+ * {@code Double.MIN_VALUE}
*
* </ul>
*
@@ -935,12 +929,12 @@
}
/**
- * Returns the floating-point value adjacent to <code>f</code> in
+ * Returns the floating-point value adjacent to {@code f} in
* the direction of positive infinity. This method is
- * semantically equivalent to <code>nextAfter(f,
- * Double.POSITIVE_INFINITY)</code>; however, a <code>nextUp</code>
+ * semantically equivalent to {@code nextAfter(f,
+ * Double.POSITIVE_INFINITY)}; however, a {@code nextUp}
* implementation may run faster than its equivalent
- * <code>nextAfter</code> call.
+ * {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
@@ -950,7 +944,7 @@
* positive infinity.
*
* <li> If the argument is zero, the result is
- * <code>Float.MIN_VALUE</code>
+ * {@code Float.MIN_VALUE}
*
* </ul>
*
@@ -970,12 +964,12 @@
}
/**
- * Returns the floating-point value adjacent to <code>d</code> in
+ * Returns the floating-point value adjacent to {@code d} in
* the direction of negative infinity. This method is
- * semantically equivalent to <code>nextAfter(d,
- * Double.NEGATIVE_INFINITY)</code>; however, a
- * <code>nextDown</code> implementation may run faster than its
- * equivalent <code>nextAfter</code> call.
+ * semantically equivalent to {@code nextAfter(d,
+ * Double.NEGATIVE_INFINITY)}; however, a
+ * {@code nextDown} implementation may run faster than its
+ * equivalent {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
@@ -985,7 +979,7 @@
* negative infinity.
*
* <li> If the argument is zero, the result is
- * <code>-Double.MIN_VALUE</code>
+ * {@code -Double.MIN_VALUE}
*
* </ul>
*
@@ -1007,12 +1001,12 @@
}
/**
- * Returns the floating-point value adjacent to <code>f</code> in
+ * Returns the floating-point value adjacent to {@code f} in
* the direction of negative infinity. This method is
- * semantically equivalent to <code>nextAfter(f,
- * Float.NEGATIVE_INFINITY)</code>; however, a
- * <code>nextDown</code> implementation may run faster than its
- * equivalent <code>nextAfter</code> call.
+ * semantically equivalent to {@code nextAfter(f,
+ * Float.NEGATIVE_INFINITY)}; however, a
+ * {@code nextDown} implementation may run faster than its
+ * equivalent {@code nextAfter} call.
*
* <p>Special Cases:
* <ul>
@@ -1022,7 +1016,7 @@
* negative infinity.
*
* <li> If the argument is zero, the result is
- * <code>-Float.MIN_VALUE</code>
+ * {@code -Float.MIN_VALUE}
*
* </ul>
*
@@ -1046,13 +1040,13 @@
/**
* Returns the first floating-point argument with the sign of the
* second floating-point argument. For this method, a NaN
- * <code>sign</code> argument is always treated as if it were
+ * {@code sign} argument is always treated as if it were
* positive.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
- * @return a value with the magnitude of <code>magnitude</code>
- * and the sign of <code>sign</code>.
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
* @author Joseph D. Darcy
* @since 1.5
*/
@@ -1063,13 +1057,13 @@
/**
* Returns the first floating-point argument with the sign of the
* second floating-point argument. For this method, a NaN
- * <code>sign</code> argument is always treated as if it were
+ * {@code sign} argument is always treated as if it were
* positive.
*
* @param magnitude the parameter providing the magnitude of the result
* @param sign the parameter providing the sign of the result
- * @return a value with the magnitude of <code>magnitude</code>
- * and the sign of <code>sign</code>.
+ * @return a value with the magnitude of {@code magnitude}
+ * and the sign of {@code sign}.
* @author Joseph D. Darcy
*/
public static float copySign(float magnitude, float sign) {
@@ -1078,8 +1072,8 @@
/**
* Returns the size of an ulp of the argument. An ulp of a
- * <code>double</code> value is the positive distance between this
- * floating-point value and the <code>double</code> value next
+ * {@code double} value is the positive distance between this
+ * floating-point value and the {@code double} value next
* larger in magnitude. Note that for non-NaN <i>x</i>,
* <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
*
@@ -1089,8 +1083,8 @@
* <li> If the argument is positive or negative infinity, then the
* result is positive infinity.
* <li> If the argument is positive or negative zero, then the result is
- * <code>Double.MIN_VALUE</code>.
- * <li> If the argument is ±<code>Double.MAX_VALUE</code>, then
+ * {@code Double.MIN_VALUE}.
+ * <li> If the argument is ±{@code Double.MAX_VALUE}, then
* the result is equal to 2<sup>971</sup>.
* </ul>
*
@@ -1105,11 +1099,9 @@
switch(exp) {
case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity
return Math.abs(d);
- // break;
case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal
return Double.MIN_VALUE;
- // break
default:
assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT;
@@ -1126,14 +1118,13 @@
return Double.longBitsToDouble(1L <<
(exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
}
- // break
}
}
/**
* Returns the size of an ulp of the argument. An ulp of a
- * <code>float</code> value is the positive distance between this
- * floating-point value and the <code>float</code> value next
+ * {@code float} value is the positive distance between this
+ * floating-point value and the {@code float} value next
* larger in magnitude. Note that for non-NaN <i>x</i>,
* <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
*
@@ -1143,8 +1134,8 @@
* <li> If the argument is positive or negative infinity, then the
* result is positive infinity.
* <li> If the argument is positive or negative zero, then the result is
- * <code>Float.MIN_VALUE</code>.
- * <li> If the argument is ±<code>Float.MAX_VALUE</code>, then
+ * {@code Float.MIN_VALUE}.
+ * <li> If the argument is ±{@code Float.MAX_VALUE}, then
* the result is equal to 2<sup>104</sup>.
* </ul>
*
@@ -1159,11 +1150,9 @@
switch(exp) {
case FloatConsts.MAX_EXPONENT+1: // NaN or infinity
return Math.abs(f);
- // break;
case FloatConsts.MIN_EXPONENT-1: // zero or subnormal
return FloatConsts.MIN_VALUE;
- // break
default:
assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT;
@@ -1180,7 +1169,6 @@
return Float.intBitsToFloat(1 <<
(exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
}
- // break
}
}
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -235,8 +235,6 @@
if (remoteAddress == null)
throw new NotYetConnectedException();
- if (timeout < 0L)
- throw new IllegalArgumentException("Negative timeout");
boolean hasSpaceToRead = isScatteringRead || dst.hasRemaining();
boolean shutdown = false;
@@ -342,8 +340,6 @@
if (isOpen()) {
if (remoteAddress == null)
throw new NotYetConnectedException();
- if (timeout < 0L)
- throw new IllegalArgumentException("Negative timeout");
// check and update state
synchronized (writeLock) {
if (writeKilled)
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -39,12 +39,11 @@
public class FileChannelImpl
extends FileChannel
{
+ // Memory allocation size for mapping buffers
+ private static final long allocationGranularity;
// Used to make native read and write calls
- private static final FileDispatcher nd;
-
- // Memory allocation size for mapping buffers
- private static final long allocationGranularity;
+ private final FileDispatcher nd;
// File descriptor
private final FileDescriptor fd;
@@ -63,22 +62,29 @@
private final Object positionLock = new Object();
private FileChannelImpl(FileDescriptor fd, boolean readable,
- boolean writable, Object parent)
+ boolean writable, boolean append, Object parent)
{
this.fd = fd;
this.readable = readable;
this.writable = writable;
this.parent = parent;
+ this.nd = new FileDispatcherImpl(append);
}
- // Invoked by getChannel() methods
- // of java.io.File{Input,Output}Stream and RandomAccessFile
- //
+ // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel()
public static FileChannel open(FileDescriptor fd,
boolean readable, boolean writable,
Object parent)
{
- return new FileChannelImpl(fd, readable, writable, parent);
+ return new FileChannelImpl(fd, readable, writable, false, parent);
+ }
+
+ // Used by FileOutputStream.getChannel
+ public static FileChannel open(FileDescriptor fd,
+ boolean readable, boolean writable,
+ boolean append, Object parent)
+ {
+ return new FileChannelImpl(fd, readable, writable, append, parent);
}
private void ensureOpen() throws IOException {
@@ -704,6 +710,9 @@
private static class Unmapper
implements Runnable
{
+ // may be required to close file
+ private static final NativeDispatcher nd = new FileDispatcherImpl();
+
// keep track of mapped buffer usage
static volatile int count;
static volatile long totalSize;
@@ -1119,7 +1128,6 @@
static {
Util.load();
allocationGranularity = initIDs();
- nd = new FileDispatcherImpl();
}
}
--- a/jdk/src/share/classes/sun/security/rsa/RSASignature.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/security/rsa/RSASignature.java Tue Dec 07 13:29:20 2010 +0000
@@ -185,6 +185,11 @@
// verify the data and return the result. See JCA doc
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
+ if (sigBytes.length != RSACore.getByteLength(publicKey)) {
+ throw new SignatureException("Signature length not correct: got " +
+ sigBytes.length + " but was expecting " +
+ RSACore.getByteLength(publicKey));
+ }
byte[] digest = getDigestValue();
try {
byte[] decrypted = RSACore.rsa(sigBytes, publicKey);
--- a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Dec 07 13:29:20 2010 +0000
@@ -103,7 +103,8 @@
String s = ((protocolVersion.v >= ProtocolVersion.TLS12.v) ?
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
KeyGenerator kg = JsseJce.getKeyGenerator(s);
- kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor));
+ kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor),
+ generator);
preMaster = kg.generateKey();
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
--- a/jdk/src/share/classes/sun/security/tools/JarSigner.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java Tue Dec 07 13:29:20 2010 +0000
@@ -658,7 +658,9 @@
boolean inScope = (inStoreOrScope & IN_SCOPE) != 0;
notSignedByAlias |= (inStoreOrScope & NOT_ALIAS) != 0;
- aliasNotInStore |= isSigned && (!inStore && !inScope);
+ if (keystore != null) {
+ aliasNotInStore |= isSigned && (!inStore && !inScope);
+ }
// Only used when -verbose provided
StringBuffer sb = null;
@@ -723,7 +725,7 @@
if (signatureRelated(name)) {
// Entries inside META-INF and other unsigned
// entries are grouped separately.
- label = "-" + label.substring(1);
+ label = "-" + label;
}
// The label finally contains 2 parts separated by '|':
@@ -752,7 +754,7 @@
List<String> files = s.getValue();
String key = s.getKey();
if (key.charAt(0) == '-') { // the signature-related group
- key = ' ' + key.substring(1);
+ key = key.substring(1);
}
int pipe = key.indexOf('|');
if (verbose.equals("all")) {
@@ -889,7 +891,7 @@
* Note: no newline character at the end
*/
String printCert(String tab, Certificate c, boolean checkValidityPeriod,
- long now) {
+ long now, boolean checkUsage) {
StringBuilder certStr = new StringBuilder();
String space = rb.getString("SPACE");
@@ -959,24 +961,26 @@
}
certStr.append("]");
- boolean[] bad = new boolean[3];
- checkCertUsage(x509Cert, bad);
- if (bad[0] || bad[1] || bad[2]) {
- String x = "";
- if (bad[0]) {
- x ="KeyUsage";
- }
- if (bad[1]) {
- if (x.length() > 0) x = x + ", ";
- x = x + "ExtendedKeyUsage";
- }
- if (bad[2]) {
- if (x.length() > 0) x = x + ", ";
- x = x + "NetscapeCertType";
- }
- certStr.append("\n").append(tab)
+ if (checkUsage) {
+ boolean[] bad = new boolean[3];
+ checkCertUsage(x509Cert, bad);
+ if (bad[0] || bad[1] || bad[2]) {
+ String x = "";
+ if (bad[0]) {
+ x ="KeyUsage";
+ }
+ if (bad[1]) {
+ if (x.length() > 0) x = x + ", ";
+ x = x + "ExtendedKeyUsage";
+ }
+ if (bad[2]) {
+ if (x.length() > 0) x = x + ", ";
+ x = x + "NetscapeCertType";
+ }
+ certStr.append("\n").append(tab)
.append(MessageFormat.format(rb.getString(
".{0}.extension.does.not.support.code.signing."), x));
+ }
}
}
return certStr.toString();
@@ -1335,7 +1339,7 @@
certUrl);
}
System.out.println(rb.getString("TSA.certificate.") +
- printCert("", tsaCert, false, 0));
+ printCert("", tsaCert, false, 0, false));
}
if (signingMechanism != null) {
System.out.println(
@@ -1544,10 +1548,13 @@
s.append(printTimestamp(tab, timestamp));
s.append('\n');
}
- // display the certificate(s)
+ // display the certificate(s). The first one is end-enity cert and
+ // its KeyUsage should be checked.
+ boolean first = true;
for (Certificate c : certs) {
- s.append(printCert(tab, c, true, now));
+ s.append(printCert(tab, c, true, now, first));
s.append('\n');
+ first = false;
}
try {
CertPath cp = certificateFactory.generateCertPath(certs);
@@ -1847,7 +1854,7 @@
// We don't meant to print anything, the next call
// checks validity and keyUsage etc
- printCert("", certChain[0], true, 0);
+ printCert("", certChain[0], true, 0, true);
try {
CertPath cp = certificateFactory.generateCertPath(Arrays.asList(certChain));
--- a/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java Tue Dec 07 13:29:20 2010 +0000
@@ -49,7 +49,7 @@
/**
* PolicyTool may be used by users and administrators to configure the
* overall java security policy (currently stored in the policy file).
- * Using PolicyTool administators may add and remove policies from
+ * Using PolicyTool administrators may add and remove policies from
* the policy file. <p>
*
* @see java.security.Policy
@@ -1343,11 +1343,6 @@
PolicyTool.rb.getString
("Actions.");
- /* gridbag index for display OverWriteFile (OW) components */
- public static final int OW_LABEL = 0;
- public static final int OW_OK_BUTTON = 1;
- public static final int OW_CANCEL_BUTTON = 2;
-
/* gridbag index for display PolicyEntry (PE) components */
public static final int PE_CODEBASE_LABEL = 0;
public static final int PE_CODEBASE_TEXTFIELD = 1;
@@ -1523,44 +1518,6 @@
}
/**
- * ask user if they want to overwrite an existing file
- */
- void displayOverWriteFileDialog(String filename, int nextEvent) {
-
- // find where the PolicyTool gui is
- Point location = tw.getLocationOnScreen();
- setBounds(location.x + 75, location.y + 100, 400, 150);
- setLayout(new GridBagLayout());
-
- // ask the user if they want to over write the existing file
- MessageFormat form = new MessageFormat(PolicyTool.rb.getString
- ("OK.to.overwrite.existing.file.filename."));
- Object[] source = {filename};
- Label label = new Label(form.format(source));
- tw.addNewComponent(this, label, OW_LABEL,
- 0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.BOTH,
- tw.TOP_PADDING);
-
- // OK button
- Button button = new Button(PolicyTool.rb.getString("OK"));
- button.addActionListener(new OverWriteFileOKButtonListener
- (tool, tw, this, filename, nextEvent));
- tw.addNewComponent(this, button, OW_OK_BUTTON,
- 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.VERTICAL,
- tw.TOP_PADDING);
-
- // Cancel button
- // -- if the user hits cancel, do NOT go on to the next event
- button = new Button(PolicyTool.rb.getString("Cancel"));
- button.addActionListener(new CancelButtonListener(this));
- tw.addNewComponent(this, button, OW_CANCEL_BUTTON,
- 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.VERTICAL,
- tw.TOP_PADDING);
-
- setVisible(true);
- }
-
- /**
* pop up a dialog so the user can enter info to add a new PolicyEntry
* - if edit is TRUE, then the user is editing an existing entry
* and we should display the original info as well.
@@ -2339,47 +2296,39 @@
return;
// get the entered filename
- String filename = new String(fd.getDirectory() + fd.getFile());
+ File saveAsFile = new File(fd.getDirectory(), fd.getFile());
+ String filename = saveAsFile.getPath();
fd.dispose();
- // see if the file already exists
- File saveAsFile = new File(filename);
- if (saveAsFile.exists()) {
- // display a dialog box for the user to enter policy info
- ToolDialog td = new ToolDialog
- (PolicyTool.rb.getString("Overwrite.File"), tool, tw, true);
- td.displayOverWriteFileDialog(filename, nextEvent);
- } else {
- try {
- // save the policy entries to a file
- tool.savePolicy(filename);
-
- // display status
- MessageFormat form = new MessageFormat(PolicyTool.rb.getString
- ("Policy.successfully.written.to.filename"));
- Object[] source = {filename};
- tw.displayStatusDialog(null, form.format(source));
-
- // display the new policy filename
- TextField newFilename = (TextField)tw.getComponent
- (tw.MW_FILENAME_TEXTFIELD);
- newFilename.setText(filename);
- tw.setVisible(true);
-
- // now continue with the originally requested command
- // (QUIT, NEW, or OPEN)
- userSaveContinue(tool, tw, this, nextEvent);
-
- } catch (FileNotFoundException fnfe) {
- if (filename == null || filename.equals("")) {
- tw.displayErrorDialog(null, new FileNotFoundException
- (PolicyTool.rb.getString("null.filename")));
- } else {
- tw.displayErrorDialog(null, fnfe);
- }
- } catch (Exception ee) {
- tw.displayErrorDialog(null, ee);
+ try {
+ // save the policy entries to a file
+ tool.savePolicy(filename);
+
+ // display status
+ MessageFormat form = new MessageFormat(PolicyTool.rb.getString
+ ("Policy.successfully.written.to.filename"));
+ Object[] source = {filename};
+ tw.displayStatusDialog(null, form.format(source));
+
+ // display the new policy filename
+ TextField newFilename = (TextField)tw.getComponent
+ (tw.MW_FILENAME_TEXTFIELD);
+ newFilename.setText(filename);
+ tw.setVisible(true);
+
+ // now continue with the originally requested command
+ // (QUIT, NEW, or OPEN)
+ userSaveContinue(tool, tw, this, nextEvent);
+
+ } catch (FileNotFoundException fnfe) {
+ if (filename == null || filename.equals("")) {
+ tw.displayErrorDialog(null, new FileNotFoundException
+ (PolicyTool.rb.getString("null.filename")));
+ } else {
+ tw.displayErrorDialog(null, fnfe);
}
+ } catch (Exception ee) {
+ tw.displayErrorDialog(null, ee);
}
}
@@ -2494,7 +2443,7 @@
return;
// get the entered filename
- String policyFile = new String(fd.getDirectory() + fd.getFile());
+ String policyFile = new File(fd.getDirectory(), fd.getFile()).getPath();
try {
// open the policy file
@@ -2862,67 +2811,6 @@
}
/**
- * Event handler for OverWriteFileOKButton button
- */
-class OverWriteFileOKButtonListener implements ActionListener {
-
- private PolicyTool tool;
- private ToolWindow tw;
- private ToolDialog td;
- private String filename;
- private int nextEvent;
-
- OverWriteFileOKButtonListener(PolicyTool tool, ToolWindow tw,
- ToolDialog td, String filename, int nextEvent) {
- this.tool = tool;
- this.tw = tw;
- this.td = td;
- this.filename = filename;
- this.nextEvent = nextEvent;
- }
-
- public void actionPerformed(ActionEvent e) {
- try {
- // save the policy entries to a file
- tool.savePolicy(filename);
-
- // display status
- MessageFormat form = new MessageFormat
- (PolicyTool.rb.getString
- ("Policy.successfully.written.to.filename"));
- Object[] source = {filename};
- tw.displayStatusDialog(null, form.format(source));
-
- // display the new policy filename
- TextField newFilename = (TextField)tw.getComponent
- (tw.MW_FILENAME_TEXTFIELD);
- newFilename.setText(filename);
- tw.setVisible(true);
-
- // now continue with the originally requested command
- // (QUIT, NEW, or OPEN)
- td.setVisible(false);
- td.dispose();
- td.userSaveContinue(tool, tw, td, nextEvent);
-
- } catch (FileNotFoundException fnfe) {
- if (filename == null || filename.equals("")) {
- tw.displayErrorDialog(null, new FileNotFoundException
- (PolicyTool.rb.getString("null.filename")));
- } else {
- tw.displayErrorDialog(null, fnfe);
- }
- td.setVisible(false);
- td.dispose();
- } catch (Exception ee) {
- tw.displayErrorDialog(null, ee);
- td.setVisible(false);
- td.dispose();
- }
- }
-}
-
-/**
* Event handler for AddEntryDoneButton button
*
* -- if edit is TRUE, then we are EDITing an existing PolicyEntry
--- a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -185,7 +185,10 @@
Hashtable<String, CodeSigner[]> sigFileSigners)
throws JarException
{
- if (skip) return null;
+ // MANIFEST.MF should not be skipped. It has signers.
+ if (skip && !entry.getName().equals(JarFile.MANIFEST_NAME)) {
+ return null;
+ }
if (signers != null)
return signers;
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue Dec 07 13:29:20 2010 +0000
@@ -265,6 +265,9 @@
debug.println("processSignature unsigned name = "+name);
}
}
+
+ // MANIFEST.MF is always regarded as signed
+ updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
}
/**
--- a/jdk/src/share/demo/nio/zipfs/Demo.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/demo/nio/zipfs/Demo.java Tue Dec 07 13:29:20 2010 +0000
@@ -45,12 +45,7 @@
/*
* ZipFileSystem usage demo
*
- * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...]
- *
- * To deploy the provider, either copy the zipfs.jar into JDK/JRE
- * extensions directory or add
- * <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
- * into your class path as showed above.
+ * java Demo action ZipfileName [...]
*
* @author Xueming Shen
*/
@@ -153,14 +148,11 @@
Action action = Action.valueOf(args[0]);
Map<String, Object> env = env = new HashMap<>();
if (action == Action.create)
- env.put("createNew", true);
+ env.put("create", "true");
if (action == Action.tlist || action == Action.twalk)
env.put("buildDirTree", true);
+ FileSystem fs = FileSystems.newFileSystem(Paths.get(args[1]), env, null);
- FileSystem fs = FileSystems.newFileSystem(
- URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)),
- env,
- null);
try {
FileSystem fs2;
Path path, src, dst;
@@ -207,19 +199,13 @@
src.copyTo(dst, COPY_ATTRIBUTES);
break;
case zzmove:
- fs2 = FileSystems.newFileSystem(
- URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
- env,
- null);
+ fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
//sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
z2zmove(fs, fs2, args[3]);
fs2.close();
break;
case zzcopy:
- fs2 = FileSystems.newFileSystem(
- URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
- env,
- null);
+ fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
//sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
z2zcopy(fs, fs2, args[3]);
fs2.close();
--- a/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-com.sun.nio.zipfs.ZipFileSystemProvider
-com.sun.nio.zipfs.JarFileSystemProvider
-
--- a/jdk/src/share/demo/nio/zipfs/README.txt Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/demo/nio/zipfs/README.txt Tue Dec 07 13:29:20 2010 +0000
@@ -1,10 +1,6 @@
ZipFileSystem is a file system provider that treats the contents of a zip or
JAR file as a java.nio.file.FileSystem.
-To deploy the provider you must copy zipfs.jar into your extensions
-directory or else add <JDK_HOME>/demo/nio/zipfs/zipfs.jar
-to your class path.
-
The factory methods defined by the java.nio.file.FileSystems class can be
used to create a FileSystem, eg:
@@ -15,9 +11,9 @@
-or
- // locate file system by URI
+ // locate file system by the legacy JAR URL syntax
Map<String,?> env = Collections.emptyMap();
- URI uri = URI.create("zip:///mydir/foo.jar");
+ URI uri = URI.create("jar:file:/mydir/foo.jar");
FileSystem fs = FileSystems.newFileSystem(uri, env);
Once a FileSystem is created then classes in the java.nio.file package
@@ -26,4 +22,6 @@
Path mf = fs.getPath("/META-INF/MANIFEST.MF");
InputStream in = mf.newInputStream();
+See Demo.java for more interesting usages.
+
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Sun Microsystems nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.sun.nio.zipfs;
-
-import java.nio.file.*;
-import java.nio.file.spi.*;
-import java.nio.file.attribute.*;
-import java.nio.file.spi.FileSystemProvider;
-
-import java.net.URI;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.channels.FileChannel;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class JarFileSystemProvider extends ZipFileSystemProvider
-{
-
- @Override
- public String getScheme() {
- return "jar";
- }
-
- @Override
- protected Path uriToPath(URI uri) {
- String scheme = uri.getScheme();
- if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
- throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
- }
- try {
- String uristr = uri.toString();
- int end = uristr.indexOf("!/");
- uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
- uri = new URI(uristr);
- return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
- .toAbsolutePath();
- } catch (URISyntaxException e) {
- throw new AssertionError(e); //never thrown
- }
- }
-
- @Override
- public Path getPath(URI uri) {
- FileSystem fs = getFileSystem(uri);
- String path = uri.getFragment();
- if (path == null) {
- String uristr = uri.toString();
- int off = uristr.indexOf("!/");
- if (off != -1)
- path = uristr.substring(off + 2);
- }
- if (path != null)
- return fs.getPath(path);
- throw new IllegalArgumentException("URI: "
- + uri
- + " does not contain path fragment ex. jar:///c:/foo.zip!/BAR");
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.util.Arrays;
-
-/**
- * Utility class for zipfile name and comment decoding and encoding
- *
- * @author Xueming Shen
- */
-
-final class ZipCoder {
-
- String toString(byte[] ba, int length) {
- CharsetDecoder cd = decoder().reset();
- int len = (int)(length * cd.maxCharsPerByte());
- char[] ca = new char[len];
- if (len == 0)
- return new String(ca);
- ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
- CharBuffer cb = CharBuffer.wrap(ca);
- CoderResult cr = cd.decode(bb, cb, true);
- if (!cr.isUnderflow())
- throw new IllegalArgumentException(cr.toString());
- cr = cd.flush(cb);
- if (!cr.isUnderflow())
- throw new IllegalArgumentException(cr.toString());
- return new String(ca, 0, cb.position());
- }
-
- String toString(byte[] ba) {
- return toString(ba, ba.length);
- }
-
- byte[] getBytes(String s) {
- CharsetEncoder ce = encoder().reset();
- char[] ca = s.toCharArray();
- int len = (int)(ca.length * ce.maxBytesPerChar());
- byte[] ba = new byte[len];
- if (len == 0)
- return ba;
- ByteBuffer bb = ByteBuffer.wrap(ba);
- CharBuffer cb = CharBuffer.wrap(ca);
- CoderResult cr = ce.encode(cb, bb, true);
- if (!cr.isUnderflow())
- throw new IllegalArgumentException(cr.toString());
- cr = ce.flush(bb);
- if (!cr.isUnderflow())
- throw new IllegalArgumentException(cr.toString());
- if (bb.position() == ba.length) // defensive copy?
- return ba;
- else
- return Arrays.copyOf(ba, bb.position());
- }
-
- // assume invoked only if "this" is not utf8
- byte[] getBytesUTF8(String s) {
- if (isutf8)
- return getBytes(s);
- if (utf8 == null)
- utf8 = new ZipCoder(Charset.forName("UTF-8"));
- return utf8.getBytes(s);
- }
-
- String toStringUTF8(byte[] ba, int len) {
- if (isutf8)
- return toString(ba, len);
- if (utf8 == null)
- utf8 = new ZipCoder(Charset.forName("UTF-8"));
- return utf8.toString(ba, len);
- }
-
- boolean isUTF8() {
- return isutf8;
- }
-
- private Charset cs;
- private boolean isutf8;
- private ZipCoder utf8;
-
- private ZipCoder(Charset cs) {
- this.cs = cs;
- this.isutf8 = cs.name().equals("UTF-8");
- }
-
- static ZipCoder get(Charset charset) {
- return new ZipCoder(charset);
- }
-
- static ZipCoder get(String csn) {
- try {
- return new ZipCoder(Charset.forName(csn));
- } catch (Throwable t) {
- t.printStackTrace();
- }
- return new ZipCoder(Charset.defaultCharset());
- }
-
- private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
- private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
-
- private CharsetDecoder decoder() {
- CharsetDecoder dec = decTL.get();
- if (dec == null) {
- dec = cs.newDecoder()
- .onMalformedInput(CodingErrorAction.REPORT)
- .onUnmappableCharacter(CodingErrorAction.REPORT);
- decTL.set(dec);
- }
- return dec;
- }
-
- private CharsetEncoder encoder() {
- CharsetEncoder enc = encTL.get();
- if (enc == null) {
- enc = cs.newEncoder()
- .onMalformedInput(CodingErrorAction.REPORT)
- .onUnmappableCharacter(CodingErrorAction.REPORT);
- encTL.set(enc);
- }
- return enc;
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-
-/**
- *
- * @author Xueming Shen
- */
-
-class ZipConstants {
- /*
- * Compression methods
- */
- static final int METHOD_STORED = 0;
- static final int METHOD_DEFLATED = 8;
- static final int METHOD_DEFLATED64 = 9;
- static final int METHOD_BZIP2 = 12;
- static final int METHOD_LZMA = 14;
- static final int METHOD_LZ77 = 19;
- static final int METHOD_AES = 99;
-
- /*
- * General purpose big flag
- */
- static final int FLAG_ENCRYPTED = 0x01;
- static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd
- static final int FLAG_EFS = 0x800; // If this bit is set the filename and
- // comment fields for this file must be
- // encoded using UTF-8.
- /*
- * Header signatures
- */
- static long LOCSIG = 0x04034b50L; // "PK\003\004"
- static long EXTSIG = 0x08074b50L; // "PK\007\008"
- static long CENSIG = 0x02014b50L; // "PK\001\002"
- static long ENDSIG = 0x06054b50L; // "PK\005\006"
-
- /*
- * Header sizes in bytes (including signatures)
- */
- static final int LOCHDR = 30; // LOC header size
- static final int EXTHDR = 16; // EXT header size
- static final int CENHDR = 46; // CEN header size
- static final int ENDHDR = 22; // END header size
-
- /*
- * Local file (LOC) header field offsets
- */
- static final int LOCVER = 4; // version needed to extract
- static final int LOCFLG = 6; // general purpose bit flag
- static final int LOCHOW = 8; // compression method
- static final int LOCTIM = 10; // modification time
- static final int LOCCRC = 14; // uncompressed file crc-32 value
- static final int LOCSIZ = 18; // compressed size
- static final int LOCLEN = 22; // uncompressed size
- static final int LOCNAM = 26; // filename length
- static final int LOCEXT = 28; // extra field length
-
- /*
- * Extra local (EXT) header field offsets
- */
- static final int EXTCRC = 4; // uncompressed file crc-32 value
- static final int EXTSIZ = 8; // compressed size
- static final int EXTLEN = 12; // uncompressed size
-
- /*
- * Central directory (CEN) header field offsets
- */
- static final int CENVEM = 4; // version made by
- static final int CENVER = 6; // version needed to extract
- static final int CENFLG = 8; // encrypt, decrypt flags
- static final int CENHOW = 10; // compression method
- static final int CENTIM = 12; // modification time
- static final int CENCRC = 16; // uncompressed file crc-32 value
- static final int CENSIZ = 20; // compressed size
- static final int CENLEN = 24; // uncompressed size
- static final int CENNAM = 28; // filename length
- static final int CENEXT = 30; // extra field length
- static final int CENCOM = 32; // comment length
- static final int CENDSK = 34; // disk number start
- static final int CENATT = 36; // internal file attributes
- static final int CENATX = 38; // external file attributes
- static final int CENOFF = 42; // LOC header offset
-
- /*
- * End of central directory (END) header field offsets
- */
- static final int ENDSUB = 8; // number of entries on this disk
- static final int ENDTOT = 10; // total number of entries
- static final int ENDSIZ = 12; // central directory size in bytes
- static final int ENDOFF = 16; // offset of first CEN header
- static final int ENDCOM = 20; // zip file comment length
-
- /*
- * ZIP64 constants
- */
- static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
- static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
- static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
- static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
- static final int ZIP64_EXTHDR = 24; // EXT header size
- static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
-
- static final int ZIP64_MINVAL32 = 0xFFFF;
- static final long ZIP64_MINVAL = 0xFFFFFFFFL;
-
- /*
- * Zip64 End of central directory (END) header field offsets
- */
- static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
- static final int ZIP64_ENDVEM = 12; // version made by
- static final int ZIP64_ENDVER = 14; // version needed to extract
- static final int ZIP64_ENDNMD = 16; // number of this disk
- static final int ZIP64_ENDDSK = 20; // disk number of start
- static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
- static final int ZIP64_ENDTOT = 32; // total number of entries
- static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
- static final int ZIP64_ENDOFF = 48; // offset of first CEN header
- static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
-
- /*
- * Zip64 End of central directory locator field offsets
- */
- static final int ZIP64_LOCDSK = 4; // disk number start
- static final int ZIP64_LOCOFF = 8; // offset of zip64 end
- static final int ZIP64_LOCTOT = 16; // total number of disks
-
- /*
- * Zip64 Extra local (EXT) header field offsets
- */
- static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
- static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
- static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
-
- /*
- * Extra field header ID
- */
- static final int EXTID_ZIP64 = 0x0001; // ZIP64
- static final int EXTID_NTFS = 0x000a; // NTFS
- static final int EXTID_UNIX = 0x000d; // UNIX
- static final int EXTID_EFS = 0x0017; // Strong Encryption
- static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
-
- /*
- * fields access methods
- */
- ///////////////////////////////////////////////////////
- static final int CH(byte[] b, int n) {
- return b[n] & 0xff;
- }
-
- static final int SH(byte[] b, int n) {
- return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
- }
-
- static final long LG(byte[] b, int n) {
- return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
- }
-
- static final long LL(byte[] b, int n) {
- return (LG(b, n)) | (LG(b, n + 4) << 32);
- }
-
- static final long GETSIG(byte[] b) {
- return LG(b, 0);
- }
-
- // local file (LOC) header fields
- static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
- static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
- static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
- static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method
- static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
- static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
- static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
- static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
- static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length
- static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
-
- // extra local (EXT) header fields
- static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data
- static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size
- static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
-
- // end of central directory header (END) fields
- static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk
- static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries
- static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size
- static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset
- static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment
- static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
-
- // zip64 end of central directory recoder fields
- static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk
- static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries
- static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size
- static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset
- static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
-
- // central directory header (CEN) fields
- static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
- static final int CENVEM(byte[] b, int pos) { return SH(b, pos + 4); }
- static final int CENVER(byte[] b, int pos) { return SH(b, pos + 6); }
- static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
- static final int CENHOW(byte[] b, int pos) { return SH(b, pos + 10);}
- static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);}
- static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
- static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);}
- static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);}
- static final int CENNAM(byte[] b, int pos) { return SH(b, pos + 28);}
- static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
- static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
- static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
- static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
- static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
- static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
-
- /* The END header is followed by a variable length comment of size < 64k. */
- static final long END_MAXLEN = 0xFFFF + ENDHDR;
- static final int READBLOCKSZ = 128;
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.nio.file.DirectoryStream;
-import java.nio.file.ClosedDirectoryStreamException;
-import java.nio.file.NotDirectoryException;
-import java.nio.file.Path;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.io.IOException;
-
-/**
- *
- * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
- */
-
-public class ZipDirectoryStream implements DirectoryStream<Path> {
-
- private final ZipFileSystem zipfs;
- private final byte[] path;
- private final DirectoryStream.Filter<? super Path> filter;
- private volatile boolean isClosed;
- private volatile Iterator<Path> itr;
-
- ZipDirectoryStream(ZipPath zipPath,
- DirectoryStream.Filter<? super java.nio.file.Path> filter)
- throws IOException
- {
- this.zipfs = zipPath.getFileSystem();
- this.path = zipPath.getResolvedPath();
- this.filter = filter;
- // sanity check
- if (!zipfs.isDirectory(path))
- throw new NotDirectoryException(zipPath.toString());
- }
-
- @Override
- public synchronized Iterator<Path> iterator() {
- if (isClosed)
- throw new ClosedDirectoryStreamException();
- if (itr != null)
- throw new IllegalStateException("Iterator has already been returned");
-
- try {
- itr = zipfs.iteratorOf(path, filter);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- return new Iterator<>() {
- private Path next;
- @Override
- public boolean hasNext() {
- if (isClosed)
- return false;
- return itr.hasNext();
- }
-
- @Override
- public synchronized Path next() {
- if (isClosed)
- throw new NoSuchElementException();
- return itr.next();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- @Override
- public synchronized void close() throws IOException {
- isClosed = true;
- }
-
-
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-package com.sun.nio.zipfs;
-
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileTime;
-import java.io.IOException;
-import java.util.LinkedHashMap;
-
-/*
- * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
- */
-
-public class ZipFileAttributeView implements BasicFileAttributeView
-{
- private static enum AttrID {
- size,
- creationTime,
- lastAccessTime,
- lastModifiedTime,
- isDirectory,
- isRegularFile,
- isSymbolicLink,
- isOther,
- fileKey,
- compressedSize,
- crc,
- method
- };
-
- private final ZipPath path;
- private final boolean isZipView;
-
- private ZipFileAttributeView(ZipPath path, boolean isZipView) {
- this.path = path;
- this.isZipView = isZipView;
- }
-
- static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
- if (type == null)
- throw new NullPointerException();
- if (type == BasicFileAttributeView.class)
- return (V)new ZipFileAttributeView(path, false);
- if (type == ZipFileAttributeView.class)
- return (V)new ZipFileAttributeView(path, true);
- return null;
- }
-
- static ZipFileAttributeView get(ZipPath path, String type) {
- if (type == null)
- throw new NullPointerException();
- if (type.equals("basic"))
- return new ZipFileAttributeView(path, false);
- if (type.equals("zip"))
- return new ZipFileAttributeView(path, true);
- return null;
- }
-
- @Override
- public String name() {
- return isZipView ? "zip" : "basic";
- }
-
- public ZipFileAttributes readAttributes() throws IOException
- {
- return path.getAttributes();
- }
-
- @Override
- public void setTimes(FileTime lastModifiedTime,
- FileTime lastAccessTime,
- FileTime createTime)
- throws IOException
- {
- path.setTimes(lastModifiedTime, lastAccessTime, createTime);
- }
-
- void setAttribute(String attribute, Object value)
- throws IOException
- {
- try {
- if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
- setTimes ((FileTime)value, null, null);
- if (AttrID.valueOf(attribute) == AttrID.lastAccessTime)
- setTimes (null, (FileTime)value, null);
- if (AttrID.valueOf(attribute) == AttrID.creationTime)
- setTimes (null, null, (FileTime)value);
- return;
- } catch (IllegalArgumentException x) {}
- throw new UnsupportedOperationException("'" + attribute +
- "' is unknown or read-only attribute");
- }
-
- public Object getAttribute(String attribute, boolean domap)
- throws IOException
- {
- ZipFileAttributes zfas = readAttributes();
- if (!domap) {
- try {
- return attribute(AttrID.valueOf(attribute), zfas);
- } catch (IllegalArgumentException x) {}
- return null;
- }
- LinkedHashMap<String, Object> map = new LinkedHashMap<>();
- if ("*".equals(attribute)) {
- for (AttrID id : AttrID.values()) {
- try {
- map.put(id.name(), attribute(id, zfas));
- } catch (IllegalArgumentException x) {}
- }
- } else {
- String[] as = attribute.split(",");
- for (String a : as) {
- try {
- map.put(a, attribute(AttrID.valueOf(a), zfas));
- } catch (IllegalArgumentException x) {}
- }
- }
- return map;
- }
-
- Object attribute(AttrID id, ZipFileAttributes zfas) {
- switch (id) {
- case size:
- return zfas.size();
- case creationTime:
- return zfas.creationTime();
- case lastAccessTime:
- return zfas.lastAccessTime();
- case lastModifiedTime:
- return zfas.lastModifiedTime();
- case isDirectory:
- return zfas.isDirectory();
- case isRegularFile:
- return zfas.isRegularFile();
- case isSymbolicLink:
- return zfas.isSymbolicLink();
- case isOther:
- return zfas.isOther();
- case fileKey:
- return zfas.fileKey();
- case compressedSize:
- if (isZipView)
- return zfas.compressedSize();
- break;
- case crc:
- if (isZipView)
- return zfas.crc();
- break;
- case method:
- if (isZipView)
- return zfas.method();
- break;
- }
- return null;
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-package com.sun.nio.zipfs;
-
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileTime;
-import java.util.Arrays;
-import java.util.Formatter;
-import static com.sun.nio.zipfs.ZipUtils.*;
-
-/**
- *
- * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
- */
-
-public class ZipFileAttributes implements BasicFileAttributes
-
-{
- private final ZipFileSystem.Entry e;
-
- ZipFileAttributes(ZipFileSystem.Entry e) {
- this.e = e;
- }
-
- ///////// basic attributes ///////////
- @Override
- public FileTime creationTime() {
- if (e.ctime != -1)
- return FileTime.fromMillis(e.ctime);
- return null;
- }
-
- @Override
- public boolean isDirectory() {
- return e.isDir();
- }
-
- @Override
- public boolean isOther() {
- return false;
- }
-
- @Override
- public boolean isRegularFile() {
- return !e.isDir();
- }
-
- @Override
- public FileTime lastAccessTime() {
- if (e.atime != -1)
- return FileTime.fromMillis(e.atime);
- return null;
- }
-
- @Override
- public FileTime lastModifiedTime() {
- return FileTime.fromMillis(e.mtime);
- }
-
- @Override
- public long size() {
- return e.size;
- }
-
- @Override
- public boolean isSymbolicLink() {
- return false;
- }
-
- @Override
- public Object fileKey() {
- return null;
- }
-
- ///////// zip entry attributes ///////////
- public long compressedSize() {
- return e.csize;
- }
-
- public long crc() {
- return e.crc;
- }
-
- public int method() {
- return e.method;
- }
-
- public byte[] extra() {
- if (e.extra != null)
- return Arrays.copyOf(e.extra, e.extra.length);
- return null;
- }
-
- public byte[] comment() {
- if (e.comment != null)
- return Arrays.copyOf(e.comment, e.comment.length);
- return null;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder(1024);
- Formatter fm = new Formatter(sb);
- if (creationTime() != null)
- fm.format(" creationTime : %tc%n", creationTime().toMillis());
- else
- fm.format(" creationTime : null%n");
-
- if (lastAccessTime() != null)
- fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
- else
- fm.format(" lastAccessTime : null%n");
- fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
- fm.format(" isRegularFile : %b%n", isRegularFile());
- fm.format(" isDirectory : %b%n", isDirectory());
- fm.format(" isSymbolicLink : %b%n", isSymbolicLink());
- fm.format(" isOther : %b%n", isOther());
- fm.format(" fileKey : %s%n", fileKey());
- fm.format(" size : %d%n", size());
- fm.format(" compressedSize : %d%n", compressedSize());
- fm.format(" crc : %x%n", crc());
- fm.format(" method : %d%n", method());
- fm.close();
- return sb.toString();
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.io.IOException;
-import java.nio.file.FileStore;
-import java.nio.file.FileSystems;
-import java.nio.file.Path;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileStoreAttributeView;
-import java.nio.file.attribute.FileStoreSpaceAttributeView;
-import java.nio.file.attribute.FileStoreSpaceAttributes;
-import java.nio.file.attribute.Attributes;
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.util.Formatter;
-
-/*
- *
- * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
- */
-
-public class ZipFileStore extends FileStore {
-
- private final ZipFileSystem zfs;
-
- ZipFileStore(ZipPath zpath) {
- this.zfs = (ZipFileSystem)zpath.getFileSystem();
- }
-
- @Override
- public String name() {
- return zfs.toString() + "/";
- }
-
- @Override
- public String type() {
- return "zipfs";
- }
-
- @Override
- public boolean isReadOnly() {
- return zfs.isReadOnly();
- }
-
- @Override
- public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
- return (type == BasicFileAttributeView.class ||
- type == ZipFileAttributeView.class);
- }
-
- @Override
- public boolean supportsFileAttributeView(String name) {
- return name.equals("basic") || name.equals("zip");
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
- if (type == null)
- throw new NullPointerException();
- if (type == FileStoreSpaceAttributeView.class)
- return (V) new ZipFileStoreAttributeView(this);
- return null;
- }
-
- @Override
- public Object getAttribute(String attribute) throws IOException {
- if (attribute.equals("space:totalSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
- if (attribute.equals("space:usableSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
- if (attribute.equals("space:unallocatedSpace"))
- return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
- throw new UnsupportedOperationException("does not support the given attribute");
- }
-
- private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
-
- private final ZipFileStore fileStore;
-
- public ZipFileStoreAttributeView(ZipFileStore fileStore) {
- this.fileStore = fileStore;
- }
-
- @Override
- public String name() {
- return "space";
- }
-
- @Override
- public FileStoreSpaceAttributes readAttributes() throws IOException {
- final String file = fileStore.name();
- Path path = FileSystems.getDefault().getPath(file);
- final long size = Attributes.readBasicFileAttributes(path).size();
- final FileStore fstore = path.getFileStore();
- final FileStoreSpaceAttributes fstoreAttrs =
- Attributes.readFileStoreSpaceAttributes(fstore);
- return new FileStoreSpaceAttributes() {
- public long totalSpace() {
- return size;
- }
-
- public long usableSpace() {
- if (!fstore.isReadOnly())
- return fstoreAttrs.usableSpace();
- return 0;
- }
-
- public long unallocatedSpace() {
- if (!fstore.isReadOnly())
- return fstoreAttrs.unallocatedSpace();
- return 0;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- Formatter fm = new Formatter(sb);
- fm.format("FileStoreSpaceAttributes[%s]%n", file);
- fm.format(" totalSpace: %d%n", totalSpace());
- fm.format(" usableSpace: %d%n", usableSpace());
- fm.format(" unallocSpace: %d%n", unallocatedSpace());
- fm.close();
- return sb.toString();
- }
- };
- }
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2367 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.nio.file.spi.*;
-import java.util.*;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.regex.Pattern;
-import java.util.zip.CRC32;
-import java.util.zip.Inflater;
-import java.util.zip.Deflater;
-import java.util.zip.InflaterInputStream;
-import java.util.zip.DeflaterOutputStream;
-import java.util.zip.ZipException;
-import java.util.zip.ZipError;
-import static java.lang.Boolean.*;
-import static com.sun.nio.zipfs.ZipConstants.*;
-import static com.sun.nio.zipfs.ZipUtils.*;
-import static java.nio.file.StandardOpenOption.*;
-import static java.nio.file.StandardCopyOption.*;
-
-/**
- * A FileSystem built on a zip file
- *
- * @author Xueming Shen
- */
-
-public class ZipFileSystem extends FileSystem {
-
- private final ZipFileSystemProvider provider;
- private final ZipPath defaultdir;
- private boolean readOnly = false;
- private final Path zfpath;
- private final ZipCoder zc;
-
- // configurable by env map
- private final String defaultDir; // default dir for the file system
- private final String nameEncoding; // default encoding for name/comment
- private final boolean buildDirTree; // build a dir tree for directoryStream ops
- private final boolean useTempFile; // use a temp file for newOS, default
- // is to use BAOS for better performance
- private final boolean createNew; // create a new zip if not exists
- private static final boolean isWindows =
- System.getProperty("os.name").startsWith("Windows");
-
- ZipFileSystem(ZipFileSystemProvider provider,
- Path zfpath,
- Map<String, ?> env)
- throws IOException
- {
- // configurable env setup
- this.buildDirTree = TRUE.equals(env.get("buildDirTreea"));
- this.useTempFile = TRUE.equals(env.get("useTempFile"));
- this.createNew = TRUE.equals(env.get("createNew"));
- this.nameEncoding = env.containsKey("nameEncoding") ?
- (String)env.get("nameEncoding") : "UTF-8";
- this.defaultDir = env.containsKey("default.dir") ?
- (String)env.get("default.dir") : "/";
- if (this.defaultDir.charAt(0) != '/')
- throw new IllegalArgumentException("default dir should be absolute");
-
- this.provider = provider;
- this.zfpath = zfpath;
- if (zfpath.notExists()) {
- if (createNew) {
- OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
- new END().write(os, 0);
- os.close();
- } else {
- throw new FileSystemNotFoundException(zfpath.toString());
- }
- }
- zfpath.checkAccess(AccessMode.READ); // sm and existence check
- try {
- zfpath.checkAccess(AccessMode.WRITE);
- } catch (AccessDeniedException x) {
- this.readOnly = true;
- }
- this.zc = ZipCoder.get(nameEncoding);
- this.defaultdir = new ZipPath(this, getBytes(defaultDir));
- this.ch = zfpath.newByteChannel(READ);
- this.cen = initCEN();
- }
-
- @Override
- public FileSystemProvider provider() {
- return provider;
- }
-
- @Override
- public String getSeparator() {
- return "/";
- }
-
- @Override
- public boolean isOpen() {
- return isOpen;
- }
-
- @Override
- public boolean isReadOnly() {
- return readOnly;
- }
-
- private void checkWritable() throws IOException {
- if (readOnly)
- throw new ReadOnlyFileSystemException();
- }
-
- @Override
- public Iterable<Path> getRootDirectories() {
- ArrayList<Path> pathArr = new ArrayList<>();
- pathArr.add(new ZipPath(this, new byte[]{'/'}));
- return pathArr;
- }
-
- ZipPath getDefaultDir() { // package private
- return defaultdir;
- }
-
- @Override
- public ZipPath getPath(String path) {
- if (path.length() == 0)
- throw new InvalidPathException(path, "path should not be empty");
- return new ZipPath(this, getBytes(path));
- }
-
- @Override
- public UserPrincipalLookupService getUserPrincipalLookupService() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public WatchService newWatchService() {
- throw new UnsupportedOperationException();
- }
-
- FileStore getFileStore(ZipPath path) {
- return new ZipFileStore(path);
- }
-
- @Override
- public Iterable<FileStore> getFileStores() {
- ArrayList<FileStore> list = new ArrayList<>(1);
- list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
- return list;
- }
-
- private static final Set<String> supportedFileAttributeViews =
- Collections.unmodifiableSet(
- new HashSet<String>(Arrays.asList("basic", "zip")));
-
- @Override
- public Set<String> supportedFileAttributeViews() {
- return supportedFileAttributeViews;
- }
-
- @Override
- public String toString() {
- return zfpath.toString();
- }
-
- Path getZipFile() {
- return zfpath;
- }
-
- private static final String GLOB_SYNTAX = "glob";
- private static final String REGEX_SYNTAX = "regex";
-
- @Override
- public PathMatcher getPathMatcher(String syntaxAndInput) {
- int pos = syntaxAndInput.indexOf(':');
- if (pos <= 0 || pos == syntaxAndInput.length()) {
- throw new IllegalArgumentException();
- }
- String syntax = syntaxAndInput.substring(0, pos);
- String input = syntaxAndInput.substring(pos + 1);
- String expr;
- if (syntax.equals(GLOB_SYNTAX)) {
- expr = toRegexPattern(input);
- } else {
- if (syntax.equals(REGEX_SYNTAX)) {
- expr = input;
- } else {
- throw new UnsupportedOperationException("Syntax '" + syntax +
- "' not recognized");
- }
- }
- // return matcher
- final Pattern pattern = Pattern.compile(expr);
- return new PathMatcher() {
- @Override
- public boolean matches(Path path) {
- return pattern.matcher(path.toString()).matches();
- }
- };
- }
-
- @Override
- public void close() throws IOException {
- beginWrite();
- try {
- if (!isOpen)
- return;
- isOpen = false; // set closed
- } finally {
- endWrite();
- }
- if (!streams.isEmpty()) { // unlock and close all remaining streams
- Set<InputStream> copy = new HashSet<>(streams);
- for (InputStream is: copy)
- is.close();
- }
- beginWrite(); // lock and sync
- try {
- sync();
- ch.close(); // close the ch just in case no update
- } finally { // and sync dose not close the ch
- endWrite();
- }
-
- synchronized (inflaters) {
- for (Inflater inf : inflaters)
- inf.end();
- }
- synchronized (deflaters) {
- for (Deflater def : deflaters)
- def.end();
- }
-
- synchronized (tmppaths) {
- for (Path p: tmppaths) {
- try {
- p.deleteIfExists();
- } catch (IOException x) {
- x.printStackTrace();
- }
- }
- }
- provider.removeFileSystem(zfpath);
- }
-
- ZipFileAttributes getFileAttributes(byte[] path)
- throws IOException
- {
- Entry e;
- beginRead();
- try {
- ensureOpen();
- e = getEntry0(path);
- } finally {
- endRead();
- }
- if (e == null) {
- if (path.length == 0) {
- e = new Entry(new byte[0]); // root
- } else if (buildDirTree) {
- IndexNode inode = getDirs().get(IndexNode.keyOf(path));
- if (inode == null)
- return null;
- e = new Entry(inode.name);
- } else {
- return null;
- }
- e.method = METHOD_STORED; // STORED for dir
- BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
- if (bfas.lastModifiedTime() != null)
- e.mtime = bfas.lastModifiedTime().toMillis();
- if (bfas.lastAccessTime() != null)
- e.atime = bfas.lastAccessTime().toMillis();
- if (bfas.creationTime() != null)
- e.ctime = bfas.creationTime().toMillis();
- }
- return new ZipFileAttributes(e);
- }
-
- void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
- throws IOException
- {
- checkWritable();
- beginWrite();
- try {
- ensureOpen();
- Entry e = getEntry0(path); // ensureOpen checked
- if (e == null)
- throw new NoSuchFileException(getString(path));
- if (e.type == Entry.CEN)
- e.type = Entry.COPY; // copy e
- if (mtime != null)
- e.mtime = mtime.toMillis();
- if (atime != null)
- e.atime = atime.toMillis();
- if (ctime != null)
- e.ctime = ctime.toMillis();
- update(e);
- } finally {
- endWrite();
- }
- }
-
- boolean exists(byte[] path)
- throws IOException
- {
- beginRead();
- try {
- ensureOpen();
- return getEntry0(path) != null;
- } finally {
- endRead();
- }
- }
-
- boolean isDirectory(byte[] path)
- throws IOException
- {
- if (buildDirTree)
- return getDirs().containsKey(IndexNode.keyOf(path));
-
- beginRead();
- try {
- Entry e = getEntry0(path);
- return (e != null && e.isDir()) || path.length == 0;
- } finally {
- endRead();
- }
- }
-
- private ZipPath toZipPath(byte[] path) {
- // make it absolute
- byte[] p = new byte[path.length + 1];
- p[0] = '/';
- System.arraycopy(path, 0, p, 1, path.length);
- return new ZipPath(this, p);
- }
-
- // returns the list of child paths of "path"
- Iterator<Path> iteratorOf(byte[] path,
- DirectoryStream.Filter<? super Path> filter)
- throws IOException
- {
- beginWrite(); // iteration of inodes needs exclusive lock
- try {
- ensureOpen();
- if (buildDirTree) {
- IndexNode inode = getDirs().get(IndexNode.keyOf(path));
- if (inode == null)
- throw new NotDirectoryException(getString(path));
- List<Path> list = new ArrayList<>();
- IndexNode child = inode.child;
- while (child != null) {
- ZipPath zp = toZipPath(child.name);
- if (filter == null || filter.accept(zp))
- list.add(zp);
- child = child.sibling;
- }
- return list.iterator();
- }
-
- if (!isDirectory(path))
- throw new NotDirectoryException(getString(path));
- List<Path> list = new ArrayList<>();
- path = toDirectoryPath(path);
- for (IndexNode key : inodes.keySet()) {
- if (!isParentOf(path, key.name)) // is "path" the parent of "name"
- continue;
- int off = path.length;
- while (off < key.name.length) {
- if (key.name[off] == '/')
- break;
- off++;
- }
- if (off < (key.name.length - 1))
- continue;
- ZipPath zp = toZipPath(key.name);
- if (filter == null || filter.accept(zp))
- list.add(zp);
- }
- return list.iterator();
- } finally {
- endWrite();
- }
- }
-
- void createDirectory(byte[] dir, FileAttribute<?>... attrs)
- throws IOException
- {
- checkWritable();
- dir = toDirectoryPath(dir);
- beginWrite();
- try {
- ensureOpen();
- if (dir.length == 0 || exists(dir)) // root dir, or exiting dir
- throw new FileAlreadyExistsException(getString(dir));
-
- checkParents(dir);
- Entry e = new Entry(dir, Entry.NEW);
- e.method = METHOD_STORED; // STORED for dir
- update(e);
- } finally {
- endWrite();
- }
- }
-
- void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
- throws IOException
- {
- checkWritable();
- if (Arrays.equals(src, dst))
- return; // do nothing, src and dst are the same
-
- beginWrite();
- try {
- ensureOpen();
- Entry eSrc = getEntry0(src); // ensureOpen checked
- if (eSrc == null)
- throw new NoSuchFileException(getString(src));
- if (eSrc.isDir()) { // spec says to create dst dir
- createDirectory(dst);
- return;
- }
- boolean hasReplace = false;
- boolean hasCopyAttrs = false;
- for (CopyOption opt : options) {
- if (opt == REPLACE_EXISTING)
- hasReplace = true;
- else if (opt == COPY_ATTRIBUTES)
- hasCopyAttrs = true;
- }
- Entry eDst = getEntry0(dst);
- if (eDst != null) {
- if (!hasReplace)
- throw new FileAlreadyExistsException(getString(dst));
- } else {
- checkParents(dst);
- }
- Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry
- u.name = dst; // change name
- if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
- {
- u.type = eSrc.type; // make it the same type
- if (!deletesrc) { // if it's not "rename", just take the data
- if (eSrc.bytes != null)
- u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
- else if (eSrc.file != null) {
- u.file = getTempPathForEntry(null);
- eSrc.file.copyTo(u.file, REPLACE_EXISTING);
- }
- }
- }
- if (!hasCopyAttrs)
- u.mtime = u.atime= u.ctime = System.currentTimeMillis();
- update(u);
- if (deletesrc)
- updateDelete(eSrc);
- } finally {
- endWrite();
- }
- }
-
- // Returns an output stream for writing the contents into the specified
- // entry.
- OutputStream newOutputStream(byte[] path, OpenOption... options)
- throws IOException
- {
- checkWritable();
- boolean hasCreateNew = false;
- boolean hasCreate = false;
- boolean hasAppend = false;
- for (OpenOption opt: options) {
- if (opt == READ)
- throw new IllegalArgumentException("READ not allowed");
- if (opt == CREATE_NEW)
- hasCreateNew = true;
- if (opt == CREATE)
- hasCreate = true;
- if (opt == APPEND)
- hasAppend = true;
- }
- beginRead(); // only need a readlock, the "update()" will
- try { // try to obtain a writelock when the os is
- ensureOpen(); // being closed.
- Entry e = getEntry0(path);
- if (e != null) {
- if (e.isDir() || hasCreateNew)
- throw new FileAlreadyExistsException(getString(path));
- if (hasAppend) {
- InputStream is = getInputStream(e);
- OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
- copyStream(is, os);
- is.close();
- return os;
- }
- return getOutputStream(new Entry(e, Entry.NEW));
- } else {
- if (!hasCreate && !hasCreateNew)
- throw new NoSuchFileException(getString(path));
- checkParents(path);
- return getOutputStream(new Entry(path, Entry.NEW));
- }
- } finally {
- endRead();
- }
- }
-
- // Returns an input stream for reading the contents of the specified
- // file entry.
- InputStream newInputStream(byte[] path) throws IOException {
- beginRead();
- try {
- ensureOpen();
- Entry e = getEntry0(path);
- if (e == null)
- throw new NoSuchFileException(getString(path));
- if (e.isDir())
- throw new FileSystemException(getString(path), "is a directory", null);
- return getInputStream(e);
- } finally {
- endRead();
- }
- }
-
- private void checkOptions(Set<? extends OpenOption> options) {
- // check for options of null type and option is an intance of StandardOpenOption
- for (OpenOption option : options) {
- if (option == null)
- throw new NullPointerException();
- if (!(option instanceof StandardOpenOption))
- throw new IllegalArgumentException();
- }
- }
-
- // Returns a Writable/ReadByteChannel for now. Might consdier to use
- // newFileChannel() instead, which dump the entry data into a regular
- // file on the default file system and create a FileChannel on top of
- // it.
- SeekableByteChannel newByteChannel(byte[] path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- checkOptions(options);
- if (options.contains(StandardOpenOption.WRITE) ||
- options.contains(StandardOpenOption.APPEND)) {
- checkWritable();
- beginRead();
- try {
- final WritableByteChannel wbc = Channels.newChannel(
- newOutputStream(path, options.toArray(new OpenOption[0])));
- long leftover = 0;
- if (options.contains(StandardOpenOption.APPEND)) {
- Entry e = getEntry0(path);
- if (e != null && e.size >= 0)
- leftover = e.size;
- }
- final long offset = leftover;
- return new SeekableByteChannel() {
- long written = offset;
- public boolean isOpen() {
- return wbc.isOpen();
- }
-
- public long position() throws IOException {
- return written;
- }
-
- public SeekableByteChannel position(long pos)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
-
- public int read(ByteBuffer dst) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- public SeekableByteChannel truncate(long size)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
-
- public int write(ByteBuffer src) throws IOException {
- int n = wbc.write(src);
- written += n;
- return n;
- }
-
- public long size() throws IOException {
- return written;
- }
-
- public void close() throws IOException {
- wbc.close();
- }
- };
- } finally {
- endRead();
- }
- } else {
- beginRead();
- try {
- ensureOpen();
- Entry e = getEntry0(path);
- if (e == null || e.isDir())
- throw new NoSuchFileException(getString(path));
- final ReadableByteChannel rbc =
- Channels.newChannel(getInputStream(e));
- final long size = e.size;
- return new SeekableByteChannel() {
- long read = 0;
- public boolean isOpen() {
- return rbc.isOpen();
- }
-
- public long position() throws IOException {
- return read;
- }
-
- public SeekableByteChannel position(long pos)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
-
- public int read(ByteBuffer dst) throws IOException {
- return rbc.read(dst);
- }
-
- public SeekableByteChannel truncate(long size)
- throws IOException
- {
- throw new NonWritableChannelException();
- }
-
- public int write (ByteBuffer src) throws IOException {
- throw new NonWritableChannelException();
- }
-
- public long size() throws IOException {
- return size;
- }
-
- public void close() throws IOException {
- rbc.close();
- }
- };
- } finally {
- endRead();
- }
- }
- }
-
- // Returns a FileChannel of the specified entry.
- //
- // This implementation creates a temporary file on the default file system,
- // copy the entry data into it if the entry exists, and then create a
- // FileChannel on top of it.
- FileChannel newFileChannel(byte[] path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- checkOptions(options);
- final boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
- options.contains(StandardOpenOption.APPEND));
- beginRead();
- try {
- ensureOpen();
- Entry e = getEntry0(path);
- if (forWrite) {
- checkWritable();
- if (e == null) {
- if (!options.contains(StandardOpenOption.CREATE_NEW))
- throw new NoSuchFileException(getString(path));
- } else {
- if (options.contains(StandardOpenOption.CREATE_NEW))
- throw new FileAlreadyExistsException(getString(path));
- if (e.isDir())
- throw new FileAlreadyExistsException("directory <"
- + getString(path) + "> exists");
- }
- options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
- } else if (e == null || e.isDir()) {
- throw new NoSuchFileException(getString(path));
- }
-
- final boolean isFCH = (e != null && e.type == Entry.FILECH);
- final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
- final FileChannel fch = tmpfile.getFileSystem()
- .provider()
- .newFileChannel(tmpfile, options, attrs);
- final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
- if (forWrite) {
- u.flag = FLAG_DATADESCR;
- u.method = METHOD_DEFLATED;
- }
- // is there a better way to hook into the FileChannel's close method?
- return new FileChannel() {
- public int write(ByteBuffer src) throws IOException {
- return fch.write(src);
- }
- public long write(ByteBuffer[] srcs, int offset, int length)
- throws IOException
- {
- return fch.write(srcs, offset, length);
- }
- public long position() throws IOException {
- return fch.position();
- }
- public FileChannel position(long newPosition)
- throws IOException
- {
- fch.position(newPosition);
- return this;
- }
- public long size() throws IOException {
- return fch.size();
- }
- public FileChannel truncate(long size)
- throws IOException
- {
- fch.truncate(size);
- return this;
- }
- public void force(boolean metaData)
- throws IOException
- {
- fch.force(metaData);
- }
- public long transferTo(long position, long count,
- WritableByteChannel target)
- throws IOException
- {
- return fch.transferTo(position, count, target);
- }
- public long transferFrom(ReadableByteChannel src,
- long position, long count)
- throws IOException
- {
- return fch.transferFrom(src, position, count);
- }
- public int read(ByteBuffer dst) throws IOException {
- return fch.read(dst);
- }
- public int read(ByteBuffer dst, long position)
- throws IOException
- {
- return fch.read(dst, position);
- }
- public long read(ByteBuffer[] dsts, int offset, int length)
- throws IOException
- {
- return fch.read(dsts, offset, length);
- }
- public int write(ByteBuffer src, long position)
- throws IOException
- {
- return fch.write(src, position);
- }
- public MappedByteBuffer map(MapMode mode,
- long position, long size)
- throws IOException
- {
- throw new UnsupportedOperationException();
- }
- public FileLock lock(long position, long size, boolean shared)
- throws IOException
- {
- return fch.lock(position, size, shared);
- }
- public FileLock tryLock(long position, long size, boolean shared)
- throws IOException
- {
- return fch.tryLock(position, size, shared);
- }
- protected void implCloseChannel() throws IOException {
- fch.close();
- if (forWrite) {
- u.mtime = System.currentTimeMillis();
- u.size = Attributes.readBasicFileAttributes(u.file).size();
- update(u);
- } else {
- if (!isFCH) // if this is a new fch for reading
- removeTempPathForEntry(tmpfile);
- }
- }
- };
- } finally {
- endRead();
- }
- }
-
- // the outstanding input streams that need to be closed
- private Set<InputStream> streams =
- Collections.synchronizedSet(new HashSet<InputStream>());
-
- // the ex-channel and ex-path that need to close when their outstanding
- // input streams are all closed by the obtainers.
- private Set<ExChannelCloser> exChClosers = new HashSet<>();
-
- private Set<Path> tmppaths = Collections.synchronizedSet(new HashSet<Path>());
- private Path getTempPathForEntry(byte[] path) throws IOException {
- Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
- if (path != null) {
- Entry e = getEntry0(path);
- if (e != null) {
- InputStream is = newInputStream(path);
- OutputStream os = tmpPath.newOutputStream(WRITE);
- try {
- copyStream(is, os);
- } finally {
- is.close();
- os.close();
- }
- }
- }
- return tmpPath;
- }
-
- private void removeTempPathForEntry(Path path) throws IOException {
- path.delete();
- tmppaths.remove(path);
- }
-
- // check if all parents really exit. ZIP spec does not require
- // the existence of any "parent directory".
- private void checkParents(byte[] path) throws IOException {
- beginRead();
- try {
- while ((path = getParent(path)) != null) {
- if (!inodes.containsKey(IndexNode.keyOf(path)))
- throw new NoSuchFileException(getString(path));
- }
- } finally {
- endRead();
- }
- }
-
- private static byte[] getParent(byte[] path) {
- int off = path.length - 1;
- if (off > 0 && path[off] == '/') // isDirectory
- off--;
- while (off > 0 && path[off] != '/') { off--; }
- if (off == 0)
- return null; // top entry
- return Arrays.copyOf(path, off + 1);
- }
-
- // If "starter" is the parent directory of "path"
- private static boolean isParentOf(byte[] p, byte[] c) {
- final int plen = p.length;
- if (plen == 0) // root dir
- return true;
- if (plen >= c.length)
- return false;
- int n = 0;
- while (n < plen) {
- if (p[n] != c[n])
- return false;
- n++;
- }
- if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
- return false;
- return true;
- }
-
- private final void beginWrite() {
- rwlock.writeLock().lock();
- }
-
- private final void endWrite() {
- rwlock.writeLock().unlock();
- }
-
- private final void beginRead() {
- rwlock.readLock().lock();
- }
-
- private final void endRead() {
- rwlock.readLock().unlock();
- }
-
- ///////////////////////////////////////////////////////////////////
-
- private volatile boolean isOpen = true;
- private final SeekableByteChannel ch; // channel to the zipfile
- final byte[] cen; // CEN & ENDHDR
- private END end;
- private long locpos; // position of first LOC header (usually 0)
-
- private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
-
- // name -> pos (in cen), IndexNode itself can be used as a "key"
- private LinkedHashMap<IndexNode, IndexNode> inodes;
-
- final byte[] getBytes(String name) {
- return zc.getBytes(name);
- }
-
- final String getString(byte[] name) {
- return zc.toString(name);
- }
-
- protected void finalize() throws IOException {
- close();
- }
-
- private long getDataPos(Entry e) throws IOException {
- if (e.locoff == -1) {
- Entry e2 = getEntry0(e.name);
- if (e2 == null)
- throw new ZipException("invalid loc for entry <" + e.name + ">");
- e.locoff = e2.locoff;
- }
- byte[] buf = new byte[LOCHDR];
- if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
- throw new ZipException("invalid loc for entry <" + e.name + ">");
- return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
- }
-
- // Reads len bytes of data from the specified offset into buf.
- // Returns the total number of bytes read.
- // Each/every byte read from here (except the cen, which is mapped).
- final long readFullyAt(byte[] buf, int off, long len, long pos)
- throws IOException
- {
- ByteBuffer bb = ByteBuffer.wrap(buf);
- bb.position(off);
- bb.limit((int)(off + len));
- return readFullyAt(bb, pos);
- }
-
- private final long readFullyAt(ByteBuffer bb, long pos)
- throws IOException
- {
- synchronized(ch) {
- return ch.position(pos).read(bb);
- }
- }
-
- // Searches for end of central directory (END) header. The contents of
- // the END header will be read and placed in endbuf. Returns the file
- // position of the END header, otherwise returns -1 if the END header
- // was not found or an error occurred.
- private END findEND() throws IOException
- {
- byte[] buf = new byte[READBLOCKSZ];
- long ziplen = ch.size();
- long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
- long minPos = minHDR - (buf.length - ENDHDR);
-
- for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
- {
- int off = 0;
- if (pos < 0) {
- // Pretend there are some NUL bytes before start of file
- off = (int)-pos;
- Arrays.fill(buf, 0, off, (byte)0);
- }
- int len = buf.length - off;
- if (readFullyAt(buf, off, len, pos + off) != len)
- zerror("zip END header not found");
-
- // Now scan the block backwards for END header signature
- for (int i = buf.length - ENDHDR; i >= 0; i--) {
- if (buf[i+0] == (byte)'P' &&
- buf[i+1] == (byte)'K' &&
- buf[i+2] == (byte)'\005' &&
- buf[i+3] == (byte)'\006' &&
- (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
- // Found END header
- buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
- END end = new END();
- end.endsub = ENDSUB(buf);
- end.centot = ENDTOT(buf);
- end.cenlen = ENDSIZ(buf);
- end.cenoff = ENDOFF(buf);
- end.comlen = ENDCOM(buf);
- end.endpos = pos + i;
- if (end.cenlen == ZIP64_MINVAL ||
- end.cenoff == ZIP64_MINVAL ||
- end.centot == ZIP64_MINVAL32)
- {
- // need to find the zip64 end;
- byte[] loc64 = new byte[ZIP64_LOCHDR];
- if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
- != loc64.length) {
- return end;
- }
- long end64pos = ZIP64_LOCOFF(loc64);
- byte[] end64buf = new byte[ZIP64_ENDHDR];
- if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
- != end64buf.length) {
- return end;
- }
- // end64 found, re-calcualte everything.
- end.cenlen = ZIP64_ENDSIZ(end64buf);
- end.cenoff = ZIP64_ENDOFF(end64buf);
- end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
- end.endpos = end64pos;
- }
- return end;
- }
- }
- }
- zerror("zip END header not found");
- return null; //make compiler happy
- }
-
- // Reads zip file central directory. Returns the file position of first
- // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
- // then the error was a zip format error and zip->msg has the error text.
- // Always pass in -1 for knownTotal; it's used for a recursive call.
- private byte[] initCEN() throws IOException {
- end = findEND();
- if (end.endpos == 0) {
- inodes = new LinkedHashMap<>(10);
- locpos = 0;
- return null; // only END header present
- }
- if (end.cenlen > end.endpos)
- zerror("invalid END header (bad central directory size)");
- long cenpos = end.endpos - end.cenlen; // position of CEN table
-
- // Get position of first local file (LOC) header, taking into
- // account that there may be a stub prefixed to the zip file.
- locpos = cenpos - end.cenoff;
- if (locpos < 0)
- zerror("invalid END header (bad central directory offset)");
-
- // read in the CEN and END
- byte[] cen = new byte[(int)(end.cenlen + ENDHDR)];
- if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
- zerror("read CEN tables failed");
- }
- // Iterate through the entries in the central directory
- inodes = new LinkedHashMap<>(end.centot + 1);
- int pos = 0;
- int limit = cen.length - ENDHDR;
- while (pos < limit) {
- if (CENSIG(cen, pos) != CENSIG)
- zerror("invalid CEN header (bad signature)");
- int method = CENHOW(cen, pos);
- int nlen = CENNAM(cen, pos);
- int elen = CENEXT(cen, pos);
- int clen = CENCOM(cen, pos);
- if ((CENFLG(cen, pos) & 1) != 0)
- zerror("invalid CEN header (encrypted entry)");
- if (method != METHOD_STORED && method != METHOD_DEFLATED)
- zerror("invalid CEN header (unsupported compression method: " + method + ")");
- if (pos + CENHDR + nlen > limit)
- zerror("invalid CEN header (bad header size)");
- byte[] name = Arrays.copyOfRange(cen, pos + CENHDR, pos + CENHDR + nlen);
- IndexNode inode = new IndexNode(name, pos);
- inodes.put(inode, inode);
- // skip ext and comment
- pos += (CENHDR + nlen + elen + clen);
- }
- if (pos + ENDHDR != cen.length) {
- zerror("invalid CEN header (bad header size)");
- }
- return cen;
- }
-
- private void ensureOpen() throws IOException {
- if (!isOpen)
- throw new ClosedFileSystemException();
- }
-
- // Creates a new empty temporary file in the same directory as the
- // specified file. A variant of File.createTempFile.
- private Path createTempFileInSameDirectoryAs(Path path)
- throws IOException
- {
- Path parent = path.toAbsolutePath().getParent();
- String dir = (parent == null)? "." : parent.toString();
- Path tmpPath = File.createTempFile("zipfstmp", null, new File(dir)).toPath();
- tmppaths.add(tmpPath);
- return tmpPath;
- }
-
- ////////////////////update & sync //////////////////////////////////////
-
- private boolean hasUpdate = false;
-
- private void updateDelete(Entry e) {
- beginWrite();
- try {
- inodes.remove(IndexNode.keyOf(e.name)); //inodes.remove(e.name);
- hasUpdate = true;
- dirs = null;
- } finally {
- endWrite();
- }
- }
-
- private void update(Entry e) {
- beginWrite();
- try {
- inodes.put(IndexNode.keyOf(e.name), e); //inodes.put(e, e);
- hasUpdate = true;
- dirs = null;
- } finally {
- endWrite();
- }
- }
-
- // copy over the whole LOC entry (header if necessary, data and ext) from
- // old zip to the new one.
- private long copyLOCEntry(Entry e, boolean updateHeader,
- OutputStream os,
- long written, byte[] buf)
- throws IOException
- {
- long locoff = e.locoff; // where to read
- e.locoff = written; // update the e.locoff with new value
-
- // calculate the size need to write out
- long size = 0;
- // if there is A ext
- if ((e.flag & FLAG_DATADESCR) != 0) {
- if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
- size = 24;
- else
- size = 16;
- }
- // read loc, use the original loc.elen/nlen
- if (readFullyAt(buf, 0, LOCHDR , locoff) != LOCHDR)
- throw new ZipException("loc: reading failed");
- if (updateHeader) {
- locoff += LOCHDR + LOCNAM(buf) + LOCEXT(buf); // skip header
- size += e.csize;
- written = e.writeLOC(os) + size;
- } else {
- os.write(buf, 0, LOCHDR); // write out the loc header
- locoff += LOCHDR;
- size += LOCNAM(buf) + LOCEXT(buf) + LOCSIZ(buf);
- written = LOCHDR + size;
- }
- int n;
- while (size > 0 &&
- (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
- {
- if (size < n)
- n = (int)size;
- os.write(buf, 0, n);
- size -= n;
- locoff += n;
- }
- return written;
- }
-
- // sync the zip file system, if there is any udpate
- private void sync() throws IOException {
- //System.out.printf("->sync(%s) starting....!%n", toString());
-
- // check ex-closer
- if (!exChClosers.isEmpty()) {
- for (ExChannelCloser ecc : exChClosers) {
- if (ecc.streams.isEmpty()) {
- ecc.ch.close();
- ecc.path.delete();
- exChClosers.remove(ecc);
- }
- }
- }
- if (!hasUpdate)
- return;
- Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
- OutputStream os = tmpFile.newOutputStream(WRITE);
- ArrayList<Entry> elist = new ArrayList<>(inodes.size());
- long written = 0;
- byte[] buf = new byte[8192];
- Entry e = null;
-
- // write loc
- for (IndexNode inode : inodes.values()) {
- if (inode instanceof Entry) { // an updated inode
- e = (Entry)inode;
- try {
- if (e.type == Entry.COPY) {
- // entry copy: the only thing changed is the "name"
- // and "nlen" in LOC header, so we udpate/rewrite the
- // LOC in new file and simply copy the rest (data and
- // ext) without enflating/deflating from the old zip
- // file LOC entry.
- written += copyLOCEntry(e, true, os, written, buf);
- } else { // NEW or FILECH
- e.locoff = written;
- written += e.writeLOC(os); // write loc header
- if (e.bytes != null) { // in-memory, deflated
- os.write(e.bytes); // already
- written += e.bytes.length;
- } else if (e.file != null) { // tmp file
- InputStream is = e.file.newInputStream();
- int n;
- if (e.type == Entry.NEW) { // deflated already
- while ((n = is.read(buf)) != -1) {
- os.write(buf, 0, n);
- written += n;
- }
- } else if (e.type == Entry.FILECH) {
- // the data are not deflated, use ZEOS
- OutputStream os2 = new EntryOutputStream(e, os);
- while ((n = is.read(buf)) != -1) {
- os2.write(buf, 0, n);
- }
- os2.close();
- written += e.csize;
- if ((e.flag & FLAG_DATADESCR) != 0)
- written += e.writeEXT(os);
- }
- is.close();
- e.file.delete();
- tmppaths.remove(e.file);
- } else {
- // dir, 0-length data
- }
- }
- elist.add(e);
- } catch (IOException x) {
- x.printStackTrace(); // skip any in-accurate entry
- }
- } else { // unchanged inode
- e = Entry.readCEN(this, inode.pos);
- try {
- written += copyLOCEntry(e, false, os, written, buf);
- elist.add(e);
- } catch (IOException x) {
- x.printStackTrace(); // skip any wrong entry
- }
- }
- }
-
- // now write back the cen and end table
- end.cenoff = written;
- for (Entry entry : elist) {
- written += entry.writeCEN(os);
- }
- end.centot = elist.size();
- end.cenlen = written - end.cenoff;
- end.write(os, written);
- os.close();
-
- if (!streams.isEmpty()) {
- //
- // TBD: ExChannelCloser should not be necessary if we only
- // sync when being closed, all streams should have been
- // closed already. Keep the logic here for now.
- //
- // There are outstanding input streams open on existing "ch",
- // so, don't close the "cha" and delete the "file for now, let
- // the "ex-channel-closer" to handle them
- ExChannelCloser ecc = new ExChannelCloser(
- createTempFileInSameDirectoryAs(zfpath),
- ch,
- streams);
- zfpath.moveTo(ecc.path, REPLACE_EXISTING);
- exChClosers.add(ecc);
- streams = Collections.synchronizedSet(new HashSet<InputStream>());
- } else {
- ch.close();
- zfpath.delete();
- }
-
- tmpFile.moveTo(zfpath, REPLACE_EXISTING);
- hasUpdate = false; // clear
- /*
- if (isOpen) {
- ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
- cen = initCEN();
- }
- */
- //System.out.printf("->sync(%s) done!%n", toString());
- }
-
- private Entry getEntry0(byte[] path) throws IOException {
- if (path == null)
- throw new NullPointerException("path");
- if (path.length == 0)
- return null;
- IndexNode inode = null;
- IndexNode key = IndexNode.keyOf(path);
- if ((inode = inodes.get(key)) == null) {
- if (path[path.length -1] == '/') // already has a slash
- return null;
- path = Arrays.copyOf(path, path.length + 1);
- path[path.length - 1] = '/';
- if ((inode = inodes.get(key.as(path))) == null)
- return null;
- }
- if (inode instanceof Entry)
- return (Entry)inode;
- return Entry.readCEN(this, inode.pos);
- }
-
- // Test if the "name" a parent directory of any entry (dir empty)
- boolean isAncestor(byte[] name) {
- for (Map.Entry<IndexNode, IndexNode> entry : inodes.entrySet()) {
- byte[] ename = entry.getKey().name;
- if (isParentOf(name, ename))
- return true;
- }
- return false;
- }
-
- public void deleteFile(byte[] path, boolean failIfNotExists)
- throws IOException
- {
- checkWritable();
- Entry e = getEntry0(path);
- if (e == null) {
- if (path != null && path.length == 0)
- throw new ZipException("root directory </> can't not be delete");
- if (failIfNotExists)
- throw new NoSuchFileException(getString(path));
- } else {
- if (e.isDir() && isAncestor(path))
- throw new DirectoryNotEmptyException(getString(path));
- updateDelete(e);
- }
- }
-
- private static void copyStream(InputStream is, OutputStream os)
- throws IOException
- {
- byte[] copyBuf = new byte[8192];
- int n;
- while ((n = is.read(copyBuf)) != -1) {
- os.write(copyBuf, 0, n);
- }
- }
-
- // Returns an out stream for either
- // (1) writing the contents of a new entry, if the entry exits, or
- // (2) updating/replacing the contents of the specified existing entry.
- private OutputStream getOutputStream(Entry e) throws IOException {
-
- if (e.mtime == -1)
- e.mtime = System.currentTimeMillis();
- if (e.method == -1)
- e.method = METHOD_DEFLATED; // TBD: use default method
- // store size, compressed size, and crc-32 in LOC header
- e.flag = 0;
- if (zc.isUTF8())
- e.flag |= FLAG_EFS;
- OutputStream os;
- if (useTempFile) {
- e.file = getTempPathForEntry(null);
- os = e.file.newOutputStream(WRITE);
- } else {
- os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
- }
- return new EntryOutputStream(e, os);
- }
-
- private InputStream getInputStream(Entry e)
- throws IOException
- {
- InputStream eis = null;
-
- if (e.type == Entry.NEW) {
- if (e.bytes != null)
- eis = new ByteArrayInputStream(e.bytes);
- else if (e.file != null)
- eis = e.file.newInputStream();
- else
- throw new ZipException("update entry data is missing");
- } else if (e.type == Entry.FILECH) {
- // FILECH result is un-compressed.
- eis = e.file.newInputStream();
- // TBD: wrap to hook close()
- // streams.add(eis);
- return eis;
- } else { // untouced CEN or COPY
- eis = new EntryInputStream(e, ch);
- }
- if (e.method == METHOD_DEFLATED) {
- // MORE: Compute good size for inflater stream:
- long bufSize = e.size + 2; // Inflater likes a bit of slack
- if (bufSize > 65536)
- bufSize = 8192;
- final long size = e.size;
- eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
-
- private boolean isClosed = false;
- public void close() throws IOException {
- if (!isClosed) {
- releaseInflater(inf);
- this.in.close();
- isClosed = true;
- streams.remove(this);
- }
- }
- // Override fill() method to provide an extra "dummy" byte
- // at the end of the input stream. This is required when
- // using the "nowrap" Inflater option. (it appears the new
- // zlib in 7 does not need it, but keep it for now)
- protected void fill() throws IOException {
- if (eof) {
- throw new EOFException(
- "Unexpected end of ZLIB input stream");
- }
- len = this.in.read(buf, 0, buf.length);
- if (len == -1) {
- buf[0] = 0;
- len = 1;
- eof = true;
- }
- inf.setInput(buf, 0, len);
- }
- private boolean eof;
-
- public int available() throws IOException {
- if (isClosed)
- return 0;
- long avail = size - inf.getBytesWritten();
- return avail > (long) Integer.MAX_VALUE ?
- Integer.MAX_VALUE : (int) avail;
- }
- };
- } else if (e.method == METHOD_STORED) {
- // TBD: wrap/ it does not seem necessary
- } else {
- throw new ZipException("invalid compression method");
- }
- streams.add(eis);
- return eis;
- }
-
- // Inner class implementing the input stream used to read
- // a (possibly compressed) zip file entry.
- private class EntryInputStream extends InputStream {
- private final SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
- // point to a new channel after sync()
- private long pos; // current position within entry data
- protected long rem; // number of remaining bytes within entry
- protected final long size; // uncompressed size of this entry
-
- EntryInputStream(Entry e, SeekableByteChannel zfch)
- throws IOException
- {
- this.zfch = zfch;
- rem = e.csize;
- size = e.size;
- pos = getDataPos(e);
- }
- public int read(byte b[], int off, int len) throws IOException {
- ensureOpen();
- if (rem == 0) {
- return -1;
- }
- if (len <= 0) {
- return 0;
- }
- if (len > rem) {
- len = (int) rem;
- }
- // readFullyAt()
- long n = 0;
- ByteBuffer bb = ByteBuffer.wrap(b);
- bb.position(off);
- bb.limit(off + len);
- synchronized(zfch) {
- n = zfch.position(pos).read(bb);
- }
- if (n > 0) {
- pos += n;
- rem -= n;
- }
- if (rem == 0) {
- close();
- }
- return (int)n;
- }
- public int read() throws IOException {
- byte[] b = new byte[1];
- if (read(b, 0, 1) == 1) {
- return b[0] & 0xff;
- } else {
- return -1;
- }
- }
- public long skip(long n) throws IOException {
- ensureOpen();
- if (n > rem)
- n = rem;
- pos += n;
- rem -= n;
- if (rem == 0) {
- close();
- }
- return n;
- }
- public int available() {
- return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
- }
-
- public long size() {
- return size;
- }
- public void close() {
- rem = 0;
- streams.remove(this);
- }
- }
-
- class EntryOutputStream extends DeflaterOutputStream
- {
- private CRC32 crc;
- private Entry e;
- private long written;
-
- EntryOutputStream(Entry e, OutputStream os)
- throws IOException
- {
- super(os, getDeflater());
- if (e == null)
- throw new NullPointerException("Zip entry is null");
- this.e = e;
- crc = new CRC32();
- }
-
- @Override
- public void write(byte b[], int off, int len) throws IOException {
- if (e.type != Entry.FILECH) // only from sync
- ensureOpen();
- if (off < 0 || len < 0 || off > b.length - len) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return;
- }
- switch (e.method) {
- case METHOD_DEFLATED:
- super.write(b, off, len);
- break;
- case METHOD_STORED:
- written += len;
- out.write(b, off, len);
- break;
- default:
- throw new ZipException("invalid compression method");
- }
- crc.update(b, off, len);
- }
-
- @Override
- public void close() throws IOException {
- // TBD ensureOpen();
- switch (e.method) {
- case METHOD_DEFLATED:
- finish();
- e.size = def.getBytesRead();
- e.csize = def.getBytesWritten();
- e.crc = crc.getValue();
- break;
- case METHOD_STORED:
- // we already know that both e.size and e.csize are the same
- e.size = e.csize = written;
- e.crc = crc.getValue();
- break;
- default:
- throw new ZipException("invalid compression method");
- }
- //crc.reset();
- if (out instanceof ByteArrayOutputStream)
- e.bytes = ((ByteArrayOutputStream)out).toByteArray();
-
- if (e.type == Entry.FILECH) {
- releaseDeflater(def);
- return;
- }
- super.close();
- releaseDeflater(def);
- update(e);
- }
- }
-
- static void zerror(String msg) {
- throw new ZipError(msg);
- }
-
- // Maxmum number of de/inflater we cache
- private final int MAX_FLATER = 20;
- // List of available Inflater objects for decompression
- private final List<Inflater> inflaters = new ArrayList<>();
-
- // Gets an inflater from the list of available inflaters or allocates
- // a new one.
- private Inflater getInflater() {
- synchronized (inflaters) {
- int size = inflaters.size();
- if (size > 0) {
- Inflater inf = (Inflater)inflaters.remove(size - 1);
- return inf;
- } else {
- return new Inflater(true);
- }
- }
- }
-
- // Releases the specified inflater to the list of available inflaters.
- private void releaseInflater(Inflater inf) {
- synchronized (inflaters) {
- if (inflaters.size() < MAX_FLATER) {
- inf.reset();
- inflaters.add(inf);
- } else {
- inf.end();
- }
- }
- }
-
- // List of available Deflater objects for compression
- private final List<Deflater> deflaters = new ArrayList<>();
-
- // Gets an deflater from the list of available deflaters or allocates
- // a new one.
- private Deflater getDeflater() {
- synchronized (deflaters) {
- int size = deflaters.size();
- if (size > 0) {
- Deflater def = (Deflater)deflaters.remove(size - 1);
- return def;
- } else {
- return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
- }
- }
- }
-
- // Releases the specified inflater to the list of available inflaters.
- private void releaseDeflater(Deflater def) {
- synchronized (deflaters) {
- if (inflaters.size() < MAX_FLATER) {
- def.reset();
- deflaters.add(def);
- } else {
- def.end();
- }
- }
- }
-
- // End of central directory record
- static class END {
- int disknum;
- int sdisknum;
- int endsub; // endsub
- int centot; // 4 bytes
- long cenlen; // 4 bytes
- long cenoff; // 4 bytes
- int comlen; // comment length
- byte[] comment;
-
- /* members of Zip64 end of central directory locator */
- int diskNum;
- long endpos;
- int disktot;
-
- void write(OutputStream os, long offset) throws IOException {
- boolean hasZip64 = false;
- long xlen = cenlen;
- long xoff = cenoff;
- if (xlen >= ZIP64_MINVAL) {
- xlen = ZIP64_MINVAL;
- hasZip64 = true;
- }
- if (xoff >= ZIP64_MINVAL) {
- xoff = ZIP64_MINVAL;
- hasZip64 = true;
- }
- int count = centot;
- if (count >= ZIP64_MINVAL32) {
- count = ZIP64_MINVAL32;
- hasZip64 = true;
- }
- if (hasZip64) {
- long off64 = offset;
- //zip64 end of central directory record
- writeInt(os, ZIP64_ENDSIG); // zip64 END record signature
- writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
- writeShort(os, 45); // version made by
- writeShort(os, 45); // version needed to extract
- writeInt(os, 0); // number of this disk
- writeInt(os, 0); // central directory start disk
- writeLong(os, centot); // number of directory entires on disk
- writeLong(os, centot); // number of directory entires
- writeLong(os, cenlen); // length of central directory
- writeLong(os, cenoff); // offset of central directory
-
- //zip64 end of central directory locator
- writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature
- writeInt(os, 0); // zip64 END start disk
- writeLong(os, off64); // offset of zip64 END
- writeInt(os, 1); // total number of disks (?)
- }
- writeInt(os, ENDSIG); // END record signature
- writeShort(os, 0); // number of this disk
- writeShort(os, 0); // central directory start disk
- writeShort(os, count); // number of directory entries on disk
- writeShort(os, count); // total number of directory entries
- writeInt(os, xlen); // length of central directory
- writeInt(os, xoff); // offset of central directory
- if (comment != null) { // zip file comment
- writeShort(os, comment.length);
- writeBytes(os, comment);
- } else {
- writeShort(os, 0);
- }
- }
- }
-
- // Internal node that links a "name" to its pos in cen table.
- // The node itself can be used as a "key" to lookup itself in
- // the HashMap inodes.
- static class IndexNode {
- byte[] name;
- int hashcode; // node is hashable/hashed by its name
- int pos = -1; // postion in cen table, -1 menas the
- // entry does not exists in zip file
- IndexNode(byte[] name, int pos) {
- as(name);
- this.pos = pos;
- }
-
- final static IndexNode keyOf(byte[] name) { // get a lookup key;
- return new IndexNode(name, -1);
- }
-
- final IndexNode as(byte[] name) { // reuse the node, mostly
- this.name = name; // as a lookup "key"
- this.hashcode = Arrays.hashCode(name);
- return this;
- }
-
- public boolean equals(Object other) {
- if (!(other instanceof IndexNode))
- return false;
- return Arrays.equals(name, ((IndexNode)other).name);
- }
-
- public int hashCode() {
- return hashcode;
- }
-
- IndexNode() {}
- IndexNode sibling;
- IndexNode child; // 1st child
- }
-
- static class Entry extends IndexNode {
-
- static final int CEN = 1; // entry read from cen
- static final int NEW = 2; // updated contents in bytes or file
- static final int FILECH = 3; // fch update in "file"
- static final int COPY = 4; // copy of a CEN entry
-
- byte[] bytes; // updated content bytes
- Path file; // use tmp file to store bytes;
- int type = CEN; // default is the entry read from cen
-
- // entry attributes
- int version;
- int flag;
- int method = -1; // compression method
- long mtime = -1; // last modification time (in DOS time)
- long atime = -1; // last access time
- long ctime = -1; // create time
- long crc = -1; // crc-32 of entry data
- long csize = -1; // compressed size of entry data
- long size = -1; // uncompressed size of entry data
- byte[] extra;
-
- // cen
- int versionMade;
- int disk;
- int attrs;
- long attrsEx;
- long locoff;
- byte[] comment;
-
- Entry() {}
-
- Entry(byte[] name) {
- this.name = name;
- this.mtime = System.currentTimeMillis();
- this.crc = 0;
- this.size = 0;
- this.csize = 0;
- this.method = METHOD_DEFLATED;
- }
-
- Entry(byte[] name, int type) {
- this(name);
- this.type = type;
- }
-
- Entry (Entry e, int type) {
- this.version = e.version;
- this.name = e.name;
- this.ctime = e.ctime;
- this.atime = e.atime;
- this.mtime = e.mtime;
- this.crc = e.crc;
- this.size = e.size;
- this.csize = e.csize;
- this.method = e.method;
- this.extra = e.extra;
- this.versionMade = e.versionMade;
- this.disk = e.disk;
- this.attrs = e.attrs;
- this.attrsEx = e.attrsEx;
- this.locoff = e.locoff;
- this.comment = e.comment;
-
- this.type = type;
- }
-
- Entry (byte[] name, Path file, int type) {
- this(name, type);
- this.file = file;
- this.method = METHOD_STORED;
- }
-
- boolean isDir() {
- return name != null &&
- (name.length == 0 ||
- name[name.length - 1] == '/');
- }
-
- int version() throws ZipException {
- if (method == METHOD_DEFLATED)
- return 20;
- else if (method == METHOD_STORED)
- return 10;
- throw new ZipException("unsupported compression method");
- }
-
- ///////////////////// CEN //////////////////////
- static Entry readCEN(ZipFileSystem zipfs, int pos)
- throws IOException
- {
- return new Entry().cen(zipfs, pos);
- }
-
- private Entry cen(ZipFileSystem zipfs, int pos)
- throws IOException
- {
- byte[] cen = zipfs.cen;
- if (CENSIG(cen, pos) != CENSIG)
- zerror("invalid CEN header (bad signature)");
- versionMade = CENVEM(cen, pos);
- version = CENVER(cen, pos);
- flag = CENFLG(cen, pos);
- method = CENHOW(cen, pos);
- mtime = dosToJavaTime(CENTIM(cen, pos));
- crc = CENCRC(cen, pos);
- csize = CENSIZ(cen, pos);
- size = CENLEN(cen, pos);
- int nlen = CENNAM(cen, pos);
- int elen = CENEXT(cen, pos);
- int clen = CENCOM(cen, pos);
- disk = CENDSK(cen, pos);
- attrs = CENATT(cen, pos);
- attrsEx = CENATX(cen, pos);
- locoff = CENOFF(cen, pos);
-
- pos += CENHDR;
- name = Arrays.copyOfRange(cen, pos, pos + nlen);
-
- pos += nlen;
- if (elen > 0) {
- extra = Arrays.copyOfRange(cen, pos, pos + elen);
- pos += elen;
- readExtra(zipfs);
- }
- if (clen > 0) {
- comment = Arrays.copyOfRange(cen, pos, pos + clen);
- }
- return this;
- }
-
- int writeCEN(OutputStream os) throws IOException
- {
- int written = CENHDR;
- int version0 = version();
-
- long csize0 = csize;
- long size0 = size;
- long locoff0 = locoff;
- int elen64 = 0; // extra for ZIP64
- int elenNTFS = 0; // extra for NTFS (a/c/mtime)
- int elenEXTT = 0; // extra for Extended Timestamp
-
- // confirm size/length
- int nlen = (name != null) ? name.length : 0;
- int elen = (extra != null) ? extra.length : 0;
- int clen = (comment != null) ? comment.length : 0;
- if (csize >= ZIP64_MINVAL) {
- csize0 = ZIP64_MINVAL;
- elen64 += 8; // csize(8)
- }
- if (size >= ZIP64_MINVAL) {
- size0 = ZIP64_MINVAL; // size(8)
- elen64 += 8;
- }
- if (locoff >= ZIP64_MINVAL) {
- locoff0 = ZIP64_MINVAL;
- elen64 += 8; // offset(8)
- }
- if (elen64 != 0)
- elen64 += 4; // header and data sz 4 bytes
-
- if (atime != -1) {
- if (isWindows) // use NTFS
- elenNTFS = 36; // total 36 bytes
- else // Extended Timestamp otherwise
- elenEXTT = 9; // only mtime in cen
- }
- writeInt(os, CENSIG); // CEN header signature
- if (elen64 != 0) {
- writeShort(os, 45); // ver 4.5 for zip64
- writeShort(os, 45);
- } else {
- writeShort(os, version0); // version made by
- writeShort(os, version0); // version needed to extract
- }
- writeShort(os, flag); // general purpose bit flag
- writeShort(os, method); // compression method
- // last modification time
- writeInt(os, (int)javaToDosTime(mtime));
- writeInt(os, crc); // crc-32
- writeInt(os, csize0); // compressed size
- writeInt(os, size0); // uncompressed size
- writeShort(os, name.length);
- writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
-
- if (comment != null) {
- writeShort(os, Math.min(clen, 0xffff));
- } else {
- writeShort(os, 0);
- }
- writeShort(os, 0); // starting disk number
- writeShort(os, 0); // internal file attributes (unused)
- writeInt(os, 0); // external file attributes (unused)
- writeInt(os, locoff0); // relative offset of local header
- writeBytes(os, name);
- if (elen64 != 0) {
- writeShort(os, EXTID_ZIP64);// Zip64 extra
- writeShort(os, elen64); // size of "this" extra block
- if (size0 == ZIP64_MINVAL)
- writeLong(os, size);
- if (csize0 == ZIP64_MINVAL)
- writeLong(os, csize);
- if (locoff0 == ZIP64_MINVAL)
- writeLong(os, locoff);
- }
- if (elenNTFS != 0) {
- // System.out.println("writing NTFS:" + elenNTFS);
- writeShort(os, EXTID_NTFS);
- writeShort(os, elenNTFS - 4);
- writeInt(os, 0); // reserved
- writeShort(os, 0x0001); // NTFS attr tag
- writeShort(os, 24);
- writeLong(os, javaToWinTime(mtime));
- writeLong(os, javaToWinTime(atime));
- writeLong(os, javaToWinTime(ctime));
- }
- if (elenEXTT != 0) {
- writeShort(os, EXTID_EXTT);
- writeShort(os, elenEXTT - 4);
- if (ctime == -1)
- os.write(0x3); // mtime and atime
- else
- os.write(0x7); // mtime, atime and ctime
- writeInt(os, javaToUnixTime(mtime));
- }
- if (extra != null) // whatever not recognized
- writeBytes(os, extra);
- if (comment != null) //TBD: 0, Math.min(commentBytes.length, 0xffff));
- writeBytes(os, comment);
- return CENHDR + nlen + elen + clen + elen64 + elenNTFS + elenEXTT;
- }
-
- ///////////////////// LOC //////////////////////
- static Entry readLOC(ZipFileSystem zipfs, long pos)
- throws IOException
- {
- return readLOC(zipfs, pos, new byte[1024]);
- }
-
- static Entry readLOC(ZipFileSystem zipfs, long pos, byte[] buf)
- throws IOException
- {
- return new Entry().loc(zipfs, pos, buf);
- }
-
- Entry loc(ZipFileSystem zipfs, long pos, byte[] buf)
- throws IOException
- {
- assert (buf.length >= LOCHDR);
- if (zipfs.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR)
- throw new ZipException("loc: reading failed");
- if (LOCSIG(buf) != LOCSIG)
- throw new ZipException("loc: wrong sig ->"
- + Long.toString(LOCSIG(buf), 16));
- //startPos = pos;
- version = LOCVER(buf);
- flag = LOCFLG(buf);
- method = LOCHOW(buf);
- mtime = dosToJavaTime(LOCTIM(buf));
- crc = LOCCRC(buf);
- csize = LOCSIZ(buf);
- size = LOCLEN(buf);
- int nlen = LOCNAM(buf);
- int elen = LOCEXT(buf);
-
- name = new byte[nlen];
- if (zipfs.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
- throw new ZipException("loc: name reading failed");
- }
- if (elen > 0) {
- extra = new byte[elen];
- if (zipfs.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
- != elen) {
- throw new ZipException("loc: ext reading failed");
- }
- }
- pos += (LOCHDR + nlen + elen);
- if ((flag & FLAG_DATADESCR) != 0) {
- // Data Descriptor
- Entry e = zipfs.getEntry0(name); // get the size/csize from cen
- if (e == null)
- throw new ZipException("loc: name not found in cen");
- size = e.size;
- csize = e.csize;
- pos += (method == METHOD_STORED ? size : csize);
- if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
- pos += 24;
- else
- pos += 16;
- } else {
- if (extra != null &&
- (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
- // zip64 ext: must include both size and csize
- int off = 0;
- while (off + 20 < elen) { // HeaderID+DataSize+Data
- int sz = SH(extra, off + 2);
- if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
- size = LL(extra, off + 4);
- csize = LL(extra, off + 12);
- break;
- }
- off += (sz + 4);
- }
- }
- pos += (method == METHOD_STORED ? size : csize);
- }
- return this;
- }
-
- int writeLOC(OutputStream os)
- throws IOException
- {
- writeInt(os, LOCSIG); // LOC header signature
- int version = version();
-
- int nlen = (name != null) ? name.length : 0;
- int elen = (extra != null) ? extra.length : 0;
- int elen64 = 0;
- int elenEXTT = 0;
- if ((flag & FLAG_DATADESCR) != 0) {
- writeShort(os, version()); // version needed to extract
- writeShort(os, flag); // general purpose bit flag
- writeShort(os, method); // compression method
- // last modification time
- writeInt(os, (int)javaToDosTime(mtime));
- // store size, uncompressed size, and crc-32 in data descriptor
- // immediately following compressed entry data
- writeInt(os, 0);
- writeInt(os, 0);
- writeInt(os, 0);
- } else {
- if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
- elen64 = 20; //headid(2) + size(2) + size(8) + csize(8)
- writeShort(os, 45); // ver 4.5 for zip64
- } else {
- writeShort(os, version()); // version needed to extract
- }
- writeShort(os, flag); // general purpose bit flag
- writeShort(os, method); // compression method
- writeInt(os, mtime); // last modification time
- writeInt(os, crc); // crc-32
- if (elen64 != 0) {
- writeInt(os, ZIP64_MINVAL);
- writeInt(os, ZIP64_MINVAL);
- } else {
- writeInt(os, csize); // compressed size
- writeInt(os, size); // uncompressed size
- }
- }
- if (atime != -1 && !isWindows) { // on unix use "ext time"
- if (ctime == -1)
- elenEXTT = 13;
- else
- elenEXTT = 17;
- }
- writeShort(os, name.length);
- writeShort(os, elen + elen64 + elenEXTT);
- writeBytes(os, name);
- if (elen64 != 0) {
- writeShort(os, EXTID_ZIP64);
- writeShort(os, 16);
- writeLong(os, size);
- writeLong(os, csize);
- }
- if (elenEXTT != 0) {
- writeShort(os, EXTID_EXTT);
- writeShort(os, elenEXTT - 4);// size for the folowing data block
- if (ctime == -1)
- os.write(0x3); // mtime and atime
- else
- os.write(0x7); // mtime, atime and ctime
- writeInt(os, javaToUnixTime(mtime));
- writeInt(os, javaToUnixTime(atime));
- if (ctime != -1)
- writeInt(os, javaToUnixTime(ctime));
- }
- if (extra != null) {
- writeBytes(os, extra);
- }
- return LOCHDR + name.length + elen + elen64 + elenEXTT;
- }
-
- // Data Descriptior
- int writeEXT(OutputStream os)
- throws IOException
- {
- writeInt(os, EXTSIG); // EXT header signature
- writeInt(os, crc); // crc-32
- if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
- writeLong(os, csize);
- writeLong(os, size);
- return 24;
- } else {
- writeInt(os, csize); // compressed size
- writeInt(os, size); // uncompressed size
- return 16;
- }
- }
-
- // read NTFS, UNIX and ZIP64 data from cen.extra
- void readExtra(ZipFileSystem zipfs) throws IOException {
- if (extra == null)
- return;
- int elen = extra.length;
- int off = 0;
- int newOff = 0;
- while (off + 4 < elen) {
- // extra spec: HeaderID+DataSize+Data
- int pos = off;
- int tag = SH(extra, pos);
- int sz = SH(extra, pos + 2);
- pos += 4;
- if (pos + sz > elen) // invalid data
- break;
- switch (tag) {
- case EXTID_ZIP64 :
- if (size == ZIP64_MINVAL) {
- if (pos + 8 > elen) // invalid zip64 extra
- break; // fields, just skip
- size = LL(extra, pos);
- pos += 8;
- }
- if (csize == ZIP64_MINVAL) {
- if (pos + 8 > elen)
- break;
- csize = LL(extra, pos);
- pos += 8;
- }
- if (locoff == ZIP64_MINVAL) {
- if (pos + 8 > elen)
- break;
- locoff = LL(extra, pos);
- pos += 8;
- }
- break;
- case EXTID_NTFS:
- pos += 4; // reserved 4 bytes
- if (SH(extra, pos) != 0x0001)
- break;
- if (SH(extra, pos + 2) != 24)
- break;
- // override the loc field, datatime here is
- // more "accurate"
- mtime = winToJavaTime(LL(extra, pos + 4));
- atime = winToJavaTime(LL(extra, pos + 12));
- ctime = winToJavaTime(LL(extra, pos + 20));
- break;
- case EXTID_EXTT:
- // spec says the Extened timestamp in cen only has mtime
- // need to read the loc to get the extra a/ctime
- byte[] buf = new byte[LOCHDR];
- if (zipfs.readFullyAt(buf, 0, buf.length , locoff)
- != buf.length)
- throw new ZipException("loc: reading failed");
- if (LOCSIG(buf) != LOCSIG)
- throw new ZipException("loc: wrong sig ->"
- + Long.toString(LOCSIG(buf), 16));
-
- int locElen = LOCEXT(buf);
- if (locElen < 9) // EXTT is at lease 9 bytes
- break;
- int locNlen = LOCNAM(buf);
- buf = new byte[locElen];
- if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen)
- != buf.length)
- throw new ZipException("loc extra: reading failed");
- int locPos = 0;
- while (locPos + 4 < buf.length) {
- int locTag = SH(buf, locPos);
- int locSZ = SH(buf, locPos + 2);
- locPos += 4;
- if (locTag != EXTID_EXTT) {
- locPos += locSZ;
- continue;
- }
- int flag = CH(buf, locPos++);
- if ((flag & 0x1) != 0) {
- mtime = unixToJavaTime(LG(buf, locPos));
- locPos += 4;
- }
- if ((flag & 0x2) != 0) {
- atime = unixToJavaTime(LG(buf, locPos));
- locPos += 4;
- }
- if ((flag & 0x4) != 0) {
- ctime = unixToJavaTime(LG(buf, locPos));
- locPos += 4;
- }
- break;
- }
- break;
- default: // unknown tag
- System.arraycopy(extra, off, extra, newOff, sz + 4);
- newOff += (sz + 4);
- }
- off += (sz + 4);
- }
- if (newOff != 0 && newOff != extra.length)
- extra = Arrays.copyOf(extra, newOff);
- else
- extra = null;
- }
- }
-
- private static class ExChannelCloser {
- Path path;
- SeekableByteChannel ch;
- Set<InputStream> streams;
- ExChannelCloser(Path path,
- SeekableByteChannel ch,
- Set<InputStream> streams)
- {
- this.path = path;
- this.ch = ch;
- this.streams = streams;
- }
- }
-
- // ZIP directory has two issues:
- // (1) ZIP spec does not require the ZIP file to include
- // directory entry
- // (2) all entries are not stored/organized in a "tree"
- // structure.
- // A possible solution is to build the node tree ourself as
- // implemented below.
- private HashMap<IndexNode, IndexNode> dirs;
- private IndexNode root;
- private IndexNode addToDir(IndexNode child) {
- IndexNode cinode = dirs.get(child);
- if (cinode != null)
- return cinode;
-
- byte[] cname = child.name;
- byte[] pname = getParent(cname);
- IndexNode pinode;
-
- if (pname != null)
- pinode = addToDir(IndexNode.keyOf(pname));
- else
- pinode = root;
- cinode = inodes.get(child);
- if (cname[cname.length -1] != '/') { // not a dir
- cinode.sibling = pinode.child;
- pinode.child = cinode;
- return null;
- }
- //cinode = dirs.get(child);
- if (cinode == null) // pseudo directry entry
- cinode = new IndexNode(cname, -1);
- cinode.sibling = pinode.child;
- pinode.child = cinode;
-
- dirs.put(child, cinode);
- return cinode;
- }
-
- private HashMap<IndexNode, IndexNode> getDirs()
- throws IOException
- {
- beginWrite();
- try {
- if (dirs != null)
- return dirs;
- dirs = new HashMap<>();
- root = new IndexNode(new byte[0], -1);
- dirs.put(root, root);
- for (IndexNode node : inodes.keySet())
- addToDir(node);
- return dirs;
- } finally {
- endWrite();
- }
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.file.FileRef;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystemNotFoundException;
-import java.nio.file.FileSystemAlreadyExistsException;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.ProviderMismatchException;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.spi.FileSystemProvider;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/*
- *
- * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
- */
-
-public class ZipFileSystemProvider extends FileSystemProvider {
-
-
- private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
-
- public ZipFileSystemProvider() {}
-
- @Override
- public String getScheme() {
- return "zip";
- }
-
- protected Path uriToPath(URI uri) {
- String scheme = uri.getScheme();
- if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
- throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
- }
- try {
- return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
- .toAbsolutePath();
- } catch (URISyntaxException e) {
- throw new AssertionError(e); //never thrown
- }
- }
-
- @Override
- public FileSystem newFileSystem(URI uri, Map<String, ?> env)
- throws IOException
- {
- return newFileSystem(uriToPath(uri), env);
- }
-
- @Override
- public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
- throws IOException
- {
- if (!(file instanceof Path))
- throw new UnsupportedOperationException();
- Path path = (Path)file;
- if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
- throw new UnsupportedOperationException();
- }
- return newFileSystem(path, env);
- }
-
- private FileSystem newFileSystem(Path path, Map<String, ?> env)
- throws IOException
- {
- synchronized(filesystems) {
- Path realPath = null;
- if (path.exists()) {
- realPath = path.toRealPath(true);
- if (filesystems.containsKey(realPath))
- throw new FileSystemAlreadyExistsException();
- }
- ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
- if (realPath == null)
- realPath = path.toRealPath(true);
- filesystems.put(realPath, zipfs);
- return zipfs;
- }
- }
-
- @Override
- public Path getPath(URI uri) {
- FileSystem fs = getFileSystem(uri);
- String fragment = uri.getFragment();
- if (fragment == null) {
- throw new IllegalArgumentException("URI: "
- + uri
- + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
- }
- return fs.getPath(fragment);
- }
-
- @Override
- public FileChannel newFileChannel(Path path,
- Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- if (path == null)
- throw new NullPointerException("path is null");
- if (path instanceof ZipPath)
- return ((ZipPath)path).newFileChannel(options, attrs);
- throw new ProviderMismatchException();
- }
-
- @Override
- public FileSystem getFileSystem(URI uri) {
- synchronized (filesystems) {
- ZipFileSystem zipfs = null;
- try {
- zipfs = filesystems.get(uriToPath(uri).toRealPath(true));
- } catch (IOException x) {
- // ignore the ioe from toRealPath(), return FSNFE
- }
- if (zipfs == null)
- throw new FileSystemNotFoundException();
- return zipfs;
- }
- }
-
- void removeFileSystem(Path zfpath) throws IOException {
- synchronized (filesystems) {
- filesystems.remove(zfpath.toRealPath(true));
- }
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.nio.file.Paths;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-import com.sun.nio.zipfs.ZipFileSystem.Entry;
-import static com.sun.nio.zipfs.ZipConstants.*;
-import static com.sun.nio.zipfs.ZipUtils.*;
-
-/**
- * Print all loc and cen headers of the ZIP file
- *
- * @author Xueming Shen
- */
-
-public class ZipInfo {
-
- public static void main(String[] args) throws Throwable {
- if (args.length < 1) {
- print("Usage: java ZipInfo zfname");
- } else {
- Map<String, ?> env = Collections.emptyMap();
- ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
- .newFileSystem(Paths.get(args[0]), env));
- byte[] cen = zfs.cen;
- if (cen == null) {
- print("zip file is empty%n");
- return;
- }
- int pos = 0;
- byte[] buf = new byte[1024];
- int no = 1;
- while (pos + CENHDR < cen.length) {
- print("----------------#%d--------------------%n", no++);
- printCEN(cen, pos);
-
- // use size CENHDR as the extra bytes to read, just in case the
- // loc.extra is bigger than the cen.extra, try to avoid to read
- // twice
- long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
- if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
- zfs.zerror("read loc header failed");
- if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
- // have to read the second time;
- len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
- if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
- zfs.zerror("read loc header failed");
- }
- printLOC(buf);
- pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
- }
- zfs.close();
- }
- }
-
- static void print(String fmt, Object... objs) {
- System.out.printf(fmt, objs);
- }
-
- static void printLOC(byte[] loc) {
- print("%n");
- print("[Local File Header]%n");
- print(" Signature : %#010x%n", LOCSIG(loc));
- if (LOCSIG(loc) != LOCSIG) {
- print(" Wrong signature!");
- return;
- }
- print(" Version : %#6x [%d.%d]%n",
- LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10);
- print(" Flag : %#6x%n", LOCFLG(loc));
- print(" Method : %#6x%n", LOCHOW(loc));
- print(" LastMTime : %#10x [%tc]%n",
- LOCTIM(loc), dosToJavaTime(LOCTIM(loc)));
- print(" CRC : %#10x%n", LOCCRC(loc));
- print(" CSize : %#10x%n", LOCSIZ(loc));
- print(" Size : %#10x%n", LOCLEN(loc));
- print(" NameLength : %#6x [%s]%n",
- LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc)));
- print(" ExtraLength : %#6x%n", LOCEXT(loc));
- if (LOCEXT(loc) != 0)
- printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc));
- }
-
- static void printCEN(byte[] cen, int off) {
- print("[Central Directory Header]%n");
- print(" Signature : %#010x%n", CENSIG(cen, off));
- if (CENSIG(cen, off) != CENSIG) {
- print(" Wrong signature!");
- return;
- }
- print(" VerMadeby : %#6x [%d, %d.%d]%n",
- CENVEM(cen, off), (CENVEM(cen, off) >> 8),
- (CENVEM(cen, off) & 0xff) / 10,
- (CENVEM(cen, off) & 0xff) % 10);
- print(" VerExtract : %#6x [%d.%d]%n",
- CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10);
- print(" Flag : %#6x%n", CENFLG(cen, off));
- print(" Method : %#6x%n", CENHOW(cen, off));
- print(" LastMTime : %#10x [%tc]%n",
- CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off)));
- print(" CRC : %#10x%n", CENCRC(cen, off));
- print(" CSize : %#10x%n", CENSIZ(cen, off));
- print(" Size : %#10x%n", CENLEN(cen, off));
- print(" NameLen : %#6x [%s]%n",
- CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off)));
- print(" ExtraLen : %#6x%n", CENEXT(cen, off));
- if (CENEXT(cen, off) != 0)
- printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off));
- print(" CommentLen : %#6x%n", CENCOM(cen, off));
- print(" DiskStart : %#6x%n", CENDSK(cen, off));
- print(" Attrs : %#6x%n", CENATT(cen, off));
- print(" AttrsEx : %#10x%n", CENATX(cen, off));
- print(" LocOff : %#10x%n", CENOFF(cen, off));
-
- }
-
- static long locoff(byte[] cen, int pos) {
- long locoff = CENOFF(cen, pos);
- if (locoff == ZIP64_MINVAL) { //ZIP64
- int off = pos + CENHDR + CENNAM(cen, pos);
- int end = off + CENEXT(cen, pos);
- while (off + 4 < end) {
- int tag = SH(cen, off);
- int sz = SH(cen, off + 2);
- if (tag != EXTID_ZIP64) {
- off += 4 + sz;
- continue;
- }
- off += 4;
- if (CENLEN(cen, pos) == ZIP64_MINVAL)
- off += 8;
- if (CENSIZ(cen, pos) == ZIP64_MINVAL)
- off += 8;
- return LL(cen, off);
- }
- // should never be here
- }
- return locoff;
- }
-
- static void printExtra(byte[] extra, int off, int len) {
- int end = off + len;
- while (off + 4 < end) {
- int tag = SH(extra, off);
- int sz = SH(extra, off + 2);
- print(" [tag=0x%04x, sz=%d, data= ", tag, sz);
- if (off + sz > end) {
- print(" Error: Invalid extra data, beyond extra length");
- break;
- }
- off += 4;
- for (int i = 0; i < sz; i++)
- print("%02x ", extra[off + i]);
- print("]%n");
- switch (tag) {
- case EXTID_ZIP64 :
- print(" ->ZIP64: ");
- int pos = off;
- while (pos + 8 <= off + sz) {
- print(" *0x%x ", LL(extra, pos));
- pos += 8;
- }
- print("%n");
- break;
- case EXTID_NTFS:
- print(" ->PKWare NTFS%n");
- // 4 bytes reserved
- if (SH(extra, off + 4) != 0x0001 || SH(extra, off + 6) != 24)
- print(" Error: Invalid NTFS sub-tag or subsz");
- print(" mtime:%tc%n",
- winToJavaTime(LL(extra, off + 8)));
- print(" atime:%tc%n",
- winToJavaTime(LL(extra, off + 16)));
- print(" ctime:%tc%n",
- winToJavaTime(LL(extra, off + 24)));
- break;
- case EXTID_EXTT:
- print(" ->Inof-ZIP Extended Timestamp: flag=%x%n",extra[off]);
- pos = off + 1 ;
- while (pos + 4 <= off + sz) {
- print(" *%tc%n",
- unixToJavaTime(LG(extra, pos)));
- pos += 4;
- }
- break;
- default:
- }
- off += sz;
- }
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,961 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SeekableByteChannel;
-import java.nio.file.*;
-import java.nio.file.DirectoryStream.Filter;
-import java.nio.file.attribute.BasicFileAttributeView;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.FileAttributeView;
-import java.nio.file.attribute.FileTime;
-import java.util.*;
-import static java.nio.file.StandardOpenOption.*;
-import static java.nio.file.StandardCopyOption.*;
-
-/**
- *
- * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
- */
-
-public class ZipPath extends Path {
-
- private final ZipFileSystem zfs;
- private final byte[] path;
- private volatile int[] offsets;
- private int hashcode = 0; // cached hashcode (created lazily)
-
- ZipPath(ZipFileSystem zfs, byte[] path) {
- this(zfs, path, false);
- }
-
- ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
- {
- this.zfs = zfs;
- if (normalized)
- this.path = path;
- else
- this.path = normalize(path);
- }
-
- @Override
- public ZipPath getRoot() {
- if (this.isAbsolute())
- return new ZipPath(zfs, new byte[]{path[0]});
- else
- return null;
- }
-
- @Override
- public Path getName() {
- initOffsets();
- int count = offsets.length;
- if (count == 0)
- return null; // no elements so no name
- if (count == 1 && path[0] != '/')
- return this;
- int lastOffset = offsets[count-1];
- int len = path.length - lastOffset;
- byte[] result = new byte[len];
- System.arraycopy(path, lastOffset, result, 0, len);
- return new ZipPath(zfs, result);
- }
-
- @Override
- public ZipPath getParent() {
- initOffsets();
- int count = offsets.length;
- if (count == 0) // no elements so no parent
- return null;
- int len = offsets[count-1] - 1;
- if (len <= 0) // parent is root only (may be null)
- return getRoot();
- byte[] result = new byte[len];
- System.arraycopy(path, 0, result, 0, len);
- return new ZipPath(zfs, result);
- }
-
- @Override
- public int getNameCount() {
- initOffsets();
- return offsets.length;
- }
-
- @Override
- public ZipPath getName(int index) {
- initOffsets();
- if (index < 0 || index >= offsets.length)
- throw new IllegalArgumentException();
- int begin = offsets[index];
- int len;
- if (index == (offsets.length-1))
- len = path.length - begin;
- else
- len = offsets[index+1] - begin - 1;
- // construct result
- byte[] result = new byte[len];
- System.arraycopy(path, begin, result, 0, len);
- return new ZipPath(zfs, result);
- }
-
- @Override
- public ZipPath subpath(int beginIndex, int endIndex) {
- initOffsets();
- if (beginIndex < 0 ||
- beginIndex >= offsets.length ||
- endIndex > offsets.length ||
- beginIndex >= endIndex)
- throw new IllegalArgumentException();
-
- // starting offset and length
- int begin = offsets[beginIndex];
- int len;
- if (endIndex == offsets.length)
- len = path.length - begin;
- else
- len = offsets[endIndex] - begin - 1;
- // construct result
- byte[] result = new byte[len];
- System.arraycopy(path, begin, result, 0, len);
- return new ZipPath(zfs, result);
- }
-
- @Override
- public ZipPath toRealPath(boolean resolveLinks) throws IOException {
- ZipPath realPath = new ZipPath(zfs, getResolvedPath());
- realPath.checkAccess();
- return realPath;
- }
-
- @Override
- public boolean isHidden() {
- return false;
- }
-
- @Override
- public ZipPath toAbsolutePath() {
- if (isAbsolute()) {
- return this;
- } else {
- //add / bofore the existing path
- byte[] defaultdir = zfs.getDefaultDir().path;
- int defaultlen = defaultdir.length;
- boolean endsWith = (defaultdir[defaultlen - 1] == '/');
- byte[] t = null;
- if (endsWith)
- t = new byte[defaultlen + path.length];
- else
- t = new byte[defaultlen + 1 + path.length];
- System.arraycopy(defaultdir, 0, t, 0, defaultlen);
- if (!endsWith)
- t[defaultlen++] = '/';
- System.arraycopy(path, 0, t, defaultlen, path.length);
- return new ZipPath(zfs, t, true); // normalized
- }
- }
-
- @Override
- public URI toUri() {
- String zfPath = zfs.toString();
- if (File.separatorChar == '\\') // replace all separators by '/'
- zfPath = "/" + zfPath.replace("\\", "/");
- try {
- return new URI("zip", "",
- zfPath,
- zfs.getString(toAbsolutePath().path));
- } catch (Exception ex) {
- throw new AssertionError(ex);
- }
- }
-
- private boolean equalsNameAt(ZipPath other, int index) {
- int mbegin = offsets[index];
- int mlen = 0;
- if (index == (offsets.length-1))
- mlen = path.length - mbegin;
- else
- mlen = offsets[index + 1] - mbegin - 1;
- int obegin = other.offsets[index];
- int olen = 0;
- if (index == (other.offsets.length - 1))
- olen = other.path.length - obegin;
- else
- olen = other.offsets[index + 1] - obegin - 1;
- if (mlen != olen)
- return false;
- int n = 0;
- while(n < mlen) {
- if (path[mbegin + n] != other.path[obegin + n])
- return false;
- n++;
- }
- return true;
- }
-
- @Override
- public Path relativize(Path other) {
- final ZipPath o = checkPath(other);
- if (o.equals(this))
- return null;
- if (/* this.getFileSystem() != o.getFileSystem() || */
- this.isAbsolute() != o.isAbsolute()) {
- throw new IllegalArgumentException();
- }
- int mc = this.getNameCount();
- int oc = o.getNameCount();
- int n = Math.min(mc, oc);
- int i = 0;
- while (i < n) {
- if (!equalsNameAt(o, i))
- break;
- i++;
- }
- int dotdots = mc - i;
- int len = dotdots * 3 - 1;
- if (i < oc)
- len += (o.path.length - o.offsets[i] + 1);
- byte[] result = new byte[len];
-
- int pos = 0;
- while (dotdots > 0) {
- result[pos++] = (byte)'.';
- result[pos++] = (byte)'.';
- if (pos < len) // no tailing slash at the end
- result[pos++] = (byte)'/';
- dotdots--;
- }
- if (i < oc)
- System.arraycopy(o.path, o.offsets[i],
- result, pos,
- o.path.length - o.offsets[i]);
- return new ZipPath(getFileSystem(), result);
- }
-
- @Override
- public ZipFileSystem getFileSystem() {
- return zfs;
- }
-
- @Override
- public boolean isAbsolute() {
- return (this.path[0] == '/');
- }
-
- @Override
- public ZipPath resolve(Path other) {
- if (other == null)
- return this;
- final ZipPath o = checkPath(other);
- if (o.isAbsolute())
- return o;
- byte[] resolved = null;
- if (this.path[path.length - 1] == '/') {
- resolved = new byte[path.length + o.path.length];
- System.arraycopy(path, 0, resolved, 0, path.length);
- System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
- } else {
- resolved = new byte[path.length + 1 + o.path.length];
- System.arraycopy(path, 0, resolved, 0, path.length);
- resolved[path.length] = '/';
- System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
- }
- return new ZipPath(zfs, resolved);
- }
-
- @Override
- public ZipPath resolve(String other) {
- return resolve(getFileSystem().getPath(other));
- }
-
- @Override
- public boolean startsWith(Path other) {
- final ZipPath o = checkPath(other);
- if (o.isAbsolute() != this.isAbsolute())
- return false;
- final int oCount = o.getNameCount();
- if (getNameCount() < oCount)
- return false;
- for (int i = 0; i < oCount; i++) {
- if (!o.getName(i).equals(getName(i)))
- return false;
- }
- return true;
- }
-
- @Override
- public boolean endsWith(Path other) {
- final ZipPath o = checkPath(other);
- if (o.isAbsolute())
- return this.isAbsolute() ? this.equals(o) : false;
- int i = o.getNameCount();
- int j = this.getNameCount();
- if (j < i)
- return false;
- for (--i, --j; i >= 0; i--, j--) {
- if (!o.getName(i).equals(this.getName(j)))
- return false;
- }
- return true;
- }
-
- @Override
- public Path normalize() {
- byte[] resolved = getResolved();
- if (resolved == path) // no change
- return this;
- if (resolved.length == 0)
- return null;
- return new ZipPath(zfs, resolved, true);
- }
-
- private ZipPath checkPath(Path path) {
- if (path == null)
- throw new NullPointerException();
- if (!(path instanceof ZipPath))
- throw new ProviderMismatchException();
- return (ZipPath) path;
- }
-
- // create offset list if not already created
- private void initOffsets() {
- if (offsets == null) {
- int count, index;
- // count names
- count = 0;
- index = 0;
- while (index < path.length) {
- byte c = path[index++];
- if (c != '/') {
- count++;
- while (index < path.length && path[index] != '/')
- index++;
- }
- }
- // populate offsets
- int[] result = new int[count];
- count = 0;
- index = 0;
- while (index < path.length) {
- byte c = path[index];
- if (c == '/') {
- index++;
- } else {
- result[count++] = index++;
- while (index < path.length && path[index] != '/')
- index++;
- }
- }
- synchronized (this) {
- if (offsets == null)
- offsets = result;
- }
- }
- }
-
- // resolved path for locating zip entry inside the zip file,
- // the result path does not contain ./ and .. components
- private volatile byte[] resolved = null;
- byte[] getResolvedPath() {
- byte[] r = resolved;
- if (r == null) {
- if (isAbsolute())
- r = getResolved();
- else
- r = toAbsolutePath().getResolvedPath();
- if (r[0] == '/')
- r = Arrays.copyOfRange(r, 1, r.length);
- resolved = r;
- }
- return resolved;
- }
-
- // removes redundant slashs, replace "\" to zip separator "/"
- // and check for invalid characters
- private byte[] normalize(byte[] path) {
- if (path.length == 0)
- return path;
- byte prevC = 0;
- for (int i = 0; i < path.length; i++) {
- byte c = path[i];
- if (c == '\\')
- return normalize(path, i);
- if (c == (byte)'/' && prevC == '/')
- return normalize(path, i - 1);
- if (c == '\u0000')
- throw new InvalidPathException(zfs.getString(path),
- "Path: nul character not allowed");
- prevC = c;
- }
- return path;
- }
-
- private byte[] normalize(byte[] path, int off) {
- byte[] to = new byte[path.length];
- int n = 0;
- while (n < off) {
- to[n] = path[n];
- n++;
- }
- int m = n;
- byte prevC = 0;
- while (n < path.length) {
- byte c = path[n++];
- if (c == (byte)'\\')
- c = (byte)'/';
- if (c == (byte)'/' && prevC == (byte)'/')
- continue;
- if (c == '\u0000')
- throw new InvalidPathException(zfs.getString(path),
- "Path: nul character not allowed");
- to[m++] = c;
- prevC = c;
- }
- if (m > 1 && to[m - 1] == '/')
- m--;
- return (m == to.length)? to : Arrays.copyOf(to, m);
- }
-
- // Remove DotSlash(./) and resolve DotDot (..) components
- private byte[] getResolved() {
- if (path.length == 0)
- return path;
- for (int i = 0; i < path.length; i++) {
- byte c = path[i];
- if (c == (byte)'.')
- return resolve0();
- }
- return path;
- }
-
- // TBD: performance, avoid initOffsets
- private byte[] resolve0() {
- byte[] to = new byte[path.length];
- int nc = getNameCount();
- int[] lastM = new int[nc];
- int lastMOff = -1;
- int m = 0;
- for (int i = 0; i < nc; i++) {
- int n = offsets[i];
- int len = (i == offsets.length - 1)?
- (path.length - n):(offsets[i + 1] - n - 1);
- if (len == 1 && path[n] == (byte)'.')
- continue;
- if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
- if (lastMOff >= 0) {
- m = lastM[lastMOff--]; // retreat
- continue;
- }
- if (path[0] == '/') { // "/../xyz" skip
- if (m == 0)
- to[m++] = '/';
- } else { // "../xyz" -> "../xyz"
- if (m != 0 && to[m-1] != '/')
- to[m++] = '/';
- while (len-- > 0)
- to[m++] = path[n++];
- }
- continue;
- }
- if (m == 0 && path[0] == '/' || // absolute path
- m != 0 && to[m-1] != '/') { // not the first name
- to[m++] = '/';
- }
- lastM[++lastMOff] = m;
- while (len-- > 0)
- to[m++] = path[n++];
- }
- if (m > 1 && to[m - 1] == '/')
- m--;
- return (m == to.length)? to : Arrays.copyOf(to, m);
- }
-
- @Override
- public String toString() {
- return zfs.getString(path);
- }
-
- @Override
- public int hashCode() {
- int h = hashcode;
- if (h == 0)
- hashcode = h = Arrays.hashCode(path);
- return h;
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj != null &&
- obj instanceof ZipPath &&
- this.zfs == ((ZipPath)obj).zfs &&
- compareTo((Path) obj) == 0;
- }
-
- @Override
- public int compareTo(Path other) {
- final ZipPath o = checkPath(other);
- int len1 = this.path.length;
- int len2 = o.path.length;
-
- int n = Math.min(len1, len2);
- byte v1[] = this.path;
- byte v2[] = o.path;
-
- int k = 0;
- while (k < n) {
- int c1 = v1[k] & 0xff;
- int c2 = v2[k] & 0xff;
- if (c1 != c2)
- return c1 - c2;
- k++;
- }
- return len1 - len2;
- }
-
- @Override
- public Path createSymbolicLink(
- Path target, FileAttribute<?>... attrs) throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path createLink(
- Path existing) throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path readSymbolicLink() throws IOException {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public Path createDirectory(FileAttribute<?>... attrs)
- throws IOException
- {
- zfs.createDirectory(getResolvedPath(), attrs);
- return this;
- }
-
- public final Path createFile(FileAttribute<?>... attrs)
- throws IOException
- {
- OutputStream os = newOutputStream(CREATE_NEW, WRITE);
- try {
- os.close();
- } catch (IOException x) {}
- return this;
- }
-
- @Override
- public InputStream newInputStream(OpenOption... options)
- throws IOException {
- if (options.length > 0) {
- for (OpenOption opt : options) {
- if (opt != READ)
- throw new UnsupportedOperationException("'" + opt + "' not allowed");
- }
- }
- return zfs.newInputStream(getResolvedPath());
- }
-
- private static final DirectoryStream.Filter<Path> acceptAllFilter =
- new DirectoryStream.Filter<>() {
- @Override public boolean accept(Path entry) { return true; }
- };
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream() throws IOException {
- return newDirectoryStream(acceptAllFilter);
- }
-
- @Override
- public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
- throws IOException
- {
- return new ZipDirectoryStream(this, filter);
- }
-
- @Override
- public final DirectoryStream<Path> newDirectoryStream(String glob)
- throws IOException
- {
- // avoid creating a matcher if all entries are required.
- if (glob.equals("*"))
- return newDirectoryStream();
-
- // create a matcher and return a filter that uses it.
- final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
- DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
- @Override
- public boolean accept(Path entry) {
- return matcher.matches(entry.getName());
- }
- };
- return newDirectoryStream(filter);
- }
-
- @Override
- public final void delete() throws IOException {
- zfs.deleteFile(getResolvedPath(), true);
- }
-
- @Override
- public final void deleteIfExists() throws IOException {
- zfs.deleteFile(getResolvedPath(), false);
- }
-
- ZipFileAttributes getAttributes() throws IOException
- {
- ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
- if (zfas == null)
- throw new NoSuchFileException(toString());
- return zfas;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
- LinkOption... options)
- {
- return (V)ZipFileAttributeView.get(this, type);
- }
-
- @Override
- public void setAttribute(String attribute,
- Object value,
- LinkOption... options)
- throws IOException
- {
- String type = null;
- String attr = null;
- int colonPos = attribute.indexOf(':');
- if (colonPos == -1) {
- type = "basic";
- attr = attribute;
- } else {
- type = attribute.substring(0, colonPos++);
- attr = attribute.substring(colonPos);
- }
- ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
- if (view == null)
- throw new UnsupportedOperationException("view <" + view + "> is not supported");
- view.setAttribute(attr, value);
- }
-
- void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
- throws IOException
- {
- zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
- }
-
- private Object getAttributesImpl(String attribute, boolean domap)
- throws IOException
- {
- String view = null;
- String attr = null;
- int colonPos = attribute.indexOf(':');
- if (colonPos == -1) {
- view = "basic";
- attr = attribute;
- } else {
- view = attribute.substring(0, colonPos++);
- attr = attribute.substring(colonPos);
- }
- ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
- if (zfv == null) {
- throw new UnsupportedOperationException("view not supported");
- }
- return zfv.getAttribute(attr, domap);
- }
-
- @Override
- public Object getAttribute(String attribute, LinkOption... options)
- throws IOException
- {
- return getAttributesImpl(attribute, false);
- }
-
- @Override
- public Map<String,?> readAttributes(String attribute, LinkOption... options)
- throws IOException
- {
- return (Map<String, ?>)getAttributesImpl(attribute, true);
- }
-
- @Override
- public FileStore getFileStore() throws IOException {
- // each ZipFileSystem only has one root (as requested for now)
- if (exists())
- return zfs.getFileStore(this);
- throw new NoSuchFileException(zfs.getString(path));
- }
-
- @Override
- public boolean isSameFile(Path other) throws IOException {
- if (other == null ||
- this.getFileSystem() != other.getFileSystem())
- return false;
- this.checkAccess();
- other.checkAccess();
- return Arrays.equals(this.getResolvedPath(),
- ((ZipPath)other).getResolvedPath());
- }
-
- public WatchKey register(
- WatchService watcher,
- WatchEvent.Kind<?>[] events,
- WatchEvent.Modifier... modifiers) {
- if (watcher == null || events == null || modifiers == null) {
- throw new NullPointerException();
- }
- throw new UnsupportedOperationException();
- }
-
- @Override
- public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
- return register(watcher, events, new WatchEvent.Modifier[0]);
- }
-
- @Override
- public Iterator<Path> iterator() {
- return new Iterator<>() {
- private int i = 0;
-
- @Override
- public boolean hasNext() {
- return (i < getNameCount());
- }
-
- @Override
- public Path next() {
- if (i < getNameCount()) {
- Path result = getName(i);
- i++;
- return result;
- } else {
- throw new NoSuchElementException();
- }
- }
-
- @Override
- public void remove() {
- throw new ReadOnlyFileSystemException();
- }
- };
- }
-
- @Override
- public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- return zfs.newByteChannel(getResolvedPath(), options, attrs);
- }
-
-
- FileChannel newFileChannel(Set<? extends OpenOption> options,
- FileAttribute<?>... attrs)
- throws IOException
- {
- return zfs.newFileChannel(getResolvedPath(), options, attrs);
- }
-
- @Override
- public SeekableByteChannel newByteChannel(OpenOption... options)
- throws IOException {
- Set<OpenOption> set = new HashSet<>(options.length);
- Collections.addAll(set, options);
- return newByteChannel(set);
- }
-
- @Override
- public void checkAccess(AccessMode... modes) throws IOException {
- boolean w = false;
- boolean x = false;
- for (AccessMode mode : modes) {
- switch (mode) {
- case READ:
- break;
- case WRITE:
- w = true;
- break;
- case EXECUTE:
- x = true;
- break;
- default:
- throw new UnsupportedOperationException();
- }
- }
- ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
- if (attrs == null && (path.length != 1 || path[0] != '/'))
- throw new NoSuchFileException(toString());
- if (w) {
- if (zfs.isReadOnly())
- throw new AccessDeniedException(toString());
- }
- if (x)
- throw new AccessDeniedException(toString());
-
- }
-
- @Override
- public boolean exists() {
- if (path.length == 1 && path[0] == '/')
- return true;
- try {
- return zfs.exists(getResolvedPath());
- } catch (IOException x) {}
- return false;
- }
-
- @Override
- public boolean notExists() {
- return !exists();
- }
-
-
- @Override
- public OutputStream newOutputStream(OpenOption... options)
- throws IOException
- {
- if (options.length == 0)
- return zfs.newOutputStream(getResolvedPath(),
- CREATE_NEW, WRITE);
- return zfs.newOutputStream(getResolvedPath(), options);
- }
-
- @Override
- public Path moveTo(Path target, CopyOption... options)
- throws IOException
- {
- if (this.zfs.provider() == target.getFileSystem().provider() &&
- this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
- {
- zfs.copyFile(true,
- getResolvedPath(),
- ((ZipPath)target).getResolvedPath(),
- options);
- } else {
- copyToTarget(target, options);
- delete();
- }
- return target;
- }
-
- @Override
- public Path copyTo(Path target, CopyOption... options)
- throws IOException
- {
- if (this.zfs.provider() == target.getFileSystem().provider() &&
- this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
- {
- zfs.copyFile(false,
- getResolvedPath(),
- ((ZipPath)target).getResolvedPath(),
- options);
- } else {
- copyToTarget(target, options);
- }
- return target;
- }
-
- private void copyToTarget(Path target, CopyOption... options)
- throws IOException
- {
- boolean replaceExisting = false;
- boolean copyAttrs = false;
- for (CopyOption opt : options) {
- if (opt == REPLACE_EXISTING)
- replaceExisting = true;
- else if (opt == COPY_ATTRIBUTES)
- copyAttrs = true;
- }
- // attributes of source file
- ZipFileAttributes zfas = getAttributes();
- // check if target exists
- boolean exists;
- if (replaceExisting) {
- try {
- target.deleteIfExists();
- exists = false;
- } catch (DirectoryNotEmptyException x) {
- exists = true;
- }
- } else {
- exists = target.exists();
- }
- if (exists)
- throw new FileAlreadyExistsException(target.toString());
-
- if (zfas.isDirectory()) {
- // create directory or file
- target.createDirectory();
- } else {
- InputStream is = zfs.newInputStream(getResolvedPath());
- try {
- OutputStream os = target.newOutputStream();
- try {
- byte[] buf = new byte[8192];
- int n = 0;
- while ((n = is.read(buf)) != -1) {
- os.write(buf, 0, n);
- }
- } finally {
- os.close();
- }
- } finally {
- is.close();
- }
- }
- if (copyAttrs) {
- BasicFileAttributeView view =
- target.getFileAttributeView(BasicFileAttributeView.class);
- try {
- view.setTimes(zfas.lastModifiedTime(),
- zfas.lastAccessTime(),
- zfas.creationTime());
- } catch (IOException x) {
- // rollback?
- try {
- target.delete();
- } catch (IOException ignore) { }
- throw x;
- }
- }
- }
-}
--- a/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,311 +0,0 @@
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.sun.nio.zipfs;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.regex.PatternSyntaxException;
-import java.util.concurrent.TimeUnit;
-
-/**
- *
- * @author Xueming Shen
- */
-
-class ZipUtils {
-
- /*
- * Writes a 16-bit short to the output stream in little-endian byte order.
- */
- public static void writeShort(OutputStream os, int v) throws IOException {
- os.write(v & 0xff);
- os.write((v >>> 8) & 0xff);
- }
-
- /*
- * Writes a 32-bit int to the output stream in little-endian byte order.
- */
- public static void writeInt(OutputStream os, long v) throws IOException {
- os.write((int)(v & 0xff));
- os.write((int)((v >>> 8) & 0xff));
- os.write((int)((v >>> 16) & 0xff));
- os.write((int)((v >>> 24) & 0xff));
- }
-
- /*
- * Writes a 64-bit int to the output stream in little-endian byte order.
- */
- public static void writeLong(OutputStream os, long v) throws IOException {
- os.write((int)(v & 0xff));
- os.write((int)((v >>> 8) & 0xff));
- os.write((int)((v >>> 16) & 0xff));
- os.write((int)((v >>> 24) & 0xff));
- os.write((int)((v >>> 32) & 0xff));
- os.write((int)((v >>> 40) & 0xff));
- os.write((int)((v >>> 48) & 0xff));
- os.write((int)((v >>> 56) & 0xff));
- }
-
- /*
- * Writes an array of bytes to the output stream.
- */
- public static void writeBytes(OutputStream os, byte[] b)
- throws IOException
- {
- os.write(b, 0, b.length);
- }
-
- /*
- * Writes an array of bytes to the output stream.
- */
- public static void writeBytes(OutputStream os, byte[] b, int off, int len)
- throws IOException
- {
- os.write(b, off, len);
- }
-
- /*
- * Append a slash at the end, if it does not have one yet
- */
- public static byte[] toDirectoryPath(byte[] dir) {
- if (dir.length != 0 && dir[dir.length - 1] != '/') {
- dir = Arrays.copyOf(dir, dir.length + 1);
- dir[dir.length - 1] = '/';
- }
- return dir;
- }
-
- /*
- * Converts DOS time to Java time (number of milliseconds since epoch).
- */
- public static long dosToJavaTime(long dtime) {
- Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
- (int)(((dtime >> 21) & 0x0f) - 1),
- (int)((dtime >> 16) & 0x1f),
- (int)((dtime >> 11) & 0x1f),
- (int)((dtime >> 5) & 0x3f),
- (int)((dtime << 1) & 0x3e));
- return d.getTime();
- }
-
- /*
- * Converts Java time to DOS time.
- */
- public static long javaToDosTime(long time) {
- Date d = new Date(time);
- int year = d.getYear() + 1900;
- if (year < 1980) {
- return (1 << 21) | (1 << 16);
- }
- return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
- d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
- d.getSeconds() >> 1;
- }
-
-
- // used to adjust values between Windows and java epoch
- private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
- public static final long winToJavaTime(long wtime) {
- return TimeUnit.MILLISECONDS.convert(
- wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
- }
-
- public static final long javaToWinTime(long time) {
- return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
- - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
- }
-
- public static final long unixToJavaTime(long utime) {
- return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
- }
-
- public static final long javaToUnixTime(long time) {
- return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
- }
-
- private static final String regexMetaChars = ".^$+{[]|()";
- private static final String globMetaChars = "\\*?[{";
- private static boolean isRegexMeta(char c) {
- return regexMetaChars.indexOf(c) != -1;
- }
- private static boolean isGlobMeta(char c) {
- return globMetaChars.indexOf(c) != -1;
- }
- private static char EOL = 0; //TBD
- private static char next(String glob, int i) {
- if (i < glob.length()) {
- return glob.charAt(i);
- }
- return EOL;
- }
-
- /*
- * Creates a regex pattern from the given glob expression.
- *
- * @throws PatternSyntaxException
- */
- public static String toRegexPattern(String globPattern) {
- boolean inGroup = false;
- StringBuilder regex = new StringBuilder("^");
-
- int i = 0;
- while (i < globPattern.length()) {
- char c = globPattern.charAt(i++);
- switch (c) {
- case '\\':
- // escape special characters
- if (i == globPattern.length()) {
- throw new PatternSyntaxException("No character to escape",
- globPattern, i - 1);
- }
- char next = globPattern.charAt(i++);
- if (isGlobMeta(next) || isRegexMeta(next)) {
- regex.append('\\');
- }
- regex.append(next);
- break;
- case '/':
- regex.append(c);
- break;
- case '[':
- // don't match name separator in class
- regex.append("[[^/]&&[");
- if (next(globPattern, i) == '^') {
- // escape the regex negation char if it appears
- regex.append("\\^");
- i++;
- } else {
- // negation
- if (next(globPattern, i) == '!') {
- regex.append('^');
- i++;
- }
- // hyphen allowed at start
- if (next(globPattern, i) == '-') {
- regex.append('-');
- i++;
- }
- }
- boolean hasRangeStart = false;
- char last = 0;
- while (i < globPattern.length()) {
- c = globPattern.charAt(i++);
- if (c == ']') {
- break;
- }
- if (c == '/') {
- throw new PatternSyntaxException("Explicit 'name separator' in class",
- globPattern, i - 1);
- }
- // TBD: how to specify ']' in a class?
- if (c == '\\' || c == '[' ||
- c == '&' && next(globPattern, i) == '&') {
- // escape '\', '[' or "&&" for regex class
- regex.append('\\');
- }
- regex.append(c);
-
- if (c == '-') {
- if (!hasRangeStart) {
- throw new PatternSyntaxException("Invalid range",
- globPattern, i - 1);
- }
- if ((c = next(globPattern, i++)) == EOL || c == ']') {
- break;
- }
- if (c < last) {
- throw new PatternSyntaxException("Invalid range",
- globPattern, i - 3);
- }
- regex.append(c);
- hasRangeStart = false;
- } else {
- hasRangeStart = true;
- last = c;
- }
- }
- if (c != ']') {
- throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
- }
- regex.append("]]");
- break;
- case '{':
- if (inGroup) {
- throw new PatternSyntaxException("Cannot nest groups",
- globPattern, i - 1);
- }
- regex.append("(?:(?:");
- inGroup = true;
- break;
- case '}':
- if (inGroup) {
- regex.append("))");
- inGroup = false;
- } else {
- regex.append('}');
- }
- break;
- case ',':
- if (inGroup) {
- regex.append(")|(?:");
- } else {
- regex.append(',');
- }
- break;
- case '*':
- if (next(globPattern, i) == '*') {
- // crosses directory boundaries
- regex.append(".*");
- i++;
- } else {
- // within directory boundary
- regex.append("[^/]*");
- }
- break;
- case '?':
- regex.append("[^/]");
- break;
- default:
- if (isRegexMeta(c)) {
- regex.append('\\');
- }
- regex.append(c);
- }
- }
- if (inGroup) {
- throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
- }
- return regex.append('$').toString();
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+com.sun.nio.zipfs.ZipFileSystemProvider
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/JarFileSystemProvider.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Sun Microsystems nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.spi.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+
+import java.net.URI;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.channels.FileChannel;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class JarFileSystemProvider extends ZipFileSystemProvider
+{
+
+ @Override
+ public String getScheme() {
+ return "jar";
+ }
+
+ @Override
+ protected Path uriToPath(URI uri) {
+ String scheme = uri.getScheme();
+ if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
+ throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
+ }
+ try {
+ String uristr = uri.toString();
+ int end = uristr.indexOf("!/");
+ uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
+ uri = new URI(uristr);
+ return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
+ .toAbsolutePath();
+ } catch (URISyntaxException e) {
+ throw new AssertionError(e); //never thrown
+ }
+ }
+
+ @Override
+ public Path getPath(URI uri) {
+ FileSystem fs = getFileSystem(uri);
+ String path = uri.getFragment();
+ if (path == null) {
+ String uristr = uri.toString();
+ int off = uristr.indexOf("!/");
+ if (off != -1)
+ path = uristr.substring(off + 2);
+ }
+ if (path != null)
+ return fs.getPath(path);
+ throw new IllegalArgumentException("URI: "
+ + uri
+ + " does not contain path fragment ex. jar:///c:/foo.zip!/BAR");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipCoder.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
+
+/**
+ * Utility class for zipfile name and comment decoding and encoding
+ *
+ * @author Xueming Shen
+ */
+
+final class ZipCoder {
+
+ String toString(byte[] ba, int length) {
+ CharsetDecoder cd = decoder().reset();
+ int len = (int)(length * cd.maxCharsPerByte());
+ char[] ca = new char[len];
+ if (len == 0)
+ return new String(ca);
+ ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
+ CharBuffer cb = CharBuffer.wrap(ca);
+ CoderResult cr = cd.decode(bb, cb, true);
+ if (!cr.isUnderflow())
+ throw new IllegalArgumentException(cr.toString());
+ cr = cd.flush(cb);
+ if (!cr.isUnderflow())
+ throw new IllegalArgumentException(cr.toString());
+ return new String(ca, 0, cb.position());
+ }
+
+ String toString(byte[] ba) {
+ return toString(ba, ba.length);
+ }
+
+ byte[] getBytes(String s) {
+ CharsetEncoder ce = encoder().reset();
+ char[] ca = s.toCharArray();
+ int len = (int)(ca.length * ce.maxBytesPerChar());
+ byte[] ba = new byte[len];
+ if (len == 0)
+ return ba;
+ ByteBuffer bb = ByteBuffer.wrap(ba);
+ CharBuffer cb = CharBuffer.wrap(ca);
+ CoderResult cr = ce.encode(cb, bb, true);
+ if (!cr.isUnderflow())
+ throw new IllegalArgumentException(cr.toString());
+ cr = ce.flush(bb);
+ if (!cr.isUnderflow())
+ throw new IllegalArgumentException(cr.toString());
+ if (bb.position() == ba.length) // defensive copy?
+ return ba;
+ else
+ return Arrays.copyOf(ba, bb.position());
+ }
+
+ // assume invoked only if "this" is not utf8
+ byte[] getBytesUTF8(String s) {
+ if (isutf8)
+ return getBytes(s);
+ if (utf8 == null)
+ utf8 = new ZipCoder(Charset.forName("UTF-8"));
+ return utf8.getBytes(s);
+ }
+
+ String toStringUTF8(byte[] ba, int len) {
+ if (isutf8)
+ return toString(ba, len);
+ if (utf8 == null)
+ utf8 = new ZipCoder(Charset.forName("UTF-8"));
+ return utf8.toString(ba, len);
+ }
+
+ boolean isUTF8() {
+ return isutf8;
+ }
+
+ private Charset cs;
+ private boolean isutf8;
+ private ZipCoder utf8;
+
+ private ZipCoder(Charset cs) {
+ this.cs = cs;
+ this.isutf8 = cs.name().equals("UTF-8");
+ }
+
+ static ZipCoder get(Charset charset) {
+ return new ZipCoder(charset);
+ }
+
+ static ZipCoder get(String csn) {
+ try {
+ return new ZipCoder(Charset.forName(csn));
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ return new ZipCoder(Charset.defaultCharset());
+ }
+
+ private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
+ private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
+
+ private CharsetDecoder decoder() {
+ CharsetDecoder dec = decTL.get();
+ if (dec == null) {
+ dec = cs.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPORT)
+ .onUnmappableCharacter(CodingErrorAction.REPORT);
+ decTL.set(dec);
+ }
+ return dec;
+ }
+
+ private CharsetEncoder encoder() {
+ CharsetEncoder enc = encTL.get();
+ if (enc == null) {
+ enc = cs.newEncoder()
+ .onMalformedInput(CodingErrorAction.REPORT)
+ .onUnmappableCharacter(CodingErrorAction.REPORT);
+ encTL.set(enc);
+ }
+ return enc;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipConstants.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+
+/**
+ *
+ * @author Xueming Shen
+ */
+
+class ZipConstants {
+ /*
+ * Compression methods
+ */
+ static final int METHOD_STORED = 0;
+ static final int METHOD_DEFLATED = 8;
+ static final int METHOD_DEFLATED64 = 9;
+ static final int METHOD_BZIP2 = 12;
+ static final int METHOD_LZMA = 14;
+ static final int METHOD_LZ77 = 19;
+ static final int METHOD_AES = 99;
+
+ /*
+ * General purpose big flag
+ */
+ static final int FLAG_ENCRYPTED = 0x01;
+ static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd
+ static final int FLAG_EFS = 0x800; // If this bit is set the filename and
+ // comment fields for this file must be
+ // encoded using UTF-8.
+ /*
+ * Header signatures
+ */
+ static long LOCSIG = 0x04034b50L; // "PK\003\004"
+ static long EXTSIG = 0x08074b50L; // "PK\007\008"
+ static long CENSIG = 0x02014b50L; // "PK\001\002"
+ static long ENDSIG = 0x06054b50L; // "PK\005\006"
+
+ /*
+ * Header sizes in bytes (including signatures)
+ */
+ static final int LOCHDR = 30; // LOC header size
+ static final int EXTHDR = 16; // EXT header size
+ static final int CENHDR = 46; // CEN header size
+ static final int ENDHDR = 22; // END header size
+
+ /*
+ * Local file (LOC) header field offsets
+ */
+ static final int LOCVER = 4; // version needed to extract
+ static final int LOCFLG = 6; // general purpose bit flag
+ static final int LOCHOW = 8; // compression method
+ static final int LOCTIM = 10; // modification time
+ static final int LOCCRC = 14; // uncompressed file crc-32 value
+ static final int LOCSIZ = 18; // compressed size
+ static final int LOCLEN = 22; // uncompressed size
+ static final int LOCNAM = 26; // filename length
+ static final int LOCEXT = 28; // extra field length
+
+ /*
+ * Extra local (EXT) header field offsets
+ */
+ static final int EXTCRC = 4; // uncompressed file crc-32 value
+ static final int EXTSIZ = 8; // compressed size
+ static final int EXTLEN = 12; // uncompressed size
+
+ /*
+ * Central directory (CEN) header field offsets
+ */
+ static final int CENVEM = 4; // version made by
+ static final int CENVER = 6; // version needed to extract
+ static final int CENFLG = 8; // encrypt, decrypt flags
+ static final int CENHOW = 10; // compression method
+ static final int CENTIM = 12; // modification time
+ static final int CENCRC = 16; // uncompressed file crc-32 value
+ static final int CENSIZ = 20; // compressed size
+ static final int CENLEN = 24; // uncompressed size
+ static final int CENNAM = 28; // filename length
+ static final int CENEXT = 30; // extra field length
+ static final int CENCOM = 32; // comment length
+ static final int CENDSK = 34; // disk number start
+ static final int CENATT = 36; // internal file attributes
+ static final int CENATX = 38; // external file attributes
+ static final int CENOFF = 42; // LOC header offset
+
+ /*
+ * End of central directory (END) header field offsets
+ */
+ static final int ENDSUB = 8; // number of entries on this disk
+ static final int ENDTOT = 10; // total number of entries
+ static final int ENDSIZ = 12; // central directory size in bytes
+ static final int ENDOFF = 16; // offset of first CEN header
+ static final int ENDCOM = 20; // zip file comment length
+
+ /*
+ * ZIP64 constants
+ */
+ static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
+ static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
+ static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
+ static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
+ static final int ZIP64_EXTHDR = 24; // EXT header size
+ static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
+
+ static final int ZIP64_MINVAL32 = 0xFFFF;
+ static final long ZIP64_MINVAL = 0xFFFFFFFFL;
+
+ /*
+ * Zip64 End of central directory (END) header field offsets
+ */
+ static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
+ static final int ZIP64_ENDVEM = 12; // version made by
+ static final int ZIP64_ENDVER = 14; // version needed to extract
+ static final int ZIP64_ENDNMD = 16; // number of this disk
+ static final int ZIP64_ENDDSK = 20; // disk number of start
+ static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
+ static final int ZIP64_ENDTOT = 32; // total number of entries
+ static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
+ static final int ZIP64_ENDOFF = 48; // offset of first CEN header
+ static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
+
+ /*
+ * Zip64 End of central directory locator field offsets
+ */
+ static final int ZIP64_LOCDSK = 4; // disk number start
+ static final int ZIP64_LOCOFF = 8; // offset of zip64 end
+ static final int ZIP64_LOCTOT = 16; // total number of disks
+
+ /*
+ * Zip64 Extra local (EXT) header field offsets
+ */
+ static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
+ static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
+ static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
+
+ /*
+ * Extra field header ID
+ */
+ static final int EXTID_ZIP64 = 0x0001; // ZIP64
+ static final int EXTID_NTFS = 0x000a; // NTFS
+ static final int EXTID_UNIX = 0x000d; // UNIX
+ static final int EXTID_EFS = 0x0017; // Strong Encryption
+ static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
+
+ /*
+ * fields access methods
+ */
+ ///////////////////////////////////////////////////////
+ static final int CH(byte[] b, int n) {
+ return b[n] & 0xff;
+ }
+
+ static final int SH(byte[] b, int n) {
+ return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
+ }
+
+ static final long LG(byte[] b, int n) {
+ return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
+ }
+
+ static final long LL(byte[] b, int n) {
+ return (LG(b, n)) | (LG(b, n + 4) << 32);
+ }
+
+ static final long GETSIG(byte[] b) {
+ return LG(b, 0);
+ }
+
+ // local file (LOC) header fields
+ static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
+ static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
+ static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
+ static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method
+ static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
+ static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
+ static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
+ static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
+ static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length
+ static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
+
+ // extra local (EXT) header fields
+ static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data
+ static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size
+ static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
+
+ // end of central directory header (END) fields
+ static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk
+ static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries
+ static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size
+ static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset
+ static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment
+ static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
+
+ // zip64 end of central directory recoder fields
+ static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk
+ static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries
+ static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size
+ static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset
+ static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
+
+ // central directory header (CEN) fields
+ static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
+ static final int CENVEM(byte[] b, int pos) { return SH(b, pos + 4); }
+ static final int CENVER(byte[] b, int pos) { return SH(b, pos + 6); }
+ static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
+ static final int CENHOW(byte[] b, int pos) { return SH(b, pos + 10);}
+ static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);}
+ static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
+ static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);}
+ static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);}
+ static final int CENNAM(byte[] b, int pos) { return SH(b, pos + 28);}
+ static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
+ static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
+ static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
+ static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
+ static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
+ static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
+
+ /* The END header is followed by a variable length comment of size < 64k. */
+ static final long END_MAXLEN = 0xFFFF + ENDHDR;
+ static final int READBLOCKSZ = 128;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipDirectoryStream.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.DirectoryStream;
+import java.nio.file.ClosedDirectoryStreamException;
+import java.nio.file.NotDirectoryException;
+import java.nio.file.Path;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.io.IOException;
+
+/**
+ *
+ * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipDirectoryStream implements DirectoryStream<Path> {
+
+ private final ZipFileSystem zipfs;
+ private final byte[] path;
+ private final DirectoryStream.Filter<? super Path> filter;
+ private volatile boolean isClosed;
+ private volatile Iterator<Path> itr;
+
+ ZipDirectoryStream(ZipPath zipPath,
+ DirectoryStream.Filter<? super java.nio.file.Path> filter)
+ throws IOException
+ {
+ this.zipfs = zipPath.getFileSystem();
+ this.path = zipPath.getResolvedPath();
+ this.filter = filter;
+ // sanity check
+ if (!zipfs.isDirectory(path))
+ throw new NotDirectoryException(zipPath.toString());
+ }
+
+ @Override
+ public synchronized Iterator<Path> iterator() {
+ if (isClosed)
+ throw new ClosedDirectoryStreamException();
+ if (itr != null)
+ throw new IllegalStateException("Iterator has already been returned");
+
+ try {
+ itr = zipfs.iteratorOf(path, filter);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ return new Iterator<>() {
+ private Path next;
+ @Override
+ public boolean hasNext() {
+ if (isClosed)
+ return false;
+ return itr.hasNext();
+ }
+
+ @Override
+ public synchronized Path next() {
+ if (isClosed)
+ throw new NoSuchElementException();
+ return itr.next();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public synchronized void close() throws IOException {
+ isClosed = true;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributeView.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+
+/*
+ * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipFileAttributeView implements BasicFileAttributeView
+{
+ private static enum AttrID {
+ size,
+ creationTime,
+ lastAccessTime,
+ lastModifiedTime,
+ isDirectory,
+ isRegularFile,
+ isSymbolicLink,
+ isOther,
+ fileKey,
+ compressedSize,
+ crc,
+ method
+ };
+
+ private final ZipPath path;
+ private final boolean isZipView;
+
+ private ZipFileAttributeView(ZipPath path, boolean isZipView) {
+ this.path = path;
+ this.isZipView = isZipView;
+ }
+
+ static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
+ if (type == null)
+ throw new NullPointerException();
+ if (type == BasicFileAttributeView.class)
+ return (V)new ZipFileAttributeView(path, false);
+ if (type == ZipFileAttributeView.class)
+ return (V)new ZipFileAttributeView(path, true);
+ return null;
+ }
+
+ static ZipFileAttributeView get(ZipPath path, String type) {
+ if (type == null)
+ throw new NullPointerException();
+ if (type.equals("basic"))
+ return new ZipFileAttributeView(path, false);
+ if (type.equals("zip"))
+ return new ZipFileAttributeView(path, true);
+ return null;
+ }
+
+ @Override
+ public String name() {
+ return isZipView ? "zip" : "basic";
+ }
+
+ public ZipFileAttributes readAttributes() throws IOException
+ {
+ return path.getAttributes();
+ }
+
+ @Override
+ public void setTimes(FileTime lastModifiedTime,
+ FileTime lastAccessTime,
+ FileTime createTime)
+ throws IOException
+ {
+ path.setTimes(lastModifiedTime, lastAccessTime, createTime);
+ }
+
+ void setAttribute(String attribute, Object value)
+ throws IOException
+ {
+ try {
+ if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
+ setTimes ((FileTime)value, null, null);
+ if (AttrID.valueOf(attribute) == AttrID.lastAccessTime)
+ setTimes (null, (FileTime)value, null);
+ if (AttrID.valueOf(attribute) == AttrID.creationTime)
+ setTimes (null, null, (FileTime)value);
+ return;
+ } catch (IllegalArgumentException x) {}
+ throw new UnsupportedOperationException("'" + attribute +
+ "' is unknown or read-only attribute");
+ }
+
+ public Object getAttribute(String attribute, boolean domap)
+ throws IOException
+ {
+ ZipFileAttributes zfas = readAttributes();
+ if (!domap) {
+ try {
+ return attribute(AttrID.valueOf(attribute), zfas);
+ } catch (IllegalArgumentException x) {}
+ return null;
+ }
+ LinkedHashMap<String, Object> map = new LinkedHashMap<>();
+ if ("*".equals(attribute)) {
+ for (AttrID id : AttrID.values()) {
+ try {
+ map.put(id.name(), attribute(id, zfas));
+ } catch (IllegalArgumentException x) {}
+ }
+ } else {
+ String[] as = attribute.split(",");
+ for (String a : as) {
+ try {
+ map.put(a, attribute(AttrID.valueOf(a), zfas));
+ } catch (IllegalArgumentException x) {}
+ }
+ }
+ return map;
+ }
+
+ Object attribute(AttrID id, ZipFileAttributes zfas) {
+ switch (id) {
+ case size:
+ return zfas.size();
+ case creationTime:
+ return zfas.creationTime();
+ case lastAccessTime:
+ return zfas.lastAccessTime();
+ case lastModifiedTime:
+ return zfas.lastModifiedTime();
+ case isDirectory:
+ return zfas.isDirectory();
+ case isRegularFile:
+ return zfas.isRegularFile();
+ case isSymbolicLink:
+ return zfas.isSymbolicLink();
+ case isOther:
+ return zfas.isOther();
+ case fileKey:
+ return zfas.fileKey();
+ case compressedSize:
+ if (isZipView)
+ return zfas.compressedSize();
+ break;
+ case crc:
+ if (isZipView)
+ return zfas.crc();
+ break;
+ case method:
+ if (isZipView)
+ return zfas.method();
+ break;
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileAttributes.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
+import java.util.Formatter;
+import static com.sun.nio.zipfs.ZipUtils.*;
+
+/**
+ *
+ * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
+ */
+
+public class ZipFileAttributes implements BasicFileAttributes
+
+{
+ private final ZipFileSystem.Entry e;
+
+ ZipFileAttributes(ZipFileSystem.Entry e) {
+ this.e = e;
+ }
+
+ ///////// basic attributes ///////////
+ @Override
+ public FileTime creationTime() {
+ if (e.ctime != -1)
+ return FileTime.fromMillis(e.ctime);
+ return null;
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return e.isDir();
+ }
+
+ @Override
+ public boolean isOther() {
+ return false;
+ }
+
+ @Override
+ public boolean isRegularFile() {
+ return !e.isDir();
+ }
+
+ @Override
+ public FileTime lastAccessTime() {
+ if (e.atime != -1)
+ return FileTime.fromMillis(e.atime);
+ return null;
+ }
+
+ @Override
+ public FileTime lastModifiedTime() {
+ return FileTime.fromMillis(e.mtime);
+ }
+
+ @Override
+ public long size() {
+ return e.size;
+ }
+
+ @Override
+ public boolean isSymbolicLink() {
+ return false;
+ }
+
+ @Override
+ public Object fileKey() {
+ return null;
+ }
+
+ ///////// zip entry attributes ///////////
+ public long compressedSize() {
+ return e.csize;
+ }
+
+ public long crc() {
+ return e.crc;
+ }
+
+ public int method() {
+ return e.method;
+ }
+
+ public byte[] extra() {
+ if (e.extra != null)
+ return Arrays.copyOf(e.extra, e.extra.length);
+ return null;
+ }
+
+ public byte[] comment() {
+ if (e.comment != null)
+ return Arrays.copyOf(e.comment, e.comment.length);
+ return null;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(1024);
+ Formatter fm = new Formatter(sb);
+ if (creationTime() != null)
+ fm.format(" creationTime : %tc%n", creationTime().toMillis());
+ else
+ fm.format(" creationTime : null%n");
+
+ if (lastAccessTime() != null)
+ fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
+ else
+ fm.format(" lastAccessTime : null%n");
+ fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
+ fm.format(" isRegularFile : %b%n", isRegularFile());
+ fm.format(" isDirectory : %b%n", isDirectory());
+ fm.format(" isSymbolicLink : %b%n", isSymbolicLink());
+ fm.format(" isOther : %b%n", isOther());
+ fm.format(" fileKey : %s%n", fileKey());
+ fm.format(" size : %d%n", size());
+ fm.format(" compressedSize : %d%n", compressedSize());
+ fm.format(" crc : %x%n", crc());
+ fm.format(" method : %d%n", method());
+ fm.close();
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileStore.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileStoreSpaceAttributeView;
+import java.nio.file.attribute.FileStoreSpaceAttributes;
+import java.nio.file.attribute.Attributes;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.util.Formatter;
+
+/*
+ *
+ * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipFileStore extends FileStore {
+
+ private final ZipFileSystem zfs;
+
+ ZipFileStore(ZipPath zpath) {
+ this.zfs = (ZipFileSystem)zpath.getFileSystem();
+ }
+
+ @Override
+ public String name() {
+ return zfs.toString() + "/";
+ }
+
+ @Override
+ public String type() {
+ return "zipfs";
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return zfs.isReadOnly();
+ }
+
+ @Override
+ public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
+ return (type == BasicFileAttributeView.class ||
+ type == ZipFileAttributeView.class);
+ }
+
+ @Override
+ public boolean supportsFileAttributeView(String name) {
+ return name.equals("basic") || name.equals("zip");
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
+ if (type == null)
+ throw new NullPointerException();
+ if (type == FileStoreSpaceAttributeView.class)
+ return (V) new ZipFileStoreAttributeView(this);
+ return null;
+ }
+
+ @Override
+ public Object getAttribute(String attribute) throws IOException {
+ if (attribute.equals("space:totalSpace"))
+ return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
+ if (attribute.equals("space:usableSpace"))
+ return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
+ if (attribute.equals("space:unallocatedSpace"))
+ return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
+ throw new UnsupportedOperationException("does not support the given attribute");
+ }
+
+ private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
+
+ private final ZipFileStore fileStore;
+
+ public ZipFileStoreAttributeView(ZipFileStore fileStore) {
+ this.fileStore = fileStore;
+ }
+
+ @Override
+ public String name() {
+ return "space";
+ }
+
+ @Override
+ public FileStoreSpaceAttributes readAttributes() throws IOException {
+ final String file = fileStore.name();
+ Path path = FileSystems.getDefault().getPath(file);
+ final long size = Attributes.readBasicFileAttributes(path).size();
+ final FileStore fstore = path.getFileStore();
+ final FileStoreSpaceAttributes fstoreAttrs =
+ Attributes.readFileStoreSpaceAttributes(fstore);
+ return new FileStoreSpaceAttributes() {
+ public long totalSpace() {
+ return size;
+ }
+
+ public long usableSpace() {
+ if (!fstore.isReadOnly())
+ return fstoreAttrs.usableSpace();
+ return 0;
+ }
+
+ public long unallocatedSpace() {
+ if (!fstore.isReadOnly())
+ return fstoreAttrs.unallocatedSpace();
+ return 0;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ Formatter fm = new Formatter(sb);
+ fm.format("FileStoreSpaceAttributes[%s]%n", file);
+ fm.format(" totalSpace: %d%n", totalSpace());
+ fm.format(" usableSpace: %d%n", usableSpace());
+ fm.format(" unallocSpace: %d%n", unallocatedSpace());
+ fm.close();
+ return sb.toString();
+ }
+ };
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2369 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.*;
+import java.util.*;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.regex.Pattern;
+import java.util.zip.CRC32;
+import java.util.zip.Inflater;
+import java.util.zip.Deflater;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.ZipException;
+import java.util.zip.ZipError;
+import static java.lang.Boolean.*;
+import static com.sun.nio.zipfs.ZipConstants.*;
+import static com.sun.nio.zipfs.ZipUtils.*;
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/**
+ * A FileSystem built on a zip file
+ *
+ * @author Xueming Shen
+ */
+
+public class ZipFileSystem extends FileSystem {
+
+ private final ZipFileSystemProvider provider;
+ private final ZipPath defaultdir;
+ private boolean readOnly = false;
+ private final Path zfpath;
+ private final ZipCoder zc;
+
+ // configurable by env map
+ private final String defaultDir; // default dir for the file system
+ private final String nameEncoding; // default encoding for name/comment
+ private final boolean buildDirTree; // build a dir tree for directoryStream ops
+ private final boolean useTempFile; // use a temp file for newOS, default
+ // is to use BAOS for better performance
+ private final boolean createNew; // create a new zip if not exists
+ private static final boolean isWindows =
+ System.getProperty("os.name").startsWith("Windows");
+
+ ZipFileSystem(ZipFileSystemProvider provider,
+ Path zfpath,
+ Map<String, ?> env)
+ throws IOException
+ {
+ // configurable env setup
+ this.createNew = "true".equals(env.get("create"));
+ this.nameEncoding = env.containsKey("encoding") ?
+ (String)env.get("encoding") : "UTF-8";
+ this.buildDirTree = TRUE.equals(env.get("buildDirTreea"));
+ this.useTempFile = TRUE.equals(env.get("useTempFile"));
+ this.defaultDir = env.containsKey("default.dir") ?
+ (String)env.get("default.dir") : "/";
+ if (this.defaultDir.charAt(0) != '/')
+ throw new IllegalArgumentException("default dir should be absolute");
+
+ this.provider = provider;
+ this.zfpath = zfpath;
+ if (zfpath.notExists()) {
+ if (createNew) {
+ OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
+ new END().write(os, 0);
+ os.close();
+ } else {
+ throw new FileSystemNotFoundException(zfpath.toString());
+ }
+ }
+ zfpath.checkAccess(AccessMode.READ); // sm and existence check
+ try {
+ zfpath.checkAccess(AccessMode.WRITE);
+ } catch (AccessDeniedException x) {
+ this.readOnly = true;
+ }
+ this.zc = ZipCoder.get(nameEncoding);
+ this.defaultdir = new ZipPath(this, getBytes(defaultDir));
+ this.ch = zfpath.newByteChannel(READ);
+ this.cen = initCEN();
+ }
+
+ @Override
+ public FileSystemProvider provider() {
+ return provider;
+ }
+
+ @Override
+ public String getSeparator() {
+ return "/";
+ }
+
+ @Override
+ public boolean isOpen() {
+ return isOpen;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ private void checkWritable() throws IOException {
+ if (readOnly)
+ throw new ReadOnlyFileSystemException();
+ }
+
+ @Override
+ public Iterable<Path> getRootDirectories() {
+ ArrayList<Path> pathArr = new ArrayList<>();
+ pathArr.add(new ZipPath(this, new byte[]{'/'}));
+ return pathArr;
+ }
+
+ ZipPath getDefaultDir() { // package private
+ return defaultdir;
+ }
+
+ @Override
+ public ZipPath getPath(String path) {
+ if (path.length() == 0)
+ throw new InvalidPathException(path, "path should not be empty");
+ return new ZipPath(this, getBytes(path));
+ }
+
+ @Override
+ public UserPrincipalLookupService getUserPrincipalLookupService() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public WatchService newWatchService() {
+ throw new UnsupportedOperationException();
+ }
+
+ FileStore getFileStore(ZipPath path) {
+ return new ZipFileStore(path);
+ }
+
+ @Override
+ public Iterable<FileStore> getFileStores() {
+ ArrayList<FileStore> list = new ArrayList<>(1);
+ list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
+ return list;
+ }
+
+ private static final Set<String> supportedFileAttributeViews =
+ Collections.unmodifiableSet(
+ new HashSet<String>(Arrays.asList("basic", "zip")));
+
+ @Override
+ public Set<String> supportedFileAttributeViews() {
+ return supportedFileAttributeViews;
+ }
+
+ @Override
+ public String toString() {
+ return zfpath.toString();
+ }
+
+ Path getZipFile() {
+ return zfpath;
+ }
+
+ private static final String GLOB_SYNTAX = "glob";
+ private static final String REGEX_SYNTAX = "regex";
+
+ @Override
+ public PathMatcher getPathMatcher(String syntaxAndInput) {
+ int pos = syntaxAndInput.indexOf(':');
+ if (pos <= 0 || pos == syntaxAndInput.length()) {
+ throw new IllegalArgumentException();
+ }
+ String syntax = syntaxAndInput.substring(0, pos);
+ String input = syntaxAndInput.substring(pos + 1);
+ String expr;
+ if (syntax.equals(GLOB_SYNTAX)) {
+ expr = toRegexPattern(input);
+ } else {
+ if (syntax.equals(REGEX_SYNTAX)) {
+ expr = input;
+ } else {
+ throw new UnsupportedOperationException("Syntax '" + syntax +
+ "' not recognized");
+ }
+ }
+ // return matcher
+ final Pattern pattern = Pattern.compile(expr);
+ return new PathMatcher() {
+ @Override
+ public boolean matches(Path path) {
+ return pattern.matcher(path.toString()).matches();
+ }
+ };
+ }
+
+ @Override
+ public void close() throws IOException {
+ beginWrite();
+ try {
+ if (!isOpen)
+ return;
+ isOpen = false; // set closed
+ } finally {
+ endWrite();
+ }
+ if (!streams.isEmpty()) { // unlock and close all remaining streams
+ Set<InputStream> copy = new HashSet<>(streams);
+ for (InputStream is: copy)
+ is.close();
+ }
+ beginWrite(); // lock and sync
+ try {
+ sync();
+ ch.close(); // close the ch just in case no update
+ } finally { // and sync dose not close the ch
+ endWrite();
+ }
+
+ synchronized (inflaters) {
+ for (Inflater inf : inflaters)
+ inf.end();
+ }
+ synchronized (deflaters) {
+ for (Deflater def : deflaters)
+ def.end();
+ }
+
+ synchronized (tmppaths) {
+ for (Path p: tmppaths) {
+ try {
+ p.deleteIfExists();
+ } catch (IOException x) {
+ x.printStackTrace();
+ }
+ }
+ }
+ provider.removeFileSystem(zfpath);
+ }
+
+ ZipFileAttributes getFileAttributes(byte[] path)
+ throws IOException
+ {
+ Entry e;
+ beginRead();
+ try {
+ ensureOpen();
+ e = getEntry0(path);
+ } finally {
+ endRead();
+ }
+ if (e == null) {
+ if (path.length == 0) {
+ e = new Entry(new byte[0]); // root
+ } else if (buildDirTree) {
+ IndexNode inode = getDirs().get(IndexNode.keyOf(path));
+ if (inode == null)
+ return null;
+ e = new Entry(inode.name);
+ } else {
+ return null;
+ }
+ e.method = METHOD_STORED; // STORED for dir
+ BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
+ if (bfas.lastModifiedTime() != null)
+ e.mtime = bfas.lastModifiedTime().toMillis();
+ if (bfas.lastAccessTime() != null)
+ e.atime = bfas.lastAccessTime().toMillis();
+ if (bfas.creationTime() != null)
+ e.ctime = bfas.creationTime().toMillis();
+ }
+ return new ZipFileAttributes(e);
+ }
+
+ void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
+ throws IOException
+ {
+ checkWritable();
+ beginWrite();
+ try {
+ ensureOpen();
+ Entry e = getEntry0(path); // ensureOpen checked
+ if (e == null)
+ throw new NoSuchFileException(getString(path));
+ if (e.type == Entry.CEN)
+ e.type = Entry.COPY; // copy e
+ if (mtime != null)
+ e.mtime = mtime.toMillis();
+ if (atime != null)
+ e.atime = atime.toMillis();
+ if (ctime != null)
+ e.ctime = ctime.toMillis();
+ update(e);
+ } finally {
+ endWrite();
+ }
+ }
+
+ boolean exists(byte[] path)
+ throws IOException
+ {
+ beginRead();
+ try {
+ ensureOpen();
+ return getEntry0(path) != null;
+ } finally {
+ endRead();
+ }
+ }
+
+ boolean isDirectory(byte[] path)
+ throws IOException
+ {
+ if (buildDirTree)
+ return getDirs().containsKey(IndexNode.keyOf(path));
+
+ beginRead();
+ try {
+ Entry e = getEntry0(path);
+ return (e != null && e.isDir()) || path.length == 0;
+ } finally {
+ endRead();
+ }
+ }
+
+ private ZipPath toZipPath(byte[] path) {
+ // make it absolute
+ byte[] p = new byte[path.length + 1];
+ p[0] = '/';
+ System.arraycopy(path, 0, p, 1, path.length);
+ return new ZipPath(this, p);
+ }
+
+ // returns the list of child paths of "path"
+ Iterator<Path> iteratorOf(byte[] path,
+ DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ beginWrite(); // iteration of inodes needs exclusive lock
+ try {
+ ensureOpen();
+ if (buildDirTree) {
+ IndexNode inode = getDirs().get(IndexNode.keyOf(path));
+ if (inode == null)
+ throw new NotDirectoryException(getString(path));
+ List<Path> list = new ArrayList<>();
+ IndexNode child = inode.child;
+ while (child != null) {
+ ZipPath zp = toZipPath(child.name);
+ if (filter == null || filter.accept(zp))
+ list.add(zp);
+ child = child.sibling;
+ }
+ return list.iterator();
+ }
+
+ if (!isDirectory(path))
+ throw new NotDirectoryException(getString(path));
+ List<Path> list = new ArrayList<>();
+ path = toDirectoryPath(path);
+ for (IndexNode key : inodes.keySet()) {
+ if (!isParentOf(path, key.name)) // is "path" the parent of "name"
+ continue;
+ int off = path.length;
+ while (off < key.name.length) {
+ if (key.name[off] == '/')
+ break;
+ off++;
+ }
+ if (off < (key.name.length - 1))
+ continue;
+ ZipPath zp = toZipPath(key.name);
+ if (filter == null || filter.accept(zp))
+ list.add(zp);
+ }
+ return list.iterator();
+ } finally {
+ endWrite();
+ }
+ }
+
+ void createDirectory(byte[] dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ checkWritable();
+ dir = toDirectoryPath(dir);
+ beginWrite();
+ try {
+ ensureOpen();
+ if (dir.length == 0 || exists(dir)) // root dir, or exiting dir
+ throw new FileAlreadyExistsException(getString(dir));
+
+ checkParents(dir);
+ Entry e = new Entry(dir, Entry.NEW);
+ e.method = METHOD_STORED; // STORED for dir
+ update(e);
+ } finally {
+ endWrite();
+ }
+ }
+
+ void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
+ throws IOException
+ {
+ checkWritable();
+ if (Arrays.equals(src, dst))
+ return; // do nothing, src and dst are the same
+
+ beginWrite();
+ try {
+ ensureOpen();
+ Entry eSrc = getEntry0(src); // ensureOpen checked
+ if (eSrc == null)
+ throw new NoSuchFileException(getString(src));
+ if (eSrc.isDir()) { // spec says to create dst dir
+ createDirectory(dst);
+ return;
+ }
+ boolean hasReplace = false;
+ boolean hasCopyAttrs = false;
+ for (CopyOption opt : options) {
+ if (opt == REPLACE_EXISTING)
+ hasReplace = true;
+ else if (opt == COPY_ATTRIBUTES)
+ hasCopyAttrs = true;
+ }
+ Entry eDst = getEntry0(dst);
+ if (eDst != null) {
+ if (!hasReplace)
+ throw new FileAlreadyExistsException(getString(dst));
+ } else {
+ checkParents(dst);
+ }
+ Entry u = new Entry(eSrc, Entry.COPY); // copy eSrc entry
+ u.name = dst; // change name
+ if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
+ {
+ u.type = eSrc.type; // make it the same type
+ if (!deletesrc) { // if it's not "rename", just take the data
+ if (eSrc.bytes != null)
+ u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
+ else if (eSrc.file != null) {
+ u.file = getTempPathForEntry(null);
+ eSrc.file.copyTo(u.file, REPLACE_EXISTING);
+ }
+ }
+ }
+ if (!hasCopyAttrs)
+ u.mtime = u.atime= u.ctime = System.currentTimeMillis();
+ update(u);
+ if (deletesrc)
+ updateDelete(eSrc);
+ } finally {
+ endWrite();
+ }
+ }
+
+ // Returns an output stream for writing the contents into the specified
+ // entry.
+ OutputStream newOutputStream(byte[] path, OpenOption... options)
+ throws IOException
+ {
+ checkWritable();
+ boolean hasCreateNew = false;
+ boolean hasCreate = false;
+ boolean hasAppend = false;
+ for (OpenOption opt: options) {
+ if (opt == READ)
+ throw new IllegalArgumentException("READ not allowed");
+ if (opt == CREATE_NEW)
+ hasCreateNew = true;
+ if (opt == CREATE)
+ hasCreate = true;
+ if (opt == APPEND)
+ hasAppend = true;
+ }
+ beginRead(); // only need a readlock, the "update()" will
+ try { // try to obtain a writelock when the os is
+ ensureOpen(); // being closed.
+ Entry e = getEntry0(path);
+ if (e != null) {
+ if (e.isDir() || hasCreateNew)
+ throw new FileAlreadyExistsException(getString(path));
+ if (hasAppend) {
+ InputStream is = getInputStream(e);
+ OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
+ copyStream(is, os);
+ is.close();
+ return os;
+ }
+ return getOutputStream(new Entry(e, Entry.NEW));
+ } else {
+ if (!hasCreate && !hasCreateNew)
+ throw new NoSuchFileException(getString(path));
+ checkParents(path);
+ return getOutputStream(new Entry(path, Entry.NEW));
+ }
+ } finally {
+ endRead();
+ }
+ }
+
+ // Returns an input stream for reading the contents of the specified
+ // file entry.
+ InputStream newInputStream(byte[] path) throws IOException {
+ beginRead();
+ try {
+ ensureOpen();
+ Entry e = getEntry0(path);
+ if (e == null)
+ throw new NoSuchFileException(getString(path));
+ if (e.isDir())
+ throw new FileSystemException(getString(path), "is a directory", null);
+ return getInputStream(e);
+ } finally {
+ endRead();
+ }
+ }
+
+ private void checkOptions(Set<? extends OpenOption> options) {
+ // check for options of null type and option is an intance of StandardOpenOption
+ for (OpenOption option : options) {
+ if (option == null)
+ throw new NullPointerException();
+ if (!(option instanceof StandardOpenOption))
+ throw new IllegalArgumentException();
+ }
+ }
+
+ // Returns a Writable/ReadByteChannel for now. Might consdier to use
+ // newFileChannel() instead, which dump the entry data into a regular
+ // file on the default file system and create a FileChannel on top of
+ // it.
+ SeekableByteChannel newByteChannel(byte[] path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ checkOptions(options);
+ if (options.contains(StandardOpenOption.WRITE) ||
+ options.contains(StandardOpenOption.APPEND)) {
+ checkWritable();
+ beginRead();
+ try {
+ final WritableByteChannel wbc = Channels.newChannel(
+ newOutputStream(path, options.toArray(new OpenOption[0])));
+ long leftover = 0;
+ if (options.contains(StandardOpenOption.APPEND)) {
+ Entry e = getEntry0(path);
+ if (e != null && e.size >= 0)
+ leftover = e.size;
+ }
+ final long offset = leftover;
+ return new SeekableByteChannel() {
+ long written = offset;
+ public boolean isOpen() {
+ return wbc.isOpen();
+ }
+
+ public long position() throws IOException {
+ return written;
+ }
+
+ public SeekableByteChannel position(long pos)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int read(ByteBuffer dst) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ public SeekableByteChannel truncate(long size)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int write(ByteBuffer src) throws IOException {
+ int n = wbc.write(src);
+ written += n;
+ return n;
+ }
+
+ public long size() throws IOException {
+ return written;
+ }
+
+ public void close() throws IOException {
+ wbc.close();
+ }
+ };
+ } finally {
+ endRead();
+ }
+ } else {
+ beginRead();
+ try {
+ ensureOpen();
+ Entry e = getEntry0(path);
+ if (e == null || e.isDir())
+ throw new NoSuchFileException(getString(path));
+ final ReadableByteChannel rbc =
+ Channels.newChannel(getInputStream(e));
+ final long size = e.size;
+ return new SeekableByteChannel() {
+ long read = 0;
+ public boolean isOpen() {
+ return rbc.isOpen();
+ }
+
+ public long position() throws IOException {
+ return read;
+ }
+
+ public SeekableByteChannel position(long pos)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int read(ByteBuffer dst) throws IOException {
+ return rbc.read(dst);
+ }
+
+ public SeekableByteChannel truncate(long size)
+ throws IOException
+ {
+ throw new NonWritableChannelException();
+ }
+
+ public int write (ByteBuffer src) throws IOException {
+ throw new NonWritableChannelException();
+ }
+
+ public long size() throws IOException {
+ return size;
+ }
+
+ public void close() throws IOException {
+ rbc.close();
+ }
+ };
+ } finally {
+ endRead();
+ }
+ }
+ }
+
+ // Returns a FileChannel of the specified entry.
+ //
+ // This implementation creates a temporary file on the default file system,
+ // copy the entry data into it if the entry exists, and then create a
+ // FileChannel on top of it.
+ FileChannel newFileChannel(byte[] path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ checkOptions(options);
+ final boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
+ options.contains(StandardOpenOption.APPEND));
+ beginRead();
+ try {
+ ensureOpen();
+ Entry e = getEntry0(path);
+ if (forWrite) {
+ checkWritable();
+ if (e == null) {
+ if (!options.contains(StandardOpenOption.CREATE_NEW))
+ throw new NoSuchFileException(getString(path));
+ } else {
+ if (options.contains(StandardOpenOption.CREATE_NEW))
+ throw new FileAlreadyExistsException(getString(path));
+ if (e.isDir())
+ throw new FileAlreadyExistsException("directory <"
+ + getString(path) + "> exists");
+ }
+ options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
+ } else if (e == null || e.isDir()) {
+ throw new NoSuchFileException(getString(path));
+ }
+
+ final boolean isFCH = (e != null && e.type == Entry.FILECH);
+ final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
+ final FileChannel fch = tmpfile.getFileSystem()
+ .provider()
+ .newFileChannel(tmpfile, options, attrs);
+ final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
+ if (forWrite) {
+ u.flag = FLAG_DATADESCR;
+ u.method = METHOD_DEFLATED;
+ }
+ // is there a better way to hook into the FileChannel's close method?
+ return new FileChannel() {
+ public int write(ByteBuffer src) throws IOException {
+ return fch.write(src);
+ }
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException
+ {
+ return fch.write(srcs, offset, length);
+ }
+ public long position() throws IOException {
+ return fch.position();
+ }
+ public FileChannel position(long newPosition)
+ throws IOException
+ {
+ fch.position(newPosition);
+ return this;
+ }
+ public long size() throws IOException {
+ return fch.size();
+ }
+ public FileChannel truncate(long size)
+ throws IOException
+ {
+ fch.truncate(size);
+ return this;
+ }
+ public void force(boolean metaData)
+ throws IOException
+ {
+ fch.force(metaData);
+ }
+ public long transferTo(long position, long count,
+ WritableByteChannel target)
+ throws IOException
+ {
+ return fch.transferTo(position, count, target);
+ }
+ public long transferFrom(ReadableByteChannel src,
+ long position, long count)
+ throws IOException
+ {
+ return fch.transferFrom(src, position, count);
+ }
+ public int read(ByteBuffer dst) throws IOException {
+ return fch.read(dst);
+ }
+ public int read(ByteBuffer dst, long position)
+ throws IOException
+ {
+ return fch.read(dst, position);
+ }
+ public long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException
+ {
+ return fch.read(dsts, offset, length);
+ }
+ public int write(ByteBuffer src, long position)
+ throws IOException
+ {
+ return fch.write(src, position);
+ }
+ public MappedByteBuffer map(MapMode mode,
+ long position, long size)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+ public FileLock lock(long position, long size, boolean shared)
+ throws IOException
+ {
+ return fch.lock(position, size, shared);
+ }
+ public FileLock tryLock(long position, long size, boolean shared)
+ throws IOException
+ {
+ return fch.tryLock(position, size, shared);
+ }
+ protected void implCloseChannel() throws IOException {
+ fch.close();
+ if (forWrite) {
+ u.mtime = System.currentTimeMillis();
+ u.size = Attributes.readBasicFileAttributes(u.file).size();
+ update(u);
+ } else {
+ if (!isFCH) // if this is a new fch for reading
+ removeTempPathForEntry(tmpfile);
+ }
+ }
+ };
+ } finally {
+ endRead();
+ }
+ }
+
+ // the outstanding input streams that need to be closed
+ private Set<InputStream> streams =
+ Collections.synchronizedSet(new HashSet<InputStream>());
+
+ // the ex-channel and ex-path that need to close when their outstanding
+ // input streams are all closed by the obtainers.
+ private Set<ExChannelCloser> exChClosers = new HashSet<>();
+
+ private Set<Path> tmppaths = Collections.synchronizedSet(new HashSet<Path>());
+ private Path getTempPathForEntry(byte[] path) throws IOException {
+ Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
+ if (path != null) {
+ Entry e = getEntry0(path);
+ if (e != null) {
+ InputStream is = newInputStream(path);
+ OutputStream os = tmpPath.newOutputStream(WRITE);
+ try {
+ copyStream(is, os);
+ } finally {
+ is.close();
+ os.close();
+ }
+ }
+ }
+ return tmpPath;
+ }
+
+ private void removeTempPathForEntry(Path path) throws IOException {
+ path.delete();
+ tmppaths.remove(path);
+ }
+
+ // check if all parents really exit. ZIP spec does not require
+ // the existence of any "parent directory".
+ private void checkParents(byte[] path) throws IOException {
+ beginRead();
+ try {
+ while ((path = getParent(path)) != null) {
+ if (!inodes.containsKey(IndexNode.keyOf(path)))
+ throw new NoSuchFileException(getString(path));
+ }
+ } finally {
+ endRead();
+ }
+ }
+
+ private static byte[] getParent(byte[] path) {
+ int off = path.length - 1;
+ if (off > 0 && path[off] == '/') // isDirectory
+ off--;
+ while (off > 0 && path[off] != '/') { off--; }
+ if (off == 0)
+ return null; // top entry
+ return Arrays.copyOf(path, off + 1);
+ }
+
+ // If "starter" is the parent directory of "path"
+ private static boolean isParentOf(byte[] p, byte[] c) {
+ final int plen = p.length;
+ if (plen == 0) // root dir
+ return true;
+ if (plen >= c.length)
+ return false;
+ int n = 0;
+ while (n < plen) {
+ if (p[n] != c[n])
+ return false;
+ n++;
+ }
+ if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
+ return false;
+ return true;
+ }
+
+ private final void beginWrite() {
+ rwlock.writeLock().lock();
+ }
+
+ private final void endWrite() {
+ rwlock.writeLock().unlock();
+ }
+
+ private final void beginRead() {
+ rwlock.readLock().lock();
+ }
+
+ private final void endRead() {
+ rwlock.readLock().unlock();
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
+ private volatile boolean isOpen = true;
+ private final SeekableByteChannel ch; // channel to the zipfile
+ final byte[] cen; // CEN & ENDHDR
+ private END end;
+ private long locpos; // position of first LOC header (usually 0)
+
+ private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
+
+ // name -> pos (in cen), IndexNode itself can be used as a "key"
+ private LinkedHashMap<IndexNode, IndexNode> inodes;
+
+ final byte[] getBytes(String name) {
+ return zc.getBytes(name);
+ }
+
+ final String getString(byte[] name) {
+ return zc.toString(name);
+ }
+
+ protected void finalize() throws IOException {
+ close();
+ }
+
+ private long getDataPos(Entry e) throws IOException {
+ if (e.locoff == -1) {
+ Entry e2 = getEntry0(e.name);
+ if (e2 == null)
+ throw new ZipException("invalid loc for entry <" + e.name + ">");
+ e.locoff = e2.locoff;
+ }
+ byte[] buf = new byte[LOCHDR];
+ if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
+ throw new ZipException("invalid loc for entry <" + e.name + ">");
+ return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
+ }
+
+ // Reads len bytes of data from the specified offset into buf.
+ // Returns the total number of bytes read.
+ // Each/every byte read from here (except the cen, which is mapped).
+ final long readFullyAt(byte[] buf, int off, long len, long pos)
+ throws IOException
+ {
+ ByteBuffer bb = ByteBuffer.wrap(buf);
+ bb.position(off);
+ bb.limit((int)(off + len));
+ return readFullyAt(bb, pos);
+ }
+
+ private final long readFullyAt(ByteBuffer bb, long pos)
+ throws IOException
+ {
+ synchronized(ch) {
+ return ch.position(pos).read(bb);
+ }
+ }
+
+ // Searches for end of central directory (END) header. The contents of
+ // the END header will be read and placed in endbuf. Returns the file
+ // position of the END header, otherwise returns -1 if the END header
+ // was not found or an error occurred.
+ private END findEND() throws IOException
+ {
+ byte[] buf = new byte[READBLOCKSZ];
+ long ziplen = ch.size();
+ long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
+ long minPos = minHDR - (buf.length - ENDHDR);
+
+ for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
+ {
+ int off = 0;
+ if (pos < 0) {
+ // Pretend there are some NUL bytes before start of file
+ off = (int)-pos;
+ Arrays.fill(buf, 0, off, (byte)0);
+ }
+ int len = buf.length - off;
+ if (readFullyAt(buf, off, len, pos + off) != len)
+ zerror("zip END header not found");
+
+ // Now scan the block backwards for END header signature
+ for (int i = buf.length - ENDHDR; i >= 0; i--) {
+ if (buf[i+0] == (byte)'P' &&
+ buf[i+1] == (byte)'K' &&
+ buf[i+2] == (byte)'\005' &&
+ buf[i+3] == (byte)'\006' &&
+ (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
+ // Found END header
+ buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
+ END end = new END();
+ end.endsub = ENDSUB(buf);
+ end.centot = ENDTOT(buf);
+ end.cenlen = ENDSIZ(buf);
+ end.cenoff = ENDOFF(buf);
+ end.comlen = ENDCOM(buf);
+ end.endpos = pos + i;
+ if (end.cenlen == ZIP64_MINVAL ||
+ end.cenoff == ZIP64_MINVAL ||
+ end.centot == ZIP64_MINVAL32)
+ {
+ // need to find the zip64 end;
+ byte[] loc64 = new byte[ZIP64_LOCHDR];
+ if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
+ != loc64.length) {
+ return end;
+ }
+ long end64pos = ZIP64_LOCOFF(loc64);
+ byte[] end64buf = new byte[ZIP64_ENDHDR];
+ if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
+ != end64buf.length) {
+ return end;
+ }
+ // end64 found, re-calcualte everything.
+ end.cenlen = ZIP64_ENDSIZ(end64buf);
+ end.cenoff = ZIP64_ENDOFF(end64buf);
+ end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
+ end.endpos = end64pos;
+ }
+ return end;
+ }
+ }
+ }
+ zerror("zip END header not found");
+ return null; //make compiler happy
+ }
+
+ // Reads zip file central directory. Returns the file position of first
+ // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
+ // then the error was a zip format error and zip->msg has the error text.
+ // Always pass in -1 for knownTotal; it's used for a recursive call.
+ private byte[] initCEN() throws IOException {
+ end = findEND();
+ if (end.endpos == 0) {
+ inodes = new LinkedHashMap<>(10);
+ locpos = 0;
+ return null; // only END header present
+ }
+ if (end.cenlen > end.endpos)
+ zerror("invalid END header (bad central directory size)");
+ long cenpos = end.endpos - end.cenlen; // position of CEN table
+
+ // Get position of first local file (LOC) header, taking into
+ // account that there may be a stub prefixed to the zip file.
+ locpos = cenpos - end.cenoff;
+ if (locpos < 0)
+ zerror("invalid END header (bad central directory offset)");
+
+ // read in the CEN and END
+ byte[] cen = new byte[(int)(end.cenlen + ENDHDR)];
+ if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
+ zerror("read CEN tables failed");
+ }
+ // Iterate through the entries in the central directory
+ inodes = new LinkedHashMap<>(end.centot + 1);
+ int pos = 0;
+ int limit = cen.length - ENDHDR;
+ while (pos < limit) {
+ if (CENSIG(cen, pos) != CENSIG)
+ zerror("invalid CEN header (bad signature)");
+ int method = CENHOW(cen, pos);
+ int nlen = CENNAM(cen, pos);
+ int elen = CENEXT(cen, pos);
+ int clen = CENCOM(cen, pos);
+ if ((CENFLG(cen, pos) & 1) != 0)
+ zerror("invalid CEN header (encrypted entry)");
+ if (method != METHOD_STORED && method != METHOD_DEFLATED)
+ zerror("invalid CEN header (unsupported compression method: " + method + ")");
+ if (pos + CENHDR + nlen > limit)
+ zerror("invalid CEN header (bad header size)");
+ byte[] name = Arrays.copyOfRange(cen, pos + CENHDR, pos + CENHDR + nlen);
+ IndexNode inode = new IndexNode(name, pos);
+ inodes.put(inode, inode);
+ // skip ext and comment
+ pos += (CENHDR + nlen + elen + clen);
+ }
+ if (pos + ENDHDR != cen.length) {
+ zerror("invalid CEN header (bad header size)");
+ }
+ return cen;
+ }
+
+ private void ensureOpen() throws IOException {
+ if (!isOpen)
+ throw new ClosedFileSystemException();
+ }
+
+ // Creates a new empty temporary file in the same directory as the
+ // specified file. A variant of File.createTempFile.
+ private Path createTempFileInSameDirectoryAs(Path path)
+ throws IOException
+ {
+ Path parent = path.toAbsolutePath().getParent();
+ String dir = (parent == null)? "." : parent.toString();
+ Path tmpPath = File.createTempFile("zipfstmp", null, new File(dir)).toPath();
+ tmppaths.add(tmpPath);
+ return tmpPath;
+ }
+
+ ////////////////////update & sync //////////////////////////////////////
+
+ private boolean hasUpdate = false;
+
+ private void updateDelete(Entry e) {
+ beginWrite();
+ try {
+ inodes.remove(IndexNode.keyOf(e.name)); //inodes.remove(e.name);
+ hasUpdate = true;
+ dirs = null;
+ } finally {
+ endWrite();
+ }
+ }
+
+ private void update(Entry e) {
+ beginWrite();
+ try {
+ inodes.put(IndexNode.keyOf(e.name), e); //inodes.put(e, e);
+ hasUpdate = true;
+ dirs = null;
+ } finally {
+ endWrite();
+ }
+ }
+
+ // copy over the whole LOC entry (header if necessary, data and ext) from
+ // old zip to the new one.
+ private long copyLOCEntry(Entry e, boolean updateHeader,
+ OutputStream os,
+ long written, byte[] buf)
+ throws IOException
+ {
+ long locoff = e.locoff; // where to read
+ e.locoff = written; // update the e.locoff with new value
+
+ // calculate the size need to write out
+ long size = 0;
+ // if there is A ext
+ if ((e.flag & FLAG_DATADESCR) != 0) {
+ if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
+ size = 24;
+ else
+ size = 16;
+ }
+ // read loc, use the original loc.elen/nlen
+ if (readFullyAt(buf, 0, LOCHDR , locoff) != LOCHDR)
+ throw new ZipException("loc: reading failed");
+ if (updateHeader) {
+ locoff += LOCHDR + LOCNAM(buf) + LOCEXT(buf); // skip header
+ size += e.csize;
+ written = e.writeLOC(os) + size;
+ } else {
+ os.write(buf, 0, LOCHDR); // write out the loc header
+ locoff += LOCHDR;
+ // use e.csize, LOCSIZ(buf) is zero if FLAG_DATADESCR is on
+ // size += LOCNAM(buf) + LOCEXT(buf) + LOCSIZ(buf);
+ size += LOCNAM(buf) + LOCEXT(buf) + e.csize;
+ written = LOCHDR + size;
+ }
+ int n;
+ while (size > 0 &&
+ (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
+ {
+ if (size < n)
+ n = (int)size;
+ os.write(buf, 0, n);
+ size -= n;
+ locoff += n;
+ }
+ return written;
+ }
+
+ // sync the zip file system, if there is any udpate
+ private void sync() throws IOException {
+ //System.out.printf("->sync(%s) starting....!%n", toString());
+
+ // check ex-closer
+ if (!exChClosers.isEmpty()) {
+ for (ExChannelCloser ecc : exChClosers) {
+ if (ecc.streams.isEmpty()) {
+ ecc.ch.close();
+ ecc.path.delete();
+ exChClosers.remove(ecc);
+ }
+ }
+ }
+ if (!hasUpdate)
+ return;
+ Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
+ OutputStream os = tmpFile.newOutputStream(WRITE);
+ ArrayList<Entry> elist = new ArrayList<>(inodes.size());
+ long written = 0;
+ byte[] buf = new byte[8192];
+ Entry e = null;
+
+ // write loc
+ for (IndexNode inode : inodes.values()) {
+ if (inode instanceof Entry) { // an updated inode
+ e = (Entry)inode;
+ try {
+ if (e.type == Entry.COPY) {
+ // entry copy: the only thing changed is the "name"
+ // and "nlen" in LOC header, so we udpate/rewrite the
+ // LOC in new file and simply copy the rest (data and
+ // ext) without enflating/deflating from the old zip
+ // file LOC entry.
+ written += copyLOCEntry(e, true, os, written, buf);
+ } else { // NEW or FILECH
+ e.locoff = written;
+ written += e.writeLOC(os); // write loc header
+ if (e.bytes != null) { // in-memory, deflated
+ os.write(e.bytes); // already
+ written += e.bytes.length;
+ } else if (e.file != null) { // tmp file
+ InputStream is = e.file.newInputStream();
+ int n;
+ if (e.type == Entry.NEW) { // deflated already
+ while ((n = is.read(buf)) != -1) {
+ os.write(buf, 0, n);
+ written += n;
+ }
+ } else if (e.type == Entry.FILECH) {
+ // the data are not deflated, use ZEOS
+ OutputStream os2 = new EntryOutputStream(e, os);
+ while ((n = is.read(buf)) != -1) {
+ os2.write(buf, 0, n);
+ }
+ os2.close();
+ written += e.csize;
+ if ((e.flag & FLAG_DATADESCR) != 0)
+ written += e.writeEXT(os);
+ }
+ is.close();
+ e.file.delete();
+ tmppaths.remove(e.file);
+ } else {
+ // dir, 0-length data
+ }
+ }
+ elist.add(e);
+ } catch (IOException x) {
+ x.printStackTrace(); // skip any in-accurate entry
+ }
+ } else { // unchanged inode
+ e = Entry.readCEN(this, inode.pos);
+ try {
+ written += copyLOCEntry(e, false, os, written, buf);
+ elist.add(e);
+ } catch (IOException x) {
+ x.printStackTrace(); // skip any wrong entry
+ }
+ }
+ }
+
+ // now write back the cen and end table
+ end.cenoff = written;
+ for (Entry entry : elist) {
+ written += entry.writeCEN(os);
+ }
+ end.centot = elist.size();
+ end.cenlen = written - end.cenoff;
+ end.write(os, written);
+ os.close();
+
+ if (!streams.isEmpty()) {
+ //
+ // TBD: ExChannelCloser should not be necessary if we only
+ // sync when being closed, all streams should have been
+ // closed already. Keep the logic here for now.
+ //
+ // There are outstanding input streams open on existing "ch",
+ // so, don't close the "cha" and delete the "file for now, let
+ // the "ex-channel-closer" to handle them
+ ExChannelCloser ecc = new ExChannelCloser(
+ createTempFileInSameDirectoryAs(zfpath),
+ ch,
+ streams);
+ zfpath.moveTo(ecc.path, REPLACE_EXISTING);
+ exChClosers.add(ecc);
+ streams = Collections.synchronizedSet(new HashSet<InputStream>());
+ } else {
+ ch.close();
+ zfpath.delete();
+ }
+
+ tmpFile.moveTo(zfpath, REPLACE_EXISTING);
+ hasUpdate = false; // clear
+ /*
+ if (isOpen) {
+ ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
+ cen = initCEN();
+ }
+ */
+ //System.out.printf("->sync(%s) done!%n", toString());
+ }
+
+ private Entry getEntry0(byte[] path) throws IOException {
+ if (path == null)
+ throw new NullPointerException("path");
+ if (path.length == 0)
+ return null;
+ IndexNode inode = null;
+ IndexNode key = IndexNode.keyOf(path);
+ if ((inode = inodes.get(key)) == null) {
+ if (path[path.length -1] == '/') // already has a slash
+ return null;
+ path = Arrays.copyOf(path, path.length + 1);
+ path[path.length - 1] = '/';
+ if ((inode = inodes.get(key.as(path))) == null)
+ return null;
+ }
+ if (inode instanceof Entry)
+ return (Entry)inode;
+ return Entry.readCEN(this, inode.pos);
+ }
+
+ // Test if the "name" a parent directory of any entry (dir empty)
+ boolean isAncestor(byte[] name) {
+ for (Map.Entry<IndexNode, IndexNode> entry : inodes.entrySet()) {
+ byte[] ename = entry.getKey().name;
+ if (isParentOf(name, ename))
+ return true;
+ }
+ return false;
+ }
+
+ public void deleteFile(byte[] path, boolean failIfNotExists)
+ throws IOException
+ {
+ checkWritable();
+ Entry e = getEntry0(path);
+ if (e == null) {
+ if (path != null && path.length == 0)
+ throw new ZipException("root directory </> can't not be delete");
+ if (failIfNotExists)
+ throw new NoSuchFileException(getString(path));
+ } else {
+ if (e.isDir() && isAncestor(path))
+ throw new DirectoryNotEmptyException(getString(path));
+ updateDelete(e);
+ }
+ }
+
+ private static void copyStream(InputStream is, OutputStream os)
+ throws IOException
+ {
+ byte[] copyBuf = new byte[8192];
+ int n;
+ while ((n = is.read(copyBuf)) != -1) {
+ os.write(copyBuf, 0, n);
+ }
+ }
+
+ // Returns an out stream for either
+ // (1) writing the contents of a new entry, if the entry exits, or
+ // (2) updating/replacing the contents of the specified existing entry.
+ private OutputStream getOutputStream(Entry e) throws IOException {
+
+ if (e.mtime == -1)
+ e.mtime = System.currentTimeMillis();
+ if (e.method == -1)
+ e.method = METHOD_DEFLATED; // TBD: use default method
+ // store size, compressed size, and crc-32 in LOC header
+ e.flag = 0;
+ if (zc.isUTF8())
+ e.flag |= FLAG_EFS;
+ OutputStream os;
+ if (useTempFile) {
+ e.file = getTempPathForEntry(null);
+ os = e.file.newOutputStream(WRITE);
+ } else {
+ os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
+ }
+ return new EntryOutputStream(e, os);
+ }
+
+ private InputStream getInputStream(Entry e)
+ throws IOException
+ {
+ InputStream eis = null;
+
+ if (e.type == Entry.NEW) {
+ if (e.bytes != null)
+ eis = new ByteArrayInputStream(e.bytes);
+ else if (e.file != null)
+ eis = e.file.newInputStream();
+ else
+ throw new ZipException("update entry data is missing");
+ } else if (e.type == Entry.FILECH) {
+ // FILECH result is un-compressed.
+ eis = e.file.newInputStream();
+ // TBD: wrap to hook close()
+ // streams.add(eis);
+ return eis;
+ } else { // untouced CEN or COPY
+ eis = new EntryInputStream(e, ch);
+ }
+ if (e.method == METHOD_DEFLATED) {
+ // MORE: Compute good size for inflater stream:
+ long bufSize = e.size + 2; // Inflater likes a bit of slack
+ if (bufSize > 65536)
+ bufSize = 8192;
+ final long size = e.size;
+ eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
+
+ private boolean isClosed = false;
+ public void close() throws IOException {
+ if (!isClosed) {
+ releaseInflater(inf);
+ this.in.close();
+ isClosed = true;
+ streams.remove(this);
+ }
+ }
+ // Override fill() method to provide an extra "dummy" byte
+ // at the end of the input stream. This is required when
+ // using the "nowrap" Inflater option. (it appears the new
+ // zlib in 7 does not need it, but keep it for now)
+ protected void fill() throws IOException {
+ if (eof) {
+ throw new EOFException(
+ "Unexpected end of ZLIB input stream");
+ }
+ len = this.in.read(buf, 0, buf.length);
+ if (len == -1) {
+ buf[0] = 0;
+ len = 1;
+ eof = true;
+ }
+ inf.setInput(buf, 0, len);
+ }
+ private boolean eof;
+
+ public int available() throws IOException {
+ if (isClosed)
+ return 0;
+ long avail = size - inf.getBytesWritten();
+ return avail > (long) Integer.MAX_VALUE ?
+ Integer.MAX_VALUE : (int) avail;
+ }
+ };
+ } else if (e.method == METHOD_STORED) {
+ // TBD: wrap/ it does not seem necessary
+ } else {
+ throw new ZipException("invalid compression method");
+ }
+ streams.add(eis);
+ return eis;
+ }
+
+ // Inner class implementing the input stream used to read
+ // a (possibly compressed) zip file entry.
+ private class EntryInputStream extends InputStream {
+ private final SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
+ // point to a new channel after sync()
+ private long pos; // current position within entry data
+ protected long rem; // number of remaining bytes within entry
+ protected final long size; // uncompressed size of this entry
+
+ EntryInputStream(Entry e, SeekableByteChannel zfch)
+ throws IOException
+ {
+ this.zfch = zfch;
+ rem = e.csize;
+ size = e.size;
+ pos = getDataPos(e);
+ }
+ public int read(byte b[], int off, int len) throws IOException {
+ ensureOpen();
+ if (rem == 0) {
+ return -1;
+ }
+ if (len <= 0) {
+ return 0;
+ }
+ if (len > rem) {
+ len = (int) rem;
+ }
+ // readFullyAt()
+ long n = 0;
+ ByteBuffer bb = ByteBuffer.wrap(b);
+ bb.position(off);
+ bb.limit(off + len);
+ synchronized(zfch) {
+ n = zfch.position(pos).read(bb);
+ }
+ if (n > 0) {
+ pos += n;
+ rem -= n;
+ }
+ if (rem == 0) {
+ close();
+ }
+ return (int)n;
+ }
+ public int read() throws IOException {
+ byte[] b = new byte[1];
+ if (read(b, 0, 1) == 1) {
+ return b[0] & 0xff;
+ } else {
+ return -1;
+ }
+ }
+ public long skip(long n) throws IOException {
+ ensureOpen();
+ if (n > rem)
+ n = rem;
+ pos += n;
+ rem -= n;
+ if (rem == 0) {
+ close();
+ }
+ return n;
+ }
+ public int available() {
+ return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
+ }
+
+ public long size() {
+ return size;
+ }
+ public void close() {
+ rem = 0;
+ streams.remove(this);
+ }
+ }
+
+ class EntryOutputStream extends DeflaterOutputStream
+ {
+ private CRC32 crc;
+ private Entry e;
+ private long written;
+
+ EntryOutputStream(Entry e, OutputStream os)
+ throws IOException
+ {
+ super(os, getDeflater());
+ if (e == null)
+ throw new NullPointerException("Zip entry is null");
+ this.e = e;
+ crc = new CRC32();
+ }
+
+ @Override
+ public void write(byte b[], int off, int len) throws IOException {
+ if (e.type != Entry.FILECH) // only from sync
+ ensureOpen();
+ if (off < 0 || len < 0 || off > b.length - len) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ switch (e.method) {
+ case METHOD_DEFLATED:
+ super.write(b, off, len);
+ break;
+ case METHOD_STORED:
+ written += len;
+ out.write(b, off, len);
+ break;
+ default:
+ throw new ZipException("invalid compression method");
+ }
+ crc.update(b, off, len);
+ }
+
+ @Override
+ public void close() throws IOException {
+ // TBD ensureOpen();
+ switch (e.method) {
+ case METHOD_DEFLATED:
+ finish();
+ e.size = def.getBytesRead();
+ e.csize = def.getBytesWritten();
+ e.crc = crc.getValue();
+ break;
+ case METHOD_STORED:
+ // we already know that both e.size and e.csize are the same
+ e.size = e.csize = written;
+ e.crc = crc.getValue();
+ break;
+ default:
+ throw new ZipException("invalid compression method");
+ }
+ //crc.reset();
+ if (out instanceof ByteArrayOutputStream)
+ e.bytes = ((ByteArrayOutputStream)out).toByteArray();
+
+ if (e.type == Entry.FILECH) {
+ releaseDeflater(def);
+ return;
+ }
+ super.close();
+ releaseDeflater(def);
+ update(e);
+ }
+ }
+
+ static void zerror(String msg) {
+ throw new ZipError(msg);
+ }
+
+ // Maxmum number of de/inflater we cache
+ private final int MAX_FLATER = 20;
+ // List of available Inflater objects for decompression
+ private final List<Inflater> inflaters = new ArrayList<>();
+
+ // Gets an inflater from the list of available inflaters or allocates
+ // a new one.
+ private Inflater getInflater() {
+ synchronized (inflaters) {
+ int size = inflaters.size();
+ if (size > 0) {
+ Inflater inf = (Inflater)inflaters.remove(size - 1);
+ return inf;
+ } else {
+ return new Inflater(true);
+ }
+ }
+ }
+
+ // Releases the specified inflater to the list of available inflaters.
+ private void releaseInflater(Inflater inf) {
+ synchronized (inflaters) {
+ if (inflaters.size() < MAX_FLATER) {
+ inf.reset();
+ inflaters.add(inf);
+ } else {
+ inf.end();
+ }
+ }
+ }
+
+ // List of available Deflater objects for compression
+ private final List<Deflater> deflaters = new ArrayList<>();
+
+ // Gets an deflater from the list of available deflaters or allocates
+ // a new one.
+ private Deflater getDeflater() {
+ synchronized (deflaters) {
+ int size = deflaters.size();
+ if (size > 0) {
+ Deflater def = (Deflater)deflaters.remove(size - 1);
+ return def;
+ } else {
+ return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
+ }
+ }
+ }
+
+ // Releases the specified inflater to the list of available inflaters.
+ private void releaseDeflater(Deflater def) {
+ synchronized (deflaters) {
+ if (inflaters.size() < MAX_FLATER) {
+ def.reset();
+ deflaters.add(def);
+ } else {
+ def.end();
+ }
+ }
+ }
+
+ // End of central directory record
+ static class END {
+ int disknum;
+ int sdisknum;
+ int endsub; // endsub
+ int centot; // 4 bytes
+ long cenlen; // 4 bytes
+ long cenoff; // 4 bytes
+ int comlen; // comment length
+ byte[] comment;
+
+ /* members of Zip64 end of central directory locator */
+ int diskNum;
+ long endpos;
+ int disktot;
+
+ void write(OutputStream os, long offset) throws IOException {
+ boolean hasZip64 = false;
+ long xlen = cenlen;
+ long xoff = cenoff;
+ if (xlen >= ZIP64_MINVAL) {
+ xlen = ZIP64_MINVAL;
+ hasZip64 = true;
+ }
+ if (xoff >= ZIP64_MINVAL) {
+ xoff = ZIP64_MINVAL;
+ hasZip64 = true;
+ }
+ int count = centot;
+ if (count >= ZIP64_MINVAL32) {
+ count = ZIP64_MINVAL32;
+ hasZip64 = true;
+ }
+ if (hasZip64) {
+ long off64 = offset;
+ //zip64 end of central directory record
+ writeInt(os, ZIP64_ENDSIG); // zip64 END record signature
+ writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
+ writeShort(os, 45); // version made by
+ writeShort(os, 45); // version needed to extract
+ writeInt(os, 0); // number of this disk
+ writeInt(os, 0); // central directory start disk
+ writeLong(os, centot); // number of directory entires on disk
+ writeLong(os, centot); // number of directory entires
+ writeLong(os, cenlen); // length of central directory
+ writeLong(os, cenoff); // offset of central directory
+
+ //zip64 end of central directory locator
+ writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature
+ writeInt(os, 0); // zip64 END start disk
+ writeLong(os, off64); // offset of zip64 END
+ writeInt(os, 1); // total number of disks (?)
+ }
+ writeInt(os, ENDSIG); // END record signature
+ writeShort(os, 0); // number of this disk
+ writeShort(os, 0); // central directory start disk
+ writeShort(os, count); // number of directory entries on disk
+ writeShort(os, count); // total number of directory entries
+ writeInt(os, xlen); // length of central directory
+ writeInt(os, xoff); // offset of central directory
+ if (comment != null) { // zip file comment
+ writeShort(os, comment.length);
+ writeBytes(os, comment);
+ } else {
+ writeShort(os, 0);
+ }
+ }
+ }
+
+ // Internal node that links a "name" to its pos in cen table.
+ // The node itself can be used as a "key" to lookup itself in
+ // the HashMap inodes.
+ static class IndexNode {
+ byte[] name;
+ int hashcode; // node is hashable/hashed by its name
+ int pos = -1; // postion in cen table, -1 menas the
+ // entry does not exists in zip file
+ IndexNode(byte[] name, int pos) {
+ as(name);
+ this.pos = pos;
+ }
+
+ final static IndexNode keyOf(byte[] name) { // get a lookup key;
+ return new IndexNode(name, -1);
+ }
+
+ final IndexNode as(byte[] name) { // reuse the node, mostly
+ this.name = name; // as a lookup "key"
+ this.hashcode = Arrays.hashCode(name);
+ return this;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof IndexNode))
+ return false;
+ return Arrays.equals(name, ((IndexNode)other).name);
+ }
+
+ public int hashCode() {
+ return hashcode;
+ }
+
+ IndexNode() {}
+ IndexNode sibling;
+ IndexNode child; // 1st child
+ }
+
+ static class Entry extends IndexNode {
+
+ static final int CEN = 1; // entry read from cen
+ static final int NEW = 2; // updated contents in bytes or file
+ static final int FILECH = 3; // fch update in "file"
+ static final int COPY = 4; // copy of a CEN entry
+
+ byte[] bytes; // updated content bytes
+ Path file; // use tmp file to store bytes;
+ int type = CEN; // default is the entry read from cen
+
+ // entry attributes
+ int version;
+ int flag;
+ int method = -1; // compression method
+ long mtime = -1; // last modification time (in DOS time)
+ long atime = -1; // last access time
+ long ctime = -1; // create time
+ long crc = -1; // crc-32 of entry data
+ long csize = -1; // compressed size of entry data
+ long size = -1; // uncompressed size of entry data
+ byte[] extra;
+
+ // cen
+ int versionMade;
+ int disk;
+ int attrs;
+ long attrsEx;
+ long locoff;
+ byte[] comment;
+
+ Entry() {}
+
+ Entry(byte[] name) {
+ this.name = name;
+ this.mtime = System.currentTimeMillis();
+ this.crc = 0;
+ this.size = 0;
+ this.csize = 0;
+ this.method = METHOD_DEFLATED;
+ }
+
+ Entry(byte[] name, int type) {
+ this(name);
+ this.type = type;
+ }
+
+ Entry (Entry e, int type) {
+ this.version = e.version;
+ this.name = e.name;
+ this.ctime = e.ctime;
+ this.atime = e.atime;
+ this.mtime = e.mtime;
+ this.crc = e.crc;
+ this.size = e.size;
+ this.csize = e.csize;
+ this.method = e.method;
+ this.extra = e.extra;
+ this.versionMade = e.versionMade;
+ this.disk = e.disk;
+ this.attrs = e.attrs;
+ this.attrsEx = e.attrsEx;
+ this.locoff = e.locoff;
+ this.comment = e.comment;
+
+ this.type = type;
+ }
+
+ Entry (byte[] name, Path file, int type) {
+ this(name, type);
+ this.file = file;
+ this.method = METHOD_STORED;
+ }
+
+ boolean isDir() {
+ return name != null &&
+ (name.length == 0 ||
+ name[name.length - 1] == '/');
+ }
+
+ int version() throws ZipException {
+ if (method == METHOD_DEFLATED)
+ return 20;
+ else if (method == METHOD_STORED)
+ return 10;
+ throw new ZipException("unsupported compression method");
+ }
+
+ ///////////////////// CEN //////////////////////
+ static Entry readCEN(ZipFileSystem zipfs, int pos)
+ throws IOException
+ {
+ return new Entry().cen(zipfs, pos);
+ }
+
+ private Entry cen(ZipFileSystem zipfs, int pos)
+ throws IOException
+ {
+ byte[] cen = zipfs.cen;
+ if (CENSIG(cen, pos) != CENSIG)
+ zerror("invalid CEN header (bad signature)");
+ versionMade = CENVEM(cen, pos);
+ version = CENVER(cen, pos);
+ flag = CENFLG(cen, pos);
+ method = CENHOW(cen, pos);
+ mtime = dosToJavaTime(CENTIM(cen, pos));
+ crc = CENCRC(cen, pos);
+ csize = CENSIZ(cen, pos);
+ size = CENLEN(cen, pos);
+ int nlen = CENNAM(cen, pos);
+ int elen = CENEXT(cen, pos);
+ int clen = CENCOM(cen, pos);
+ disk = CENDSK(cen, pos);
+ attrs = CENATT(cen, pos);
+ attrsEx = CENATX(cen, pos);
+ locoff = CENOFF(cen, pos);
+
+ pos += CENHDR;
+ name = Arrays.copyOfRange(cen, pos, pos + nlen);
+
+ pos += nlen;
+ if (elen > 0) {
+ extra = Arrays.copyOfRange(cen, pos, pos + elen);
+ pos += elen;
+ readExtra(zipfs);
+ }
+ if (clen > 0) {
+ comment = Arrays.copyOfRange(cen, pos, pos + clen);
+ }
+ return this;
+ }
+
+ int writeCEN(OutputStream os) throws IOException
+ {
+ int written = CENHDR;
+ int version0 = version();
+
+ long csize0 = csize;
+ long size0 = size;
+ long locoff0 = locoff;
+ int elen64 = 0; // extra for ZIP64
+ int elenNTFS = 0; // extra for NTFS (a/c/mtime)
+ int elenEXTT = 0; // extra for Extended Timestamp
+
+ // confirm size/length
+ int nlen = (name != null) ? name.length : 0;
+ int elen = (extra != null) ? extra.length : 0;
+ int clen = (comment != null) ? comment.length : 0;
+ if (csize >= ZIP64_MINVAL) {
+ csize0 = ZIP64_MINVAL;
+ elen64 += 8; // csize(8)
+ }
+ if (size >= ZIP64_MINVAL) {
+ size0 = ZIP64_MINVAL; // size(8)
+ elen64 += 8;
+ }
+ if (locoff >= ZIP64_MINVAL) {
+ locoff0 = ZIP64_MINVAL;
+ elen64 += 8; // offset(8)
+ }
+ if (elen64 != 0)
+ elen64 += 4; // header and data sz 4 bytes
+
+ if (atime != -1) {
+ if (isWindows) // use NTFS
+ elenNTFS = 36; // total 36 bytes
+ else // Extended Timestamp otherwise
+ elenEXTT = 9; // only mtime in cen
+ }
+ writeInt(os, CENSIG); // CEN header signature
+ if (elen64 != 0) {
+ writeShort(os, 45); // ver 4.5 for zip64
+ writeShort(os, 45);
+ } else {
+ writeShort(os, version0); // version made by
+ writeShort(os, version0); // version needed to extract
+ }
+ writeShort(os, flag); // general purpose bit flag
+ writeShort(os, method); // compression method
+ // last modification time
+ writeInt(os, (int)javaToDosTime(mtime));
+ writeInt(os, crc); // crc-32
+ writeInt(os, csize0); // compressed size
+ writeInt(os, size0); // uncompressed size
+ writeShort(os, name.length);
+ writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
+
+ if (comment != null) {
+ writeShort(os, Math.min(clen, 0xffff));
+ } else {
+ writeShort(os, 0);
+ }
+ writeShort(os, 0); // starting disk number
+ writeShort(os, 0); // internal file attributes (unused)
+ writeInt(os, 0); // external file attributes (unused)
+ writeInt(os, locoff0); // relative offset of local header
+ writeBytes(os, name);
+ if (elen64 != 0) {
+ writeShort(os, EXTID_ZIP64);// Zip64 extra
+ writeShort(os, elen64); // size of "this" extra block
+ if (size0 == ZIP64_MINVAL)
+ writeLong(os, size);
+ if (csize0 == ZIP64_MINVAL)
+ writeLong(os, csize);
+ if (locoff0 == ZIP64_MINVAL)
+ writeLong(os, locoff);
+ }
+ if (elenNTFS != 0) {
+ // System.out.println("writing NTFS:" + elenNTFS);
+ writeShort(os, EXTID_NTFS);
+ writeShort(os, elenNTFS - 4);
+ writeInt(os, 0); // reserved
+ writeShort(os, 0x0001); // NTFS attr tag
+ writeShort(os, 24);
+ writeLong(os, javaToWinTime(mtime));
+ writeLong(os, javaToWinTime(atime));
+ writeLong(os, javaToWinTime(ctime));
+ }
+ if (elenEXTT != 0) {
+ writeShort(os, EXTID_EXTT);
+ writeShort(os, elenEXTT - 4);
+ if (ctime == -1)
+ os.write(0x3); // mtime and atime
+ else
+ os.write(0x7); // mtime, atime and ctime
+ writeInt(os, javaToUnixTime(mtime));
+ }
+ if (extra != null) // whatever not recognized
+ writeBytes(os, extra);
+ if (comment != null) //TBD: 0, Math.min(commentBytes.length, 0xffff));
+ writeBytes(os, comment);
+ return CENHDR + nlen + elen + clen + elen64 + elenNTFS + elenEXTT;
+ }
+
+ ///////////////////// LOC //////////////////////
+ static Entry readLOC(ZipFileSystem zipfs, long pos)
+ throws IOException
+ {
+ return readLOC(zipfs, pos, new byte[1024]);
+ }
+
+ static Entry readLOC(ZipFileSystem zipfs, long pos, byte[] buf)
+ throws IOException
+ {
+ return new Entry().loc(zipfs, pos, buf);
+ }
+
+ Entry loc(ZipFileSystem zipfs, long pos, byte[] buf)
+ throws IOException
+ {
+ assert (buf.length >= LOCHDR);
+ if (zipfs.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR)
+ throw new ZipException("loc: reading failed");
+ if (LOCSIG(buf) != LOCSIG)
+ throw new ZipException("loc: wrong sig ->"
+ + Long.toString(LOCSIG(buf), 16));
+ //startPos = pos;
+ version = LOCVER(buf);
+ flag = LOCFLG(buf);
+ method = LOCHOW(buf);
+ mtime = dosToJavaTime(LOCTIM(buf));
+ crc = LOCCRC(buf);
+ csize = LOCSIZ(buf);
+ size = LOCLEN(buf);
+ int nlen = LOCNAM(buf);
+ int elen = LOCEXT(buf);
+
+ name = new byte[nlen];
+ if (zipfs.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
+ throw new ZipException("loc: name reading failed");
+ }
+ if (elen > 0) {
+ extra = new byte[elen];
+ if (zipfs.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
+ != elen) {
+ throw new ZipException("loc: ext reading failed");
+ }
+ }
+ pos += (LOCHDR + nlen + elen);
+ if ((flag & FLAG_DATADESCR) != 0) {
+ // Data Descriptor
+ Entry e = zipfs.getEntry0(name); // get the size/csize from cen
+ if (e == null)
+ throw new ZipException("loc: name not found in cen");
+ size = e.size;
+ csize = e.csize;
+ pos += (method == METHOD_STORED ? size : csize);
+ if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
+ pos += 24;
+ else
+ pos += 16;
+ } else {
+ if (extra != null &&
+ (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
+ // zip64 ext: must include both size and csize
+ int off = 0;
+ while (off + 20 < elen) { // HeaderID+DataSize+Data
+ int sz = SH(extra, off + 2);
+ if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
+ size = LL(extra, off + 4);
+ csize = LL(extra, off + 12);
+ break;
+ }
+ off += (sz + 4);
+ }
+ }
+ pos += (method == METHOD_STORED ? size : csize);
+ }
+ return this;
+ }
+
+ int writeLOC(OutputStream os)
+ throws IOException
+ {
+ writeInt(os, LOCSIG); // LOC header signature
+ int version = version();
+
+ int nlen = (name != null) ? name.length : 0;
+ int elen = (extra != null) ? extra.length : 0;
+ int elen64 = 0;
+ int elenEXTT = 0;
+ if ((flag & FLAG_DATADESCR) != 0) {
+ writeShort(os, version()); // version needed to extract
+ writeShort(os, flag); // general purpose bit flag
+ writeShort(os, method); // compression method
+ // last modification time
+ writeInt(os, (int)javaToDosTime(mtime));
+ // store size, uncompressed size, and crc-32 in data descriptor
+ // immediately following compressed entry data
+ writeInt(os, 0);
+ writeInt(os, 0);
+ writeInt(os, 0);
+ } else {
+ if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
+ elen64 = 20; //headid(2) + size(2) + size(8) + csize(8)
+ writeShort(os, 45); // ver 4.5 for zip64
+ } else {
+ writeShort(os, version()); // version needed to extract
+ }
+ writeShort(os, flag); // general purpose bit flag
+ writeShort(os, method); // compression method
+ writeInt(os, mtime); // last modification time
+ writeInt(os, crc); // crc-32
+ if (elen64 != 0) {
+ writeInt(os, ZIP64_MINVAL);
+ writeInt(os, ZIP64_MINVAL);
+ } else {
+ writeInt(os, csize); // compressed size
+ writeInt(os, size); // uncompressed size
+ }
+ }
+ if (atime != -1 && !isWindows) { // on unix use "ext time"
+ if (ctime == -1)
+ elenEXTT = 13;
+ else
+ elenEXTT = 17;
+ }
+ writeShort(os, name.length);
+ writeShort(os, elen + elen64 + elenEXTT);
+ writeBytes(os, name);
+ if (elen64 != 0) {
+ writeShort(os, EXTID_ZIP64);
+ writeShort(os, 16);
+ writeLong(os, size);
+ writeLong(os, csize);
+ }
+ if (elenEXTT != 0) {
+ writeShort(os, EXTID_EXTT);
+ writeShort(os, elenEXTT - 4);// size for the folowing data block
+ if (ctime == -1)
+ os.write(0x3); // mtime and atime
+ else
+ os.write(0x7); // mtime, atime and ctime
+ writeInt(os, javaToUnixTime(mtime));
+ writeInt(os, javaToUnixTime(atime));
+ if (ctime != -1)
+ writeInt(os, javaToUnixTime(ctime));
+ }
+ if (extra != null) {
+ writeBytes(os, extra);
+ }
+ return LOCHDR + name.length + elen + elen64 + elenEXTT;
+ }
+
+ // Data Descriptior
+ int writeEXT(OutputStream os)
+ throws IOException
+ {
+ writeInt(os, EXTSIG); // EXT header signature
+ writeInt(os, crc); // crc-32
+ if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
+ writeLong(os, csize);
+ writeLong(os, size);
+ return 24;
+ } else {
+ writeInt(os, csize); // compressed size
+ writeInt(os, size); // uncompressed size
+ return 16;
+ }
+ }
+
+ // read NTFS, UNIX and ZIP64 data from cen.extra
+ void readExtra(ZipFileSystem zipfs) throws IOException {
+ if (extra == null)
+ return;
+ int elen = extra.length;
+ int off = 0;
+ int newOff = 0;
+ while (off + 4 < elen) {
+ // extra spec: HeaderID+DataSize+Data
+ int pos = off;
+ int tag = SH(extra, pos);
+ int sz = SH(extra, pos + 2);
+ pos += 4;
+ if (pos + sz > elen) // invalid data
+ break;
+ switch (tag) {
+ case EXTID_ZIP64 :
+ if (size == ZIP64_MINVAL) {
+ if (pos + 8 > elen) // invalid zip64 extra
+ break; // fields, just skip
+ size = LL(extra, pos);
+ pos += 8;
+ }
+ if (csize == ZIP64_MINVAL) {
+ if (pos + 8 > elen)
+ break;
+ csize = LL(extra, pos);
+ pos += 8;
+ }
+ if (locoff == ZIP64_MINVAL) {
+ if (pos + 8 > elen)
+ break;
+ locoff = LL(extra, pos);
+ pos += 8;
+ }
+ break;
+ case EXTID_NTFS:
+ pos += 4; // reserved 4 bytes
+ if (SH(extra, pos) != 0x0001)
+ break;
+ if (SH(extra, pos + 2) != 24)
+ break;
+ // override the loc field, datatime here is
+ // more "accurate"
+ mtime = winToJavaTime(LL(extra, pos + 4));
+ atime = winToJavaTime(LL(extra, pos + 12));
+ ctime = winToJavaTime(LL(extra, pos + 20));
+ break;
+ case EXTID_EXTT:
+ // spec says the Extened timestamp in cen only has mtime
+ // need to read the loc to get the extra a/ctime
+ byte[] buf = new byte[LOCHDR];
+ if (zipfs.readFullyAt(buf, 0, buf.length , locoff)
+ != buf.length)
+ throw new ZipException("loc: reading failed");
+ if (LOCSIG(buf) != LOCSIG)
+ throw new ZipException("loc: wrong sig ->"
+ + Long.toString(LOCSIG(buf), 16));
+
+ int locElen = LOCEXT(buf);
+ if (locElen < 9) // EXTT is at lease 9 bytes
+ break;
+ int locNlen = LOCNAM(buf);
+ buf = new byte[locElen];
+ if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen)
+ != buf.length)
+ throw new ZipException("loc extra: reading failed");
+ int locPos = 0;
+ while (locPos + 4 < buf.length) {
+ int locTag = SH(buf, locPos);
+ int locSZ = SH(buf, locPos + 2);
+ locPos += 4;
+ if (locTag != EXTID_EXTT) {
+ locPos += locSZ;
+ continue;
+ }
+ int flag = CH(buf, locPos++);
+ if ((flag & 0x1) != 0) {
+ mtime = unixToJavaTime(LG(buf, locPos));
+ locPos += 4;
+ }
+ if ((flag & 0x2) != 0) {
+ atime = unixToJavaTime(LG(buf, locPos));
+ locPos += 4;
+ }
+ if ((flag & 0x4) != 0) {
+ ctime = unixToJavaTime(LG(buf, locPos));
+ locPos += 4;
+ }
+ break;
+ }
+ break;
+ default: // unknown tag
+ System.arraycopy(extra, off, extra, newOff, sz + 4);
+ newOff += (sz + 4);
+ }
+ off += (sz + 4);
+ }
+ if (newOff != 0 && newOff != extra.length)
+ extra = Arrays.copyOf(extra, newOff);
+ else
+ extra = null;
+ }
+ }
+
+ private static class ExChannelCloser {
+ Path path;
+ SeekableByteChannel ch;
+ Set<InputStream> streams;
+ ExChannelCloser(Path path,
+ SeekableByteChannel ch,
+ Set<InputStream> streams)
+ {
+ this.path = path;
+ this.ch = ch;
+ this.streams = streams;
+ }
+ }
+
+ // ZIP directory has two issues:
+ // (1) ZIP spec does not require the ZIP file to include
+ // directory entry
+ // (2) all entries are not stored/organized in a "tree"
+ // structure.
+ // A possible solution is to build the node tree ourself as
+ // implemented below.
+ private HashMap<IndexNode, IndexNode> dirs;
+ private IndexNode root;
+ private IndexNode addToDir(IndexNode child) {
+ IndexNode cinode = dirs.get(child);
+ if (cinode != null)
+ return cinode;
+
+ byte[] cname = child.name;
+ byte[] pname = getParent(cname);
+ IndexNode pinode;
+
+ if (pname != null)
+ pinode = addToDir(IndexNode.keyOf(pname));
+ else
+ pinode = root;
+ cinode = inodes.get(child);
+ if (cname[cname.length -1] != '/') { // not a dir
+ cinode.sibling = pinode.child;
+ pinode.child = cinode;
+ return null;
+ }
+ //cinode = dirs.get(child);
+ if (cinode == null) // pseudo directry entry
+ cinode = new IndexNode(cname, -1);
+ cinode.sibling = pinode.child;
+ pinode.child = cinode;
+
+ dirs.put(child, cinode);
+ return cinode;
+ }
+
+ private HashMap<IndexNode, IndexNode> getDirs()
+ throws IOException
+ {
+ beginWrite();
+ try {
+ if (dirs != null)
+ return dirs;
+ dirs = new HashMap<>();
+ root = new IndexNode(new byte[0], -1);
+ dirs.put(root, root);
+ for (IndexNode node : inodes.keySet())
+ addToDir(node);
+ return dirs;
+ } finally {
+ endWrite();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.FileRef;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.FileSystemAlreadyExistsException;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/*
+ *
+ * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipFileSystemProvider extends FileSystemProvider {
+
+
+ private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
+
+ public ZipFileSystemProvider() {}
+
+ @Override
+ public String getScheme() {
+ return "jar";
+ }
+
+ protected Path uriToPath(URI uri) {
+ String scheme = uri.getScheme();
+ if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
+ throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
+ }
+ try {
+ // only support legacy JAR URL syntax jar:{uri}!/{entry} for now
+ String spec = uri.getSchemeSpecificPart();
+ int sep = spec.indexOf("!/");
+ if (sep != -1)
+ spec = spec.substring(0, sep);
+ return Paths.get(new URI(spec)).toAbsolutePath();
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public FileSystem newFileSystem(URI uri, Map<String, ?> env)
+ throws IOException
+ {
+ return newFileSystem(uriToPath(uri), env);
+ }
+
+ @Override
+ public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
+ throws IOException
+ {
+ if (!(file instanceof Path))
+ throw new UnsupportedOperationException();
+ Path path = (Path)file;
+ if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
+ throw new UnsupportedOperationException();
+ }
+ return newFileSystem(path, env);
+ }
+
+ private FileSystem newFileSystem(Path path, Map<String, ?> env)
+ throws IOException
+ {
+ synchronized(filesystems) {
+ Path realPath = null;
+ if (path.exists()) {
+ realPath = path.toRealPath(true);
+ if (filesystems.containsKey(realPath))
+ throw new FileSystemAlreadyExistsException();
+ }
+ ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
+ if (realPath == null)
+ realPath = path.toRealPath(true);
+ filesystems.put(realPath, zipfs);
+ return zipfs;
+ }
+ }
+
+ @Override
+ public Path getPath(URI uri) {
+
+ String spec = uri.getSchemeSpecificPart();
+ int sep = spec.indexOf("!/");
+ if (sep == -1)
+ throw new IllegalArgumentException("URI: "
+ + uri
+ + " does not contain path info ex. jar:file:/c:/foo.zip!/BAR");
+ return getFileSystem(uri).getPath(spec.substring(sep + 1));
+ }
+
+ @Override
+ public FileChannel newFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ if (path == null)
+ throw new NullPointerException("path is null");
+ if (path instanceof ZipPath)
+ return ((ZipPath)path).newFileChannel(options, attrs);
+ throw new ProviderMismatchException();
+ }
+
+ @Override
+ public FileSystem getFileSystem(URI uri) {
+ synchronized (filesystems) {
+ ZipFileSystem zipfs = null;
+ try {
+ zipfs = filesystems.get(uriToPath(uri).toRealPath(true));
+ } catch (IOException x) {
+ // ignore the ioe from toRealPath(), return FSNFE
+ }
+ if (zipfs == null)
+ throw new FileSystemNotFoundException();
+ return zipfs;
+ }
+ }
+
+ void removeFileSystem(Path zfpath) throws IOException {
+ synchronized (filesystems) {
+ filesystems.remove(zfpath.toRealPath(true));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipInfo.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.Map;
+import static com.sun.nio.zipfs.ZipConstants.*;
+import static com.sun.nio.zipfs.ZipUtils.*;
+
+/**
+ * Print all loc and cen headers of the ZIP file
+ *
+ * @author Xueming Shen
+ */
+
+public class ZipInfo {
+
+ public static void main(String[] args) throws Throwable {
+ if (args.length < 1) {
+ print("Usage: java ZipInfo zfname");
+ } else {
+ Map<String, ?> env = Collections.emptyMap();
+ ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
+ .newFileSystem(Paths.get(args[0]), env));
+ byte[] cen = zfs.cen;
+ if (cen == null) {
+ print("zip file is empty%n");
+ return;
+ }
+ int pos = 0;
+ byte[] buf = new byte[1024];
+ int no = 1;
+ while (pos + CENHDR < cen.length) {
+ print("----------------#%d--------------------%n", no++);
+ printCEN(cen, pos);
+
+ // use size CENHDR as the extra bytes to read, just in case the
+ // loc.extra is bigger than the cen.extra, try to avoid to read
+ // twice
+ long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
+ if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
+ zfs.zerror("read loc header failed");
+ if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
+ // have to read the second time;
+ len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
+ if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
+ zfs.zerror("read loc header failed");
+ }
+ printLOC(buf);
+ pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
+ }
+ zfs.close();
+ }
+ }
+
+ static void print(String fmt, Object... objs) {
+ System.out.printf(fmt, objs);
+ }
+
+ static void printLOC(byte[] loc) {
+ print("%n");
+ print("[Local File Header]%n");
+ print(" Signature : %#010x%n", LOCSIG(loc));
+ if (LOCSIG(loc) != LOCSIG) {
+ print(" Wrong signature!");
+ return;
+ }
+ print(" Version : %#6x [%d.%d]%n",
+ LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10);
+ print(" Flag : %#6x%n", LOCFLG(loc));
+ print(" Method : %#6x%n", LOCHOW(loc));
+ print(" LastMTime : %#10x [%tc]%n",
+ LOCTIM(loc), dosToJavaTime(LOCTIM(loc)));
+ print(" CRC : %#10x%n", LOCCRC(loc));
+ print(" CSize : %#10x%n", LOCSIZ(loc));
+ print(" Size : %#10x%n", LOCLEN(loc));
+ print(" NameLength : %#6x [%s]%n",
+ LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc)));
+ print(" ExtraLength : %#6x%n", LOCEXT(loc));
+ if (LOCEXT(loc) != 0)
+ printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc));
+ }
+
+ static void printCEN(byte[] cen, int off) {
+ print("[Central Directory Header]%n");
+ print(" Signature : %#010x%n", CENSIG(cen, off));
+ if (CENSIG(cen, off) != CENSIG) {
+ print(" Wrong signature!");
+ return;
+ }
+ print(" VerMadeby : %#6x [%d, %d.%d]%n",
+ CENVEM(cen, off), (CENVEM(cen, off) >> 8),
+ (CENVEM(cen, off) & 0xff) / 10,
+ (CENVEM(cen, off) & 0xff) % 10);
+ print(" VerExtract : %#6x [%d.%d]%n",
+ CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10);
+ print(" Flag : %#6x%n", CENFLG(cen, off));
+ print(" Method : %#6x%n", CENHOW(cen, off));
+ print(" LastMTime : %#10x [%tc]%n",
+ CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off)));
+ print(" CRC : %#10x%n", CENCRC(cen, off));
+ print(" CSize : %#10x%n", CENSIZ(cen, off));
+ print(" Size : %#10x%n", CENLEN(cen, off));
+ print(" NameLen : %#6x [%s]%n",
+ CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off)));
+ print(" ExtraLen : %#6x%n", CENEXT(cen, off));
+ if (CENEXT(cen, off) != 0)
+ printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off));
+ print(" CommentLen : %#6x%n", CENCOM(cen, off));
+ print(" DiskStart : %#6x%n", CENDSK(cen, off));
+ print(" Attrs : %#6x%n", CENATT(cen, off));
+ print(" AttrsEx : %#10x%n", CENATX(cen, off));
+ print(" LocOff : %#10x%n", CENOFF(cen, off));
+
+ }
+
+ static long locoff(byte[] cen, int pos) {
+ long locoff = CENOFF(cen, pos);
+ if (locoff == ZIP64_MINVAL) { //ZIP64
+ int off = pos + CENHDR + CENNAM(cen, pos);
+ int end = off + CENEXT(cen, pos);
+ while (off + 4 < end) {
+ int tag = SH(cen, off);
+ int sz = SH(cen, off + 2);
+ if (tag != EXTID_ZIP64) {
+ off += 4 + sz;
+ continue;
+ }
+ off += 4;
+ if (CENLEN(cen, pos) == ZIP64_MINVAL)
+ off += 8;
+ if (CENSIZ(cen, pos) == ZIP64_MINVAL)
+ off += 8;
+ return LL(cen, off);
+ }
+ // should never be here
+ }
+ return locoff;
+ }
+
+ static void printExtra(byte[] extra, int off, int len) {
+ int end = off + len;
+ while (off + 4 <= end) {
+ int tag = SH(extra, off);
+ int sz = SH(extra, off + 2);
+ print(" [tag=0x%04x, sz=%d, data= ", tag, sz);
+ if (off + sz > end) {
+ print(" Error: Invalid extra data, beyond extra length");
+ break;
+ }
+ off += 4;
+ for (int i = 0; i < sz; i++)
+ print("%02x ", extra[off + i]);
+ print("]%n");
+ switch (tag) {
+ case EXTID_ZIP64 :
+ print(" ->ZIP64: ");
+ int pos = off;
+ while (pos + 8 <= off + sz) {
+ print(" *0x%x ", LL(extra, pos));
+ pos += 8;
+ }
+ print("%n");
+ break;
+ case EXTID_NTFS:
+ print(" ->PKWare NTFS%n");
+ // 4 bytes reserved
+ if (SH(extra, off + 4) != 0x0001 || SH(extra, off + 6) != 24)
+ print(" Error: Invalid NTFS sub-tag or subsz");
+ print(" mtime:%tc%n",
+ winToJavaTime(LL(extra, off + 8)));
+ print(" atime:%tc%n",
+ winToJavaTime(LL(extra, off + 16)));
+ print(" ctime:%tc%n",
+ winToJavaTime(LL(extra, off + 24)));
+ break;
+ case EXTID_EXTT:
+ print(" ->Inof-ZIP Extended Timestamp: flag=%x%n",extra[off]);
+ pos = off + 1 ;
+ while (pos + 4 <= off + sz) {
+ print(" *%tc%n",
+ unixToJavaTime(LG(extra, pos)));
+ pos += 4;
+ }
+ break;
+ default:
+ }
+ off += sz;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,960 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.*;
+import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.util.*;
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/**
+ *
+ * @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
+ */
+
+public class ZipPath extends Path {
+
+ private final ZipFileSystem zfs;
+ private final byte[] path;
+ private volatile int[] offsets;
+ private int hashcode = 0; // cached hashcode (created lazily)
+
+ ZipPath(ZipFileSystem zfs, byte[] path) {
+ this(zfs, path, false);
+ }
+
+ ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
+ {
+ this.zfs = zfs;
+ if (normalized)
+ this.path = path;
+ else
+ this.path = normalize(path);
+ }
+
+ @Override
+ public ZipPath getRoot() {
+ if (this.isAbsolute())
+ return new ZipPath(zfs, new byte[]{path[0]});
+ else
+ return null;
+ }
+
+ @Override
+ public Path getName() {
+ initOffsets();
+ int count = offsets.length;
+ if (count == 0)
+ return null; // no elements so no name
+ if (count == 1 && path[0] != '/')
+ return this;
+ int lastOffset = offsets[count-1];
+ int len = path.length - lastOffset;
+ byte[] result = new byte[len];
+ System.arraycopy(path, lastOffset, result, 0, len);
+ return new ZipPath(zfs, result);
+ }
+
+ @Override
+ public ZipPath getParent() {
+ initOffsets();
+ int count = offsets.length;
+ if (count == 0) // no elements so no parent
+ return null;
+ int len = offsets[count-1] - 1;
+ if (len <= 0) // parent is root only (may be null)
+ return getRoot();
+ byte[] result = new byte[len];
+ System.arraycopy(path, 0, result, 0, len);
+ return new ZipPath(zfs, result);
+ }
+
+ @Override
+ public int getNameCount() {
+ initOffsets();
+ return offsets.length;
+ }
+
+ @Override
+ public ZipPath getName(int index) {
+ initOffsets();
+ if (index < 0 || index >= offsets.length)
+ throw new IllegalArgumentException();
+ int begin = offsets[index];
+ int len;
+ if (index == (offsets.length-1))
+ len = path.length - begin;
+ else
+ len = offsets[index+1] - begin - 1;
+ // construct result
+ byte[] result = new byte[len];
+ System.arraycopy(path, begin, result, 0, len);
+ return new ZipPath(zfs, result);
+ }
+
+ @Override
+ public ZipPath subpath(int beginIndex, int endIndex) {
+ initOffsets();
+ if (beginIndex < 0 ||
+ beginIndex >= offsets.length ||
+ endIndex > offsets.length ||
+ beginIndex >= endIndex)
+ throw new IllegalArgumentException();
+
+ // starting offset and length
+ int begin = offsets[beginIndex];
+ int len;
+ if (endIndex == offsets.length)
+ len = path.length - begin;
+ else
+ len = offsets[endIndex] - begin - 1;
+ // construct result
+ byte[] result = new byte[len];
+ System.arraycopy(path, begin, result, 0, len);
+ return new ZipPath(zfs, result);
+ }
+
+ @Override
+ public ZipPath toRealPath(boolean resolveLinks) throws IOException {
+ ZipPath realPath = new ZipPath(zfs, getResolvedPath());
+ realPath.checkAccess();
+ return realPath;
+ }
+
+ @Override
+ public boolean isHidden() {
+ return false;
+ }
+
+ @Override
+ public ZipPath toAbsolutePath() {
+ if (isAbsolute()) {
+ return this;
+ } else {
+ //add / bofore the existing path
+ byte[] defaultdir = zfs.getDefaultDir().path;
+ int defaultlen = defaultdir.length;
+ boolean endsWith = (defaultdir[defaultlen - 1] == '/');
+ byte[] t = null;
+ if (endsWith)
+ t = new byte[defaultlen + path.length];
+ else
+ t = new byte[defaultlen + 1 + path.length];
+ System.arraycopy(defaultdir, 0, t, 0, defaultlen);
+ if (!endsWith)
+ t[defaultlen++] = '/';
+ System.arraycopy(path, 0, t, defaultlen, path.length);
+ return new ZipPath(zfs, t, true); // normalized
+ }
+ }
+
+ @Override
+ public URI toUri() {
+ try {
+ return new URI("jar",
+ zfs.getZipFile().toUri() +
+ "!" +
+ zfs.getString(toAbsolutePath().path),
+ null);
+ } catch (Exception ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+ private boolean equalsNameAt(ZipPath other, int index) {
+ int mbegin = offsets[index];
+ int mlen = 0;
+ if (index == (offsets.length-1))
+ mlen = path.length - mbegin;
+ else
+ mlen = offsets[index + 1] - mbegin - 1;
+ int obegin = other.offsets[index];
+ int olen = 0;
+ if (index == (other.offsets.length - 1))
+ olen = other.path.length - obegin;
+ else
+ olen = other.offsets[index + 1] - obegin - 1;
+ if (mlen != olen)
+ return false;
+ int n = 0;
+ while(n < mlen) {
+ if (path[mbegin + n] != other.path[obegin + n])
+ return false;
+ n++;
+ }
+ return true;
+ }
+
+ @Override
+ public Path relativize(Path other) {
+ final ZipPath o = checkPath(other);
+ if (o.equals(this))
+ return null;
+ if (/* this.getFileSystem() != o.getFileSystem() || */
+ this.isAbsolute() != o.isAbsolute()) {
+ throw new IllegalArgumentException();
+ }
+ int mc = this.getNameCount();
+ int oc = o.getNameCount();
+ int n = Math.min(mc, oc);
+ int i = 0;
+ while (i < n) {
+ if (!equalsNameAt(o, i))
+ break;
+ i++;
+ }
+ int dotdots = mc - i;
+ int len = dotdots * 3 - 1;
+ if (i < oc)
+ len += (o.path.length - o.offsets[i] + 1);
+ byte[] result = new byte[len];
+
+ int pos = 0;
+ while (dotdots > 0) {
+ result[pos++] = (byte)'.';
+ result[pos++] = (byte)'.';
+ if (pos < len) // no tailing slash at the end
+ result[pos++] = (byte)'/';
+ dotdots--;
+ }
+ if (i < oc)
+ System.arraycopy(o.path, o.offsets[i],
+ result, pos,
+ o.path.length - o.offsets[i]);
+ return new ZipPath(getFileSystem(), result);
+ }
+
+ @Override
+ public ZipFileSystem getFileSystem() {
+ return zfs;
+ }
+
+ @Override
+ public boolean isAbsolute() {
+ return (this.path[0] == '/');
+ }
+
+ @Override
+ public ZipPath resolve(Path other) {
+ if (other == null)
+ return this;
+ final ZipPath o = checkPath(other);
+ if (o.isAbsolute())
+ return o;
+ byte[] resolved = null;
+ if (this.path[path.length - 1] == '/') {
+ resolved = new byte[path.length + o.path.length];
+ System.arraycopy(path, 0, resolved, 0, path.length);
+ System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
+ } else {
+ resolved = new byte[path.length + 1 + o.path.length];
+ System.arraycopy(path, 0, resolved, 0, path.length);
+ resolved[path.length] = '/';
+ System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
+ }
+ return new ZipPath(zfs, resolved);
+ }
+
+ @Override
+ public ZipPath resolve(String other) {
+ return resolve(getFileSystem().getPath(other));
+ }
+
+ @Override
+ public boolean startsWith(Path other) {
+ final ZipPath o = checkPath(other);
+ if (o.isAbsolute() != this.isAbsolute())
+ return false;
+ final int oCount = o.getNameCount();
+ if (getNameCount() < oCount)
+ return false;
+ for (int i = 0; i < oCount; i++) {
+ if (!o.getName(i).equals(getName(i)))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean endsWith(Path other) {
+ final ZipPath o = checkPath(other);
+ if (o.isAbsolute())
+ return this.isAbsolute() ? this.equals(o) : false;
+ int i = o.getNameCount();
+ int j = this.getNameCount();
+ if (j < i)
+ return false;
+ for (--i, --j; i >= 0; i--, j--) {
+ if (!o.getName(i).equals(this.getName(j)))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public Path normalize() {
+ byte[] resolved = getResolved();
+ if (resolved == path) // no change
+ return this;
+ if (resolved.length == 0)
+ return null;
+ return new ZipPath(zfs, resolved, true);
+ }
+
+ private ZipPath checkPath(Path path) {
+ if (path == null)
+ throw new NullPointerException();
+ if (!(path instanceof ZipPath))
+ throw new ProviderMismatchException();
+ return (ZipPath) path;
+ }
+
+ // create offset list if not already created
+ private void initOffsets() {
+ if (offsets == null) {
+ int count, index;
+ // count names
+ count = 0;
+ index = 0;
+ while (index < path.length) {
+ byte c = path[index++];
+ if (c != '/') {
+ count++;
+ while (index < path.length && path[index] != '/')
+ index++;
+ }
+ }
+ // populate offsets
+ int[] result = new int[count];
+ count = 0;
+ index = 0;
+ while (index < path.length) {
+ byte c = path[index];
+ if (c == '/') {
+ index++;
+ } else {
+ result[count++] = index++;
+ while (index < path.length && path[index] != '/')
+ index++;
+ }
+ }
+ synchronized (this) {
+ if (offsets == null)
+ offsets = result;
+ }
+ }
+ }
+
+ // resolved path for locating zip entry inside the zip file,
+ // the result path does not contain ./ and .. components
+ private volatile byte[] resolved = null;
+ byte[] getResolvedPath() {
+ byte[] r = resolved;
+ if (r == null) {
+ if (isAbsolute())
+ r = getResolved();
+ else
+ r = toAbsolutePath().getResolvedPath();
+ if (r[0] == '/')
+ r = Arrays.copyOfRange(r, 1, r.length);
+ resolved = r;
+ }
+ return resolved;
+ }
+
+ // removes redundant slashs, replace "\" to zip separator "/"
+ // and check for invalid characters
+ private byte[] normalize(byte[] path) {
+ if (path.length == 0)
+ return path;
+ byte prevC = 0;
+ for (int i = 0; i < path.length; i++) {
+ byte c = path[i];
+ if (c == '\\')
+ return normalize(path, i);
+ if (c == (byte)'/' && prevC == '/')
+ return normalize(path, i - 1);
+ if (c == '\u0000')
+ throw new InvalidPathException(zfs.getString(path),
+ "Path: nul character not allowed");
+ prevC = c;
+ }
+ return path;
+ }
+
+ private byte[] normalize(byte[] path, int off) {
+ byte[] to = new byte[path.length];
+ int n = 0;
+ while (n < off) {
+ to[n] = path[n];
+ n++;
+ }
+ int m = n;
+ byte prevC = 0;
+ while (n < path.length) {
+ byte c = path[n++];
+ if (c == (byte)'\\')
+ c = (byte)'/';
+ if (c == (byte)'/' && prevC == (byte)'/')
+ continue;
+ if (c == '\u0000')
+ throw new InvalidPathException(zfs.getString(path),
+ "Path: nul character not allowed");
+ to[m++] = c;
+ prevC = c;
+ }
+ if (m > 1 && to[m - 1] == '/')
+ m--;
+ return (m == to.length)? to : Arrays.copyOf(to, m);
+ }
+
+ // Remove DotSlash(./) and resolve DotDot (..) components
+ private byte[] getResolved() {
+ if (path.length == 0)
+ return path;
+ for (int i = 0; i < path.length; i++) {
+ byte c = path[i];
+ if (c == (byte)'.')
+ return resolve0();
+ }
+ return path;
+ }
+
+ // TBD: performance, avoid initOffsets
+ private byte[] resolve0() {
+ byte[] to = new byte[path.length];
+ int nc = getNameCount();
+ int[] lastM = new int[nc];
+ int lastMOff = -1;
+ int m = 0;
+ for (int i = 0; i < nc; i++) {
+ int n = offsets[i];
+ int len = (i == offsets.length - 1)?
+ (path.length - n):(offsets[i + 1] - n - 1);
+ if (len == 1 && path[n] == (byte)'.')
+ continue;
+ if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
+ if (lastMOff >= 0) {
+ m = lastM[lastMOff--]; // retreat
+ continue;
+ }
+ if (path[0] == '/') { // "/../xyz" skip
+ if (m == 0)
+ to[m++] = '/';
+ } else { // "../xyz" -> "../xyz"
+ if (m != 0 && to[m-1] != '/')
+ to[m++] = '/';
+ while (len-- > 0)
+ to[m++] = path[n++];
+ }
+ continue;
+ }
+ if (m == 0 && path[0] == '/' || // absolute path
+ m != 0 && to[m-1] != '/') { // not the first name
+ to[m++] = '/';
+ }
+ lastM[++lastMOff] = m;
+ while (len-- > 0)
+ to[m++] = path[n++];
+ }
+ if (m > 1 && to[m - 1] == '/')
+ m--;
+ return (m == to.length)? to : Arrays.copyOf(to, m);
+ }
+
+ @Override
+ public String toString() {
+ return zfs.getString(path);
+ }
+
+ @Override
+ public int hashCode() {
+ int h = hashcode;
+ if (h == 0)
+ hashcode = h = Arrays.hashCode(path);
+ return h;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj != null &&
+ obj instanceof ZipPath &&
+ this.zfs == ((ZipPath)obj).zfs &&
+ compareTo((Path) obj) == 0;
+ }
+
+ @Override
+ public int compareTo(Path other) {
+ final ZipPath o = checkPath(other);
+ int len1 = this.path.length;
+ int len2 = o.path.length;
+
+ int n = Math.min(len1, len2);
+ byte v1[] = this.path;
+ byte v2[] = o.path;
+
+ int k = 0;
+ while (k < n) {
+ int c1 = v1[k] & 0xff;
+ int c2 = v2[k] & 0xff;
+ if (c1 != c2)
+ return c1 - c2;
+ k++;
+ }
+ return len1 - len2;
+ }
+
+ @Override
+ public Path createSymbolicLink(
+ Path target, FileAttribute<?>... attrs) throws IOException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public Path createLink(
+ Path existing) throws IOException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public Path readSymbolicLink() throws IOException {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public Path createDirectory(FileAttribute<?>... attrs)
+ throws IOException
+ {
+ zfs.createDirectory(getResolvedPath(), attrs);
+ return this;
+ }
+
+ public final Path createFile(FileAttribute<?>... attrs)
+ throws IOException
+ {
+ OutputStream os = newOutputStream(CREATE_NEW, WRITE);
+ try {
+ os.close();
+ } catch (IOException x) {}
+ return this;
+ }
+
+ @Override
+ public InputStream newInputStream(OpenOption... options)
+ throws IOException {
+ if (options.length > 0) {
+ for (OpenOption opt : options) {
+ if (opt != READ)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return zfs.newInputStream(getResolvedPath());
+ }
+
+ private static final DirectoryStream.Filter<Path> acceptAllFilter =
+ new DirectoryStream.Filter<>() {
+ @Override public boolean accept(Path entry) { return true; }
+ };
+
+ @Override
+ public final DirectoryStream<Path> newDirectoryStream() throws IOException {
+ return newDirectoryStream(acceptAllFilter);
+ }
+
+ @Override
+ public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
+ throws IOException
+ {
+ return new ZipDirectoryStream(this, filter);
+ }
+
+ @Override
+ public final DirectoryStream<Path> newDirectoryStream(String glob)
+ throws IOException
+ {
+ // avoid creating a matcher if all entries are required.
+ if (glob.equals("*"))
+ return newDirectoryStream();
+
+ // create a matcher and return a filter that uses it.
+ final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<>() {
+ @Override
+ public boolean accept(Path entry) {
+ return matcher.matches(entry.getName());
+ }
+ };
+ return newDirectoryStream(filter);
+ }
+
+ @Override
+ public final void delete() throws IOException {
+ zfs.deleteFile(getResolvedPath(), true);
+ }
+
+ @Override
+ public final void deleteIfExists() throws IOException {
+ zfs.deleteFile(getResolvedPath(), false);
+ }
+
+ ZipFileAttributes getAttributes() throws IOException
+ {
+ ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
+ if (zfas == null)
+ throw new NoSuchFileException(toString());
+ return zfas;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
+ LinkOption... options)
+ {
+ return (V)ZipFileAttributeView.get(this, type);
+ }
+
+ @Override
+ public void setAttribute(String attribute,
+ Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ String type = null;
+ String attr = null;
+ int colonPos = attribute.indexOf(':');
+ if (colonPos == -1) {
+ type = "basic";
+ attr = attribute;
+ } else {
+ type = attribute.substring(0, colonPos++);
+ attr = attribute.substring(colonPos);
+ }
+ ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
+ if (view == null)
+ throw new UnsupportedOperationException("view <" + view + "> is not supported");
+ view.setAttribute(attr, value);
+ }
+
+ void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
+ throws IOException
+ {
+ zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
+ }
+
+ private Object getAttributesImpl(String attribute, boolean domap)
+ throws IOException
+ {
+ String view = null;
+ String attr = null;
+ int colonPos = attribute.indexOf(':');
+ if (colonPos == -1) {
+ view = "basic";
+ attr = attribute;
+ } else {
+ view = attribute.substring(0, colonPos++);
+ attr = attribute.substring(colonPos);
+ }
+ ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
+ if (zfv == null) {
+ throw new UnsupportedOperationException("view not supported");
+ }
+ return zfv.getAttribute(attr, domap);
+ }
+
+ @Override
+ public Object getAttribute(String attribute, LinkOption... options)
+ throws IOException
+ {
+ return getAttributesImpl(attribute, false);
+ }
+
+ @Override
+ public Map<String,?> readAttributes(String attribute, LinkOption... options)
+ throws IOException
+ {
+ return (Map<String, ?>)getAttributesImpl(attribute, true);
+ }
+
+ @Override
+ public FileStore getFileStore() throws IOException {
+ // each ZipFileSystem only has one root (as requested for now)
+ if (exists())
+ return zfs.getFileStore(this);
+ throw new NoSuchFileException(zfs.getString(path));
+ }
+
+ @Override
+ public boolean isSameFile(Path other) throws IOException {
+ if (other == null ||
+ this.getFileSystem() != other.getFileSystem())
+ return false;
+ this.checkAccess();
+ other.checkAccess();
+ return Arrays.equals(this.getResolvedPath(),
+ ((ZipPath)other).getResolvedPath());
+ }
+
+ public WatchKey register(
+ WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers) {
+ if (watcher == null || events == null || modifiers == null) {
+ throw new NullPointerException();
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
+ return register(watcher, events, new WatchEvent.Modifier[0]);
+ }
+
+ @Override
+ public Iterator<Path> iterator() {
+ return new Iterator<>() {
+ private int i = 0;
+
+ @Override
+ public boolean hasNext() {
+ return (i < getNameCount());
+ }
+
+ @Override
+ public Path next() {
+ if (i < getNameCount()) {
+ Path result = getName(i);
+ i++;
+ return result;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new ReadOnlyFileSystemException();
+ }
+ };
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return zfs.newByteChannel(getResolvedPath(), options, attrs);
+ }
+
+
+ FileChannel newFileChannel(Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return zfs.newFileChannel(getResolvedPath(), options, attrs);
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(OpenOption... options)
+ throws IOException {
+ Set<OpenOption> set = new HashSet<>(options.length);
+ Collections.addAll(set, options);
+ return newByteChannel(set);
+ }
+
+ @Override
+ public void checkAccess(AccessMode... modes) throws IOException {
+ boolean w = false;
+ boolean x = false;
+ for (AccessMode mode : modes) {
+ switch (mode) {
+ case READ:
+ break;
+ case WRITE:
+ w = true;
+ break;
+ case EXECUTE:
+ x = true;
+ break;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+ ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
+ if (attrs == null && (path.length != 1 || path[0] != '/'))
+ throw new NoSuchFileException(toString());
+ if (w) {
+ if (zfs.isReadOnly())
+ throw new AccessDeniedException(toString());
+ }
+ if (x)
+ throw new AccessDeniedException(toString());
+
+ }
+
+ @Override
+ public boolean exists() {
+ if (path.length == 1 && path[0] == '/')
+ return true;
+ try {
+ return zfs.exists(getResolvedPath());
+ } catch (IOException x) {}
+ return false;
+ }
+
+ @Override
+ public boolean notExists() {
+ return !exists();
+ }
+
+
+ @Override
+ public OutputStream newOutputStream(OpenOption... options)
+ throws IOException
+ {
+ if (options.length == 0)
+ return zfs.newOutputStream(getResolvedPath(),
+ CREATE_NEW, WRITE);
+ return zfs.newOutputStream(getResolvedPath(), options);
+ }
+
+ @Override
+ public Path moveTo(Path target, CopyOption... options)
+ throws IOException
+ {
+ if (this.zfs.provider() == target.getFileSystem().provider() &&
+ this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
+ {
+ zfs.copyFile(true,
+ getResolvedPath(),
+ ((ZipPath)target).getResolvedPath(),
+ options);
+ } else {
+ copyToTarget(target, options);
+ delete();
+ }
+ return target;
+ }
+
+ @Override
+ public Path copyTo(Path target, CopyOption... options)
+ throws IOException
+ {
+ if (this.zfs.provider() == target.getFileSystem().provider() &&
+ this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
+ {
+ zfs.copyFile(false,
+ getResolvedPath(),
+ ((ZipPath)target).getResolvedPath(),
+ options);
+ } else {
+ copyToTarget(target, options);
+ }
+ return target;
+ }
+
+ private void copyToTarget(Path target, CopyOption... options)
+ throws IOException
+ {
+ boolean replaceExisting = false;
+ boolean copyAttrs = false;
+ for (CopyOption opt : options) {
+ if (opt == REPLACE_EXISTING)
+ replaceExisting = true;
+ else if (opt == COPY_ATTRIBUTES)
+ copyAttrs = true;
+ }
+ // attributes of source file
+ ZipFileAttributes zfas = getAttributes();
+ // check if target exists
+ boolean exists;
+ if (replaceExisting) {
+ try {
+ target.deleteIfExists();
+ exists = false;
+ } catch (DirectoryNotEmptyException x) {
+ exists = true;
+ }
+ } else {
+ exists = target.exists();
+ }
+ if (exists)
+ throw new FileAlreadyExistsException(target.toString());
+
+ if (zfas.isDirectory()) {
+ // create directory or file
+ target.createDirectory();
+ } else {
+ InputStream is = zfs.newInputStream(getResolvedPath());
+ try {
+ OutputStream os = target.newOutputStream();
+ try {
+ byte[] buf = new byte[8192];
+ int n = 0;
+ while ((n = is.read(buf)) != -1) {
+ os.write(buf, 0, n);
+ }
+ } finally {
+ os.close();
+ }
+ } finally {
+ is.close();
+ }
+ }
+ if (copyAttrs) {
+ BasicFileAttributeView view =
+ target.getFileAttributeView(BasicFileAttributeView.class);
+ try {
+ view.setTimes(zfas.lastModifiedTime(),
+ zfas.lastAccessTime(),
+ zfas.creationTime());
+ } catch (IOException x) {
+ // rollback?
+ try {
+ target.delete();
+ } catch (IOException ignore) { }
+ throw x;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipUtils.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.regex.PatternSyntaxException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *
+ * @author Xueming Shen
+ */
+
+class ZipUtils {
+
+ /*
+ * Writes a 16-bit short to the output stream in little-endian byte order.
+ */
+ public static void writeShort(OutputStream os, int v) throws IOException {
+ os.write(v & 0xff);
+ os.write((v >>> 8) & 0xff);
+ }
+
+ /*
+ * Writes a 32-bit int to the output stream in little-endian byte order.
+ */
+ public static void writeInt(OutputStream os, long v) throws IOException {
+ os.write((int)(v & 0xff));
+ os.write((int)((v >>> 8) & 0xff));
+ os.write((int)((v >>> 16) & 0xff));
+ os.write((int)((v >>> 24) & 0xff));
+ }
+
+ /*
+ * Writes a 64-bit int to the output stream in little-endian byte order.
+ */
+ public static void writeLong(OutputStream os, long v) throws IOException {
+ os.write((int)(v & 0xff));
+ os.write((int)((v >>> 8) & 0xff));
+ os.write((int)((v >>> 16) & 0xff));
+ os.write((int)((v >>> 24) & 0xff));
+ os.write((int)((v >>> 32) & 0xff));
+ os.write((int)((v >>> 40) & 0xff));
+ os.write((int)((v >>> 48) & 0xff));
+ os.write((int)((v >>> 56) & 0xff));
+ }
+
+ /*
+ * Writes an array of bytes to the output stream.
+ */
+ public static void writeBytes(OutputStream os, byte[] b)
+ throws IOException
+ {
+ os.write(b, 0, b.length);
+ }
+
+ /*
+ * Writes an array of bytes to the output stream.
+ */
+ public static void writeBytes(OutputStream os, byte[] b, int off, int len)
+ throws IOException
+ {
+ os.write(b, off, len);
+ }
+
+ /*
+ * Append a slash at the end, if it does not have one yet
+ */
+ public static byte[] toDirectoryPath(byte[] dir) {
+ if (dir.length != 0 && dir[dir.length - 1] != '/') {
+ dir = Arrays.copyOf(dir, dir.length + 1);
+ dir[dir.length - 1] = '/';
+ }
+ return dir;
+ }
+
+ /*
+ * Converts DOS time to Java time (number of milliseconds since epoch).
+ */
+ public static long dosToJavaTime(long dtime) {
+ Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
+ (int)(((dtime >> 21) & 0x0f) - 1),
+ (int)((dtime >> 16) & 0x1f),
+ (int)((dtime >> 11) & 0x1f),
+ (int)((dtime >> 5) & 0x3f),
+ (int)((dtime << 1) & 0x3e));
+ return d.getTime();
+ }
+
+ /*
+ * Converts Java time to DOS time.
+ */
+ public static long javaToDosTime(long time) {
+ Date d = new Date(time);
+ int year = d.getYear() + 1900;
+ if (year < 1980) {
+ return (1 << 21) | (1 << 16);
+ }
+ return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
+ d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
+ d.getSeconds() >> 1;
+ }
+
+
+ // used to adjust values between Windows and java epoch
+ private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
+ public static final long winToJavaTime(long wtime) {
+ return TimeUnit.MILLISECONDS.convert(
+ wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
+ }
+
+ public static final long javaToWinTime(long time) {
+ return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
+ - WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
+ }
+
+ public static final long unixToJavaTime(long utime) {
+ return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
+ }
+
+ public static final long javaToUnixTime(long time) {
+ return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
+ }
+
+ private static final String regexMetaChars = ".^$+{[]|()";
+ private static final String globMetaChars = "\\*?[{";
+ private static boolean isRegexMeta(char c) {
+ return regexMetaChars.indexOf(c) != -1;
+ }
+ private static boolean isGlobMeta(char c) {
+ return globMetaChars.indexOf(c) != -1;
+ }
+ private static char EOL = 0; //TBD
+ private static char next(String glob, int i) {
+ if (i < glob.length()) {
+ return glob.charAt(i);
+ }
+ return EOL;
+ }
+
+ /*
+ * Creates a regex pattern from the given glob expression.
+ *
+ * @throws PatternSyntaxException
+ */
+ public static String toRegexPattern(String globPattern) {
+ boolean inGroup = false;
+ StringBuilder regex = new StringBuilder("^");
+
+ int i = 0;
+ while (i < globPattern.length()) {
+ char c = globPattern.charAt(i++);
+ switch (c) {
+ case '\\':
+ // escape special characters
+ if (i == globPattern.length()) {
+ throw new PatternSyntaxException("No character to escape",
+ globPattern, i - 1);
+ }
+ char next = globPattern.charAt(i++);
+ if (isGlobMeta(next) || isRegexMeta(next)) {
+ regex.append('\\');
+ }
+ regex.append(next);
+ break;
+ case '/':
+ regex.append(c);
+ break;
+ case '[':
+ // don't match name separator in class
+ regex.append("[[^/]&&[");
+ if (next(globPattern, i) == '^') {
+ // escape the regex negation char if it appears
+ regex.append("\\^");
+ i++;
+ } else {
+ // negation
+ if (next(globPattern, i) == '!') {
+ regex.append('^');
+ i++;
+ }
+ // hyphen allowed at start
+ if (next(globPattern, i) == '-') {
+ regex.append('-');
+ i++;
+ }
+ }
+ boolean hasRangeStart = false;
+ char last = 0;
+ while (i < globPattern.length()) {
+ c = globPattern.charAt(i++);
+ if (c == ']') {
+ break;
+ }
+ if (c == '/') {
+ throw new PatternSyntaxException("Explicit 'name separator' in class",
+ globPattern, i - 1);
+ }
+ // TBD: how to specify ']' in a class?
+ if (c == '\\' || c == '[' ||
+ c == '&' && next(globPattern, i) == '&') {
+ // escape '\', '[' or "&&" for regex class
+ regex.append('\\');
+ }
+ regex.append(c);
+
+ if (c == '-') {
+ if (!hasRangeStart) {
+ throw new PatternSyntaxException("Invalid range",
+ globPattern, i - 1);
+ }
+ if ((c = next(globPattern, i++)) == EOL || c == ']') {
+ break;
+ }
+ if (c < last) {
+ throw new PatternSyntaxException("Invalid range",
+ globPattern, i - 3);
+ }
+ regex.append(c);
+ hasRangeStart = false;
+ } else {
+ hasRangeStart = true;
+ last = c;
+ }
+ }
+ if (c != ']') {
+ throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
+ }
+ regex.append("]]");
+ break;
+ case '{':
+ if (inGroup) {
+ throw new PatternSyntaxException("Cannot nest groups",
+ globPattern, i - 1);
+ }
+ regex.append("(?:(?:");
+ inGroup = true;
+ break;
+ case '}':
+ if (inGroup) {
+ regex.append("))");
+ inGroup = false;
+ } else {
+ regex.append('}');
+ }
+ break;
+ case ',':
+ if (inGroup) {
+ regex.append(")|(?:");
+ } else {
+ regex.append(',');
+ }
+ break;
+ case '*':
+ if (next(globPattern, i) == '*') {
+ // crosses directory boundaries
+ regex.append(".*");
+ i++;
+ } else {
+ // within directory boundary
+ regex.append("[^/]*");
+ }
+ break;
+ case '?':
+ regex.append("[^/]");
+ break;
+ default:
+ if (isRegexMeta(c)) {
+ regex.append('\\');
+ }
+ regex.append(c);
+ }
+ }
+ if (inGroup) {
+ throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
+ }
+ return regex.append('$').toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/zipfs Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,703 @@
+/*
+ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.net.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/*
+ * ZipFileSystem usage demo
+ *
+ * java Demo action ZipfileName [...]
+ *
+ * @author Xueming Shen
+ */
+
+public class Demo {
+
+ static enum Action {
+ rename, // <java Demo rename zipfile src dst>
+ // rename entry src to dst inside zipfile
+
+ movein, // <java Demo movein zipfile src dst>
+ // move an external src file into zipfile
+ // as entry dst
+
+ moveout, // <java Demo moveout zipfile src dst>
+ // move a zipfile entry src out to dst
+
+ copy, // <java Demo copy zipfile src dst>
+ // copy entry src to dst inside zipfile
+
+ copyin, // <java Demo copyin zipfile src dst>
+ // copy an external src file into zipfile
+ // as entry dst
+
+ copyin_attrs, // <java Demo copyin_attrs zipfile src dst>
+ // copy an external src file into zipfile
+ // as entry dst, with attributes (timestamp)
+
+ copyout, // <java Demo copyout zipfile src dst>
+ // copy zipfile entry src" out to file dst
+
+ copyout_attrs, // <java Demo copyout_attrs zipfile src dst>
+
+ zzmove, // <java Demo zzmove zfsrc zfdst path>
+ // move entry path/dir from zfsrc to zfdst
+
+ zzcopy, // <java Demo zzcopy zfsrc zfdst path>
+ // copy path from zipfile zfsrc to zipfile
+ // zfdst
+
+ attrs, // <java Demo attrs zipfile path>
+ // printout the attributes of entry path
+
+ attrsspace, // <java Demo attrsspace zipfile path>
+ // printout the storespace attrs of entry path
+
+ setmtime, // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
+ // set the lastModifiedTime of entry path
+
+ setatime, // <java Demo setatime zipfile "MM/dd/yy-HH:mm:ss" path...>
+ setctime, // <java Demo setctime zipfile "MM/dd/yy-HH:mm:ss" path...>
+
+ lsdir, // <java Demo lsdir zipfile dir>
+ // list dir's direct child files/dirs
+
+ mkdir, // <java Demo mkdir zipfile dir>
+
+ mkdirs, // <java Demo mkdirs zipfile dir>
+
+ rmdirs, // <java Demo rmdirs zipfile dir>
+
+ list, // <java Demo list zipfile [dir]>
+ // recursively list all entries of dir
+ // via DirectoryStream
+
+ tlist, // <java Demo tlist zipfile [dir]>
+ // list with buildDirTree=true
+
+ vlist, // <java Demo vlist zipfile [dir]>
+ // recursively verbose list all entries of
+ // dir via DirectoryStream
+
+ walk, // <java Demo walk zipfile [dir]>
+ // recursively walk all entries of dir
+ // via Files.walkFileTree
+
+ twalk, // <java Demo twalk zipfile [dir]>
+ // walk with buildDirTree=true
+
+ extract, // <java Demo extract zipfile file [...]>
+
+ update, // <java Demo extract zipfile file [...]>
+
+ delete, // <java Demo delete zipfile file [...]>
+
+ add, // <java Demo add zipfile file [...]>
+
+ create, // <java Demo create zipfile file [...]>
+ // create a new zipfile if it doesn't exit
+ // and then add the file(s) into it.
+
+ attrs2, // <java Demo attrs2 zipfile file [...]>
+ // test different ways to print attrs
+
+ prof,
+ }
+
+ public static void main(String[] args) throws Throwable {
+
+ Action action = Action.valueOf(args[0]);
+ Map<String, Object> env = env = new HashMap<>();
+ if (action == Action.create)
+ env.put("create", "true");
+ if (action == Action.tlist || action == Action.twalk)
+ env.put("buildDirTree", true);
+ FileSystem fs = FileSystems.newFileSystem(Paths.get(args[1]), env, null);
+
+ try {
+ FileSystem fs2;
+ Path path, src, dst;
+ boolean isRename = false;
+ switch (action) {
+ case rename:
+ src = fs.getPath(args[2]);
+ dst = fs.getPath(args[3]);
+ src.moveTo(dst);
+ break;
+ case moveout:
+ src = fs.getPath(args[2]);
+ dst = Paths.get(args[3]);
+ src.moveTo(dst);
+ break;
+ case movein:
+ src = Paths.get(args[2]);
+ dst = fs.getPath(args[3]);
+ src.moveTo(dst);
+ break;
+ case copy:
+ src = fs.getPath(args[2]);
+ dst = fs.getPath(args[3]);
+ src.copyTo(dst);
+ break;
+ case copyout:
+ src = fs.getPath(args[2]);
+ dst = Paths.get(args[3]);
+ src.copyTo(dst);
+ break;
+ case copyin:
+ src = Paths.get(args[2]);
+ dst = fs.getPath(args[3]);
+ src.copyTo(dst);
+ break;
+ case copyin_attrs:
+ src = Paths.get(args[2]);
+ dst = fs.getPath(args[3]);
+ src.copyTo(dst, COPY_ATTRIBUTES);
+ break;
+ case copyout_attrs:
+ src = fs.getPath(args[2]);
+ dst = Paths.get(args[3]);
+ src.copyTo(dst, COPY_ATTRIBUTES);
+ break;
+ case zzmove:
+ fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
+ //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
+ z2zmove(fs, fs2, args[3]);
+ fs2.close();
+ break;
+ case zzcopy:
+ fs2 = FileSystems.newFileSystem(Paths.get(args[2]), env, null);
+ //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
+ z2zcopy(fs, fs2, args[3]);
+ fs2.close();
+ break;
+ case attrs:
+ for (int i = 2; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ System.out.println(path);
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ }
+ break;
+ case setmtime:
+ DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
+ Date newDatetime = df.parse(args[2]);
+ for (int i = 3; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ path.setAttribute("lastModifiedTime",
+ FileTime.fromMillis(newDatetime.getTime()));
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ }
+ break;
+ case setctime:
+ df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
+ newDatetime = df.parse(args[2]);
+ for (int i = 3; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ path.setAttribute("creationTime",
+ FileTime.fromMillis(newDatetime.getTime()));
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ }
+ break;
+ case setatime:
+ df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
+ newDatetime = df.parse(args[2]);
+ for (int i = 3; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ path.setAttribute("lastAccessTime",
+ FileTime.fromMillis(newDatetime.getTime()));
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ }
+ break;
+ case attrsspace:
+ path = fs.getPath("/");
+ FileStore fstore = path.getFileStore();
+ //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
+ // .readAttributes());
+ // or
+ System.out.printf("filestore[%s]%n", fstore.name());
+ System.out.printf(" totalSpace: %d%n",
+ (Long)fstore.getAttribute("space:totalSpace"));
+ System.out.printf(" usableSpace: %d%n",
+ (Long)fstore.getAttribute("space:usableSpace"));
+ System.out.printf(" unallocSpace: %d%n",
+ (Long)fstore.getAttribute("space:unallocatedSpace"));
+ break;
+ case list:
+ case tlist:
+ if (args.length < 3)
+ list(fs.getPath("/"), false);
+ else
+ list(fs.getPath(args[2]), false);
+ break;
+ case vlist:
+ if (args.length < 3)
+ list(fs.getPath("/"), true);
+ else
+ list(fs.getPath(args[2]), true);
+ break;
+ case twalk:
+ case walk:
+ walk(fs.getPath((args.length > 2)? args[2] : "/"));
+ break;
+ case extract:
+ if (args.length == 2) {
+ extract(fs, "/");
+ } else {
+ for (int i = 2; i < args.length; i++) {
+ extract(fs, args[i]);
+ }
+ }
+ break;
+ case delete:
+ for (int i = 2; i < args.length; i++)
+ fs.getPath(args[i]).delete();
+ break;
+ case create:
+ case add:
+ case update:
+ for (int i = 2; i < args.length; i++) {
+ update(fs, args[i]);
+ }
+ break;
+ case lsdir:
+ path = fs.getPath(args[2]);
+ final String fStr = (args.length > 3)?args[3]:"";
+ DirectoryStream<Path> ds = path.newDirectoryStream(
+ new DirectoryStream.Filter<Path>() {
+ public boolean accept(Path path) {
+ return path.toString().contains(fStr);
+ }
+ });
+ for (Path p : ds)
+ System.out.println(p);
+ break;
+ case mkdir:
+ fs.getPath(args[2]).createDirectory();
+ break;
+ case mkdirs:
+ mkdirs(fs.getPath(args[2]));
+ break;
+ case attrs2:
+ for (int i = 2; i < args.length; i++) {
+ path = fs.getPath(args[i]);
+ System.out.printf("%n%s%n", path);
+ System.out.println("-------(1)---------");
+ System.out.println(
+ Attributes.readBasicFileAttributes(path).toString());
+ System.out.println("-------(2)---------");
+ Map<String, ?> map = path.readAttributes("zip:*");
+ for (Map.Entry<String, ?> e : map.entrySet()) {
+ System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
+ }
+ System.out.println("-------(3)---------");
+ map = path.readAttributes("size,lastModifiedTime,isDirectory");
+ for (Map.Entry<String, ?> e : map.entrySet()) {
+ System.out.printf(" %s : %s%n", e.getKey(), e.getValue());
+ }
+ }
+ break;
+ case prof:
+ list(fs.getPath("/"), false);
+ while (true) {
+ Thread.sleep(10000);
+ //list(fs.getPath("/"), true);
+ System.out.println("sleeping...");
+ }
+ }
+ } catch (Exception x) {
+ x.printStackTrace();
+ } finally {
+ if (fs != null)
+ fs.close();
+ }
+ }
+
+ private static byte[] getBytes(String name) {
+ return name.getBytes();
+ }
+
+ private static String getString(byte[] name) {
+ return new String(name);
+ }
+
+ private static void walk(Path path) throws IOException
+ {
+ Files.walkFileTree(
+ path,
+ new SimpleFileVisitor<Path>() {
+ private int indent = 0;
+ private void indent() {
+ int n = 0;
+ while (n++ < indent)
+ System.out.printf(" ");
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs)
+ {
+ indent();
+ System.out.printf("%s%n", file.getName().toString());
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir,
+ BasicFileAttributes attrs)
+ {
+ indent();
+ System.out.printf("[%s]%n", dir.toString());
+ indent += 2;
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir,
+ IOException ioe)
+ {
+ indent -= 2;
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ private static void update(FileSystem fs, String path) throws Throwable{
+ Path src = FileSystems.getDefault().getPath(path);
+ if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
+ DirectoryStream<Path> ds = src.newDirectoryStream();
+ for (Path child : ds)
+ update(fs, child.toString());
+ ds.close();
+ } else {
+ Path dst = fs.getPath(path);
+ Path parent = dst.getParent();
+ if (parent != null && parent.notExists())
+ mkdirs(parent);
+ src.copyTo(dst, REPLACE_EXISTING);
+ }
+ }
+
+ private static void extract(FileSystem fs, String path) throws Throwable{
+ Path src = fs.getPath(path);
+ if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
+ DirectoryStream<Path> ds = src.newDirectoryStream();
+ for (Path child : ds)
+ extract(fs, child.toString());
+ ds.close();
+ } else {
+ if (path.startsWith("/"))
+ path = path.substring(1);
+ Path dst = FileSystems.getDefault().getPath(path);
+ Path parent = dst.getParent();
+ if (parent.notExists())
+ mkdirs(parent);
+ src.copyTo(dst, REPLACE_EXISTING);
+ }
+ }
+
+ // use DirectoryStream
+ private static void z2zcopy(FileSystem src, FileSystem dst, String path)
+ throws IOException
+ {
+ Path srcPath = src.getPath(path);
+ Path dstPath = dst.getPath(path);
+
+ if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
+ if (!dstPath.exists()) {
+ try {
+ mkdirs(dstPath);
+ } catch (FileAlreadyExistsException x) {}
+ }
+ DirectoryStream<Path> ds = srcPath.newDirectoryStream();
+ for (Path child : ds) {
+ z2zcopy(src, dst,
+ path + (path.endsWith("/")?"":"/") + child.getName());
+ }
+ ds.close();
+ } else {
+ //System.out.println("copying..." + path);
+ srcPath.copyTo(dstPath);
+ }
+ }
+
+ // use TreeWalk to move
+ private static void z2zmove(FileSystem src, FileSystem dst, String path)
+ throws IOException
+ {
+ final Path srcPath = src.getPath(path).toAbsolutePath();
+ final Path dstPath = dst.getPath(path).toAbsolutePath();
+
+ Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
+
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs)
+ {
+ Path dst = srcPath.relativize(file);
+ dst = dstPath.resolve(dst);
+ try {
+ Path parent = dstPath.getParent();
+ if (parent != null && parent.notExists())
+ mkdirs(parent);
+ file.moveTo(dst);
+ } catch (IOException x) {
+ x.printStackTrace();
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir,
+ BasicFileAttributes attrs)
+ {
+ Path dst = srcPath.relativize(dir);
+ dst = dstPath.resolve(dst);
+ try {
+
+ if (dst.notExists())
+ mkdirs(dst);
+ } catch (IOException x) {
+ x.printStackTrace();
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir,
+ IOException ioe)
+ throws IOException
+ {
+ try {
+ dir.delete();
+ } catch (IOException x) {
+ //x.printStackTrace();
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+
+ }
+
+ private static void mkdirs(Path path) throws IOException {
+ path = path.toAbsolutePath();
+ Path parent = path.getParent();
+ if (parent != null) {
+ if (parent.notExists())
+ mkdirs(parent);
+ }
+ path.createDirectory();
+ }
+
+ private static void rmdirs(Path path) throws IOException {
+ while (path != null && path.getNameCount() != 0) {
+ path.delete();
+ path = path.getParent();
+ }
+ }
+
+ private static void list(Path path, boolean verbose ) throws IOException {
+ if (!"/".equals(path.toString())) {
+ System.out.printf(" %s%n", path.toString());
+ if (verbose)
+ System.out.println(Attributes.readBasicFileAttributes(path).toString());
+ }
+ if (path.notExists())
+ return;
+ if (Attributes.readBasicFileAttributes(path).isDirectory()) {
+ DirectoryStream<Path> ds = path.newDirectoryStream();
+ for (Path child : ds)
+ list(child, verbose);
+ ds.close();
+ }
+ }
+
+ // check the content of two paths are equal
+ private static void checkEqual(Path src, Path dst) throws IOException
+ {
+ //System.out.printf("checking <%s> vs <%s>...%n",
+ // src.toString(), dst.toString());
+
+ //streams
+ InputStream isSrc = src.newInputStream();
+ InputStream isDst = dst.newInputStream();
+ byte[] bufSrc = new byte[8192];
+ byte[] bufDst = new byte[8192];
+
+ try {
+ int nSrc = 0;
+ while ((nSrc = isSrc.read(bufSrc)) != -1) {
+ int nDst = 0;
+ while (nDst < nSrc) {
+ int n = isDst.read(bufDst, nDst, nSrc - nDst);
+ if (n == -1) {
+ System.out.printf("checking <%s> vs <%s>...%n",
+ src.toString(), dst.toString());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ nDst += n;
+ }
+ while (--nSrc >= 0) {
+ if (bufSrc[nSrc] != bufDst[nSrc]) {
+ System.out.printf("checking <%s> vs <%s>...%n",
+ src.toString(), dst.toString());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ nSrc--;
+ }
+ }
+ } finally {
+ isSrc.close();
+ isDst.close();
+ }
+
+ // channels
+ SeekableByteChannel chSrc = src.newByteChannel();
+ SeekableByteChannel chDst = dst.newByteChannel();
+ if (chSrc.size() != chDst.size()) {
+ System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+ chSrc.toString(), chSrc.size(),
+ chDst.toString(), chDst.size());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+ ByteBuffer bbDst = ByteBuffer.allocate(8192);
+
+ try {
+ int nSrc = 0;
+ while ((nSrc = chSrc.read(bbSrc)) != -1) {
+ int nDst = chDst.read(bbDst);
+ if (nSrc != nDst) {
+ System.out.printf("checking <%s> vs <%s>...%n",
+ src.toString(), dst.toString());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ while (--nSrc >= 0) {
+ if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
+ System.out.printf("checking <%s> vs <%s>...%n",
+ src.toString(), dst.toString());
+ throw new RuntimeException("CHECK FAILED!");
+ }
+ nSrc--;
+ }
+ bbSrc.flip();
+ bbDst.flip();
+ }
+ } catch (IOException x) {
+ x.printStackTrace();
+ } finally {
+ chSrc.close();
+ chDst.close();
+ }
+ }
+
+ private static void fchCopy(Path src, Path dst) throws IOException
+ {
+ Set<OpenOption> read = new HashSet<>();
+ read.add(READ);
+ Set<OpenOption> openwrite = new HashSet<>();
+ openwrite.add(CREATE_NEW);
+ openwrite.add(WRITE);
+
+ FileChannel srcFc = src.getFileSystem()
+ .provider()
+ .newFileChannel(src, read);
+ FileChannel dstFc = dst.getFileSystem()
+ .provider()
+ .newFileChannel(dst, openwrite);
+
+ try {
+ ByteBuffer bb = ByteBuffer.allocate(8192);
+ while (srcFc.read(bb) >= 0) {
+ bb.flip();
+ dstFc.write(bb);
+ bb.clear();
+ }
+ } finally {
+ srcFc.close();
+ dstFc.close();
+ }
+ }
+
+ private static void chCopy(Path src, Path dst) throws IOException
+ {
+ Set<OpenOption> read = new HashSet<>();
+ read.add(READ);
+ Set<OpenOption> openwrite = new HashSet<>();
+ openwrite.add(CREATE_NEW);
+ openwrite.add(WRITE);
+
+ SeekableByteChannel srcCh = src.newByteChannel(read);
+ SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
+
+ try {
+ ByteBuffer bb = ByteBuffer.allocate(8192);
+ while (srcCh.read(bb) >= 0) {
+ bb.flip();
+ dstCh.write(bb);
+ bb.clear();
+ }
+ } finally {
+ srcCh.close();
+ dstCh.close();
+ }
+ }
+
+ private static void streamCopy(Path src, Path dst) throws IOException
+ {
+ InputStream isSrc = src.newInputStream();
+ OutputStream osDst = dst.newOutputStream();
+ byte[] buf = new byte[8192];
+ try {
+ int n = 0;
+ while ((n = isSrc.read(buf)) != -1) {
+ osDst.write(buf, 0, n);
+ }
+ } finally {
+ isSrc.close();
+ osDst.close();
+ }
+ }
+}
--- a/jdk/src/share/native/java/io/RandomAccessFile.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/native/java/io/RandomAccessFile.c Tue Dec 07 13:29:20 2010 +0000
@@ -76,13 +76,13 @@
JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_write(JNIEnv *env, jobject this, jint byte) {
- writeSingle(env, this, byte, raf_fd);
+ writeSingle(env, this, byte, JNI_FALSE, raf_fd);
}
JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_writeBytes(JNIEnv *env,
jobject this, jbyteArray bytes, jint off, jint len) {
- writeBytes(env, this, bytes, off, len, raf_fd);
+ writeBytes(env, this, bytes, off, len, JNI_FALSE, raf_fd);
}
JNIEXPORT jlong JNICALL
--- a/jdk/src/share/native/java/io/io_util.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/native/java/io/io_util.c Tue Dec 07 13:29:20 2010 +0000
@@ -127,7 +127,7 @@
}
void
-writeSingle(JNIEnv *env, jobject this, jint byte, jfieldID fid) {
+writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) {
// Discard the 24 high-order bits of byte. See OutputStream#write(int)
char c = (char) byte;
jint n;
@@ -136,7 +136,11 @@
JNU_ThrowIOException(env, "Stream Closed");
return;
}
- n = IO_Write(fd, &c, 1);
+ if (append == JNI_TRUE) {
+ n = IO_Append(fd, &c, 1);
+ } else {
+ n = IO_Write(fd, &c, 1);
+ }
if (n == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Write error");
} else if (n == JVM_IO_INTR) {
@@ -146,7 +150,7 @@
void
writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
- jint off, jint len, jfieldID fid)
+ jint off, jint len, jboolean append, jfieldID fid)
{
jint n;
char stackBuf[BUF_SIZE];
@@ -185,7 +189,11 @@
JNU_ThrowIOException(env, "Stream Closed");
break;
}
- n = IO_Write(fd, buf+off, len);
+ if (append == JNI_TRUE) {
+ n = IO_Append(fd, buf+off, len);
+ } else {
+ n = IO_Write(fd, buf+off, len);
+ }
if (n == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Write error");
break;
--- a/jdk/src/share/native/java/io/io_util.h Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/native/java/io/io_util.h Tue Dec 07 13:29:20 2010 +0000
@@ -41,9 +41,9 @@
jint readSingle(JNIEnv *env, jobject this, jfieldID fid);
jint readBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off,
jint len, jfieldID fid);
-void writeSingle(JNIEnv *env, jobject this, jint byte, jfieldID fid);
+void writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid);
void writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off,
- jint len, jfieldID fid);
+ jint len, jboolean append, jfieldID fid);
void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags);
void throwFileNotFoundException(JNIEnv *env, jstring path);
--- a/jdk/src/share/native/java/util/zip/Deflater.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/native/java/util/zip/Deflater.c Tue Dec 07 13:29:20 2010 +0000
@@ -132,14 +132,17 @@
in_buf = (jbyte *) malloc(this_len);
if (in_buf == 0) {
- JNU_ThrowOutOfMemoryError(env, 0);
+ // Throw OOME only when length is not zero
+ if (this_len != 0)
+ JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
(*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
out_buf = (jbyte *) malloc(len);
if (out_buf == 0) {
free(in_buf);
- JNU_ThrowOutOfMemoryError(env, 0);
+ if (len != 0)
+ JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
@@ -173,7 +176,8 @@
jboolean finish = (*env)->GetBooleanField(env, this, finishID);
in_buf = (jbyte *) malloc(this_len);
if (in_buf == 0) {
- JNU_ThrowOutOfMemoryError(env, 0);
+ if (this_len != 0)
+ JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
(*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
@@ -181,7 +185,8 @@
out_buf = (jbyte *) malloc(len);
if (out_buf == 0) {
free(in_buf);
- JNU_ThrowOutOfMemoryError(env, 0);
+ if (len != 0)
+ JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
--- a/jdk/src/share/native/java/util/zip/Inflater.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/share/native/java/util/zip/Inflater.c Tue Dec 07 13:29:20 2010 +0000
@@ -135,7 +135,8 @@
in_buf = (jbyte *) malloc(in_len);
if (in_buf == 0) {
- JNU_ThrowOutOfMemoryError(env, 0);
+ if (in_len != 0)
+ JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
(*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf);
@@ -143,7 +144,8 @@
out_buf = (jbyte *) malloc(len);
if (out_buf == 0) {
free(in_buf);
- JNU_ThrowOutOfMemoryError(env, 0);
+ if (len != 0)
+ JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
--- a/jdk/src/solaris/classes/java/lang/ProcessImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/classes/java/lang/ProcessImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -111,7 +111,8 @@
else if (redirects[1] == Redirect.INHERIT)
std_fds[1] = 1;
else {
- f1 = redirects[1].toFileOutputStream();
+ f1 = new FileOutputStream(redirects[1].file(),
+ redirects[1].append());
std_fds[1] = fdAccess.get(f1.getFD());
}
@@ -120,7 +121,8 @@
else if (redirects[2] == Redirect.INHERIT)
std_fds[2] = 2;
else {
- f2 = redirects[2].toFileOutputStream();
+ f2 = new FileOutputStream(redirects[2].file(),
+ redirects[2].append());
std_fds[2] = fdAccess.get(f2.getFD());
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Tue Dec 07 13:29:20 2010 +0000
@@ -42,11 +42,19 @@
private FileDialog fd;
+ // A pointer to the native GTK FileChooser widget
+ private volatile long widget = 0L;
+
public GtkFileDialogPeer(FileDialog fd) {
super((Dialog) fd);
this.fd = fd;
}
+ private static native void initIDs();
+ static {
+ initIDs();
+ }
+
private native void run(String title, int mode, String dir, String file,
FilenameFilter filter, boolean isMultipleMode);
--- a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -35,6 +35,13 @@
init();
}
+ FileDispatcherImpl(boolean append) {
+ /* append is ignored */
+ }
+
+ FileDispatcherImpl() {
+ }
+
int read(FileDescriptor fd, long address, int len) throws IOException {
return read0(fd, address, len);
}
--- a/jdk/src/solaris/native/java/io/FileOutputStream_md.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/java/io/FileOutputStream_md.c Tue Dec 07 13:29:20 2010 +0000
@@ -60,14 +60,14 @@
}
JNIEXPORT void JNICALL
-Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte) {
- writeSingle(env, this, byte, fos_fd);
+Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte, jboolean append) {
+ writeSingle(env, this, byte, append, fos_fd);
}
JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_writeBytes(JNIEnv *env,
- jobject this, jbyteArray bytes, jint off, jint len) {
- writeBytes(env, this, bytes, off, len, fos_fd);
+ jobject this, jbyteArray bytes, jint off, jint len, jboolean append) {
+ writeBytes(env, this, bytes, off, len, append, fos_fd);
}
JNIEXPORT void JNICALL
--- a/jdk/src/solaris/native/java/io/io_util_md.h Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/java/io/io_util_md.h Tue Dec 07 13:29:20 2010 +0000
@@ -53,8 +53,9 @@
#define THIS_FD(obj) (*env)->GetIntField(env, obj, IO_fd_fdID)
/*
- * Route the routines through HPI
+ * Route the routines through VM
*/
+#define IO_Append JVM_Write
#define IO_Write JVM_Write
#define IO_Sync JVM_Sync
#define IO_Read JVM_Read
--- a/jdk/src/solaris/native/sun/awt/awt_MToolkit.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/sun/awt/awt_MToolkit.c Tue Dec 07 13:29:20 2010 +0000
@@ -2773,11 +2773,6 @@
}
}
- /*
- scrollBugWorkAround =
- (strcmp(XServerVendor(awt_display), "Sun Microsystems, Inc.") == 0
- && XVendorRelease(awt_display) == 3400);
- */
scrollBugWorkAround = TRUE;
/*
--- a/jdk/src/solaris/native/sun/awt/fontpath.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/sun/awt/fontpath.c Tue Dec 07 13:29:20 2010 +0000
@@ -557,7 +557,8 @@
#ifndef HEADLESS
static int isSunXServer() {
#ifdef __solaris__
- return (strcmp("Sun Microsystems, Inc.", ServerVendor(awt_display)) == 0 &&
+ return ((strncmp(ServerVendor(awt_display), "Sun Microsystems, Inc.", 22) == 0) ||
+ (strncmp(ServerVendor(awt_display), "Oracle Corporation", 18) == 0) &&
VendorRelease(awt_display) >= 6410);
#else
return 0;
--- a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c Tue Dec 07 13:29:20 2010 +0000
@@ -4,13 +4,29 @@
#include <string.h>
#include "gtk2_interface.h"
#include "sun_awt_X11_GtkFileDialogPeer.h"
+#include "debug_assert.h"
static JavaVM *jvm;
-static GtkWidget *dialog = NULL;
/* To cache some method IDs */
static jmethodID filenameFilterCallbackMethodID = NULL;
static jmethodID setFileInternalMethodID = NULL;
+static jfieldID widgetFieldID = NULL;
+
+JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
+(JNIEnv *env, jclass cx)
+{
+ filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
+ "filenameFilterCallback", "(Ljava/lang/String;)Z");
+ DASSERT(filenameFilterCallbackMethodID != NULL);
+
+ setFileInternalMethodID = (*env)->GetMethodID(env, cx,
+ "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
+ DASSERT(setFileInternalMethodID != NULL);
+
+ widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J");
+ DASSERT(widgetFieldID != NULL);
+}
static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
{
@@ -20,30 +36,17 @@
env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
- if (filenameFilterCallbackMethodID == NULL) {
- cx = (*env)->GetObjectClass(env, (jobject) obj);
- if (cx == NULL) {
- JNU_ThrowInternalError(env, "Could not get file filter class");
- return 0;
- }
-
- filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
- "filenameFilterCallback", "(Ljava/lang/String;)Z");
- if (filenameFilterCallbackMethodID == NULL) {
- JNU_ThrowInternalError(env,
- "Could not get filenameFilterCallback method id");
- return 0;
- }
- }
-
filename = (*env)->NewStringUTF(env, filter_info->filename);
return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
filename);
}
-static void quit(gboolean isSignalHandler)
+static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
{
+ GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
+ (*env)->GetLongField(env, jpeer, widgetFieldID));
+
if (dialog != NULL)
{
// Callbacks from GTK signals are made within the GTK lock
@@ -57,7 +60,8 @@
fp_gtk_widget_destroy (dialog);
fp_gtk_main_quit ();
- dialog = NULL;
+
+ (*env)->SetLongField(env, jpeer, widgetFieldID, 0);
if (!isSignalHandler) {
fp_gdk_threads_leave();
@@ -73,7 +77,7 @@
JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
(JNIEnv * env, jobject jpeer)
{
- quit(FALSE);
+ quit(env, jpeer, FALSE);
}
/**
@@ -132,24 +136,8 @@
if (responseId == GTK_RESPONSE_ACCEPT) {
current_folder = fp_gtk_file_chooser_get_current_folder(
- GTK_FILE_CHOOSER(dialog));
- filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
- }
-
- if (setFileInternalMethodID == NULL) {
- cx = (*env)->GetObjectClass(env, (jobject) obj);
- if (cx == NULL) {
- JNU_ThrowInternalError(env, "Could not get GTK peer class");
- return;
- }
-
- setFileInternalMethodID = (*env)->GetMethodID(env, cx,
- "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
- if (setFileInternalMethodID == NULL) {
- JNU_ThrowInternalError(env,
- "Could not get setFileInternalMethodID method id");
- return;
- }
+ GTK_FILE_CHOOSER(aDialog));
+ filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
}
jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
@@ -159,7 +147,7 @@
jfilenames);
fp_g_free(current_folder);
- quit(TRUE);
+ quit(env, (jobject)obj, TRUE);
}
/*
@@ -172,6 +160,7 @@
jstring jtitle, jint mode, jstring jdir, jstring jfile,
jobject jfilter, jboolean multiple)
{
+ GtkWidget *dialog = NULL;
GtkFileFilter *filter;
if (jvm == NULL) {
@@ -233,8 +222,12 @@
fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
handle_response), jpeer);
+
+ (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
+
fp_gtk_widget_show(dialog);
fp_gtk_main();
fp_gdk_threads_leave();
}
+
--- a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h Tue Dec 07 13:29:20 2010 +0000
@@ -11,6 +11,14 @@
/*
* Class: sun_awt_X11_GtkFileDialogPeer
+ * Method: initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
+(JNIEnv *, jclass);
+
+/*
+ * Class: sun_awt_X11_GtkFileDialogPeer
* Method: run
* Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;Z;)V
*/
--- a/jdk/src/solaris/native/sun/xawt/XWindow.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/solaris/native/sun/xawt/XWindow.c Tue Dec 07 13:29:20 2010 +0000
@@ -766,7 +766,9 @@
static Boolean
isXsunServer(XEvent *event) {
if( awt_ServerDetected ) return awt_IsXsun;
- if( strncmp( ServerVendor( event->xkey.display ), "Sun Microsystems, Inc.", 32) ) {
+ if( (strncmp( ServerVendor( event->xkey.display ), "Sun Microsystems, Inc.", 22) != 0) &&
+ (strncmp( ServerVendor( event->xkey.display ), "Oracle Corporation", 18) != 0) )
+ {
awt_ServerDetected = True;
awt_IsXsun = False;
return False;
--- a/jdk/src/windows/classes/java/lang/ProcessImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -35,6 +35,8 @@
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.lang.ProcessBuilder.Redirect;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/* This class is for the exclusive use of ProcessBuilder.start() to
* create new processes.
@@ -47,6 +49,35 @@
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
+ /**
+ * Open a file for writing. If {@code append} is {@code true} then the file
+ * is opened for atomic append directly and a FileOutputStream constructed
+ * with the resulting handle. This is because a FileOutputStream created
+ * to append to a file does not open the file in a manner that guarantees
+ * that writes by the child process will be atomic.
+ */
+ private static FileOutputStream newFileOutputStream(File f, boolean append)
+ throws IOException
+ {
+ if (append) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkWrite(f.getPath());
+ long handle = openForAtomicAppend(f.getPath());
+ final FileDescriptor fd = new FileDescriptor();
+ fdAccess.setHandle(fd, handle);
+ return AccessController.doPrivileged(
+ new PrivilegedAction<FileOutputStream>() {
+ public FileOutputStream run() {
+ return new FileOutputStream(fd);
+ }
+ }
+ );
+ } else {
+ return new FileOutputStream(f);
+ }
+ }
+
// System-dependent portion of ProcessBuilder.start()
static Process start(String cmdarray[],
java.util.Map<String,String> environment,
@@ -82,7 +113,8 @@
else if (redirects[1] == Redirect.INHERIT)
stdHandles[1] = fdAccess.getHandle(FileDescriptor.out);
else {
- f1 = redirects[1].toFileOutputStream();
+ f1 = newFileOutputStream(redirects[1].file(),
+ redirects[1].append());
stdHandles[1] = fdAccess.getHandle(f1.getFD());
}
@@ -91,7 +123,8 @@
else if (redirects[2] == Redirect.INHERIT)
stdHandles[2] = fdAccess.getHandle(FileDescriptor.err);
else {
- f2 = redirects[2].toFileOutputStream();
+ f2 = newFileOutputStream(redirects[2].file(),
+ redirects[2].append());
stdHandles[2] = fdAccess.getHandle(f2.getFD());
}
}
@@ -251,5 +284,15 @@
boolean redirectErrorStream)
throws IOException;
+ /**
+ * Opens a file for atomic append. The file is created if it doesn't
+ * already exist.
+ *
+ * @param file the file to open or create
+ * @return the native HANDLE
+ */
+ private static native long openForAtomicAppend(String path)
+ throws IOException;
+
private static native boolean closeHandle(long handle);
}
--- a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java Tue Dec 07 13:29:20 2010 +0000
@@ -35,6 +35,20 @@
Util.load();
}
+ /**
+ * Indicates if the dispatcher should first advance the file position
+ * to the end of file when writing.
+ */
+ private final boolean append;
+
+ FileDispatcherImpl(boolean append) {
+ this.append = append;
+ }
+
+ FileDispatcherImpl() {
+ this(false);
+ }
+
int read(FileDescriptor fd, long address, int len)
throws IOException
{
@@ -54,7 +68,7 @@
}
int write(FileDescriptor fd, long address, int len) throws IOException {
- return write0(fd, address, len);
+ return write0(fd, address, len, append);
}
int pwrite(FileDescriptor fd, long address, int len,
@@ -66,7 +80,7 @@
}
long writev(FileDescriptor fd, long address, int len) throws IOException {
- return writev0(fd, address, len);
+ return writev0(fd, address, len, append);
}
int force(FileDescriptor fd, boolean metaData) throws IOException {
@@ -116,13 +130,13 @@
static native long readv0(FileDescriptor fd, long address, int len)
throws IOException;
- static native int write0(FileDescriptor fd, long address, int len)
+ static native int write0(FileDescriptor fd, long address, int len, boolean append)
throws IOException;
static native int pwrite0(FileDescriptor fd, long address, int len,
long position) throws IOException;
- static native long writev0(FileDescriptor fd, long address, int len)
+ static native long writev0(FileDescriptor fd, long address, int len, boolean append)
throws IOException;
static native int force0(FileDescriptor fd, boolean metaData)
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java Tue Dec 07 13:29:20 2010 +0000
@@ -157,7 +157,7 @@
throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
- return FileChannelImpl.open(fdObj, flags.read, flags.write, null);
+ return FileChannelImpl.open(fdObj, flags.read, flags.write, flags.append, null);
}
/**
@@ -230,7 +230,7 @@
if (flags.read)
dwDesiredAccess |= GENERIC_READ;
if (flags.write)
- dwDesiredAccess |= (flags.append) ? FILE_APPEND_DATA : GENERIC_WRITE;
+ dwDesiredAccess |= GENERIC_WRITE;
int dwShareMode = 0;
if (flags.shareRead)
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Tue Dec 07 13:29:20 2010 +0000
@@ -129,7 +129,7 @@
ktab.deleteEntry();
break;
default:
- ktab.printHelp();
+ ktab.error("A command must be provided");
}
}
@@ -232,7 +232,7 @@
append = true;
break;
default:
- printHelp();
+ error("Unknown command: " + args[i]);
break;
}
} else { // optional standalone arguments
--- a/jdk/src/windows/native/java/io/FileOutputStream_md.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/java/io/FileOutputStream_md.c Tue Dec 07 13:29:20 2010 +0000
@@ -61,14 +61,15 @@
}
JNIEXPORT void JNICALL
-Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte) {
- writeSingle(env, this, byte, fos_fd);
+Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte, jboolean append) {
+ writeSingle(env, this, byte, append, fos_fd);
}
JNIEXPORT void JNICALL
Java_java_io_FileOutputStream_writeBytes(JNIEnv *env,
- jobject this, jbyteArray bytes, jint off, jint len) {
- writeBytes(env, this, bytes, off, len, fos_fd);
+ jobject this, jbyteArray bytes, jint off, jint len, jboolean append)
+{
+ writeBytes(env, this, bytes, off, len, append, fos_fd);
}
JNIEXPORT void JNICALL
--- a/jdk/src/windows/native/java/io/io_util_md.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/java/io/io_util_md.c Tue Dec 07 13:29:20 2010 +0000
@@ -225,14 +225,7 @@
jlong
winFileHandleOpen(JNIEnv *env, jstring path, int flags)
{
- /* To implement O_APPEND, we use the strategy from
- http://msdn2.microsoft.com/en-us/library/aa363858.aspx
- "You can get atomic append by opening a file with
- FILE_APPEND_DATA access and _without_ FILE_WRITE_DATA access.
- If you do this then all writes will ignore the current file
- pointer and be done at the end-of file." */
const DWORD access =
- (flags & O_APPEND) ? (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA) :
(flags & O_WRONLY) ? GENERIC_WRITE :
(flags & O_RDWR) ? (GENERIC_READ | GENERIC_WRITE) :
GENERIC_READ;
@@ -307,7 +300,6 @@
int
handleAvailable(jlong fd, jlong *pbytes) {
- jlong current, end;
HANDLE h = (HANDLE)fd;
DWORD type = 0;
@@ -327,18 +319,17 @@
}
/* Handle is for regular file */
if (type == FILE_TYPE_DISK) {
- long highPos = 0;
- DWORD sizeLow = 0;
- DWORD sizeHigh = 0;
- DWORD lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);
- if (lowPos == ((DWORD)-1)) {
+ jlong current, end;
+
+ LARGE_INTEGER filesize;
+ current = handleLseek(fd, 0, SEEK_CUR);
+ if (current < 0) {
return FALSE;
}
- current = (((jlong)highPos) << 32) | lowPos;
- end = GetFileSize(h, &sizeHigh);
- if (sizeLow == ((DWORD)-1)) {
+ if (GetFileSizeEx(h, &filesize) == 0) {
return FALSE;
}
+ end = long_to_jlong(filesize.QuadPart);
*pbytes = end - current;
return TRUE;
}
@@ -511,24 +502,42 @@
return read;
}
-JNIEXPORT
-size_t
-handleWrite(jlong fd, const void *buf, jint len)
+static size_t writeInternal(jlong fd, const void *buf, jint len, jboolean append)
{
BOOL result = 0;
DWORD written = 0;
HANDLE h = (HANDLE)fd;
if (h != INVALID_HANDLE_VALUE) {
- result = WriteFile(h, /* File handle to write */
- buf, /* pointers to the buffers */
- len, /* number of bytes to write */
- &written, /* receives number of bytes written */
- NULL); /* no overlapped struct */
+ OVERLAPPED ov;
+ LPOVERLAPPED lpOv;
+ if (append == JNI_TRUE) {
+ ov.Offset = (DWORD)0xFFFFFFFF;
+ ov.OffsetHigh = (DWORD)0xFFFFFFFF;
+ ov.hEvent = NULL;
+ lpOv = &ov;
+ } else {
+ lpOv = NULL;
+ }
+ result = WriteFile(h, /* File handle to write */
+ buf, /* pointers to the buffers */
+ len, /* number of bytes to write */
+ &written, /* receives number of bytes written */
+ lpOv); /* overlapped struct */
}
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
return -1;
}
- return written;
+ return (size_t)written;
+}
+
+JNIEXPORT
+size_t handleWrite(jlong fd, const void *buf, jint len) {
+ return writeInternal(fd, buf, len, JNI_FALSE);
+}
+
+JNIEXPORT
+size_t handleAppend(jlong fd, const void *buf, jint len) {
+ return writeInternal(fd, buf, len, JNI_TRUE);
}
jint
@@ -558,6 +567,7 @@
jlong
handleLseek(jlong fd, jlong offset, jint whence)
{
+ LARGE_INTEGER pos, distance;
DWORD lowPos = 0;
long highPos = 0;
DWORD op = FILE_CURRENT;
@@ -573,13 +583,9 @@
op = FILE_BEGIN;
}
- lowPos = (DWORD)offset;
- highPos = (long)(offset >> 32);
- lowPos = SetFilePointer(h, lowPos, &highPos, op);
- if (lowPos == ((DWORD)-1)) {
- if (GetLastError() != ERROR_SUCCESS) {
- return -1;
- }
+ distance.QuadPart = offset;
+ if (SetFilePointerEx(h, distance, &pos, op) == 0) {
+ return -1;
}
- return (((jlong)highPos) << 32) | lowPos;
+ return long_to_jlong(pos.QuadPart);
}
--- a/jdk/src/windows/native/java/io/io_util_md.h Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/java/io/io_util_md.h Tue Dec 07 13:29:20 2010 +0000
@@ -41,6 +41,7 @@
int handleSetLength(jlong fd, jlong length);
JNIEXPORT size_t handleRead(jlong fd, void *buf, jint len);
JNIEXPORT size_t handleWrite(jlong fd, const void *buf, jint len);
+JNIEXPORT size_t handleAppend(jlong fd, const void *buf, jint len);
jint handleClose(JNIEnv *env, jobject this, jfieldID fid);
jlong handleLseek(jlong fd, jlong offset, jint whence);
@@ -74,8 +75,9 @@
#define THIS_FD(obj) (*env)->GetLongField(env, obj, IO_handle_fdID)
/*
- * Route the routines away from HPI layer
+ * Route the routines away from VM
*/
+#define IO_Append handleAppend
#define IO_Write handleWrite
#define IO_Sync handleSync
#define IO_Read handleRead
--- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c Tue Dec 07 13:29:20 2010 +0000
@@ -315,3 +315,51 @@
{
return CloseHandle((HANDLE) handle);
}
+
+/**
+ * Returns a copy of the Unicode characters of a string. Fow now this
+ * function doesn't handle long path names and other issues.
+ */
+static WCHAR* getPath(JNIEnv *env, jstring ps) {
+ WCHAR *pathbuf = NULL;
+ const jchar *chars = (*(env))->GetStringChars(env, ps, NULL);
+ if (chars != NULL) {
+ size_t pathlen = wcslen(chars);
+ pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
+ if (pathbuf == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ } else {
+ wcscpy(pathbuf, chars);
+ }
+ (*env)->ReleaseStringChars(env, ps, chars);
+ }
+ return pathbuf;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_lang_ProcessImpl_openForAtomicAppend(JNIEnv *env, jclass ignored, jstring path)
+{
+ const DWORD access = (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA);
+ const DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ const DWORD disposition = OPEN_ALWAYS;
+ const DWORD flagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+ HANDLE h;
+ WCHAR *pathbuf = getPath(env, path);
+ if (pathbuf == NULL) {
+ /* Exception already pending */
+ return -1;
+ }
+ h = CreateFileW(
+ pathbuf, /* Wide char path name */
+ access, /* Read and/or write permission */
+ sharing, /* File sharing flags */
+ NULL, /* Security attributes */
+ disposition, /* creation disposition */
+ flagsAndAttributes, /* flags and attributes */
+ NULL);
+ free(pathbuf);
+ if (h == INVALID_HANDLE_VALUE) {
+ JNU_ThrowIOExceptionWithLastError(env, "CreateFileW");
+ }
+ return ptr_to_jlong(h);
+}
--- a/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c Tue Dec 07 13:29:20 2010 +0000
@@ -184,18 +184,28 @@
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo,
- jlong address, jint len)
+ jlong address, jint len, jboolean append)
{
BOOL result = 0;
DWORD written = 0;
HANDLE h = (HANDLE)(handleval(env, fdo));
if (h != INVALID_HANDLE_VALUE) {
+ OVERLAPPED ov;
+ LPOVERLAPPED lpOv;
+ if (append == JNI_TRUE) {
+ ov.Offset = (DWORD)0xFFFFFFFF;
+ ov.OffsetHigh = (DWORD)0xFFFFFFFF;
+ ov.hEvent = NULL;
+ lpOv = &ov;
+ } else {
+ lpOv = NULL;
+ }
result = WriteFile(h, /* File handle to write */
(LPCVOID)address, /* pointers to the buffers */
len, /* number of bytes to write */
&written, /* receives number of bytes written */
- NULL); /* no overlapped struct */
+ lpOv); /* overlapped struct */
}
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
@@ -207,7 +217,7 @@
JNIEXPORT jlong JNICALL
Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo,
- jlong address, jint len)
+ jlong address, jint len, jboolean append)
{
BOOL result = 0;
DWORD written = 0;
@@ -219,7 +229,16 @@
int i = 0;
DWORD num = 0;
struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);
-
+ OVERLAPPED ov;
+ LPOVERLAPPED lpOv;
+ if (append == JNI_TRUE) {
+ ov.Offset = (DWORD)0xFFFFFFFF;
+ ov.OffsetHigh = (DWORD)0xFFFFFFFF;
+ ov.hEvent = NULL;
+ lpOv = &ov;
+ } else {
+ lpOv = NULL;
+ }
for(i=0; i<len; i++) {
loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);
num = iovecp[i].iov_len;
@@ -227,7 +246,7 @@
loc, /* pointers to the buffers */
num, /* number of bytes to write */
&written,/* receives number of bytes written */
- NULL); /* no overlapped struct */
+ lpOv); /* overlapped struct */
if (written > 0) {
totalWritten += written;
}
@@ -444,9 +463,10 @@
}
JNIEXPORT jlong JNICALL
-Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong hFile)
+Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong handle)
{
HANDLE hProcess = GetCurrentProcess();
+ HANDLE hFile = jlong_to_ptr(handle);
HANDLE hResult;
BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE,
DUPLICATE_SAME_ACCESS);
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Tue Dec 07 13:29:20 2010 +0000
@@ -6084,63 +6084,67 @@
void AwtComponent::_SetRectangularShape(void *param)
{
- JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-
- SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param;
- jobject self = data->component;
- jint x1 = data->x1;
- jint x2 = data->x2;
- jint y1 = data->y1;
- jint y2 = data->y2;
- jobject region = data->region;
-
- AwtComponent *c = NULL;
-
- PDATA pData;
- JNI_CHECK_PEER_GOTO(self, ret);
-
- c = (AwtComponent *)pData;
- if (::IsWindow(c->GetHWnd())) {
- HRGN hRgn = NULL;
- if (region || x1 || x2 || y1 || y2) {
- // If all the params are zeros, the shape must be simply reset.
- // Otherwise, convert it into a region.
- RGNDATA *pRgnData = NULL;
- RGNDATAHEADER *pRgnHdr;
-
- /* reserving memory for the worst case */
- size_t worstBufferSize = size_t(((x2 - x1) / 2 + 1) * (y2 - y1));
- pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) +
- sizeof(RECT_T) * worstBufferSize);
- pRgnHdr = (RGNDATAHEADER *) pRgnData;
-
- pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
- pRgnHdr->iType = RDH_RECTANGLES;
- pRgnHdr->nRgnSize = 0;
- pRgnHdr->rcBound.top = 0;
- pRgnHdr->rcBound.left = 0;
- pRgnHdr->rcBound.bottom = LONG(y2 - y1);
- pRgnHdr->rcBound.right = LONG(x2 - x1);
-
- RECT_T * pRect = (RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER));
- pRgnHdr->nCount = RegionToYXBandedRectangles(env, x1, y1, x2, y2, region, &pRect, worstBufferSize);
-
- hRgn = ::ExtCreateRegion(NULL,
- sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData);
-
- free(pRgnData);
+ if (!AwtToolkit::IsMainThread()) {
+ AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetRectangularShape, param);
+ } else {
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ SetRectangularShapeStruct *data = (SetRectangularShapeStruct *)param;
+ jobject self = data->component;
+ jint x1 = data->x1;
+ jint x2 = data->x2;
+ jint y1 = data->y1;
+ jint y2 = data->y2;
+ jobject region = data->region;
+
+ AwtComponent *c = NULL;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+
+ c = (AwtComponent *)pData;
+ if (::IsWindow(c->GetHWnd())) {
+ HRGN hRgn = NULL;
+ if (region || x1 || x2 || y1 || y2) {
+ // If all the params are zeros, the shape must be simply reset.
+ // Otherwise, convert it into a region.
+ RGNDATA *pRgnData = NULL;
+ RGNDATAHEADER *pRgnHdr;
+
+ /* reserving memory for the worst case */
+ size_t worstBufferSize = size_t(((x2 - x1) / 2 + 1) * (y2 - y1));
+ pRgnData = (RGNDATA *) safe_Malloc(sizeof(RGNDATAHEADER) +
+ sizeof(RECT_T) * worstBufferSize);
+ pRgnHdr = (RGNDATAHEADER *) pRgnData;
+
+ pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
+ pRgnHdr->iType = RDH_RECTANGLES;
+ pRgnHdr->nRgnSize = 0;
+ pRgnHdr->rcBound.top = 0;
+ pRgnHdr->rcBound.left = 0;
+ pRgnHdr->rcBound.bottom = LONG(y2 - y1);
+ pRgnHdr->rcBound.right = LONG(x2 - x1);
+
+ RECT_T * pRect = (RECT_T *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER));
+ pRgnHdr->nCount = RegionToYXBandedRectangles(env, x1, y1, x2, y2, region, &pRect, worstBufferSize);
+
+ hRgn = ::ExtCreateRegion(NULL,
+ sizeof(RGNDATAHEADER) + sizeof(RECT_T) * pRgnHdr->nCount, pRgnData);
+
+ free(pRgnData);
+ }
+
+ ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE);
}
- ::SetWindowRgn(c->GetHWnd(), hRgn, TRUE);
- }
-
ret:
- env->DeleteGlobalRef(self);
- if (region) {
- env->DeleteGlobalRef(region);
- }
-
- delete data;
+ env->DeleteGlobalRef(self);
+ if (region) {
+ env->DeleteGlobalRef(region);
+ }
+
+ delete data;
+ }
}
void AwtComponent::_SetZOrder(void *param) {
--- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp Tue Dec 07 13:29:20 2010 +0000
@@ -194,9 +194,9 @@
jint AwtRobot::GetRGBPixel( jint x, jint y)
{
- HDC hdc = GetDC(NULL);
+ HDC hdc = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
COLORREF ref = ::GetPixel( hdc, x, y );
- ReleaseDC(NULL,hdc);
+ ::DeleteDC(hdc);
jint value = WinToJavaPixel(GetRValue(ref), GetGValue(ref), GetBValue(ref));
return value;
}
--- a/jdk/test/com/sun/jndi/ldap/InvalidLdapFilters.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/com/sun/jndi/ldap/InvalidLdapFilters.java Tue Dec 07 13:29:20 2010 +0000
@@ -48,6 +48,8 @@
* @run main/othervm InvalidLdapFilters valid (sn;lang-en:dn:2.4.6.8.10:=Barney)
* @run main/othervm InvalidLdapFilters valid
(&(objectClass=Person)(|(sn=Jensen)(cn=Bab*)))
+ * @run main/othervm InvalidLdapFilters valid
+ (orcluserapplnprovstatus;EMAIL_email=PROVISIONING_FAILURE)
* @run main/othervm InvalidLdapFilters invalid "(&(cn=Robert Dean)))"
* @run main/othervm InvalidLdapFilters invalid (&|(cn=Bob))
* @run main/othervm InvalidLdapFilters invalid (&&(cn=Bob))
--- a/jdk/test/demo/zipfs/Basic.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/demo/zipfs/Basic.java Tue Dec 07 13:29:20 2010 +0000
@@ -40,24 +40,24 @@
boolean found = false;
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
- if (provider.getScheme().equalsIgnoreCase("zip")) {
+ if (provider.getScheme().equalsIgnoreCase("jar")) {
found = true;
break;
}
}
if (!found)
- throw new RuntimeException("'zip' provider not installed");
+ throw new RuntimeException("'jar' provider not installed");
// Test: FileSystems#newFileSystem(FileRef)
Map<String,?> env = new HashMap<String,Object>();
FileSystems.newFileSystem(zipfile, env, null).close();
// Test: FileSystems#newFileSystem(URI)
- URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
+ URI uri = new URI("jar", zipfile.toUri().toString(), null);
FileSystem fs = FileSystems.newFileSystem(uri, env, null);
// Test: exercise toUri method
- String expected = uri.toString() + "#/foo";
+ String expected = uri.toString() + "!/foo";
String actual = fs.getPath("/foo").toUri().toString();
if (!actual.equals(expected)) {
throw new RuntimeException("toUri returned '" + actual +
--- a/jdk/test/demo/zipfs/ZipFSTester.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/demo/zipfs/ZipFSTester.java Tue Dec 07 13:29:20 2010 +0000
@@ -58,7 +58,7 @@
// clone a fs and test on it
Path tmpfsPath = getTempPath();
Map<String, Object> env = new HashMap<String, Object>();
- env.put("createNew", true);
+ env.put("create", "true");
FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
z2zcopy(fs, fs0, "/", 0);
fs0.close(); // sync to file
@@ -147,7 +147,7 @@
// create a new filesystem, copy everything from fs
Map<String, Object> env = new HashMap<String, Object>();
- env.put("createNew", true);
+ env.put("create", "true");
FileSystem fs0 = newZipFileSystem(fs1Path, env);
final FileSystem fs2 = newZipFileSystem(fs2Path, env);
@@ -282,11 +282,7 @@
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
throws IOException
{
- return FileSystems.newFileSystem(
- URI.create("zip" +
- path.toUri().toString().substring(4)),
- env,
- null);
+ return FileSystems.newFileSystem(path, env, null);
}
private static Path getTempPath() throws IOException
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 6988428
+ @summary Tests whether shape is always set
+ @author anthony.petrov@oracle.com: area=awt.toplevel
+ @run main ShapeNotSetSometimes
+*/
+
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.geom.*;
+
+
+public class ShapeNotSetSometimes {
+
+ private Frame backgroundFrame;
+ private Frame window;
+ private static final Color BACKGROUND_COLOR = Color.BLUE;
+ private Shape shape;
+ private int[][] pointsToCheck;
+
+ private static Robot robot;
+
+ public ShapeNotSetSometimes() throws Exception {
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ initializeGUI();
+ }
+ });
+ }
+
+ private void initializeGUI() {
+ backgroundFrame = new BackgroundFrame();
+ backgroundFrame.setUndecorated(true);
+ backgroundFrame.setSize(300, 300);
+ backgroundFrame.setLocation(20, 400);
+ backgroundFrame.setVisible(true);
+
+ shape = null;
+ String shape_name = null;
+ Area a;
+ GeneralPath gp;
+ shape_name = "Rounded-corners";
+ a = new Area();
+ a.add(new Area(new Rectangle2D.Float(50, 0, 100, 150)));
+ a.add(new Area(new Rectangle2D.Float(0, 50, 200, 50)));
+ a.add(new Area(new Ellipse2D.Float(0, 0, 100, 100)));
+ a.add(new Area(new Ellipse2D.Float(0, 50, 100, 100)));
+ a.add(new Area(new Ellipse2D.Float(100, 0, 100, 100)));
+ a.add(new Area(new Ellipse2D.Float(100, 50, 100, 100)));
+ shape = a;
+ pointsToCheck = new int[][] {
+ // inside shape
+ {106, 86}, {96, 38}, {76, 107}, {180, 25}, {24, 105},
+ {196, 77}, {165, 50}, {14, 113}, {89, 132}, {167, 117},
+ // outside shape
+ {165, 196}, {191, 163}, {146, 185}, {61, 170}, {148, 171},
+ {82, 172}, {186, 11}, {199, 141}, {13, 173}, {187, 3}
+ };
+
+ window = new TestFrame();
+ window.setUndecorated(true);
+ window.setSize(200, 200);
+ window.setLocation(70, 450);
+ window.setShape(shape);
+ window.setVisible(true);
+
+ System.out.println("Checking " + window.getClass().getSuperclass().getName() + " with " + shape_name + " shape (" + window.getShape() + ")...");
+ }
+
+ class BackgroundFrame extends Frame {
+
+ @Override
+ public void paint(Graphics g) {
+
+ g.setColor(BACKGROUND_COLOR);
+ g.fillRect(0, 0, 300, 300);
+
+ super.paint(g);
+ }
+ }
+
+ class TestFrame extends Frame {
+
+ @Override
+ public void paint(Graphics g) {
+
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, 200, 200);
+
+ super.paint(g);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ robot = new Robot();
+
+ for(int i = 0; i < 100; i++) {
+ System.out.println("Attempt " + i);
+ new ShapeNotSetSometimes().doTest();
+ }
+ }
+
+ private void doTest() throws Exception {
+ Point wls = backgroundFrame.getLocationOnScreen();
+
+ robot.mouseMove(wls.x + 5, wls.y + 5);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.delay(10);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ robot.delay(500);
+
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ window.requestFocus();
+ }
+ });
+
+ robot.waitForIdle();
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ // ignore this one
+ }
+
+ // check transparency
+ final int COUNT_TARGET = 10;
+
+ // checking outside points only
+ for(int i = COUNT_TARGET; i < COUNT_TARGET * 2; i++) {
+ int x = pointsToCheck[i][0];
+ int y = pointsToCheck[i][1];
+ boolean inside = i < COUNT_TARGET;
+ Color c = robot.getPixelColor(window.getX() + x, window.getY() + y);
+ System.out.println("checking " + x + ", " + y + ", color = " + c);
+ if (inside && BACKGROUND_COLOR.equals(c) || !inside && !BACKGROUND_COLOR.equals(c)) {
+ System.out.println("window.getX() = " + window.getX() + ", window.getY() = " + window.getY());
+ System.err.println("Checking for transparency failed: point: " +
+ (window.getX() + x) + ", " + (window.getY() + y) +
+ ", color = " + c + (inside ? " is of un" : " is not of ") +
+ "expected background color " + BACKGROUND_COLOR);
+ throw new RuntimeException("Test failed. The shape has not been applied.");
+ }
+ }
+
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ backgroundFrame.dispose();
+ window.dispose();
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/OtherEvents/UngrabID/UngrabID.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/*
+ @test
+ @bug 6960516
+ @summary check if the ungrab event has the ID < AWTEvent.RESERVED_ID_MAX
+ @author Andrei Dmitriev : area=awt.event
+ @run main UngrabID
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class UngrabID {
+ public static void main(String[] args){
+ Frame f = new Frame("Dummy");
+ sun.awt.UngrabEvent event = new sun.awt.UngrabEvent(f);
+ if (event.getID() > AWTEvent.RESERVED_ID_MAX) {
+ System.out.println( " Event ID : "+event.getID() + " " + event.toString());
+ throw new RuntimeException(" Ungrab Event ID should be less than AWTEvent.RESERVED_ID_MAX ("+AWTEvent.RESERVED_ID_MAX+"). Actual value : "+event.getID() + " Event:" + event.toString());
+ }
+ System.out.println("Test passed. ");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FileInputStream/LargeFileAvailable.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6402006
+ * @summary Test if available returns correct value when reading
+ * a large file.
+ */
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import static java.nio.file.StandardOpenOption.*;
+
+public class LargeFileAvailable {
+ private static final long FILESIZE = 7405576182L;
+ public static void main(String args[]) throws Exception {
+ File file = createLargeFile(FILESIZE);
+ try (FileInputStream fis = new FileInputStream(file)) {
+ if (file.length() != FILESIZE) {
+ throw new RuntimeException("unexpected file size = " + file.length());
+ }
+
+ long bigSkip = 3110608882L;
+ long remaining = FILESIZE;
+ remaining -= skipBytes(fis, bigSkip, remaining);
+ remaining -= skipBytes(fis, 10L, remaining);
+ remaining -= skipBytes(fis, bigSkip, remaining);
+ if (fis.available() != (int) remaining) {
+ throw new RuntimeException("available() returns " +
+ fis.available() +
+ " but expected " + remaining);
+ }
+ } finally {
+ file.delete();
+ }
+ }
+
+ // Skip toSkip number of bytes and expect that the available() method
+ // returns avail number of bytes.
+ private static long skipBytes(InputStream is, long toSkip, long avail)
+ throws IOException {
+ long skip = is.skip(toSkip);
+ if (skip != toSkip) {
+ throw new RuntimeException("skip() returns " + skip +
+ " but expected " + toSkip);
+ }
+ long remaining = avail - skip;
+ int expected = remaining >= Integer.MAX_VALUE
+ ? Integer.MAX_VALUE
+ : (int) remaining;
+
+ System.out.println("Skipped " + skip + " bytes " +
+ " available() returns " + expected +
+ " remaining=" + remaining);
+ if (is.available() != expected) {
+ throw new RuntimeException("available() returns " +
+ is.available() + " but expected " + expected);
+ }
+ return skip;
+ }
+
+ private static File createLargeFile(long filesize) throws Exception {
+ // Create a large file as a sparse file if possible
+ File largefile = File.createTempFile("largefile", null);
+ // re-create as a sparse file
+ largefile.toPath().delete();
+ try (FileChannel fc =
+ FileChannel.open(largefile.toPath(),
+ CREATE_NEW, WRITE, SPARSE)) {
+ ByteBuffer bb = ByteBuffer.allocate(1).put((byte)1);
+ bb.rewind();
+ int rc = fc.write(bb, filesize-1);
+ if (rc != 1) {
+ throw new RuntimeException("Failed to write 1 byte to the large file");
+ }
+ }
+ return largefile;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/Serializable/cloneArray/CloneArray.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/* @test
+ * @bug 6990094
+ * @summary Verify ObjectInputStream.cloneArray works on many kinds of arrays
+ * @author Stuart Marks, Joseph D. Darcy
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+public class CloneArray {
+ static Object replacement;
+
+ static class Resolver implements Serializable {
+ private Object readResolve() throws ObjectStreamException {
+ return replacement;
+ }
+ }
+
+ private static void test(Object rep)
+ throws IOException, ClassNotFoundException {
+
+ try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ try(ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ oos.writeObject(new Resolver());
+ oos.writeObject(new Resolver());
+ }
+
+ Object o1;
+ Object o2;
+ try(ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais)) {
+ replacement = rep;
+ o1 = ois.readUnshared();
+ o2 = ois.readUnshared();
+ }
+
+ if (o1 == o2)
+ throw new AssertionError("o1 and o2 must not be identical");
+ }
+ }
+
+ public static void main(String[] args)
+ throws IOException, ClassNotFoundException {
+ Object[] replacements = {
+ new byte[] {1},
+ new char[] {'2'},
+ new short[] {3},
+ new int[] {4},
+ new long[] {5},
+ new float[] {6.0f},
+ new double[] {7.0},
+ new boolean[] {true},
+ new Object[] {"A string."}
+ };
+
+ for(Object replacement : replacements) {
+ test(replacement);
+ }
+ }
+}
--- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java Tue Dec 07 13:29:20 2010 +0000
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4607272 6842687
+ * @bug 4607272 6842687 6878369
* @summary Unit test for AsynchronousSocketChannel
* @run main/timeout=600 Basic
*/
@@ -712,52 +712,57 @@
}
static void testTimeout() throws Exception {
+ System.out.println("-- timeouts --");
+ testTimeout(Integer.MIN_VALUE, TimeUnit.SECONDS);
+ testTimeout(-1L, TimeUnit.SECONDS);
+ testTimeout(0L, TimeUnit.SECONDS);
+ testTimeout(2L, TimeUnit.SECONDS);
+ }
+
+ static void testTimeout(final long timeout, final TimeUnit unit) throws Exception {
Server server = new Server();
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
ch.connect(server.address()).get();
- System.out.println("-- timeout when reading --");
-
ByteBuffer dst = ByteBuffer.allocate(512);
final AtomicReference<Throwable> readException = new AtomicReference<Throwable>();
- // this read should timeout
- ch.read(dst, 3, TimeUnit.SECONDS, (Void)null,
- new CompletionHandler<Integer,Void>()
- {
+ // this read should timeout if value is > 0
+ ch.read(dst, timeout, unit, null, new CompletionHandler<Integer,Void>() {
public void completed(Integer result, Void att) {
- throw new RuntimeException("Should not complete");
+ readException.set(new RuntimeException("Should not complete"));
}
public void failed(Throwable exc, Void att) {
readException.set(exc);
}
});
- // wait for exception
- while (readException.get() == null) {
- Thread.sleep(100);
- }
- if (!(readException.get() instanceof InterruptedByTimeoutException))
- throw new RuntimeException("InterruptedByTimeoutException expected");
+ if (timeout > 0L) {
+ // wait for exception
+ while (readException.get() == null) {
+ Thread.sleep(100);
+ }
+ if (!(readException.get() instanceof InterruptedByTimeoutException))
+ throw new RuntimeException("InterruptedByTimeoutException expected");
- // after a timeout then further reading should throw unspecified runtime exception
- boolean exceptionThrown = false;
- try {
- ch.read(dst);
- } catch (RuntimeException x) {
- exceptionThrown = true;
+ // after a timeout then further reading should throw unspecified runtime exception
+ boolean exceptionThrown = false;
+ try {
+ ch.read(dst);
+ } catch (RuntimeException x) {
+ exceptionThrown = true;
+ }
+ if (!exceptionThrown)
+ throw new RuntimeException("RuntimeException expected after timeout.");
+ } else {
+ Thread.sleep(1000);
+ Throwable exc = readException.get();
+ if (exc != null)
+ throw new RuntimeException(exc);
}
- if (!exceptionThrown)
- throw new RuntimeException("RuntimeException expected after timeout.");
-
-
- System.out.println("-- timeout when writing --");
final AtomicReference<Throwable> writeException = new AtomicReference<Throwable>();
- final long timeout = 5;
- final TimeUnit unit = TimeUnit.SECONDS;
-
// write bytes to fill socket buffer
ch.write(genBuffer(), timeout, unit, ch,
new CompletionHandler<Integer,AsynchronousSocketChannel>()
@@ -769,24 +774,32 @@
writeException.set(exc);
}
});
-
- // wait for exception
- while (writeException.get() == null) {
- Thread.sleep(100);
- }
- if (!(writeException.get() instanceof InterruptedByTimeoutException))
- throw new RuntimeException("InterruptedByTimeoutException expected");
+ if (timeout > 0) {
+ // wait for exception
+ while (writeException.get() == null) {
+ Thread.sleep(100);
+ }
+ if (!(writeException.get() instanceof InterruptedByTimeoutException))
+ throw new RuntimeException("InterruptedByTimeoutException expected");
- // after a timeout then further writing should throw unspecified runtime exception
- exceptionThrown = false;
- try {
- ch.write(genBuffer());
- } catch (RuntimeException x) {
- exceptionThrown = true;
+ // after a timeout then further writing should throw unspecified runtime exception
+ boolean exceptionThrown = false;
+ try {
+ ch.write(genBuffer());
+ } catch (RuntimeException x) {
+ exceptionThrown = true;
+ }
+ if (!exceptionThrown)
+ throw new RuntimeException("RuntimeException expected after timeout.");
+ } else {
+ Thread.sleep(1000);
+ Throwable exc = writeException.get();
+ if (exc != null)
+ throw new RuntimeException(exc);
}
- if (!exceptionThrown)
- throw new RuntimeException("RuntimeException expected after timeout.");
+ // clean-up
+ server.accept().close();
ch.close();
server.close();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/AtomicAppend.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Check that appends are atomic
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.Random;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import static java.nio.file.StandardOpenOption.*;
+
+public class AtomicAppend {
+ static final Random rand = new Random();
+
+ // Open file for appending, returning FileChannel
+ static FileChannel newFileChannel(File file) throws IOException {
+ if (rand.nextBoolean()) {
+ return new FileOutputStream(file, true).getChannel();
+ } else {
+ return FileChannel.open(file.toPath(), APPEND);
+ }
+ }
+
+ // Open file for append, returning OutputStream
+ static OutputStream newOutputStream(File file) throws IOException {
+ if (rand.nextBoolean()) {
+ return new FileOutputStream(file, true);
+ } else {
+ return file.toPath().newOutputStream(APPEND);
+ }
+ }
+
+ // write a byte to the given channel
+ static void write(FileChannel fc, int b) throws IOException {
+ ByteBuffer buf = ByteBuffer.allocate(1);
+ buf.put((byte)b);
+ buf.flip();
+ if (rand.nextBoolean()) {
+ ByteBuffer[] bufs = new ByteBuffer[1];
+ bufs[0] = buf;
+ fc.write(bufs);
+ } else {
+ fc.write(buf);
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ final int nThreads = 16;
+ final int writes = 1000;
+ final File file = File.createTempFile("foo", null);
+ try {
+ ExecutorService pool = Executors.newFixedThreadPool(nThreads);
+ for (int i = 0; i < nThreads; i++)
+ pool.execute(new Runnable() { public void run() {
+ try {
+ // randomly choose FileChannel or OutputStream
+ if (rand.nextBoolean()) {
+ try (FileChannel fc = newFileChannel(file)) {
+ for (int j=0; j<writes; j++) write(fc, 'x');
+ }
+ } else {
+ try (OutputStream out = newOutputStream(file)) {
+ for (int j = 0; j<writes; j++) out.write('x');
+ }
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }});
+ pool.shutdown();
+ pool.awaitTermination(1L, TimeUnit.MINUTES);
+ if (file.length() != (long) (nThreads * writes))
+ throw new RuntimeException("File not expected length");
+ } finally {
+ file.delete();
+ }
+ }
+}
--- a/jdk/test/java/nio/channels/FileChannel/Lock.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/Lock.java Tue Dec 07 13:29:20 2010 +0000
@@ -22,13 +22,13 @@
*/
/* @test
- * @bug 4429043 4493595 6332756
+ * @bug 4429043 4493595 6332756 6709457
* @summary The FileChannel file locking
*/
import java.io.*;
import java.nio.channels.*;
-import java.nio.*;
+import static java.nio.file.StandardOpenOption.*;
/**
* Testing FileChannel's lock method.
@@ -55,6 +55,7 @@
test2(blah, true);
test2(blah, false);
test3(blah);
+ test4(blah);
blah.delete();
}
@@ -163,6 +164,24 @@
fc1.close();
fc2.close();
}
+
+ /**
+ * Test file locking when file is opened for append
+ */
+ static void test4(File blah) throws Exception {
+ try (FileChannel fc = new FileOutputStream(blah, true).getChannel()) {
+ fc.tryLock().release();
+ fc.tryLock(0L, 1L, false).release();
+ fc.lock().release();
+ fc.lock(0L, 1L, false).release();
+ }
+ try (FileChannel fc = FileChannel.open(blah.toPath(), APPEND)) {
+ fc.tryLock().release();
+ fc.tryLock(0L, 1L, false).release();
+ fc.lock().release();
+ fc.lock(0L, 1L, false).release();
+ }
+ }
}
class MadWriter {
--- a/jdk/test/java/nio/channels/FileChannel/Truncate.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/Truncate.java Tue Dec 07 13:29:20 2010 +0000
@@ -22,14 +22,14 @@
*/
/* @test
- * @bug 6191269
+ * @bug 6191269 6709457
* @summary Test truncate method of FileChannel
*/
import java.io.*;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.*;
+import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import static java.nio.file.StandardOpenOption.*;
import java.util.Random;
@@ -38,43 +38,79 @@
*/
public class Truncate {
-
- private static Random generator = new Random();
-
- private static File blah;
+ private static final Random generator = new Random();
public static void main(String[] args) throws Exception {
- blah = File.createTempFile("blah", null);
+ File blah = File.createTempFile("blah", null);
blah.deleteOnExit();
+ try {
+ basicTest(blah);
+ appendTest(blah);
+ } finally {
+ blah.delete();
+ }
+ }
+
+ /**
+ * Basic test of asserts in truncate's specification.
+ */
+ static void basicTest(File blah) throws Exception {
for(int i=0; i<100; i++) {
long testSize = generator.nextInt(1000) + 10;
initTestFile(blah, testSize);
- RandomAccessFile fis = new RandomAccessFile(blah, "rw");
- FileChannel c = fis.getChannel();
- if (c.size() != testSize)
- throw new RuntimeException("Size failed");
+ FileChannel fc = (i < 50) ?
+ new RandomAccessFile(blah, "rw").getChannel() :
+ FileChannel.open(blah.toPath(), READ, WRITE);
+ try (fc) {
+ if (fc.size() != testSize)
+ throw new RuntimeException("Size failed");
+
+ long position = generator.nextInt((int)testSize);
+ fc.position(position);
+
+ long newSize = generator.nextInt((int)testSize);
+ fc.truncate(newSize);
- long position = generator.nextInt((int)testSize);
- c.position(position);
+ if (fc.size() != newSize)
+ throw new RuntimeException("Truncate failed");
- long newSize = generator.nextInt((int)testSize);
- c.truncate(newSize);
+ if (position > newSize) {
+ if (fc.position() != newSize)
+ throw new RuntimeException("Position greater than size");
+ } else {
+ if (fc.position() != position)
+ throw new RuntimeException("Truncate changed position");
+ };
+ }
+ }
+ }
- if (c.size() != newSize)
- throw new RuntimeException("Truncate failed");
+ /**
+ * Test behavior of truncate method when file is opened for append
+ */
+ static void appendTest(File blah) throws Exception {
+ for (int i=0; i<10; i++) {
+ long testSize = generator.nextInt(1000) + 10;
+ initTestFile(blah, testSize);
+ FileChannel fc = (i < 5) ?
+ new FileOutputStream(blah, true).getChannel() :
+ FileChannel.open(blah.toPath(), APPEND);
+ try (fc) {
+ // truncate file
+ long newSize = generator.nextInt((int)testSize);
+ fc.truncate(newSize);
+ if (fc.size() != newSize)
+ throw new RuntimeException("Truncate failed");
- if (position > newSize) {
- if (c.position() != newSize)
- throw new RuntimeException("Position greater than size");
- } else {
- if (c.position() != position)
- throw new RuntimeException("Truncate changed position");
+ // write one byte
+ ByteBuffer buf = ByteBuffer.allocate(1);
+ buf.put((byte)'x');
+ buf.flip();
+ fc.write(buf);
+ if (fc.size() != (newSize+1))
+ throw new RuntimeException("Unexpected size");
}
-
- c.close();
- fis.close();
}
- blah.delete();
}
/**
--- a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Tue Dec 07 13:29:20 2010 +0000
@@ -136,5 +136,5 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class Fun {abstract void f() throws Throwable;}
+ private abstract static class Fun {abstract void f() throws Throwable;}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -79,9 +79,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -79,9 +79,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile MapCheck.java
+ * @compile -source 1.5 MapCheck.java
* @run main/timeout=240 MapCheck
* @summary Times and checks basic map operations
*/
@@ -64,7 +64,7 @@
if (args.length > 0) {
try {
mapClass = Class.forName(args[0]);
- } catch(ClassNotFoundException e) {
+ } catch (ClassNotFoundException e) {
throw new RuntimeException("Class " + args[0] + " not found.");
}
}
@@ -102,7 +102,7 @@
try {
Map m = (Map)cl.newInstance();
return m;
- } catch(Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Can't instantiate " + cl + ": " + e);
}
}
@@ -139,7 +139,7 @@
}
}
timer.finish();
- reallyAssert (sum == expect * iters);
+ reallyAssert(sum == expect * iters);
}
static void t2(String nm, int n, Map s, Object[] key, int expect) {
@@ -149,7 +149,7 @@
if (s.remove(key[i]) != null) ++sum;
}
timer.finish();
- reallyAssert (sum == expect);
+ reallyAssert(sum == expect);
}
static void t3(String nm, int n, Map s, Object[] key, int expect) {
@@ -159,7 +159,7 @@
if (s.put(key[i], absent[i & absentMask]) == null) ++sum;
}
timer.finish();
- reallyAssert (sum == expect);
+ reallyAssert(sum == expect);
}
static void t4(String nm, int n, Map s, Object[] key, int expect) {
@@ -169,7 +169,7 @@
if (s.containsKey(key[i])) ++sum;
}
timer.finish();
- reallyAssert (sum == expect);
+ reallyAssert(sum == expect);
}
static void t5(String nm, int n, Map s, Object[] key, int expect) {
@@ -179,7 +179,7 @@
if (s.remove(key[i]) != null) ++sum;
}
timer.finish();
- reallyAssert (sum == expect);
+ reallyAssert(sum == expect);
}
static void t6(String nm, int n, Map s, Object[] k1, Object[] k2) {
@@ -190,7 +190,7 @@
if (s.get(k2[i & absentMask]) != null) ++sum;
}
timer.finish();
- reallyAssert (sum == n);
+ reallyAssert(sum == n);
}
static void t7(String nm, int n, Map s, Object[] k1, Object[] k2) {
@@ -201,7 +201,7 @@
if (s.containsKey(k2[i & absentMask])) ++sum;
}
timer.finish();
- reallyAssert (sum == n);
+ reallyAssert(sum == n);
}
static void t8(String nm, int n, Map s, Object[] key, int expect) {
@@ -211,7 +211,7 @@
if (s.get(key[i]) != null) ++sum;
}
timer.finish();
- reallyAssert (sum == expect);
+ reallyAssert(sum == expect);
}
@@ -223,7 +223,7 @@
for (int i = 0; i < absentSize; i += step)
if (s.containsValue(absent[i])) ++sum;
timer.finish();
- reallyAssert (sum != 0);
+ reallyAssert(sum != 0);
}
@@ -235,7 +235,7 @@
if (ks.contains(key[i])) ++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
@@ -243,37 +243,37 @@
int sum = 0;
timer.start("Iter Key ", size);
for (Iterator it = s.keySet().iterator(); it.hasNext(); ) {
- if(it.next() != MISSING)
+ if (it.next() != MISSING)
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
static void ittest2(Map s, int size) {
int sum = 0;
timer.start("Iter Value ", size);
for (Iterator it = s.values().iterator(); it.hasNext(); ) {
- if(it.next() != MISSING)
+ if (it.next() != MISSING)
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
static void ittest3(Map s, int size) {
int sum = 0;
timer.start("Iter Entry ", size);
for (Iterator it = s.entrySet().iterator(); it.hasNext(); ) {
- if(it.next() != MISSING)
+ if (it.next() != MISSING)
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
static void ittest4(Map s, int size, int pos) {
IdentityHashMap seen = new IdentityHashMap(size);
- reallyAssert (s.size() == size);
+ reallyAssert(s.size() == size);
int sum = 0;
timer.start("Iter XEntry ", size);
Iterator it = s.entrySet().iterator();
@@ -287,9 +287,9 @@
if (x != MISSING)
++sum;
}
- reallyAssert (s.containsKey(k));
+ reallyAssert(s.containsKey(k));
it.remove();
- reallyAssert (!s.containsKey(k));
+ reallyAssert(!s.containsKey(k));
while (it.hasNext()) {
Map.Entry x = (Map.Entry)(it.next());
Object k2 = x.getKey();
@@ -298,12 +298,12 @@
++sum;
}
- reallyAssert (s.size() == size-1);
+ reallyAssert(s.size() == size-1);
s.put(k, v);
- reallyAssert (seen.size() == size);
+ reallyAssert(seen.size() == size);
timer.finish();
- reallyAssert (sum == size);
- reallyAssert (s.size() == size);
+ reallyAssert(sum == size);
+ reallyAssert(s.size() == size);
}
@@ -324,7 +324,7 @@
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
static void entest2(Hashtable ht, int size) {
@@ -335,7 +335,7 @@
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
@@ -349,7 +349,7 @@
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
static void entest4(Hashtable ht, int size) {
@@ -361,7 +361,7 @@
++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
}
static void entest(Map s, int size) {
@@ -409,13 +409,13 @@
timer.start("Iter Equals ", size * 2);
boolean eqt = s2.equals(s) && s.equals(s2);
- reallyAssert (eqt);
+ reallyAssert(eqt);
timer.finish();
timer.start("Iter HashCode ", size * 2);
int shc = s.hashCode();
int s2hc = s2.hashCode();
- reallyAssert (shc == s2hc);
+ reallyAssert(shc == s2hc);
timer.finish();
timer.start("Put (present) ", size);
@@ -430,7 +430,7 @@
if (es2.contains(entry)) ++sum;
}
timer.finish();
- reallyAssert (sum == size);
+ reallyAssert(sum == size);
t6("Get ", size, s2, key, absent);
@@ -438,13 +438,13 @@
s2.put(key[size-1], absent[0]);
timer.start("Iter Equals ", size * 2);
eqt = s2.equals(s) && s.equals(s2);
- reallyAssert (!eqt);
+ reallyAssert(!eqt);
timer.finish();
timer.start("Iter HashCode ", size * 2);
int s1h = s.hashCode();
int s2h = s2.hashCode();
- reallyAssert (s1h != s2h);
+ reallyAssert(s1h != s2h);
timer.finish();
s2.put(key[size-1], hold);
@@ -455,12 +455,12 @@
es.remove(s2i.next());
timer.finish();
- reallyAssert (s.isEmpty());
+ reallyAssert(s.isEmpty());
timer.start("Clear ", size);
s2.clear();
timer.finish();
- reallyAssert (s2.isEmpty() && s.isEmpty());
+ reallyAssert(s2.isEmpty() && s.isEmpty());
}
static void stest(Map s, int size) throws Exception {
@@ -489,7 +489,7 @@
System.out.print(time + "ms");
if (s instanceof IdentityHashMap) return;
- reallyAssert (s.equals(m));
+ reallyAssert(s.equals(m));
}
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile MapLoops.java
+ * @compile -source 1.5 MapLoops.java
* @run main/timeout=1600 MapLoops
* @summary Exercise multithreaded maps, by default ConcurrentHashMap.
* Multithreaded hash table test. Each thread does a random walk
@@ -225,7 +225,7 @@
barrier.await();
}
catch (Throwable throwable) {
- synchronized(System.err) {
+ synchronized (System.err) {
System.err.println("--------------------------------");
throwable.printStackTrace();
}
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -79,9 +79,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java Tue Dec 07 13:29:20 2010 +0000
@@ -66,7 +66,7 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class CheckedThread extends Thread {
+ private abstract static class CheckedThread extends Thread {
public abstract void realRun() throws Throwable;
public void run() {
try { realRun(); } catch (Throwable t) { unexpected(t); }}}
--- a/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java Tue Dec 07 13:29:20 2010 +0000
@@ -125,7 +125,7 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class CheckedThread extends Thread {
+ private abstract static class CheckedThread extends Thread {
public abstract void realRun() throws Throwable;
public void run() {
try { realRun(); } catch (Throwable t) { unexpected(t); }}}
--- a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Tue Dec 07 13:29:20 2010 +0000
@@ -83,7 +83,7 @@
//----------------------------------------------------------------
// Convenience methods for creating threads that call CyclicBarrier.await
//----------------------------------------------------------------
- private static abstract class Awaiter extends Thread {
+ private abstract static class Awaiter extends Thread {
static AtomicInteger count = new AtomicInteger(1);
{
@@ -417,14 +417,14 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- static abstract class Fun { abstract void f() throws Throwable; }
+ abstract static class Fun { abstract void f() throws Throwable; }
private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
for (Fun f : fs)
try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
catch (Throwable t) {
if (k.isAssignableFrom(t.getClass())) pass();
else unexpected(t);}}
- private static abstract class CheckedThread extends Thread {
+ private abstract static class CheckedThread extends Thread {
abstract void realRun() throws Throwable;
public void run() {
try {realRun();} catch (Throwable t) {unexpected(t);}}}
--- a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile ExchangeLoops.java
+ * @compile -source 1.5 ExchangeLoops.java
* @run main/timeout=720 ExchangeLoops
* @summary checks to make sure a pipeline of exchangers passes data.
*/
@@ -78,9 +78,9 @@
final Exchanger<Int> right;
final CyclicBarrier barrier;
volatile int result;
- Stage (Exchanger<Int> left,
- Exchanger<Int> right,
- CyclicBarrier b, int iters) {
+ Stage(Exchanger<Int> left,
+ Exchanger<Int> right,
+ CyclicBarrier b, int iters) {
this.left = left;
this.right = right;
barrier = b;
--- a/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -78,9 +78,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4965960
- * @compile ExecutorCompletionServiceLoops.java
+ * @compile -source 1.5 ExecutorCompletionServiceLoops.java
* @run main/timeout=3600 ExecutorCompletionServiceLoops
* @summary Exercise ExecutorCompletionServiceLoops
*/
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -78,9 +78,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/Executors/Throws.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/Executors/Throws.java Tue Dec 07 13:29:20 2010 +0000
@@ -122,7 +122,7 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class Fun {abstract void f() throws Throwable;}
+ private abstract static class Fun {abstract void f() throws Throwable;}
static void THROWS(Class<? extends Throwable> k, Fun... fs) {
for (Fun f : fs)
try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
--- a/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Tue Dec 07 13:29:20 2010 +0000
@@ -87,7 +87,7 @@
* A helper class with a method to wait for a notification.
*
* The notification is received via the
- * <code>sendNotification</code> method.
+ * {@code sendNotification} method.
*/
static class NotificationReceiver {
/** Has the notifiee been notified? */
--- a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile CancelledFutureLoops.java
+ * @compile -source 1.5 CancelledFutureLoops.java
* @run main/timeout=2000 CancelledFutureLoops
* @summary Checks for responsiveness of futures to cancellation.
* Runs under the assumption that ITERS computations require more than
@@ -64,10 +64,10 @@
try {
new FutureLoop(i).test();
}
- catch(BrokenBarrierException bb) {
+ catch (BrokenBarrierException bb) {
// OK; ignore
}
- catch(ExecutionException ee) {
+ catch (ExecutionException ee) {
// OK; ignore
}
Thread.sleep(TIMEOUT);
--- a/jdk/test/java/util/concurrent/FutureTask/Customized.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/FutureTask/Customized.java Tue Dec 07 13:29:20 2010 +0000
@@ -203,7 +203,7 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class Fun {abstract void f() throws Throwable;}
+ private abstract static class Fun {abstract void f() throws Throwable;}
static void THROWS(Class<? extends Throwable> k, Fun... fs) {
for (Fun f : fs)
try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
--- a/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -78,9 +78,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Tue Dec 07 13:29:20 2010 +0000
@@ -161,11 +161,8 @@
if (x == null ? y == null : x.equals(y)) pass();
else fail(x + " not equal to " + y);}
public static void main(String[] args) throws Throwable {
- Class<?> k = new Object(){}.getClass().getEnclosingClass();
- try {k.getMethod("instanceMain",String[].class)
- .invoke( k.newInstance(), (Object) args);}
- catch (Throwable e) {throw e.getCause();}}
- public void instanceMain(String[] args) throws Throwable {
+ new DelayOverflow().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
try {test(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java Tue Dec 07 13:29:20 2010 +0000
@@ -36,9 +36,9 @@
import static java.util.concurrent.TimeUnit.*;
public class ConfigChanges {
- final static ThreadGroup tg = new ThreadGroup("pool");
+ static final ThreadGroup tg = new ThreadGroup("pool");
- final static Random rnd = new Random();
+ static final Random rnd = new Random();
static void report(ThreadPoolExecutor tpe) {
try {
@@ -241,7 +241,7 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class Fun {abstract void f() throws Throwable;}
+ private abstract static class Fun {abstract void f() throws Throwable;}
static void THROWS(Class<? extends Throwable> k, Fun... fs) {
for (Fun f : fs)
try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Tue Dec 07 13:29:20 2010 +0000
@@ -43,7 +43,7 @@
private static class CustomTask<V> extends FutureTask<V> {
- public final static AtomicInteger births = new AtomicInteger(0);
+ public static final AtomicInteger births = new AtomicInteger(0);
CustomTask(Callable<V> c) { super(c); births.getAndIncrement(); }
CustomTask(Runnable r, V v) { super(r, v); births.getAndIncrement(); }
}
@@ -63,7 +63,7 @@
}
private static class CustomSTPE extends ScheduledThreadPoolExecutor {
- public final static AtomicInteger decorations = new AtomicInteger(0);
+ public static final AtomicInteger decorations = new AtomicInteger(0);
CustomSTPE() {
super(threadCount);
}
@@ -89,7 +89,7 @@
return count;
}
- private final static int threadCount = 10;
+ private static final int threadCount = 10;
public static void main(String[] args) throws Throwable {
CustomTPE tpe = new CustomTPE();
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java Tue Dec 07 13:29:20 2010 +0000
@@ -37,10 +37,10 @@
// We get intermittent ClassCastException if greater than 1
// because of calls to compareTo
- private final static int concurrency = 2;
+ private static final int concurrency = 2;
// Record when tasks are done
- public final static CountDownLatch done = new CountDownLatch(concurrency);
+ public static final CountDownLatch done = new CountDownLatch(concurrency);
public static void realMain(String... args) throws InterruptedException {
// our tickle service
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java Tue Dec 07 13:29:20 2010 +0000
@@ -40,7 +40,7 @@
static volatile boolean quit = false;
static volatile ThreadPoolExecutor pool = null;
- final static Runnable sleeper = new Runnable() { public void run() {
+ static final Runnable sleeper = new Runnable() { public void run() {
final long ONE_HOUR = 1000L * 60L * 60L;
try { Thread.sleep(ONE_HOUR); }
catch (InterruptedException ie) {}
@@ -81,14 +81,14 @@
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
- private static abstract class Fun {abstract void f() throws Throwable;}
+ private abstract static class Fun {abstract void f() throws Throwable;}
static void THROWS(Class<? extends Throwable> k, Fun... fs) {
for (Fun f : fs)
try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
catch (Throwable t) {
if (k.isAssignableFrom(t.getClass())) pass();
else unexpected(t);}}
- private static abstract class CheckedThread extends Thread {
+ private abstract static class CheckedThread extends Thread {
abstract void realRun() throws Throwable;
public void run() {
try {realRun();} catch (Throwable t) {unexpected(t);}}}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java Tue Dec 07 13:29:20 2010 +0000
@@ -35,7 +35,7 @@
import java.util.concurrent.atomic.*;
public class ThrowingTasks {
- final static Random rnd = new Random();
+ static final Random rnd = new Random();
@SuppressWarnings("serial")
static class UncaughtExceptions
@@ -65,16 +65,16 @@
}
}
- final static UncaughtExceptions uncaughtExceptions
+ static final UncaughtExceptions uncaughtExceptions
= new UncaughtExceptions();
- final static UncaughtExceptionsTable uncaughtExceptionsTable
+ static final UncaughtExceptionsTable uncaughtExceptionsTable
= new UncaughtExceptionsTable();
- final static AtomicLong totalUncaughtExceptions
+ static final AtomicLong totalUncaughtExceptions
= new AtomicLong(0);
- final static CountDownLatch uncaughtExceptionsLatch
+ static final CountDownLatch uncaughtExceptionsLatch
= new CountDownLatch(24);
- final static Thread.UncaughtExceptionHandler handler
+ static final Thread.UncaughtExceptionHandler handler
= new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
check(! Thread.currentThread().isInterrupted());
@@ -84,19 +84,19 @@
uncaughtExceptionsLatch.countDown();
}};
- final static ThreadGroup tg = new ThreadGroup("Flaky");
+ static final ThreadGroup tg = new ThreadGroup("Flaky");
- final static ThreadFactory tf = new ThreadFactory() {
+ static final ThreadFactory tf = new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(tg, r);
t.setUncaughtExceptionHandler(handler);
return t;
}};
- final static RuntimeException rte = new RuntimeException();
- final static Error error = new Error();
- final static Throwable weird = new Throwable();
- final static Exception checkedException = new Exception();
+ static final RuntimeException rte = new RuntimeException();
+ static final Error error = new Error();
+ static final Throwable weird = new Throwable();
+ static final Exception checkedException = new Exception();
static class Thrower implements Runnable {
Throwable t;
@@ -105,13 +105,13 @@
public void run() { if (t != null) Thread.currentThread().stop(t); }
}
- final static Thrower noThrower = new Thrower(null);
- final static Thrower rteThrower = new Thrower(rte);
- final static Thrower errorThrower = new Thrower(error);
- final static Thrower weirdThrower = new Thrower(weird);
- final static Thrower checkedThrower = new Thrower(checkedException);
+ static final Thrower noThrower = new Thrower(null);
+ static final Thrower rteThrower = new Thrower(rte);
+ static final Thrower errorThrower = new Thrower(error);
+ static final Thrower weirdThrower = new Thrower(weird);
+ static final Thrower checkedThrower = new Thrower(checkedException);
- final static List<Thrower> throwers = Arrays.asList(
+ static final List<Thrower> throwers = Arrays.asList(
noThrower, rteThrower, errorThrower, weirdThrower, checkedThrower);
static class Flaky implements Runnable {
--- a/jdk/test/java/util/concurrent/atomic/VMSupportsCS8.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/atomic/VMSupportsCS8.java Tue Dec 07 13:29:20 2010 +0000
@@ -24,6 +24,8 @@
/*
* @test
* @bug 4992443 4994819
+ * @compile -source 1.5 VMSupportsCS8.java
+ * @run main VMSupportsCS8
* @summary Checks that the value of VMSupportsCS8 matches system properties.
*/
--- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Tue Dec 07 13:29:20 2010 +0000
@@ -75,10 +75,10 @@
catch (Throwable t) { checkThrowable(t); }
}
- try { check (! m.tryLock()); }
+ try { check(! m.tryLock()); }
catch (Throwable t) { checkThrowable(t); }
- try { check (! m.tryLock(1, TimeUnit.MICROSECONDS)); }
+ try { check(! m.tryLock(1, TimeUnit.MICROSECONDS)); }
catch (Throwable t) { checkThrowable(t); }
m.unlock();
--- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Tue Dec 07 13:29:20 2010 +0000
@@ -64,7 +64,7 @@
return outputOf(new InputStreamReader(is, "UTF-8"));
}
- final static ExecutorService drainers = Executors.newFixedThreadPool(12);
+ static final ExecutorService drainers = Executors.newFixedThreadPool(12);
static Future<String> futureOutputOf(final InputStream is) {
return drainers.submit(
new Callable<String>() { public String call() throws IOException {
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile CancelledLockLoops.java
+ * @compile -source 1.5 CancelledLockLoops.java
* @run main/timeout=2800 CancelledLockLoops
* @summary tests lockInterruptibly.
* Checks for responsiveness of locks to interrupts. Runs under that
@@ -64,7 +64,7 @@
try {
new ReentrantLockLoop(i).test();
}
- catch(BrokenBarrierException bb) {
+ catch (BrokenBarrierException bb) {
// OK, ignore
}
Thread.sleep(TIMEOUT);
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile LockOncePerThreadLoops.java
+ * @compile -source 1.5 LockOncePerThreadLoops.java
* @run main/timeout=15000 LockOncePerThreadLoops
* @summary Checks for missed signals by locking and unlocking each of an array of locks once per thread
*/
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -78,9 +78,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile SimpleReentrantLockLoops.java
+ * @compile -source 1.5 SimpleReentrantLockLoops.java
* @run main/timeout=4500 SimpleReentrantLockLoops
* @summary multiple threads using a single lock
*/
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,6 +34,8 @@
/*
* @test
* @bug 4486658 5031862
+ * @compile -source 1.5 TimeoutLockLoops.java
+ * @run main TimeoutLockLoops
* @summary Checks for responsiveness of locks to timeouts.
* Runs under the assumption that ITERS computations require more than
* TIMEOUT msecs to complete, which seems to be a safe assumption for
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java Tue Dec 07 13:29:20 2010 +0000
@@ -45,7 +45,7 @@
Thread thread = new Thread() { public void run() {
try {
- check (! lock.writeLock().tryLock(0, TimeUnit.DAYS));
+ check(! lock.writeLock().tryLock(0, TimeUnit.DAYS));
lock.readLock().lock();
lock.readLock().unlock();
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Tue Dec 07 13:29:20 2010 +0000
@@ -78,9 +78,9 @@
* Basically same as java.util.Random.
*/
public static class SimpleRandom {
- private final static long multiplier = 0x5DEECE66DL;
- private final static long addend = 0xBL;
- private final static long mask = (1L << 48) - 1;
+ private static final long multiplier = 0x5DEECE66DL;
+ private static final long addend = 0xBL;
+ private static final long mask = (1L << 48) - 1;
static final AtomicLong seq = new AtomicLong(1);
private long seed = System.nanoTime() + seq.getAndIncrement();
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Tue Dec 07 13:29:20 2010 +0000
@@ -34,7 +34,7 @@
/*
* @test
* @bug 4486658
- * @compile MapLoops.java
+ * @compile -source 1.5 MapLoops.java
* @run main/timeout=4700 MapLoops
* @summary Exercise multithreaded maps, by default ConcurrentHashMap.
* Multithreaded hash table test. Each thread does a random walk
@@ -65,7 +65,7 @@
if (args.length > 0) {
try {
mapClass = Class.forName(args[0]);
- } catch(ClassNotFoundException e) {
+ } catch (ClassNotFoundException e) {
throw new RuntimeException("Class " + args[0] + " not found.");
}
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Tue Dec 07 13:29:20 2010 +0000
@@ -57,21 +57,33 @@
}
public int size() {
- rwl.readLock().lock(); try {return m.size();} finally { rwl.readLock().unlock(); }
+ rwl.readLock().lock();
+ try { return m.size(); }
+ finally { rwl.readLock().unlock(); }
}
- public boolean isEmpty(){
- rwl.readLock().lock(); try {return m.isEmpty();} finally { rwl.readLock().unlock(); }
+
+ public boolean isEmpty() {
+ rwl.readLock().lock();
+ try { return m.isEmpty(); }
+ finally { rwl.readLock().unlock(); }
}
public Object get(Object key) {
- rwl.readLock().lock(); try {return m.get(key);} finally { rwl.readLock().unlock(); }
+ rwl.readLock().lock();
+ try { return m.get(key); }
+ finally { rwl.readLock().unlock(); }
}
public boolean containsKey(Object key) {
- rwl.readLock().lock(); try {return m.containsKey(key);} finally { rwl.readLock().unlock(); }
+ rwl.readLock().lock();
+ try { return m.containsKey(key); }
+ finally { rwl.readLock().unlock(); }
}
- public boolean containsValue(Object value){
- rwl.readLock().lock(); try {return m.containsValue(value);} finally { rwl.readLock().unlock(); }
+
+ public boolean containsValue(Object value) {
+ rwl.readLock().lock();
+ try { return m.containsValue(value); }
+ finally { rwl.readLock().unlock(); }
}
@@ -88,28 +100,45 @@
}
public boolean equals(Object o) {
- rwl.readLock().lock(); try {return m.equals(o);} finally { rwl.readLock().unlock(); }
+ rwl.readLock().lock();
+ try { return m.equals(o); }
+ finally { rwl.readLock().unlock(); }
}
+
public int hashCode() {
- rwl.readLock().lock(); try {return m.hashCode();} finally { rwl.readLock().unlock(); }
+ rwl.readLock().lock();
+ try { return m.hashCode(); }
+ finally { rwl.readLock().unlock(); }
}
+
public String toString() {
- rwl.readLock().lock(); try {return m.toString();} finally { rwl.readLock().unlock(); }
+ rwl.readLock().lock();
+ try { return m.toString(); }
+ finally { rwl.readLock().unlock(); }
}
-
+ public Object put(Object key, Object value) {
+ rwl.writeLock().lock();
+ try { return m.put(key, value); }
+ finally { rwl.writeLock().unlock(); }
+ }
- public Object put(Object key, Object value) {
- rwl.writeLock().lock(); try {return m.put(key, value);} finally { rwl.writeLock().unlock(); }
- }
public Object remove(Object key) {
- rwl.writeLock().lock(); try {return m.remove(key);} finally { rwl.writeLock().unlock(); }
+ rwl.writeLock().lock();
+ try { return m.remove(key); }
+ finally { rwl.writeLock().unlock(); }
}
+
public void putAll(Map map) {
- rwl.writeLock().lock(); try {m.putAll(map);} finally { rwl.writeLock().unlock(); }
+ rwl.writeLock().lock();
+ try { m.putAll(map); }
+ finally { rwl.writeLock().unlock(); }
}
+
public void clear() {
- rwl.writeLock().lock(); try {m.clear();} finally { rwl.writeLock().unlock(); }
+ rwl.writeLock().lock();
+ try { m.clear(); }
+ finally { rwl.writeLock().unlock(); }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/GroupLayout/6613904/bug6613904.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6613904
+ * @summary javax.swing.GroupLayout.createParallelGroup(..) doesn't throw IllegalArgumentException for null arg
+ * @author Pavel Porvatov
+ */
+
+import javax.swing.*;
+
+public class bug6613904 {
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ GroupLayout groupLayout = new GroupLayout(new JPanel());
+
+ try {
+ groupLayout.createParallelGroup(null);
+
+ throw new RuntimeException("groupLayout.createParallelGroup(null) doesn't throw IAE");
+ } catch (IllegalArgumentException e) {
+ // Ok
+ }
+
+ try {
+ groupLayout.createParallelGroup(null, true);
+
+ throw new RuntimeException("groupLayout.createParallelGroup(null, true) doesn't throw IAE");
+ } catch (IllegalArgumentException e) {
+ // Ok
+ }
+
+ try {
+ groupLayout.createParallelGroup(null, false);
+
+ throw new RuntimeException("groupLayout.createParallelGroup(null, false) doesn't throw IAE");
+ } catch (IllegalArgumentException e) {
+ // Ok
+ }
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/6987844/bug6987844.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6987844
+ * @summary Incorrect width of JComboBox drop down
+ * @author Alexander Potochkin
+ * @run main bug6987844
+ */
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.InputEvent;
+
+public class bug6987844 {
+ static JMenu menu1;
+ static JMenu menu2;
+
+ public static void main(String... args) throws Exception {
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ Robot robot = new Robot();
+ robot.setAutoDelay(200);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JMenuBar bar = new JMenuBar();
+ menu1 = new JMenu("Menu1");
+ menu1.add(new JMenuItem("item"));
+ bar.add(menu1);
+ menu2 = new JMenu("Menu2");
+ menu2.add(new JMenuItem("item"));
+ menu2.add(new JMenuItem("item"));
+ bar.add(menu2);
+
+ frame.setJMenuBar(bar);
+ frame.pack();
+
+ frame.setVisible(true);
+ }
+ });
+ toolkit.realSync();
+ Point point1 = menu1.getLocationOnScreen();
+ Point point2 = menu2.getLocationOnScreen();
+
+ robot.mouseMove(point1.x + 1, point1.y + 1);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+ robot.mouseMove(point2.x + 1, point2.y + 1);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+ robot.mouseMove(point1.x + 1, point1.y + 1);
+ toolkit.realSync();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ Dimension popupSize1 = menu1.getPopupMenu().getSize();
+ Dimension popupSize2 = menu2.getPopupMenu().getSize();
+ if (popupSize1.equals(popupSize2)) {
+ throw new RuntimeException("First popup unexpedetly changed its size");
+ }
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/DefaultHighlighter/6771184/bug6771184.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6771184
+ * @summary Some methods in text package don't throw BadLocationException when expected
+ * @author Pavel Porvatov
+ */
+
+import javax.swing.*;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Highlighter;
+import javax.swing.text.JTextComponent;
+import java.awt.*;
+
+public class bug6771184 {
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ JTextArea textArea = new JTextArea("Tested string");
+
+ Highlighter highlighter = textArea.getHighlighter();
+ Highlighter.HighlightPainter myPainter = new Highlighter.HighlightPainter() {
+ public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
+ }
+ };
+
+ int negativeTestedData[][] = {{50, 0},
+ {-1, 1},
+ {-5, -4},
+ {Integer.MAX_VALUE, Integer.MIN_VALUE},
+ {Integer.MIN_VALUE, Integer.MAX_VALUE},
+ {Integer.MIN_VALUE, Integer.MIN_VALUE}};
+
+ for (int[] data : negativeTestedData) {
+ try {
+ highlighter.addHighlight(data[0], data[1], myPainter);
+
+ throw new RuntimeException("Method addHighlight() does not throw BadLocationException for (" +
+ data[0] + ", " + data[1] + ") ");
+ } catch (BadLocationException e) {
+ // Ok
+ }
+
+ Object objRef;
+
+ try {
+ objRef = highlighter.addHighlight(0, 1, myPainter);
+ } catch (BadLocationException e) {
+ throw new RuntimeException("highlighter.addHighlight(0, 1, myPainter) throws exception", e);
+ }
+
+ try {
+ highlighter.changeHighlight(objRef, data[0], data[1]);
+
+ throw new RuntimeException("Method changeHighlight() does not throw BadLocationException for (" +
+ data[0] + ", " + data[1] + ") ");
+ } catch (BadLocationException e) {
+ // Ok
+ }
+ }
+ }
+ });
+ }
+}
--- a/jdk/test/sun/java2d/GdiRendering/InsetClipping.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/java2d/GdiRendering/InsetClipping.java Tue Dec 07 13:29:20 2010 +0000
@@ -85,6 +85,9 @@
} catch (Exception e) {}
}
try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ex) {}
+ try {
Robot robot = new Robot();
Point clientLoc = clipTest.getLocationOnScreen();
Insets insets = clipTest.getInsets();
--- a/jdk/test/sun/java2d/SunGraphics2D/DrawImageBilinear.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/java2d/SunGraphics2D/DrawImageBilinear.java Tue Dec 07 13:29:20 2010 +0000
@@ -56,6 +56,9 @@
private VolatileImage vimg;
private static volatile BufferedImage capture;
private static void doCapture(Component test) {
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ex) {}
// Grab the screen region
try {
Robot robot = new Robot();
--- a/jdk/test/sun/java2d/SunGraphics2D/SourceClippingBlitTest/SourceClippingBlitTest.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/java2d/SunGraphics2D/SourceClippingBlitTest/SourceClippingBlitTest.java Tue Dec 07 13:29:20 2010 +0000
@@ -204,6 +204,9 @@
int w = getWidth();
int h = getHeight();
Toolkit.getDefaultToolkit().sync();
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ex) {}
Point p = getLocationOnScreen();
grabbedBI = robot.createScreenCapture(new Rectangle(p.x, p.y, w, h));
--- a/jdk/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/java2d/X11SurfaceData/SharedMemoryPixmapsTest/SharedMemoryPixmapsTest.java Tue Dec 07 13:29:20 2010 +0000
@@ -120,6 +120,9 @@
}
private boolean testRendering() throws RuntimeException {
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ex) {}
Robot r = null;
try {
r = new Robot();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/tools/ktarg.sh Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 7002036
+# @summary ktab return code changes on a error case
+# @run shell ktarg.sh
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+OS=`uname -s`
+case "$OS" in
+ CYGWIN* )
+ FS="/"
+ ;;
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ echo "Unsupported system!"
+ exit 0;
+ ;;
+esac
+
+KEYTAB=ktarg.tmp
+
+rm $KEYTAB 2> /dev/null
+KTAB="${TESTJAVA}${FS}bin${FS}ktab -k $KEYTAB"
+
+$KTAB -a me@LOCAL mine || exit 1
+
+$KTAB -hello
+if [ $? = 0 ]; then exit 2; fi
+
+$KTAB
+if [ $? = 0 ]; then exit 3; fi
+
+exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/InvalidBitString.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Validation of signatures succeed when it should fail
+ * @bug 6896700
+ */
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.PublicKey;
+import java.security.SignatureException;
+
+public class InvalidBitString {
+
+ // Test cert for CN=CA
+ static String signerCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIBtDCCAR2gAwIBAgIEemxRHjANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" +
+ "MDMwODA2MjlaFw0xMDA5MDEwODA2MjlaMA0xCzAJBgNVBAMTAkNBMIGfMA0GCSqGSIb3DQEBAQUA\n" +
+ "A4GNADCBiQKBgQCp2G7pGwMOw4oM7zFFeRKrByuPLNAXClGsh+itdRiOeUgEby6OB9IAgXm93086\n" +
+ "Z9dWCfRYbzJbDRSnUE7FS1iQsIRIeOEuFMIMogcBK+sOf364ONwMXsI4gtYVmxn4BaaajVWt6C/g\n" +
+ "FBGZQxp81aORDyUIrlCkMIxhZBSsNPIJYwIDAQABoyEwHzAdBgNVHQ4EFgQUKrvzNhJmdKoqq2li\n" +
+ "utCzKkwA1N0wDQYJKoZIhvcNAQEFBQADgYEAEIaegsW7fWWjXk4YOMlcl893vx6tnU8ThuQSjwGI\n" +
+ "rIs93sBYuY7lQIpQw8+XM89WT1XuBB6R2SsnxeW+gHtsU/EE6iJJAEMeCILwEGUL02blwHBQWmpa\n" +
+ "i3YeGXw+IFe/4OAysPT7ZRbUb7mPt37Ht6hIjain71ShR5anXIuawVE=\n" +
+ "-----END CERTIFICATE-----\n";
+ // Test cert for CN=A, happens to have a zero at the beginning of signature
+ static String normalCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIB1DCCAT2gAwIBAgIEae+u1TANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" +
+ "MDMwODA2NTNaFw0xMDA5MDEwODA2NTNaMAwxCjAIBgNVBAMTAUEwgZ8wDQYJKoZIhvcNAQEBBQAD\n" +
+ "gY0AMIGJAoGBAKZ7C6bC8AJmXIRNwuPJcgIPW1ygN3rE5PIKPAkeK/dYnPmUJNuiSxOFPJCrLMuL\n" +
+ "sweQh82Dq/viu+KBb27xVzJ4pK02fbcWdJDo7cIms0Wm+HckK5myA6xmqnpmPOjb/vWCLE6pN2Xg\n" +
+ "pJyrdeWV77eBvqE9OiCsMTP8WgHI9zLvAgMBAAGjQjBAMB0GA1UdDgQWBBTtIKqCHnL9QeFn+YrX\n" +
+ "+k00NUk9mjAfBgNVHSMEGDAWgBQqu/M2EmZ0qiqraWK60LMqTADU3TANBgkqhkiG9w0BAQUFAAOB\n" +
+ "gQAAOcQsEruDAY/z3eXJ7OtWSZlLC0yTVNVdUVNLQ58xNqPrmKNBXNpj/72N8xrTB++ApW+DLgLy\n" +
+ "cwGU5PVRtsYeiV6prUkpqUf62SQgwI4guAQy1ileeP1CNQJI3cHQExMAHvQT8fJtlD0WZD3nfesq\n" +
+ "mmQDOpoJLkmO/73Z7IibVA==\n" +
+ "-----END CERTIFICATE-----\n";
+ // normalCertStr with an extra zero at the beginning of signature
+ static String longerCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIB1TCCAT2gAwIBAgIEae+u1TANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" +
+ "MDMwODA2NTNaFw0xMDA5MDEwODA2NTNaMAwxCjAIBgNVBAMTAUEwgZ8wDQYJKoZIhvcNAQEBBQAD\n" +
+ "gY0AMIGJAoGBAKZ7C6bC8AJmXIRNwuPJcgIPW1ygN3rE5PIKPAkeK/dYnPmUJNuiSxOFPJCrLMuL\n" +
+ "sweQh82Dq/viu+KBb27xVzJ4pK02fbcWdJDo7cIms0Wm+HckK5myA6xmqnpmPOjb/vWCLE6pN2Xg\n" +
+ "pJyrdeWV77eBvqE9OiCsMTP8WgHI9zLvAgMBAAGjQjBAMB0GA1UdDgQWBBTtIKqCHnL9QeFn+YrX\n" +
+ "+k00NUk9mjAfBgNVHSMEGDAWgBQqu/M2EmZ0qiqraWK60LMqTADU3TANBgkqhkiG9w0BAQUFAAOB\n" +
+ "ggAAADnELBK7gwGP893lyezrVkmZSwtMk1TVXVFTS0OfMTaj65ijQVzaY/+9jfMa0wfvgKVvgy4C\n" +
+ "8nMBlOT1UbbGHoleqa1JKalH+tkkIMCOILgEMtYpXnj9QjUCSN3B0BMTAB70E/HybZQ9FmQ9533r\n" +
+ "KppkAzqaCS5Jjv+92eyIm1Q=\n" +
+ "-----END CERTIFICATE-----\n";
+ // normalCertStr without the initial zero at the beginning of signature
+ static String shorterCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIIB0zCCAT2gAwIBAgIEae+u1TANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" +
+ "MDMwODA2NTNaFw0xMDA5MDEwODA2NTNaMAwxCjAIBgNVBAMTAUEwgZ8wDQYJKoZIhvcNAQEBBQAD\n" +
+ "gY0AMIGJAoGBAKZ7C6bC8AJmXIRNwuPJcgIPW1ygN3rE5PIKPAkeK/dYnPmUJNuiSxOFPJCrLMuL\n" +
+ "sweQh82Dq/viu+KBb27xVzJ4pK02fbcWdJDo7cIms0Wm+HckK5myA6xmqnpmPOjb/vWCLE6pN2Xg\n" +
+ "pJyrdeWV77eBvqE9OiCsMTP8WgHI9zLvAgMBAAGjQjBAMB0GA1UdDgQWBBTtIKqCHnL9QeFn+YrX\n" +
+ "+k00NUk9mjAfBgNVHSMEGDAWgBQqu/M2EmZ0qiqraWK60LMqTADU3TANBgkqhkiG9w0BAQUFAAOB\n" +
+ "gAA5xCwSu4MBj/Pd5cns61ZJmUsLTJNU1V1RU0tDnzE2o+uYo0Fc2mP/vY3zGtMH74Clb4MuAvJz\n" +
+ "AZTk9VG2xh6JXqmtSSmpR/rZJCDAjiC4BDLWKV54/UI1AkjdwdATEwAe9BPx8m2UPRZkPed96yqa\n" +
+ "ZAM6mgkuSY7/vdnsiJtU\n" +
+ "-----END CERTIFICATE-----\n";
+
+ public static void main(String args[]) throws Exception {
+
+ Certificate signer = generate(signerCertStr);
+
+ // the valid certificate
+ Certificate normal = generate(normalCertStr);
+ // the invalid certificate with extra signature bits
+ Certificate longer = generate(longerCertStr);
+ // the invalid certificate without enough signature bits
+ Certificate shorter = generate(shorterCertStr);
+
+ if (!test(normal, signer, " normal", true) ||
+ !test(longer, signer, " longer", false) ||
+ !test(shorter, signer, "shorter", false)) {
+ throw new Exception("Test failed.");
+ }
+ }
+
+ private static Certificate generate(String certStr) throws Exception {
+ InputStream is = null;
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ is = new ByteArrayInputStream(certStr.getBytes());
+ return cf.generateCertificate(is);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ private static boolean test(Certificate target, Certificate signer,
+ String title, boolean expected) throws Exception {
+ System.out.print("Checking " + title + ": expected: " +
+ (expected ? " verified" : "NOT verified"));
+ boolean actual;
+ try {
+ PublicKey pubKey = signer.getPublicKey();
+ target.verify(pubKey);
+ actual = true;
+ } catch (SignatureException se) {
+ actual = false;
+ }
+ System.out.println(", actual: " +
+ (actual ? " verified" : "NOT verified"));
+ return actual == expected;
+ }
+
+}
--- a/jdk/test/sun/security/rsa/TestKeyPairGenerator.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/security/rsa/TestKeyPairGenerator.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -85,8 +85,12 @@
sig.initVerify(kp2.getPublic());
sig.update(data);
// verify needs to return false and not throw an Exception
- if (sig.verify(signature)) {
- throw new Exception("verification unexpectedly succeeded");
+ try {
+ if (sig.verify(signature)) {
+ throw new Exception("verification unexpectedly succeeded");
+ }
+ } catch (SignatureException se) {
+ // Yet another kind of failure, OK.
}
}
--- a/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -113,7 +113,7 @@
}
}
- if (isSignedCount != 3) {
+ if (isSignedCount != 4) {
throw new SecurityException("error signing JAR file");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/checkusage.sh Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 7004168
+# @summary jarsigner -verify checks for KeyUsage codesigning ext on all certs
+# instead of just signing cert
+#
+# @run shell checkusage.sh
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner"
+
+rm js.jks trust.jks unrelated.jks 2> /dev/null
+
+echo x > x
+$JAR cvf a.jar x
+
+################### 3 Keystores #######################
+
+# Keystore js.jks: including CA and Publisher
+# CA contains a non-empty KeyUsage
+$KT -keystore js.jks -genkeypair -alias ca -dname CN=CA -ext KU=kCS -ext bc -validity 365
+$KT -keystore js.jks -genkeypair -alias pub -dname CN=Publisher
+
+# Publisher contains the correct KeyUsage
+$KT -keystore js.jks -certreq -alias pub | \
+ $KT -keystore js.jks -gencert -alias ca -ext KU=dig -validity 365 | \
+ $KT -keystore js.jks -importcert -alias pub
+
+# Keystore trust.jks: including CA only
+$KT -keystore js.jks -exportcert -alias ca | \
+ $KT -keystore trust.jks -importcert -alias ca -noprompt
+
+# Keystore unrelated.jks: unrelated
+$KT -keystore unrelated.jks -genkeypair -alias nothing -dname CN=Nothing -validity 365
+
+
+################### 4 Tests #######################
+
+# Test 1: Sign should be OK
+
+$JARSIGNER -keystore js.jks -storepass changeit a.jar pub
+RESULT=$?
+echo $RESULT
+#[ $RESULT = 0 ] || exit 1
+
+# Test 2: Verify should be OK
+
+$JARSIGNER -keystore trust.jks -strict -verify a.jar
+RESULT=$?
+echo $RESULT
+#[ $RESULT = 0 ] || exit 2
+
+# Test 3: When no keystore is specified, the error is only
+# "chain not validated"
+
+$JARSIGNER -strict -verify a.jar
+RESULT=$?
+echo $RESULT
+#[ $RESULT = 4 ] || exit 3
+
+# Test 4: When unrelated keystore is specified, the error is
+# "chain not validated" and "not alias in keystore"
+
+$JARSIGNER -keystore unrelated.jks -strict -verify a.jar
+RESULT=$?
+echo $RESULT
+#[ $RESULT = 36 ] || exit 4
+
+exit 0
--- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh Tue Dec 07 13:27:02 2010 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2010, 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
@@ -79,9 +79,9 @@
$JARSIGNER -verify a.jar
[ $? = 0 ] || exit $LINENO
-# 4(chainNotValidated)+16(hasUnsignedEntry)+32(aliasNotInStore)
+# 4(chainNotValidated)+16(hasUnsignedEntry)
$JARSIGNER -verify a.jar -strict
-[ $? = 52 ] || exit $LINENO
+[ $? = 20 ] || exit $LINENO
# 16(hasUnsignedEntry)
$JARSIGNER -verify a.jar -strict -keystore js.jks
@@ -103,27 +103,31 @@
LINES=`$JARSIGNER -verify a.jar -verbose:grouped | grep $YEAR | wc -l`
[ $LINES = 12 ] || exit $LINENO
-# 3 groups: unrelated, signed, unsigned
+# 4 groups: MANIFST, unrelated, signed, unsigned
LINES=`$JARSIGNER -verify a.jar -verbose:summary | grep $YEAR | wc -l`
-[ $LINES = 3 ] || exit $LINENO
-
-# 4 groups: unrelated, signed by a1/a2, signed by a2, unsigned
-LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep $YEAR | wc -l`
[ $LINES = 4 ] || exit $LINENO
-# 2*2 for A1/A2, 2 for A3/A4
-LINES=`$JARSIGNER -verify a.jar -verbose -certs | grep "\[certificate" | wc -l`
-[ $LINES = 6 ] || exit $LINENO
-
-# a1,a2 for A1/A2, a2 for A3/A4
-LINES=`$JARSIGNER -verify a.jar -verbose:grouped -certs | grep "\[certificate" | wc -l`
+# still 4 groups, but MANIFEST group has no other file
+LINES=`$JARSIGNER -verify a.jar -verbose:summary | grep "more)" | wc -l`
[ $LINES = 3 ] || exit $LINENO
-# a1,a2 for A1/A2, a2 for A3/A4
+# 5 groups: MANIFEST, unrelated, signed by a1/a2, signed by a2, unsigned
+LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep $YEAR | wc -l`
+[ $LINES = 5 ] || exit $LINENO
+
+# 2 for MANIFEST, 2*2 for A1/A2, 2 for A3/A4
+LINES=`$JARSIGNER -verify a.jar -verbose -certs | grep "\[certificate" | wc -l`
+[ $LINES = 8 ] || exit $LINENO
+
+# a1,a2 for MANIFEST, a1,a2 for A1/A2, a2 for A3/A4
+LINES=`$JARSIGNER -verify a.jar -verbose:grouped -certs | grep "\[certificate" | wc -l`
+[ $LINES = 5 ] || exit $LINENO
+
+# a1,a2 for MANIFEST, a1,a2 for A1/A2, a2 for A3/A4
LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "\[certificate" | wc -l`
-[ $LINES = 3 ] || exit $LINENO
+[ $LINES = 5 ] || exit $LINENO
-# 4 groups
+# still 5 groups, but MANIFEST group has no other file
LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l`
[ $LINES = 4 ] || exit $LINENO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 7004035
+# @summary signed jar with only META-INF/* inside is not verifiable
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+KS=onlymanifest.jks
+JFILE=onlymanifest.jar
+
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \
+ -keystore $KS"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
+
+rm $KS $JFILE 2> /dev/null
+
+# Create an empty jar file with only MANIFEST.MF
+
+echo "Key: Value" > manifest
+$JAR cvfm $JFILE manifest
+
+$KT -alias a -dname CN=a -genkey -validity 300 || exit 1
+$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 2
+$JARSIGNER -keystore $KS -storepass changeit -verify $JFILE a -debug -strict \
+ > onlymanifest.out || exit 3
+
+grep unsigned onlymanifest.out && exit 4
+
+exit 0
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/Settings.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.File;
+import java.io.IOException;
+
+/*
+ * @test
+ * @bug 6994753
+ * @summary tests -XshowSettings options
+ * @compile -XDignore.symbol.file Settings.java TestHelper.java
+ * @run main Settings
+ * @author ksrini
+ */
+public class Settings {
+ private static File testJar = null;
+
+ static void init() throws IOException {
+ if (testJar != null) {
+ return;
+ }
+ testJar = new File("test.jar");
+ StringBuilder tsrc = new StringBuilder();
+ tsrc.append("public static void main(String... args) {\n");
+ tsrc.append(" for (String x : args) {\n");
+ tsrc.append(" System.out.println(x);\n");
+ tsrc.append(" }\n");
+ tsrc.append("}\n");
+ TestHelper.createJar(testJar, tsrc.toString());
+ }
+
+ static void checkContains(TestHelper.TestResult tr, String str) {
+ if (!tr.contains(str)) {
+ System.out.println(tr);
+ throw new RuntimeException(str + " not found");
+ }
+ }
+
+ static void checkNoContains(TestHelper.TestResult tr, String str) {
+ if (tr.contains(str)) {
+ System.out.println(tr.status);
+ throw new RuntimeException(str + " found");
+ }
+ }
+
+ private static final String VM_SETTINGS = "VM settings:";
+ private static final String PROP_SETTINGS = "Property settings:";
+ private static final String LOCALE_SETTINGS = "Locale settings:";
+
+ static void containsAllOptions(TestHelper.TestResult tr) {
+ checkContains(tr, VM_SETTINGS);
+ checkContains(tr, PROP_SETTINGS);
+ checkContains(tr, LOCALE_SETTINGS);
+ }
+
+ static void runTestOptionDefault() throws IOException {
+ TestHelper.TestResult tr = null;
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-Xmx512m", "-Xss128k",
+ "-XshowSettings", "-jar", testJar.getAbsolutePath());
+ containsAllOptions(tr);
+ if (!tr.isOK()) {
+ System.out.println(tr.status);
+ throw new RuntimeException("test fails");
+ }
+ }
+
+ static void runTestOptionAll() throws IOException {
+ init();
+ TestHelper.TestResult tr = null;
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:all");
+ containsAllOptions(tr);
+ }
+
+ static void runTestOptionVM() throws IOException {
+ TestHelper.TestResult tr = null;
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:vm");
+ checkContains(tr, VM_SETTINGS);
+ checkNoContains(tr, PROP_SETTINGS);
+ checkNoContains(tr, LOCALE_SETTINGS);
+ }
+
+ static void runTestOptionProperty() throws IOException {
+ TestHelper.TestResult tr = null;
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:properties");
+ checkNoContains(tr, VM_SETTINGS);
+ checkContains(tr, PROP_SETTINGS);
+ checkNoContains(tr, LOCALE_SETTINGS);
+ }
+
+ static void runTestOptionLocale() throws IOException {
+ TestHelper.TestResult tr = null;
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettings:locale");
+ checkNoContains(tr, VM_SETTINGS);
+ checkNoContains(tr, PROP_SETTINGS);
+ checkContains(tr, LOCALE_SETTINGS);
+ }
+
+ static void runTestBadOptions() throws IOException {
+ TestHelper.TestResult tr = null;
+ tr = TestHelper.doExec(TestHelper.javaCmd, "-XshowSettingsBadOption");
+ checkNoContains(tr, VM_SETTINGS);
+ checkNoContains(tr, PROP_SETTINGS);
+ checkNoContains(tr, LOCALE_SETTINGS);
+ checkContains(tr, "Unrecognized option: -XshowSettingsBadOption");
+ }
+ public static void main(String... args) {
+ try {
+ runTestOptionAll();
+ runTestOptionDefault();
+ runTestOptionVM();
+ runTestOptionProperty();
+ runTestOptionLocale();
+ runTestBadOptions();
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Dec 07 13:29:20 2010 +0000
@@ -49,6 +49,7 @@
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Enter;
@@ -230,7 +231,7 @@
public boolean isAccessible(Scope scope, TypeElement type) {
if (scope instanceof JavacScope && type instanceof ClassSymbol) {
Env<AttrContext> env = ((JavacScope) scope).env;
- return resolve.isAccessible(env, (ClassSymbol)type);
+ return resolve.isAccessible(env, (ClassSymbol)type, true);
} else
return false;
}
@@ -240,7 +241,7 @@
&& member instanceof Symbol
&& type instanceof com.sun.tools.javac.code.Type) {
Env<AttrContext> env = ((JavacScope) scope).env;
- return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member);
+ return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member, true);
} else
return false;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Dec 07 13:29:20 2010 +0000
@@ -247,6 +247,11 @@
*/
public static final long OVERRIDE_BRIDGE = 1L<<41;
+ /**
+ * Flag that marks an 'effectively final' local variable
+ */
+ public static final long EFFECTIVELY_FINAL = 1L<<42;
+
/** Modifier masks.
*/
public static final int
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Tue Dec 07 13:29:20 2010 +0000
@@ -212,9 +212,9 @@
VARARGS("varargs"),
/**
- * Warn about arm resources
+ * Warn about issues relating to use of try blocks (i.e. try-with-resources)
*/
- ARM("arm");
+ TRY("try");
LintCategory(String option) {
this(option, false);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,8 @@
/** A scope represents an area of visibility in a Java program. The
* Scope class is a container for symbols which provides
* efficient access to symbols given their names. Scopes are implemented
- * as hash tables. Scopes can be nested; the next field of a scope points
+ * as hash tables with "open addressing" and "double hashing".
+ * Scopes can be nested; the next field of a scope points
* to its next outer scope. Nested scopes can share their hash tables.
*
* <p><b>This is NOT part of any supported API.
@@ -55,7 +56,7 @@
/** A hash table for the scope's entries.
*/
- public Entry[] table;
+ Entry[] table;
/** Mask for hash codes, always equal to (table.length - 1).
*/
@@ -67,8 +68,9 @@
public Entry elems;
/** The number of elements in this scope.
+ * This includes deleted elements, whose value is the sentinel.
*/
- public int nelems = 0;
+ int nelems = 0;
/** A timestamp - useful to quickly check whether a scope has changed or not
*/
@@ -109,7 +111,8 @@
}
}
- /** Every hash bucket is a list of Entry's which ends in sentinel.
+ /** Use as a "not-found" result for lookup.
+ * Also used to mark deleted entries in the table.
*/
private static final Entry sentinel = new Entry(null, null, null, null);
@@ -130,12 +133,15 @@
this.owner = owner;
this.table = table;
this.hashMask = table.length - 1;
- this.elems = null;
- this.nelems = 0;
- this.shared = 0;
this.scopeCounter = scopeCounter;
}
+ /** Convenience constructor used for dup and dupUnshared. */
+ private Scope(Scope next, Symbol owner, Entry[] table) {
+ this(next, owner, table, next.scopeCounter);
+ this.nelems = next.nelems;
+ }
+
/** Construct a new scope, within scope next, with given owner,
* using a fresh table of length INITIAL_SIZE.
*/
@@ -145,7 +151,6 @@
protected Scope(Symbol owner, ScopeCounter scopeCounter) {
this(null, owner, new Entry[INITIAL_SIZE], scopeCounter);
- for (int i = 0; i < INITIAL_SIZE; i++) table[i] = sentinel;
}
/** Construct a fresh scope within this scope, with same owner,
@@ -154,11 +159,7 @@
* of fresh tables.
*/
public Scope dup() {
- Scope result = new Scope(this, this.owner, this.table, scopeCounter);
- shared++;
- // System.out.println("====> duping scope " + this.hashCode() + " owned by " + this.owner + " to " + result.hashCode());
- // new Error().printStackTrace(System.out);
- return result;
+ return dup(this.owner);
}
/** Construct a fresh scope within this scope, with new owner,
@@ -167,7 +168,7 @@
* of fresh tables.
*/
public Scope dup(Symbol newOwner) {
- Scope result = new Scope(this, newOwner, this.table, scopeCounter);
+ Scope result = new Scope(this, newOwner, this.table);
shared++;
// System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
// new Error().printStackTrace(System.out);
@@ -179,7 +180,7 @@
* the table of its outer scope.
*/
public Scope dupUnshared() {
- return new Scope(this, this.owner, this.table.clone(), scopeCounter);
+ return new Scope(this, this.owner, this.table.clone());
}
/** Remove all entries of this scope from its table, if shared
@@ -189,7 +190,7 @@
assert shared == 0;
if (table != next.table) return next;
while (elems != null) {
- int hash = elems.sym.name.hashCode() & hashMask;
+ int hash = getIndex(elems.sym.name);
Entry e = table[hash];
assert e == elems : elems.sym;
table[hash] = elems.shadowed;
@@ -197,6 +198,7 @@
}
assert next.shared > 0;
next.shared--;
+ next.nelems = nelems;
// System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
// new Error().printStackTrace(System.out);
return next;
@@ -215,19 +217,17 @@
s.hashMask = newtable.length - 1;
}
}
- for (int i = 0; i < newtable.length; i++) newtable[i] = sentinel;
- for (int i = 0; i < oldtable.length; i++) copy(oldtable[i]);
- }
-
- /** Copy the given entry and all entries shadowed by it to table
- */
- private void copy(Entry e) {
- if (e.sym != null) {
- copy(e.shadowed);
- int hash = e.sym.name.hashCode() & hashMask;
- e.shadowed = table[hash];
- table[hash] = e;
+ int n = 0;
+ for (int i = oldtable.length; --i >= 0; ) {
+ Entry e = oldtable[i];
+ if (e != null && e != sentinel && ! e.isBogus()) {
+ table[getIndex(e.sym.name)] = e;
+ n++;
+ }
}
+ // We don't need to update nelems for shared inherited scopes,
+ // since that gets handled by leave().
+ nelems = n;
}
/** Enter symbol sym in this scope.
@@ -248,13 +248,17 @@
*/
public void enter(Symbol sym, Scope s, Scope origin) {
assert shared == 0;
- // Temporarily disabled (bug 6460352):
- // if (nelems * 3 >= hashMask * 2) dble();
- int hash = sym.name.hashCode() & hashMask;
- Entry e = makeEntry(sym, table[hash], elems, s, origin);
+ if (nelems * 3 >= hashMask * 2)
+ dble();
+ int hash = getIndex(sym.name);
+ Entry old = table[hash];
+ if (old == null) {
+ old = sentinel;
+ nelems++;
+ }
+ Entry e = makeEntry(sym, old, elems, s, origin);
table[hash] = e;
elems = e;
- nelems++;
scopeCounter.inc();
}
@@ -268,15 +272,15 @@
public void remove(Symbol sym) {
assert shared == 0;
Entry e = lookup(sym.name);
- while (e.scope == this && e.sym != sym) e = e.next();
if (e.scope == null) return;
scopeCounter.inc();
// remove e from table and shadowed list;
- Entry te = table[sym.name.hashCode() & hashMask];
+ int i = getIndex(sym.name);
+ Entry te = table[i];
if (te == e)
- table[sym.name.hashCode() & hashMask] = e.shadowed;
+ table[i] = e.shadowed;
else while (true) {
if (te.shadowed == e) {
te.shadowed = e.shadowed;
@@ -335,12 +339,50 @@
return lookup(name, noFilter);
}
public Entry lookup(Name name, Filter<Symbol> sf) {
- Entry e = table[name.hashCode() & hashMask];
+ Entry e = table[getIndex(name)];
+ if (e == null || e == sentinel)
+ return sentinel;
while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
e = e.shadowed;
return e;
}
+ /*void dump (java.io.PrintStream out) {
+ out.println(this);
+ for (int l=0; l < table.length; l++) {
+ Entry le = table[l];
+ out.print("#"+l+": ");
+ if (le==sentinel) out.println("sentinel");
+ else if(le == null) out.println("null");
+ else out.println(""+le+" s:"+le.sym);
+ }
+ }*/
+
+ /** Look for slot in the table.
+ * We use open addressing with double hashing.
+ */
+ int getIndex (Name name) {
+ int h = name.hashCode();
+ int i = h & hashMask;
+ // The expression below is always odd, so it is guaranteed
+ // be be mutually prime with table.length, a power of 2.
+ int x = hashMask - ((h + (h >> 16)) << 1);
+ int d = -1; // Index of a deleted item.
+ for (;;) {
+ Entry e = table[i];
+ if (e == null)
+ return d >= 0 ? d : i;
+ if (e == sentinel) {
+ // We have to keep searching even if we see a deleted item.
+ // However, remember the index in case we fail to find the name.
+ if (d < 0)
+ d = i;
+ } else if (e.sym.name == name)
+ return i;
+ i = (i + x) & hashMask;
+ }
+ }
+
public Iterable<Symbol> getElements() {
return getElements(noFilter);
}
@@ -441,10 +483,7 @@
* outwards if not found in this scope.
*/
public Entry next() {
- Entry e = shadowed;
- while (e.scope != null && e.sym.name != sym.name)
- e = e.shadowed;
- return e;
+ return shadowed;
}
public Scope getOrigin() {
@@ -456,6 +495,8 @@
// in many cases.
return scope;
}
+
+ protected boolean isBogus () { return false; }
}
public static class ImportScope extends Scope {
@@ -470,22 +511,10 @@
}
public Entry lookup(Name name) {
- Entry e = table[name.hashCode() & hashMask];
- while (e.scope != null &&
- (e.sym.name != name ||
- /* Since an inner class will show up in package and
- * import scopes until its inner class attribute has
- * been processed, we have to weed it out here. This
- * is done by comparing the owners of the entry's
- * scope and symbol fields. The scope field's owner
- * points to where the class originally was imported
- * from. The symbol field's owner points to where the
- * class is situated now. This can change when an
- * inner class is read (see ClassReader.enterClass).
- * By comparing the two fields we make sure that we do
- * not accidentally import an inner class that started
- * life as a flat class in a package. */
- e.sym.owner != e.scope.owner))
+ Entry e = table[getIndex(name)];
+ if (e == null)
+ return sentinel;
+ while (e.isBogus())
e = e.shadowed;
return e;
}
@@ -499,15 +528,33 @@
}
public Entry next() {
Entry e = super.shadowed;
- while (e.scope != null &&
- (e.sym.name != sym.name ||
- e.sym.owner != e.scope.owner)) // see lookup()
+ while (isBogus())
e = e.shadowed;
return e;
}
@Override
public Scope getOrigin() { return origin; }
+
+ /**
+ * Is this a bogus inner-class import?
+ * An inner class {@code Outer$Inner.class} read from a class file
+ * starts out in a package scope under the name {@code Outer$Inner},
+ * which (if star-imported) gets copied to the import scope.
+ * When the InnerClasses attribute is processed, the ClassSymbol
+ * is renamed in place (to {@code Inner}), and the owner changed
+ * to the {@code Outer} class. The ImportScope still has the old
+ * Entry that was created and hashed as {@code "Outer$Inner"},
+ * but whose name was changed to {@code "Inner"}. This violates
+ * the invariants for the Scope hash table, and so is pretty bogus.
+ * When the symbol was renamed, it should have been removed from
+ * the import scope (and not just the package scope); however,
+ * doing so is difficult. A better fix would be to change
+ * import scopes to indirectly reference package symbols, rather
+ * than copy from them.
+ * Until then, we detect and skip the bogus entries using this test.
+ */
+ protected boolean isBogus () { return sym.owner != scope.owner; }
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Dec 07 13:29:20 2010 +0000
@@ -3151,7 +3151,7 @@
return to.isParameterized() &&
(!(isUnbounded(to) ||
isSubtype(from, to) ||
- ((subFrom != null) && isSameType(subFrom, to))));
+ ((subFrom != null) && containsType(to.allparams(), subFrom.allparams()))));
}
private List<Type> superClosure(Type t, Type s) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Dec 07 13:29:20 2010 +0000
@@ -252,10 +252,12 @@
(base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
isAssignableAsBlankFinal(v, env)))) {
if (v.isResourceVariable()) { //TWR resource
- log.error(pos, "twr.resource.may.not.be.assigned", v);
+ log.error(pos, "try.resource.may.not.be.assigned", v);
} else {
log.error(pos, "cant.assign.val.to.final.var", v);
}
+ } else if ((v.flags() & EFFECTIVELY_FINAL) != 0) {
+ v.flags_field &= ~EFFECTIVELY_FINAL;
}
}
@@ -799,6 +801,7 @@
memberEnter.memberEnter(tree, env);
annotate.flush();
}
+ tree.sym.flags_field |= EFFECTIVELY_FINAL;
}
VarSymbol v = tree.sym;
@@ -1042,11 +1045,11 @@
for (JCTree resource : tree.resources) {
if (resource.getTag() == JCTree.VARDEF) {
attribStat(resource, tryEnv);
- chk.checkType(resource, resource.type, syms.autoCloseableType, "twr.not.applicable.to.type");
+ chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type");
VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource);
var.setData(ElementKind.RESOURCE_VARIABLE);
} else {
- attribExpr(resource, tryEnv, syms.autoCloseableType, "twr.not.applicable.to.type");
+ attribExpr(resource, tryEnv, syms.autoCloseableType, "try.not.applicable.to.type");
}
}
// Attribute body
@@ -1061,11 +1064,8 @@
localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
Type ctype = attribStat(c.param, catchEnv);
if (TreeInfo.isMultiCatch(c)) {
- //check that multi-catch parameter is marked as final
- if ((c.param.sym.flags() & FINAL) == 0) {
- log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym);
- }
- c.param.sym.flags_field = c.param.sym.flags() | DISJUNCTION;
+ //multi-catch parameter is implicitly marked as final
+ c.param.sym.flags_field |= FINAL | DISJUNCTION;
}
if (c.param.sym.kind == Kinds.VAR) {
c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
@@ -1552,7 +1552,7 @@
// Attribute clazz expression and store
// symbol + type back into the attributed tree.
Type clazztype = attribType(clazz, env);
- Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
+ Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype, cdef != null);
if (!TreeInfo.isDiamond(tree)) {
clazztype = chk.checkClassType(
tree.clazz.pos(), clazztype, true);
@@ -1849,7 +1849,7 @@
* inference. The inferred return type of the synthetic constructor IS
* the inferred type for the diamond operator.
*/
- private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
+ private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype, boolean overrideProtectedAccess) {
if (ctype.tag != CLASS) {
return erroneousMapping;
}
@@ -1860,6 +1860,12 @@
e.scope != null;
e = e.next()) {
MethodSymbol newConstr = (MethodSymbol) e.sym.clone(ctype.tsym);
+ if (overrideProtectedAccess && (newConstr.flags() & PROTECTED) != 0) {
+ //make protected constructor public (this is required for
+ //anonymous inner class creation expressions using diamond)
+ newConstr.flags_field |= PUBLIC;
+ newConstr.flags_field &= ~PROTECTED;
+ }
newConstr.name = names.init;
List<Type> oldTypeargs = List.nil();
if (newConstr.type.tag == FORALL) {
@@ -2252,8 +2258,8 @@
((VarSymbol)sitesym).isResourceVariable() &&
sym.kind == MTH &&
sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) &&
- env.info.lint.isEnabled(Lint.LintCategory.ARM)) {
- log.warning(tree, "twr.explicit.close.call");
+ env.info.lint.isEnabled(Lint.LintCategory.TRY)) {
+ log.warning(Lint.LintCategory.TRY, tree, "try.explicit.close.call");
}
// Disallow selecting a type from an expression
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Dec 07 13:29:20 2010 +0000
@@ -1510,14 +1510,7 @@
Type t1,
Type t2,
Type site) {
- Symbol sym = firstIncompatibility(t1, t2, site);
- if (sym != null) {
- log.error(pos, "types.incompatible.diff.ret",
- t1, t2, sym.name +
- "(" + types.memberType(t2, sym).getParameterTypes() + ")");
- return false;
- }
- return true;
+ return firstIncompatibility(pos, t1, t2, site) == null;
}
/** Return the first method which is defined with same args
@@ -1528,7 +1521,7 @@
* @param site The most derived type.
* @returns symbol from t2 that conflicts with one in t1.
*/
- private Symbol firstIncompatibility(Type t1, Type t2, Type site) {
+ private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>();
closure(t1, interfaces1);
Map<TypeSymbol,Type> interfaces2;
@@ -1539,7 +1532,7 @@
for (Type t3 : interfaces1.values()) {
for (Type t4 : interfaces2.values()) {
- Symbol s = firstDirectIncompatibility(t3, t4, site);
+ Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
if (s != null) return s;
}
}
@@ -1568,7 +1561,7 @@
}
/** Return the first method in t2 that conflicts with a method from t1. */
- private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) {
+ private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
Symbol s1 = e1.sym;
Type st1 = null;
@@ -1592,7 +1585,18 @@
(types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
types.covariantReturnType(rt2, rt1, Warner.noWarnings)) ||
checkCommonOverriderIn(s1,s2,site);
- if (!compat) return s2;
+ if (!compat) {
+ log.error(pos, "types.incompatible.diff.ret",
+ t1, t2, s2.name +
+ "(" + types.memberType(t2, s2).getParameterTypes() + ")");
+ return s2;
+ }
+ } else if (!checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
+ log.error(pos,
+ "name.clash.same.erasure.no.override",
+ s1, s1.location(),
+ s2, s2.location());
+ return s2;
}
}
}
@@ -1644,32 +1648,52 @@
log.error(tree.pos(), "enum.no.finalize");
return;
}
- for (Type t = types.supertype(origin.type); t.tag == CLASS;
+ for (Type t = origin.type; t.tag == CLASS;
t = types.supertype(t)) {
- TypeSymbol c = t.tsym;
- Scope.Entry e = c.members().lookup(m.name);
- while (e.scope != null) {
- if (m.overrides(e.sym, origin, types, false))
- checkOverride(tree, m, (MethodSymbol)e.sym, origin);
- else if (e.sym.kind == MTH &&
- e.sym.isInheritedIn(origin, types) &&
- (e.sym.flags() & SYNTHETIC) == 0 &&
- !m.isConstructor()) {
- Type er1 = m.erasure(types);
- Type er2 = e.sym.erasure(types);
- if (types.isSameTypes(er1.getParameterTypes(),
- er2.getParameterTypes())) {
- log.error(TreeInfo.diagnosticPositionFor(m, tree),
- "name.clash.same.erasure.no.override",
- m, m.location(),
- e.sym, e.sym.location());
- }
- }
- e = e.next();
+ if (t != origin.type) {
+ checkOverride(tree, t, origin, m);
+ }
+ for (Type t2 : types.interfaces(t)) {
+ checkOverride(tree, t2, origin, m);
}
}
}
+ void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
+ TypeSymbol c = site.tsym;
+ Scope.Entry e = c.members().lookup(m.name);
+ while (e.scope != null) {
+ if (m.overrides(e.sym, origin, types, false)) {
+ if ((e.sym.flags() & ABSTRACT) == 0) {
+ checkOverride(tree, m, (MethodSymbol)e.sym, origin);
+ }
+ }
+ else if (!checkNameClash(origin, e.sym, m)) {
+ log.error(tree,
+ "name.clash.same.erasure.no.override",
+ m, m.location(),
+ e.sym, e.sym.location());
+ }
+ e = e.next();
+ }
+ }
+
+ private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
+ if (s1.kind == MTH &&
+ s1.isInheritedIn(origin, types) &&
+ (s1.flags() & SYNTHETIC) == 0 &&
+ !s2.isConstructor()) {
+ Type er1 = s2.erasure(types);
+ Type er2 = s1.erasure(types);
+ if (types.isSameTypes(er1.getParameterTypes(),
+ er2.getParameterTypes())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
/** Check that all abstract members of given class have definitions.
* @param pos Position to be used for error reporting.
* @param c The class.
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Dec 07 13:29:20 2010 +0000
@@ -226,7 +226,7 @@
*/
Bits uninits;
- HashMap<Symbol, List<Type>> multicatchTypes;
+ HashMap<Symbol, List<Type>> preciseRethrowTypes;
/** The set of variables that are definitely unassigned everywhere
* in current try block. This variable is maintained lazily; it is
@@ -332,7 +332,7 @@
if (!chk.isUnchecked(tree.pos(), exc)) {
if (!chk.isHandled(exc, caught))
pendingExits.append(new PendingExit(tree, exc));
- thrown = chk.incl(exc, thrown);
+ thrown = chk.incl(exc, thrown);
}
}
@@ -1037,10 +1037,10 @@
int nextadrCatch = nextadr;
if (!unrefdResources.isEmpty() &&
- lint.isEnabled(Lint.LintCategory.ARM)) {
+ lint.isEnabled(Lint.LintCategory.TRY)) {
for (Map.Entry<VarSymbol, JCVariableDecl> e : unrefdResources.entrySet()) {
- log.warning(e.getValue().pos(),
- "automatic.resource.not.referenced", e.getKey());
+ log.warning(Lint.LintCategory.TRY, e.getValue().pos(),
+ "try.resource.not.referenced", e.getKey());
}
}
@@ -1077,12 +1077,12 @@
scan(param);
inits.incl(param.sym.adr);
uninits.excl(param.sym.adr);
- multicatchTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
+ preciseRethrowTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
scanStat(l.head.body);
initsEnd.andSet(inits);
uninitsEnd.andSet(uninits);
nextadr = nextadrCatch;
- multicatchTypes.remove(param.sym);
+ preciseRethrowTypes.remove(param.sym);
aliveEnd |= alive;
}
if (tree.finalizer != null) {
@@ -1215,10 +1215,10 @@
Symbol sym = TreeInfo.symbol(tree.expr);
if (sym != null &&
sym.kind == VAR &&
- (sym.flags() & FINAL) != 0 &&
- multicatchTypes.get(sym) != null &&
+ (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 &&
+ preciseRethrowTypes.get(sym) != null &&
allowRethrowAnalysis) {
- for (Type t : multicatchTypes.get(sym)) {
+ for (Type t : preciseRethrowTypes.get(sym)) {
markThrown(tree, t);
}
}
@@ -1371,11 +1371,24 @@
if (!tree.type.isErroneous()
&& lint.isEnabled(Lint.LintCategory.CAST)
&& types.isSameType(tree.expr.type, tree.clazz.type)
- && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
+ && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))
+ && !is292targetTypeCast(tree)) {
log.warning(Lint.LintCategory.CAST,
tree.pos(), "redundant.cast", tree.expr.type);
}
}
+ //where
+ private boolean is292targetTypeCast(JCTypeCast tree) {
+ boolean is292targetTypeCast = false;
+ if (tree.expr.getTag() == JCTree.APPLY) {
+ JCMethodInvocation apply = (JCMethodInvocation)tree.expr;
+ Symbol sym = TreeInfo.symbol(apply.meth);
+ is292targetTypeCast = sym != null &&
+ sym.kind == MTH &&
+ (sym.flags() & POLYMORPHIC_SIGNATURE) != 0;
+ }
+ return is292targetTypeCast;
+ }
public void visitTopLevel(JCCompilationUnit tree) {
// Do nothing for TopLevel since each class is visited individually
@@ -1422,7 +1435,7 @@
firstadr = 0;
nextadr = 0;
pendingExits = new ListBuffer<PendingExit>();
- multicatchTypes = new HashMap<Symbol, List<Type>>();
+ preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
alive = true;
this.thrown = this.caught = null;
this.classDef = null;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -1509,17 +1509,17 @@
}
private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
- // primaryException.addSuppressedException(catchException);
+ // primaryException.addSuppressed(catchException);
VarSymbol catchException =
new VarSymbol(0, make.paramName(2),
syms.throwableType,
currentMethodSym);
JCStatement addSuppressionStatement =
make.Exec(makeCall(make.Ident(primaryException),
- names.fromString("addSuppressedException"),
+ names.addSuppressed,
List.<JCExpression>of(make.Ident(catchException))));
- // try { resource.close(); } catch (e) { primaryException.addSuppressedException(e); }
+ // try { resource.close(); } catch (e) { primaryException.addSuppressed(e); }
JCBlock tryBlock =
make.Block(0L, List.<JCStatement>of(makeResourceCloseInvocation(resource)));
JCVariableDecl catchExceptionDecl = make.VarDef(catchException, null);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Dec 07 13:29:20 2010 +0000
@@ -159,33 +159,45 @@
* @param c The class whose accessibility is checked.
*/
public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
+ return isAccessible(env, c, false);
+ }
+
+ public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
+ boolean isAccessible = false;
switch ((short)(c.flags() & AccessFlags)) {
- case PRIVATE:
- return
- env.enclClass.sym.outermostClass() ==
- c.owner.outermostClass();
- case 0:
- return
- env.toplevel.packge == c.owner // fast special case
- ||
- env.toplevel.packge == c.packge()
- ||
- // Hack: this case is added since synthesized default constructors
- // of anonymous classes should be allowed to access
- // classes which would be inaccessible otherwise.
- env.enclMethod != null &&
- (env.enclMethod.mods.flags & ANONCONSTR) != 0;
- default: // error recovery
- case PUBLIC:
- return true;
- case PROTECTED:
- return
- env.toplevel.packge == c.owner // fast special case
- ||
- env.toplevel.packge == c.packge()
- ||
- isInnerSubClass(env.enclClass.sym, c.owner);
+ case PRIVATE:
+ isAccessible =
+ env.enclClass.sym.outermostClass() ==
+ c.owner.outermostClass();
+ break;
+ case 0:
+ isAccessible =
+ env.toplevel.packge == c.owner // fast special case
+ ||
+ env.toplevel.packge == c.packge()
+ ||
+ // Hack: this case is added since synthesized default constructors
+ // of anonymous classes should be allowed to access
+ // classes which would be inaccessible otherwise.
+ env.enclMethod != null &&
+ (env.enclMethod.mods.flags & ANONCONSTR) != 0;
+ break;
+ default: // error recovery
+ case PUBLIC:
+ isAccessible = true;
+ break;
+ case PROTECTED:
+ isAccessible =
+ env.toplevel.packge == c.owner // fast special case
+ ||
+ env.toplevel.packge == c.packge()
+ ||
+ isInnerSubClass(env.enclClass.sym, c.owner);
+ break;
}
+ return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
+ isAccessible :
+ isAccessible & isAccessible(env, c.type.getEnclosingType(), checkInner);
}
//where
/** Is given class a subclass of given base class, or an inner class
@@ -202,9 +214,13 @@
}
boolean isAccessible(Env<AttrContext> env, Type t) {
+ return isAccessible(env, t, false);
+ }
+
+ boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
return (t.tag == ARRAY)
? isAccessible(env, types.elemtype(t))
- : isAccessible(env, t.tsym);
+ : isAccessible(env, t.tsym, checkInner);
}
/** Is symbol accessible as a member of given type in given evironment?
@@ -214,6 +230,9 @@
* @param sym The symbol.
*/
public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
+ return isAccessible(env, site, sym, false);
+ }
+ public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
if (sym.name == names.init && sym.owner != site.tsym) return false;
ClassSymbol sub;
switch ((short)(sym.flags() & AccessFlags)) {
@@ -231,7 +250,7 @@
||
env.toplevel.packge == sym.packge())
&&
- isAccessible(env, site)
+ isAccessible(env, site, checkInner)
&&
sym.isInheritedIn(site.tsym, types)
&&
@@ -248,11 +267,11 @@
// (but type names should be disallowed elsewhere!)
env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
&&
- isAccessible(env, site)
+ isAccessible(env, site, checkInner)
&&
notOverriddenIn(site, sym);
default: // this case includes erroneous combinations as well
- return isAccessible(env, site) && notOverriddenIn(site, sym);
+ return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
}
}
//where
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Dec 07 13:29:20 2010 +0000
@@ -993,7 +993,9 @@
/** Enter an inner class into the `innerClasses' set/queue.
*/
void enterInner(ClassSymbol c) {
- assert !c.type.isCompound();
+ if (c.type.isCompound()) {
+ throw new AssertionError("Unexpected intersection type: " + c.type);
+ }
try {
c.complete();
} catch (CompletionFailure ex) {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Dec 07 13:29:20 2010 +0000
@@ -1304,7 +1304,7 @@
stackCount = 0;
for (int i=0; i<state.stacksize; i++) {
if (state.stack[i] != null) {
- frame.stack[stackCount++] = state.stack[i];
+ frame.stack[stackCount++] = types.erasure(state.stack[i]);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 07 13:29:20 2010 +0000
@@ -1712,7 +1712,7 @@
S.nextToken();
List<JCTree> resources = List.<JCTree>nil();
if (S.token() == LPAREN) {
- checkAutomaticResourceManagement();
+ checkTryWithResources();
S.nextToken();
resources = resources();
accept(RPAREN);
@@ -2970,9 +2970,9 @@
allowMulticatch = true;
}
}
- void checkAutomaticResourceManagement() {
+ void checkTryWithResources() {
if (!allowTWR) {
- error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
+ error(S.pos(), "try.with.resources.not.supported.in.source", source.name);
allowTWR = true;
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Dec 07 13:29:20 2010 +0000
@@ -63,8 +63,6 @@
anonymous class implements interface; cannot have type arguments
compiler.err.anon.class.impl.intf.no.qual.for.new=\
anonymous class implements interface; cannot have qualifier for new
-compiler.misc.twr.not.applicable.to.type=\
- automatic resource management not applicable to variable type
compiler.err.array.and.varargs=\
cannot declare both {0} and {1} in {2}
compiler.err.array.dimension.missing=\
@@ -183,12 +181,10 @@
compiler.err.final.parameter.may.not.be.assigned=\
final parameter {0} may not be assigned
-compiler.err.twr.resource.may.not.be.assigned=\
- automatic resource {0} may not be assigned
+compiler.err.try.resource.may.not.be.assigned=\
+ auto-closeable resource {0} may not be assigned
compiler.err.multicatch.parameter.may.not.be.assigned=\
multi-catch parameter {0} may not be assigned
-compiler.err.multicatch.param.must.be.final=\
- multi-catch parameter {0} must be final
compiler.err.finally.without.try=\
''finally'' without ''try''
compiler.err.foreach.not.applicable.to.type=\
@@ -825,10 +821,10 @@
compiler.warn.proc.unmatched.processor.options=\
The following options were not recognized by any processor: ''{0}''
-compiler.warn.twr.explicit.close.call=\
- [arm] explicit call to close() on an automatic resource
-compiler.warn.automatic.resource.not.referenced=\
- [arm] automatic resource {0} is never referenced in body of corresponding try statement
+compiler.warn.try.explicit.close.call=\
+ explicit call to close() on an auto-closeable resource
+compiler.warn.try.resource.not.referenced=\
+ auto-closeable resource {0} is never referenced in body of corresponding try statement
compiler.warn.unchecked.assign=\
unchecked assignment: {0} to {1}
compiler.warn.unchecked.assign.to.var=\
@@ -1052,6 +1048,9 @@
# compiler.err.no.elem.type=\
# \[\*\] cannot have a type
+compiler.misc.try.not.applicable.to.type=\
+ try-with-resources not applicable to variable type
+
#####
compiler.err.type.found.req=\
@@ -1274,9 +1273,9 @@
exotic identifiers #"___" are not supported in -source {0}\n\
(use -source 7 or higher to enable exotic identifiers)
-compiler.err.automatic.resource.management.not.supported.in.source=\
- automatic resource management is not supported in -source {0}\n\
-(use -source 7 or higher to enable automatic resource management)
+compiler.err.try.with.resources.not.supported.in.source=\
+ try-with-resources is not supported in -source {0}\n\
+(use -source 7 or higher to enable try-with-resources)
compiler.warn.enum.as.identifier=\
as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java Tue Dec 07 13:29:20 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -150,6 +150,7 @@
public final Name finalize;
public final Name java_lang_AutoCloseable;
public final Name close;
+ public final Name addSuppressed;
public final Name.Table table;
@@ -268,6 +269,7 @@
java_lang_AutoCloseable = fromString("java.lang.AutoCloseable");
close = fromString("close");
+ addSuppressed = fromString("addSuppressed");
}
protected Name.Table createTable(Options options) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6996626/Main.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6996626
+ * @summary Scope fix issues for ImportScope
+ * @compile pack1/Symbol.java
+ * @compile Main.java
+ */
+
+import pack1.*;
+import pack1.Symbol.*;
+
+// The following imports are just to trigger re-hashing (in
+// com.sun.tools.javac.code.Scope.dble()) of the star-import scope.
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+public class Main {
+ public void main (String[] args) {
+ throw new CompletionFailure();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6996626/pack1/Symbol.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pack1;
+
+public class Symbol {
+ public static class CompletionFailure extends RuntimeException { }
+}
+
+
+
--- a/langtools/test/tools/javac/TryWithResources/ArmLint.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 6911256 6964740 6965277 6967065
- * @author Joseph D. Darcy
- * @summary Check that -Xlint:arm warnings are generated as expected
- * @compile/ref=ArmLint.out -Xlint:arm,deprecation -XDrawDiagnostics ArmLint.java
- */
-
-class ArmLint implements AutoCloseable {
- private static void test1() {
- try(ArmLint r1 = new ArmLint();
- ArmLint r2 = new ArmLint();
- ArmLint r3 = new ArmLint()) {
- r1.close(); // The resource's close
- r2.close(42); // *Not* the resource's close
- // r3 not referenced
- }
-
- }
-
- @SuppressWarnings("arm")
- private static void test2() {
- try(@SuppressWarnings("deprecation") AutoCloseable r4 =
- new DeprecatedAutoCloseable()) {
- // r4 not referenced
- } catch(Exception e) {
- ;
- }
- }
-
- /**
- * The AutoCloseable method of a resource.
- */
- @Override
- public void close () {
- return;
- }
-
- /**
- * <em>Not</em> the AutoCloseable method of a resource.
- */
- public void close (int arg) {
- return;
- }
-}
-
-@Deprecated
-class DeprecatedAutoCloseable implements AutoCloseable {
- public DeprecatedAutoCloseable(){super();}
-
- @Override
- public void close () {
- return;
- }
-}
--- a/langtools/test/tools/javac/TryWithResources/ArmLint.out Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-ArmLint.java:14:15: compiler.warn.twr.explicit.close.call
-ArmLint.java:13:13: compiler.warn.automatic.resource.not.referenced: r3
-2 warnings
--- a/langtools/test/tools/javac/TryWithResources/ImplicitFinal.out Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/TryWithResources/ImplicitFinal.out Tue Dec 07 13:29:20 2010 +0000
@@ -1,2 +1,2 @@
-ImplicitFinal.java:14:13: compiler.err.twr.resource.may.not.be.assigned: r
+ImplicitFinal.java:14:13: compiler.err.try.resource.may.not.be.assigned: r
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrLint.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,55 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6911256 6964740 6965277 6967065
+ * @author Joseph D. Darcy
+ * @summary Check that -Xlint:twr warnings are generated as expected
+ * @compile/ref=TwrLint.out -Xlint:try,deprecation -XDrawDiagnostics TwrLint.java
+ */
+
+class TwrLint implements AutoCloseable {
+ private static void test1() {
+ try(TwrLint r1 = new TwrLint();
+ TwrLint r2 = new TwrLint();
+ TwrLint r3 = new TwrLint()) {
+ r1.close(); // The resource's close
+ r2.close(42); // *Not* the resource's close
+ // r3 not referenced
+ }
+
+ }
+
+ @SuppressWarnings("try")
+ private static void test2() {
+ try(@SuppressWarnings("deprecation") AutoCloseable r4 =
+ new DeprecatedAutoCloseable()) {
+ // r4 not referenced - but no warning is generated because of @SuppressWarnings
+ } catch(Exception e) {
+ ;
+ }
+ }
+
+ /**
+ * The AutoCloseable method of a resource.
+ */
+ @Override
+ public void close () {
+ return;
+ }
+
+ /**
+ * <em>Not</em> the AutoCloseable method of a resource.
+ */
+ public void close (int arg) {
+ return;
+ }
+}
+
+@Deprecated
+class DeprecatedAutoCloseable implements AutoCloseable {
+ public DeprecatedAutoCloseable(){super();}
+
+ @Override
+ public void close () {
+ return;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrLint.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,3 @@
+TwrLint.java:14:15: compiler.warn.try.explicit.close.call
+TwrLint.java:13:13: compiler.warn.try.resource.not.referenced: r3
+2 warnings
--- a/langtools/test/tools/javac/TryWithResources/TwrOnNonResource.out Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrOnNonResource.out Tue Dec 07 13:29:20 2010 +0000
@@ -1,7 +1,7 @@
-TwrOnNonResource.java:12:13: compiler.err.prob.found.req: (compiler.misc.twr.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:15:13: compiler.err.prob.found.req: (compiler.misc.twr.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:18:13: compiler.err.prob.found.req: (compiler.misc.twr.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:24:13: compiler.err.prob.found.req: (compiler.misc.twr.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:27:13: compiler.err.prob.found.req: (compiler.misc.twr.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
-TwrOnNonResource.java:30:13: compiler.err.prob.found.req: (compiler.misc.twr.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:12:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:15:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:18:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:24:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:27:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
+TwrOnNonResource.java:30:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
6 errors
--- a/langtools/test/tools/javac/TryWithResources/TwrSuppression.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrSuppression.java Tue Dec 07 13:29:20 2010 +0000
@@ -36,7 +36,7 @@
throw new RuntimeException();
}
} catch(RuntimeException e) {
- Throwable[] suppressedExceptions = e.getSuppressedExceptions();
+ Throwable[] suppressedExceptions = e.getSuppressed();
int length = suppressedExceptions.length;
if (length != 2)
throw new RuntimeException("Unexpected length " + length);
--- a/langtools/test/tools/javac/TryWithResources/TwrTests.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrTests.java Tue Dec 07 13:29:20 2010 +0000
@@ -90,7 +90,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed");
}
@@ -112,7 +112,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed");
}
@@ -134,7 +134,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e);
}
@@ -158,7 +158,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e);
}
@@ -181,7 +181,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e);
}
@@ -207,7 +207,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e);
}
@@ -231,7 +231,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e);
}
@@ -259,7 +259,7 @@
} catch (Resource.CreateFailException e) {
creationFailuresDetected++;
checkCreateFailureId(e.resourceId(), createFailureId);
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
throw new AssertionError("Secondary exception suppression failed:" + e);
}
@@ -310,7 +310,7 @@
* Check for proper suppressed exceptions in proper order.
*
* @param suppressedExceptions the suppressed exceptions array returned by
- * getSuppressedExceptions()
+ * getSuppressed()
* @bitmap a bitmap indicating which suppressed exceptions are expected.
* Bit i is set iff id should throw a CloseFailException.
*/
@@ -376,7 +376,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -388,7 +388,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 1);
}
@@ -409,7 +409,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -421,7 +421,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 2);
}
@@ -443,7 +443,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -455,7 +455,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 2);
}
@@ -477,7 +477,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -489,7 +489,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 3);
}
@@ -513,7 +513,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -525,7 +525,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 3);
}
@@ -548,7 +548,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -560,7 +560,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 4);
}
@@ -586,7 +586,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -598,7 +598,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 4);
}
@@ -621,7 +621,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -633,7 +633,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 5);
}
@@ -660,7 +660,7 @@
} catch (MyKindOfException e) {
if (failure == 0)
throw new AssertionError("Unexpected MyKindOfException");
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap);
} catch (Resource.CloseFailException e) {
if (failure == 1)
throw new AssertionError("Secondary exception suppression failed");
@@ -672,7 +672,7 @@
throw new AssertionError("CloseFailException: got id " + id
+ ", expected lg(" + highestCloseFailBit +")");
}
- checkSuppressedExceptions(e.getSuppressedExceptions(), bitMap & ~highestCloseFailBit);
+ checkSuppressedExceptions(e.getSuppressed(), bitMap & ~highestCloseFailBit);
}
checkClosedList(closedList, 5);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/api/6598108/T6598108.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6598108
+ * @summary com.sun.source.util.Trees.isAccessible incorrect
+ * @author Jan Lahoda
+ */
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Scope;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
+import java.net.URI;
+import java.util.Arrays;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+public class T6598108 {
+ public static void main(String[] args) throws Exception {
+ final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ assert tool != null;
+ final JavacTask ct = (JavacTask)tool.getTask(null, null, null, Arrays.asList("-bootclasspath", bootPath), null, Arrays.asList(new MyFileObject()));
+
+ CompilationUnitTree cut = ct.parse().iterator().next();
+ TreePath tp = new TreePath(new TreePath(cut), cut.getTypeDecls().get(0));
+ Scope s = Trees.instance(ct).getScope(tp);
+ TypeElement type = ct.getElements().getTypeElement("com.sun.java.util.jar.pack.Package.File");
+
+ if (Trees.instance(ct).isAccessible(s, type)) {
+ //com.sun.java.util.jar.pack.Package.File is a public innerclass inside a non-accessible class, so
+ //"false" would be expected here.
+ throw new IllegalStateException("");
+ }
+ }
+
+ static class MyFileObject extends SimpleJavaFileObject {
+ public MyFileObject() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ }
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return "public class Test<TTT> { public void test() {TTT ttt;}}";
+ }
+ }
+}
--- a/langtools/test/tools/javac/api/T6412669.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/api/T6412669.java Tue Dec 07 13:29:20 2010 +0000
@@ -23,11 +23,12 @@
/*
* @test
- * @bug 6412669
+ * @bug 6412669 6997958
* @summary Should be able to get SourcePositions from 269 world
*/
import java.io.*;
+import java.net.*;
import java.util.*;
import javax.annotation.*;
import javax.annotation.processing.*;
@@ -39,28 +40,59 @@
@SupportedAnnotationTypes("*")
public class T6412669 extends AbstractProcessor {
- public static void main(String... args) throws IOException {
- String testSrc = System.getProperty("test.src", ".");
- String testClasses = System.getProperty("test.classes", ".");
+ public static void main(String... args) throws Exception {
+ File testSrc = new File(System.getProperty("test.src", "."));
+ File testClasses = new File(System.getProperty("test.classes", "."));
+
+ // Determine location of necessary tools classes. Assume all in one place.
+ // Likely candidates are typically tools.jar (when testing JDK build)
+ // or build/classes or dist/javac.jar (when testing langtools, using -Xbootclasspath/p:)
+ File toolsClasses;
+ URL u = T6412669.class.getClassLoader().getResource("com/sun/source/util/JavacTask.class");
+ switch (u.getProtocol()) {
+ case "file":
+ toolsClasses = new File(u.toURI());
+ break;
+ case "jar":
+ String s = u.getFile(); // will be file:path!/entry
+ int sep = s.indexOf("!");
+ toolsClasses = new File(new URI(s.substring(0, sep)));
+ break;
+ default:
+ throw new AssertionError("Cannot locate tools classes");
+ }
+ //System.err.println("toolsClasses: " + toolsClasses);
JavacTool tool = JavacTool.create();
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
- fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File(testClasses)));
+ fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(testClasses, toolsClasses));
Iterable<? extends JavaFileObject> files =
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6412669.class.getName()+".java")));
- String[] opts = { "-proc:only", "-processor", T6412669.class.getName(),
- "-classpath", new File(testClasses).getPath() };
- JavacTask task = tool.getTask(null, fm, null, Arrays.asList(opts), null, files);
- if (!task.call())
- throw new AssertionError("test failed");
+ String[] opts = { "-proc:only", "-processor", T6412669.class.getName()};
+ StringWriter sw = new StringWriter();
+ JavacTask task = tool.getTask(sw, fm, null, Arrays.asList(opts), null, files);
+ boolean ok = task.call();
+ String out = sw.toString();
+ if (!out.isEmpty())
+ System.err.println(out);
+ if (!ok)
+ throw new AssertionError("compilation of test program failed");
+ // verify we found an annotated element to exercise the SourcePositions API
+ if (!out.contains("processing element"))
+ throw new AssertionError("expected text not found in compilation output");
}
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Trees trees = Trees.instance(processingEnv);
SourcePositions sp = trees.getSourcePositions();
Messager m = processingEnv.getMessager();
+ m.printMessage(Diagnostic.Kind.NOTE, "processing annotations");
+ int count = 0;
for (TypeElement anno: annotations) {
+ count++;
+ m.printMessage(Diagnostic.Kind.NOTE, " processing annotation " + anno);
for (Element e: roundEnv.getElementsAnnotatedWith(anno)) {
+ m.printMessage(Diagnostic.Kind.NOTE, " processing element " + e);
TreePath p = trees.getPath(e);
long start = sp.getStartPosition(p.getCompilationUnit(), p.getLeaf());
long end = sp.getEndPosition(p.getCompilationUnit(), p.getLeaf());
@@ -69,6 +101,8 @@
m.printMessage(k, "test [" + start + "," + end + "]", e);
}
}
+ if (count == 0)
+ m.printMessage(Diagnostic.Kind.NOTE, "no annotations found");
return true;
}
--- a/langtools/test/tools/javac/cast/6467183/T6467183a.out Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/cast/6467183/T6467183a.out Tue Dec 07 13:29:20 2010 +0000
@@ -1,6 +1,4 @@
T6467183a.java:16:26: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), T6467183a<T>.B, T6467183a<T>.A<T>
-T6467183a.java:24:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), T6467183a<T>.A<java.lang.Integer>, T6467183a<T>.C<? extends java.lang.Number>
-T6467183a.java:28:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), T6467183a<T>.A<java.lang.Integer>, T6467183a<T>.C<? extends java.lang.Integer>
- compiler.err.warnings.and.werror
1 error
-3 warnings
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/6714835/T6714835.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @author mcimadamore
+ * @bug 6714835
+ * @summary Safe cast is rejected (with warning) by javac
+ * @compile/fail/ref=T6714835.out -Xlint:unchecked -Werror -XDrawDiagnostics T6714835.java
+ */
+
+import java.util.*;
+
+class T6714835 {
+ void cast1(Iterable<? extends Integer> x) {
+ Collection<? extends Number> x1 = (Collection<? extends Number>)x; //ok
+ Collection<? super Integer> x2 = (Collection<? super Integer>)x; //warn
+ }
+
+ void cast2(Iterable<? super Number> x) {
+ Collection<? super Integer> x1 = (Collection<? super Integer>)x; //ok
+ Collection<? extends Number> x2 = (Collection<? extends Number>)x; //warn
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/6714835/T6714835.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,5 @@
+T6714835.java:14:71: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.lang.Iterable<compiler.misc.type.captureof: 1, ? extends java.lang.Integer>, java.util.Collection<? super java.lang.Integer>
+T6714835.java:19:73: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.lang.Iterable<compiler.misc.type.captureof: 1, ? super java.lang.Number>, java.util.Collection<? extends java.lang.Number>
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
--- a/langtools/test/tools/javac/diags/examples/MulticatchMustBeFinal.java Tue Dec 07 13:27:02 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.multicatch.param.must.be.final
-
-class MulticatchMustBeFinal {
- void e1() throws NullPointerException { }
- void e2() throws IllegalArgumentException { }
-
- void m() {
- try {
- e1();
- e2();
- } catch (NullPointerException | IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
-}
--- a/langtools/test/tools/javac/diags/examples/ResourceClosed.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/diags/examples/ResourceClosed.java Tue Dec 07 13:29:20 2010 +0000
@@ -21,8 +21,8 @@
* questions.
*/
-// key: compiler.warn.twr.explicit.close.call
-// options: -Xlint:arm
+// key: compiler.warn.try.explicit.close.call
+// options: -Xlint:try
import java.io.*;
--- a/langtools/test/tools/javac/diags/examples/ResourceMayNotBeAssigned.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/diags/examples/ResourceMayNotBeAssigned.java Tue Dec 07 13:29:20 2010 +0000
@@ -21,7 +21,7 @@
* questions.
*/
-// key: compiler.err.twr.resource.may.not.be.assigned
+// key: compiler.err.try.resource.may.not.be.assigned
import java.io.*;
--- a/langtools/test/tools/javac/diags/examples/ResourceNotApplicableToType.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/diags/examples/ResourceNotApplicableToType.java Tue Dec 07 13:29:20 2010 +0000
@@ -21,7 +21,7 @@
* questions.
*/
-// key: compiler.misc.twr.not.applicable.to.type
+// key: compiler.misc.try.not.applicable.to.type
// key: compiler.err.prob.found.req
class ResourceNotApplicableToType {
--- a/langtools/test/tools/javac/diags/examples/ResourceNotReferenced.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/diags/examples/ResourceNotReferenced.java Tue Dec 07 13:29:20 2010 +0000
@@ -21,8 +21,8 @@
* questions.
*/
-// key: compiler.warn.automatic.resource.not.referenced
-// options: -Xlint:arm
+// key: compiler.warn.try.resource.not.referenced
+// options: -Xlint:try
import java.io.*;
--- a/langtools/test/tools/javac/diags/examples/TryResourceNotSupported.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/diags/examples/TryResourceNotSupported.java Tue Dec 07 13:29:20 2010 +0000
@@ -21,7 +21,7 @@
* questions.
*/
-// key: compiler.err.automatic.resource.management.not.supported.in.source
+// key: compiler.err.try.with.resources.not.supported.in.source
// options: -source 1.6
import java.io.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719a.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719a.out -XDrawDiagnostics T6985719a.java
+ */
+
+import java.util.List;
+
+class T6985719a {
+ interface A { void f(List<String> ls); }
+ interface B { void f(List<Integer> ls); }
+ interface C extends A,B {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719a.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719a.java:14:5: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719a.B, f(java.util.List<java.lang.String>), T6985719a.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719b.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719b.out -XDrawDiagnostics T6985719b.java
+ */
+
+import java.util.List;
+
+class T6985719b {
+ abstract class A { abstract void f(List<String> ls); }
+ interface B { void f(List<Integer> ls); }
+ abstract class C extends A implements B {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719b.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719b.java:14:14: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719b.B, f(java.util.List<java.lang.String>), T6985719b.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719c.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719c.out -XDrawDiagnostics T6985719c.java
+ */
+
+import java.util.List;
+
+class T6985719c {
+ interface A { void f(List<String> ls); }
+ interface B<X> { void f(List<X> ls); }
+ interface C extends A,B<Integer> {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719c.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719c.java:14:5: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<X>), T6985719c.B, f(java.util.List<java.lang.String>), T6985719c.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719d.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719d.out -XDrawDiagnostics T6985719d.java
+ */
+
+import java.util.List;
+
+class T6985719d {
+ abstract class A { abstract void f(List<String> ls); }
+ interface B<X> { void f(List<X> ls); }
+ abstract class C extends A implements B<Integer> {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719d.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719d.java:14:14: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<X>), T6985719d.B, f(java.util.List<java.lang.String>), T6985719d.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719e.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719e.out -XDrawDiagnostics T6985719e.java
+ */
+
+import java.util.List;
+
+class T6985719e {
+ interface A { void f(List<String> ls); }
+ interface B extends A { void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719e.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719e.java:13:34: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719e.B, f(java.util.List<java.lang.String>), T6985719e.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719f.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719f.out -XDrawDiagnostics T6985719f.java
+ */
+
+import java.util.List;
+
+class T6985719f {
+ abstract class A { abstract void f(List<String> ls); }
+ abstract class B extends A { void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719f.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719f.java:13:39: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719f.B, f(java.util.List<java.lang.String>), T6985719f.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719g.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719g.out -XDrawDiagnostics T6985719g.java
+ */
+
+import java.util.List;
+
+class T6985719g {
+ interface A<X> { void f(List<X> ls); }
+ interface B extends A<String> { void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719g.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719g.java:13:42: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719g.B, f(java.util.List<X>), T6985719g.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719h.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6985719
+ * @summary Alike methods in interfaces (Inheritance and Overriding)
+ * @author mcimadamore
+ * @compile/fail/ref=T6985719h.out -XDrawDiagnostics T6985719h.java
+ */
+
+import java.util.List;
+
+class T6985719h {
+ abstract class A<X> { abstract void f(List<X> ls); }
+ abstract class B extends A<String> { abstract void f(List<Integer> ls); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6985719/T6985719h.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+T6985719h.java:13:56: compiler.err.name.clash.same.erasure.no.override: f(java.util.List<java.lang.Integer>), T6985719h.B, f(java.util.List<X>), T6985719h.A
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/6996914/T6996914a.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6996914
+ * @summary Diamond inference: problem when accessing protected constructor
+ * @run main T6996914a
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+public class T6996914a {
+
+ enum PackageKind {
+ DEFAULT("", ""),
+ A("package a;", "import a.*;");
+
+ String pkgDecl;
+ String importDecl;
+
+ PackageKind(String pkgDecl, String importDecl) {
+ this.pkgDecl = pkgDecl;
+ this.importDecl = importDecl;
+ }
+ }
+
+ enum DiamondKind {
+ STANDARD("new Foo<>();"),
+ ANON("new Foo<>() {};");
+
+ String expr;
+
+ DiamondKind(String expr) {
+ this.expr = expr;
+ }
+ }
+
+ enum ConstructorKind {
+ PACKAGE(""),
+ PROTECTED("protected"),
+ PRIVATE("private"),
+ PUBLIC("public");
+
+ String mod;
+
+ ConstructorKind(String mod) {
+ this.mod = mod;
+ }
+ }
+
+ static class FooClass extends SimpleJavaFileObject {
+
+ final static String sourceStub =
+ "#P\n" +
+ "public class Foo<X> {\n" +
+ " #M Foo() {}\n" +
+ "}\n";
+
+ String source;
+
+ public FooClass(PackageKind pk, ConstructorKind ck) {
+ super(URI.create("myfo:/" + (pk != PackageKind.DEFAULT ? "a/Foo.java" : "Foo.java")),
+ JavaFileObject.Kind.SOURCE);
+ source = sourceStub.replace("#P", pk.pkgDecl).replace("#M", ck.mod);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ static class ClientClass extends SimpleJavaFileObject {
+
+ final static String sourceStub =
+ "#I\n" +
+ "class Test {\n" +
+ " Foo<String> fs = #D\n" +
+ "}\n";
+
+ String source;
+
+ public ClientClass(PackageKind pk, DiamondKind dk) {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = sourceStub.replace("#I", pk.importDecl).replace("#D", dk.expr);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ for (PackageKind pk : PackageKind.values()) {
+ for (ConstructorKind ck : ConstructorKind.values()) {
+ for (DiamondKind dk : DiamondKind.values()) {
+ compileAndCheck(pk, ck, dk);
+ }
+ }
+ }
+ }
+
+ static void compileAndCheck(PackageKind pk, ConstructorKind ck, DiamondKind dk) throws Exception {
+ FooClass foo = new FooClass(pk, ck);
+ ClientClass client = new ClientClass(pk, dk);
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ ErrorListener el = new ErrorListener();
+ JavacTask ct = (JavacTask)tool.getTask(null, null, el,
+ null, null, Arrays.asList(foo, client));
+ ct.analyze();
+ if (el.errors > 0 == check(pk, ck, dk)) {
+ String msg = el.errors > 0 ?
+ "Error compiling files" :
+ "No error when compiling files";
+ throw new AssertionError(msg + ": \n" + foo.source + "\n" + client.source);
+ }
+ }
+
+ static boolean check(PackageKind pk, ConstructorKind ck, DiamondKind dk) {
+ switch (pk) {
+ case A: return ck == ConstructorKind.PUBLIC ||
+ (ck == ConstructorKind.PROTECTED && dk == DiamondKind.ANON);
+ case DEFAULT: return ck != ConstructorKind.PRIVATE;
+ default: throw new AssertionError("Unknown package kind");
+ }
+ }
+
+ /**
+ * DiagnosticListener to count any errors that occur
+ */
+ private static class ErrorListener implements DiagnosticListener<JavaFileObject> {
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ switch (diagnostic.getKind()) {
+ case ERROR:
+ errors++;
+ }
+ }
+ int errors;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/6996914/T6996914b.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6996914
+ * @summary Diamond inference: problem when accessing protected constructor
+ * @compile T6996914b.java
+ */
+
+class Super<X,Y> {
+ private Super(Integer i, Y y, X x) {}
+ public Super(Number n, X x, Y y) {}
+}
+
+class Test {
+ Super<String,Integer> ssi1 = new Super<>(1, "", 2);
+ Super<String,Integer> ssi2 = new Super<>(1, "", 2) {};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/XlintWarn.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6999067
+ * @summary cast for invokeExact call gets redundant cast to <type> warnings
+ * @author mcimadamore
+ *
+ * @compile -Werror -Xlint:cast XlintWarn.java
+ */
+
+import java.dyn.*;
+
+class XlintWarn {
+ void test(MethodHandle mh) throws Throwable {
+ int i1 = (int)mh.invoke();
+ int i2 = (int)mh.invokeExact();
+ int i3 = (int)mh.invokeVarargs();
+ int i4 = (int)InvokeDynamic.test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg01eff_final.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,28 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6943289
+ *
+ * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
+ * @author darcy
+ * @compile/fail/ref=Neg01eff_final.out -XDrawDiagnostics Neg01eff_final.java
+ * @compile -source 6 -XDrawDiagnostics Neg01eff_final.java
+ *
+ */
+
+class Neg01eff_final {
+ static class A extends Exception {}
+ static class B1 extends A {}
+ static class B2 extends A {}
+
+ class Test {
+ void m() throws A {
+ try {
+ throw new B1();
+ } catch (A ex1) {
+ try {
+ throw ex1; // used to throw A, now throws B1!
+ } catch (B2 ex2) { }//unreachable
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg01eff_final.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+Neg01eff_final.java:24:19: compiler.err.except.never.thrown.in.try: Neg01eff_final.B2
+1 error
--- a/langtools/test/tools/javac/multicatch/Neg02.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg02.java Tue Dec 07 13:29:20 2010 +0000
@@ -20,6 +20,8 @@
else {
throw new B();
}
- } catch (A | B ex) { }
+ } catch (final A | B ex) {
+ ex = new B();
+ }
}
}
--- a/langtools/test/tools/javac/multicatch/Neg02.out Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg02.out Tue Dec 07 13:29:20 2010 +0000
@@ -1,2 +1,2 @@
-Neg02.java:23:24: compiler.err.multicatch.param.must.be.final: ex
+Neg02.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg02eff_final.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6943289 6993963
+ *
+ * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
+ * @author mcimadamore
+ * @compile/fail/ref=Neg02eff_final.out -XDrawDiagnostics Neg02eff_final.java
+ *
+ */
+
+class Neg02eff_final {
+ static class A extends Exception {}
+ static class B extends Exception {}
+
+ void m() {
+ try {
+ if (true) {
+ throw new A();
+ }
+ else {
+ throw new B();
+ }
+ } catch (A | B ex) {
+ ex = new B();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg02eff_final.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+Neg02eff_final.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex
+1 error
--- a/langtools/test/tools/javac/multicatch/Neg03.java Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg03.java Tue Dec 07 13:29:20 2010 +0000
@@ -9,19 +9,22 @@
*/
class Neg03 {
- static class A extends Exception {}
- static class B extends Exception {}
- void m() {
+ static class A extends Exception { public void m() {}; public Object f;}
+ static class B1 extends A {}
+ static class B2 extends A {}
+
+ void m() throws B1, B2 {
try {
if (true) {
- throw new A();
+ throw new B1();
}
else {
- throw new B();
+ throw new B2();
}
- } catch (final A | B ex) {
- ex = new B();
+ } catch (Exception ex) {
+ ex = new B2(); //effectively final analysis disabled!
+ throw ex;
}
}
}
--- a/langtools/test/tools/javac/multicatch/Neg03.out Tue Dec 07 13:27:02 2010 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg03.out Tue Dec 07 13:29:20 2010 +0000
@@ -1,2 +1,2 @@
-Neg03.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex
+Neg03.java:27:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg04eff_final.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6943289
+ *
+ * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
+ * @author mcimadamore
+ * @compile/fail/ref=Neg04eff_final.out -XDrawDiagnostics Neg04eff_final.java
+ *
+ */
+
+class Neg04eff_final {
+ static class A extends Exception {}
+ static class B extends Exception {}
+
+ void test() throws B {
+ try {
+ if (true) {
+ throw new A();
+ } else if (false) {
+ throw new B();
+ } else {
+ throw (Throwable)new Exception();
+ }
+ }
+ catch (A e) {}
+ catch (Exception e) {
+ throw e;
+ }
+ catch (Throwable t) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg04eff_final.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+Neg04eff_final.java:27:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg05.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6943289
+ *
+ * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch')
+ * @author mcimadamore
+ * @compile/fail/ref=Neg05.out -XDrawDiagnostics Neg05.java
+ *
+ */
+
+class Neg02 {
+
+ static class Foo<X> {
+ Foo(X x) {}
+ }
+
+ static interface Base<X> {}
+ static class A extends Exception implements Base<String> {}
+ static class B extends Exception implements Base<Integer> {}
+
+ void m() {
+ try {
+ if (true) {
+ throw new A();
+ }
+ else {
+ throw new B();
+ }
+ } catch (A | B ex) {
+ Foo<?> f = new Foo<>(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Neg05.out Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,2 @@
+Neg05.java:30:31: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg02.Foo), (compiler.misc.diamond.invalid.arg: java.lang.Exception&Neg02.Base<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, (compiler.misc.diamond: Neg02.Foo))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Pos06.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6993963
+ *
+ * @summary Project Coin: Use precise exception analysis for effectively final catch parameters
+ * @author mcimadamore
+ * @compile Pos06.java
+ *
+ */
+
+class Pos06 {
+ static class A extends Exception {}
+ static class B extends Exception {}
+
+ void m() {
+ try {
+ if (true) {
+ throw new A();
+ }
+ else {
+ throw new B();
+ }
+ } catch (A | B ex) {
+ System.out.println(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Pos07.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6993963
+ * @summary Project Coin: Use precise exception analysis for effectively final catch parameters
+ * @compile Pos07.java
+ */
+
+class Pos07 {
+
+ static class A extends Exception { public void m() {}; public Object f;}
+ static class B1 extends A {}
+ static class B2 extends A {}
+
+ void m() throws B1, B2 {
+ try {
+ if (true) {
+ throw new B1();
+ }
+ else {
+ throw new B2();
+ }
+ } catch (Exception ex) { //effectively final analysis
+ throw ex;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Pos08.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6993963
+ * @summary Multicatch: crash while compiling simple code with a multicatch parameter
+ * @compile Pos08.java
+ */
+
+class Pos08 {
+
+ interface Foo {}
+ static class X1 extends Exception implements Foo {}
+ static class X2 extends Exception implements Foo {}
+
+ void m(boolean cond) {
+ try {
+ if (cond)
+ throw new X1();
+ else
+ throw new X2();
+ }
+ catch (final X1 | X2 ex) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/Pos08eff_final.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6993963
+ * @summary Multicatch: crash while compiling simple code with a multicatch parameter
+ * @compile Pos08eff_final.java
+ */
+
+class Pos08eff_final {
+
+ interface Foo {}
+ static class X1 extends Exception implements Foo {}
+ static class X2 extends Exception implements Foo {}
+
+ void m(boolean cond) {
+ try {
+ if (cond)
+ throw new X1();
+ else
+ throw new X2();
+ }
+ catch (X1 | X2 ex) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/model/Check.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Annotation used by ModelChecker to mark the class whose model is to be checked
+ */
+@interface Check {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/model/Member.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.lang.model.element.ElementKind;
+
+/**
+ * Annotation used by ModelChecker to mark a member that is to be checked
+ */
+@interface Member {
+ ElementKind value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/model/Model01.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.lang.model.element.ElementKind;
+
+@Check
+class Test {
+
+ class A extends Exception {
+ @Member(ElementKind.METHOD)
+ public void m() {};
+ @Member(ElementKind.FIELD)
+ public Object f;
+ }
+
+ class B1 extends A {}
+ class B2 extends A {}
+
+ void test(){
+ try {
+ if (true)
+ throw new B1();
+ else
+ throw new B2();
+ }
+ catch(B1 | B2 ex) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/multicatch/model/ModelChecker.java Tue Dec 07 13:29:20 2010 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6993963
+ * @summary Project Coin: Use precise exception analysis for effectively final catch parameters
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor ModelChecker
+ * @compile -processor ModelChecker Model01.java
+ */
+
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+import com.sun.source.util.TreePath;
+
+import java.util.Set;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
+
+@SupportedAnnotationTypes("Check")
+public class ModelChecker extends JavacTestingAbstractProcessor {
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver())
+ return true;
+
+ Trees trees = Trees.instance(processingEnv);
+
+ TypeElement testAnno = elements.getTypeElement("Check");
+ for (Element elem: roundEnv.getElementsAnnotatedWith(testAnno)) {
+ TreePath p = trees.getPath(elem);
+ new MulticatchParamTester(trees).scan(p, null);
+ }
+ return true;
+ }
+
+ class MulticatchParamTester extends TreePathScanner<Void, Void> {
+ Trees trees;
+
+ public MulticatchParamTester(Trees trees) {
+ super();
+ this.trees = trees;
+ }
+
+ @Override
+ public Void visitVariable(VariableTree node, Void p) {
+ Element ex = trees.getElement(getCurrentPath());
+ if (ex.getSimpleName().contentEquals("ex")) {
+ assertTrue(ex.getKind() == ElementKind.EXCEPTION_PARAMETER, "Expected EXCEPTION_PARAMETER - found " + ex.getKind());
+ for (Element e : types.asElement(ex.asType()).getEnclosedElements()) {
+ Member m = e.getAnnotation(Member.class);
+ if (m != null) {
+ assertTrue(e.getKind() == m.value(), "Expected " + m.value() + " - found " + e.getKind());
+ }
+ }
+ assertTrue(assertionCount == 3, "Expected 3 assertions - found " + assertionCount);
+ }
+ return super.visitVariable(node, p);
+ }
+ }
+
+ private static void assertTrue(boolean cond, String msg) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError(msg);
+ }
+
+ static int assertionCount = 0;
+}