# HG changeset patch # User lana # Date 1287017501 25200 # Node ID d954b585d3a17ab3df5861c77951ac24f77789cf # Parent 43cb79a6b12375b2b89f3021f6bb89dfbd1f516c# Parent 750c1ccb2f2d1ddfa95ab6c7f897fdab2f87f7e9 Merge diff -r 43cb79a6b123 -r d954b585d3a1 .hgtags --- a/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ e02b4d709e177d08d56130a4bc68061e4bbacc7d jdk7-b109 a6442d6bc38a44152e0662688213ce4d2701f42a jdk7-b110 69f3edf083477955b5bd2f754252c7504167d8e1 jdk7-b111 +f960f117f1623629f64203e2b09a92a8f6f14ff5 jdk7-b112 +1fee41c7ed2b3388970a756a85aa693c0de8407a jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 .hgtags-top-repo --- a/.hgtags-top-repo Tue Oct 12 17:05:28 2010 -0700 +++ b/.hgtags-top-repo Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ 81dfc728d7bb7e1fff4a4dc6d0f7cea5a3315667 jdk7-b109 2a02d4a6955c7c078aee9a604cb3be409800d82c jdk7-b110 9702d6fef68e17533ee7fcf5923b11ead3e912ce jdk7-b111 +b852103caf73da70068473777ae867a457bb3ae1 jdk7-b112 +c1df968c4527bfab5f97662a89245f15d12d378b jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 Makefile --- a/Makefile Tue Oct 12 17:05:28 2010 -0700 +++ b/Makefile Wed Oct 13 17:51:41 2010 -0700 @@ -558,9 +558,12 @@ # rule to test ################################################################ -.NOTPARALLEL: test +.NOTPARALLEL: test_run -test: test_clean test_start test_summary +test: + $(MAKE) test_run + +test_run: test_clean test_start test_summary test_start: @$(ECHO) "Tests started at `$(DATE)`" @@ -586,7 +589,7 @@ # Get failure list from log $(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt @$(RM) $@ - @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) > $@ + @( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@ # Get log file of all tests run JDK_TO_TEST := $(shell \ @@ -598,10 +601,11 @@ $(ECHO) "$(PRODUCT_HOME)"; \ fi \ ) +TEST_TARGETS=all $(OUTPUTDIR)/test_log.txt: $(RM) $@ - ( $(CD) test && \ - $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) \ + ( $(CD) test && \ + $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \ ) | tee $@ ################################################################ @@ -614,7 +618,7 @@ # PHONY ################################################################ -.PHONY: all test test_start test_summary test_clean \ +.PHONY: all test test_run test_start test_summary test_clean \ generic_build_repo_series \ what clobber insane \ dev dev-build dev-sanity dev-clobber \ diff -r 43cb79a6b123 -r d954b585d3a1 corba/.hgtags --- a/corba/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/corba/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ c3dd858e09b20206459d9e7b0ead99d27ab00eab jdk7-b109 0e1f80fda2271f53d4bbb59ec3f301dfbcef6a0a jdk7-b110 640fa4d4e2ad4c2d7e4815c955026740d8c52b7a jdk7-b111 +cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a jdk7-b112 +a89a6c5be9d1a754868d3d359cbf7ad36aa95631 jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 hotspot/.hgtags --- a/hotspot/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/hotspot/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -121,3 +121,5 @@ cc4bb3022b3144dc5db0805b9ef6c7eff2aa3b81 jdk7-b109 2f25f2b8de2700a1822463b1bd3d02b5e218018f jdk7-b110 07b042e13dde4f3479ba9ec55120fcd5e8623323 jdk7-b111 +5511edd5d719f3fc9fdd04879482026a3d2c8652 jdk7-b112 +beef35b96b81129c375d572357fb9548d9020db1 jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 jaxp/.hgtags --- a/jaxp/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/jaxp/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ 0f382d6120fc07aed2209484a42458cabf405916 jdk7-b109 d422dbdd09766269344b796b3a46a5b3f74557e1 jdk7-b110 8106c747067c905d814a737a57fea0e29057b33f jdk7-b111 +1b05254242881527b4d5d711295c0fe708c8823a jdk7-b112 +bc0c84ce54c34d3e8b0604b94da0d7c75c26755e jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 jaxws/.hgtags --- a/jaxws/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/jaxws/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ 4f626e0d70bda68c76bbd0e89d2bc2407f979736 jdk7-b109 95ecac35fb11530752bd0404c9bf02bcfb30990e jdk7-b110 2575ebca96c7fb1b78f6ae025a97321210aba309 jdk7-b111 +8e0f0054817f0f73fb33e80fb1333fb45b1d513d jdk7-b112 +d35c94fd22362f478f75b4bfcd2bef6a83cb9b3f jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 jdk/.hgtags --- a/jdk/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ ab0d3f54a63f2aadfcdd2e14b81f79362ce454e2 jdk7-b109 176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111 +b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112 +61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 jdk/make/mkdemo/Makefile --- a/jdk/make/mkdemo/Makefile Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/make/mkdemo/Makefile Wed Oct 13 17:51:41 2010 -0700 @@ -31,7 +31,7 @@ PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = jni +SUBDIRS = jni nio SUBDIRS_desktop = applets jfc SUBDIRS_management = management SUBDIRS_misc = scripting diff -r 43cb79a6b123 -r d954b585d3a1 jdk/make/mkdemo/nio/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/mkdemo/nio/Makefile Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,39 @@ +# +# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +# +# Makefile for building the jfc demos +# + +BUILDDIR = ../.. +PRODUCT = demos +include $(BUILDDIR)/common/Defs.gmk + +SUBDIRS = zipfs +include $(BUILDDIR)/common/Subdirs.gmk + +all build clean clobber:: + $(SUBDIRS-loop) + diff -r 43cb79a6b123 -r d954b585d3a1 jdk/make/mkdemo/nio/zipfs/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/mkdemo/nio/zipfs/Makefile Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,44 @@ +# +# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. +# 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. +# + +# +# Makefile to build the ZipFileSystem demo. +# + +BUILDDIR = ../../.. +PRODUCT = demo/zipfs +DEMONAME = zipfs +include $(BUILDDIR)/common/Defs.gmk + +DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME) +DEMO_TOPFILES = ./README.txt +DEMO_SRCDIR = $(DEMO_ROOT) +DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME) + +# +# Demo jar building rules. +# +include $(BUILDDIR)/common/Demo.gmk + diff -r 43cb79a6b123 -r d954b585d3a1 jdk/make/sun/cmm/lcms/Makefile --- a/jdk/make/sun/cmm/lcms/Makefile Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/make/sun/cmm/lcms/Makefile Wed Oct 13 17:51:41 2010 -0700 @@ -80,7 +80,12 @@ vpath %.c $(SHARE_SRC)/native/sun/java2d ifeq ($(PLATFORM), windows) -OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt +OTHER_CFLAGS += -DCMS_IS_WINDOWS_ + +ifeq ($(COMPILER_VERSION), VS2003) +OTHER_CFLAGS += -Dsqrtf=sqrt +endif + OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \ -I$(SHARE_SRC)/native/sun/awt/debug diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/awt/Dialog.java --- a/jdk/src/share/classes/java/awt/Dialog.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/awt/Dialog.java Wed Oct 13 17:51:41 2010 -0700 @@ -1068,7 +1068,7 @@ modalityPushed(); try { EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); - secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000); + secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0); if (!secondaryLoop.enter()) { secondaryLoop = null; } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/awt/KeyboardFocusManager.java --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Wed Oct 13 17:51:41 2010 -0700 @@ -142,6 +142,9 @@ public void removeLastFocusRequest(Component heavyweight) { KeyboardFocusManager.removeLastFocusRequest(heavyweight); } + public void setMostRecentFocusOwner(Window window, Component component) { + KeyboardFocusManager.setMostRecentFocusOwner(window, component); + } } ); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/awt/event/ActionEvent.java --- a/jdk/src/share/classes/java/awt/event/ActionEvent.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java Wed Oct 13 17:51:41 2010 -0700 @@ -51,7 +51,7 @@ * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}. * * @see ActionListener - * @see Tutorial: Java 1.1 Event Model + * @see Tutorial: How to Write an Action Listener * * @author Carl Quinn * @since 1.1 diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/awt/image/SampleModel.java --- a/jdk/src/share/classes/java/awt/image/SampleModel.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/awt/image/SampleModel.java Wed Oct 13 17:51:41 2010 -0700 @@ -937,14 +937,22 @@ int iArray[], DataBuffer data) { int pixels[]; int Offset=0; + int x1 = x + w; + int y1 = y + h; + + if (x < 0 || x1 < x || x1 > width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates."); + } if (iArray != null) pixels = iArray; else pixels = new int[w * h]; - for(int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for(int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (fArray != null) pixels = fArray; else pixels = new float[w * h]; - for (int i=y; i<(h+y); i++) { - for (int j=x; j<(w+x); j++) { + for (int i=y; i width || + y < 0 || y1 < y || y1 > height) + { + throw new ArrayIndexOutOfBoundsException("Invalid coordinates"); + } if (dArray != null) pixels = dArray; else pixels = new double[w * h]; - for (int i=y; i<(y+h); i++) { - for (int j=x; j<(x+w); j++) { + for (int i=y; i type, String name, int args) { - for (Method method : type.getMethods()) { - if (method.getName().equals(name) && (args == method.getParameterTypes().length)) { - try { - return MethodFinder.findAccessibleMethod(method); + /** + * Internal support for finding a target methodName with a given + * parameter list on a given class. + */ + private static Method internalFindMethod(Class start, String methodName, + int argCount, Class args[]) { + // For overriden methods we need to find the most derived version. + // So we start with the given class and walk up the superclass chain. + + Method method = null; + + for (Class cl = start; cl != null; cl = cl.getSuperclass()) { + Method methods[] = getPublicDeclaredMethods(cl); + for (int i = 0; i < methods.length; i++) { + method = methods[i]; + if (method == null) { + continue; } - catch (NoSuchMethodException exception) { - // continue search for a method with the specified count of parameters + + // make sure method signature matches. + Class params[] = FeatureDescriptor.getParameterTypes(start, method); + if (method.getName().equals(methodName) && + params.length == argCount) { + if (args != null) { + boolean different = false; + if (argCount > 0) { + for (int j = 0; j < argCount; j++) { + if (params[j] != args[j]) { + different = true; + continue; + } + } + if (different) { + continue; + } + } + } + return method; } } } - return null; + method = null; + + // Now check any inherited interfaces. This is necessary both when + // the argument class is itself an interface, and when the argument + // class is an abstract class. + Class ifcs[] = start.getInterfaces(); + for (int i = 0 ; i < ifcs.length; i++) { + // Note: The original implementation had both methods calling + // the 3 arg method. This is preserved but perhaps it should + // pass the args array instead of null. + method = internalFindMethod(ifcs[i], methodName, argCount, null); + if (method != null) { + break; + } + } + return method; } - static Method findInstanceMethod(Class type, String name, Class... args) { - try { - return MethodFinder.findInstanceMethod(type, name, args); - } - catch (NoSuchMethodException exception) { + /** + * Find a target methodName on a given class. + */ + static Method findMethod(Class cls, String methodName, int argCount) { + return findMethod(cls, methodName, argCount, null); + } + + /** + * Find a target methodName with specific parameter list on a given class. + *

+ * Used in the contructors of the EventSetDescriptor, + * PropertyDescriptor and the IndexedPropertyDescriptor. + *

+ * @param cls The Class object on which to retrieve the method. + * @param methodName Name of the method. + * @param argCount Number of arguments for the desired method. + * @param args Array of argument types for the method. + * @return the method or null if not found + */ + static Method findMethod(Class cls, String methodName, int argCount, + Class args[]) { + if (methodName == null) { return null; } + return internalFindMethod(cls, methodName, argCount, args); } /** diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/beans/MethodDescriptor.java --- a/jdk/src/share/classes/java/beans/MethodDescriptor.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java Wed Oct 13 17:51:41 2010 -0700 @@ -90,13 +90,13 @@ // Find methods for up to 2 params. We are guessing here. // This block should never execute unless the classloader // that loaded the argument classes disappears. - method = Introspector.findMethod(cls, name, i); + method = Introspector.findMethod(cls, name, i, null); if (method != null) { break; } } } else { - method = Statement.getMethod(cls, name, params); + method = Introspector.findMethod(cls, name, params.length, params); } setMethod(method); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/beans/PropertyDescriptor.java --- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java Wed Oct 13 17:51:41 2010 -0700 @@ -112,7 +112,8 @@ // If this class or one of its base classes allow PropertyChangeListener, // then we assume that any properties we discover are "bound". // See Introspector.getTargetPropertyInfo() method. - this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class); + Class[] args = { PropertyChangeListener.class }; + this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args); } /** @@ -223,10 +224,10 @@ // property type is. For booleans, there can be "is" and "get" // methods. If an "is" method exists, this is the official // reader method so look for this one first. - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); if (readMethod == null) { readMethodName = Introspector.GET_PREFIX + getBaseName(); - readMethod = Introspector.findInstanceMethod(cls, readMethodName); + readMethod = Introspector.findMethod(cls, readMethodName, 0); } try { setReadMethod(readMethod); @@ -291,7 +292,8 @@ writeMethodName = Introspector.SET_PREFIX + getBaseName(); } - writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type); + Class[] args = (type == null) ? null : new Class[] { type }; + writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args); if (writeMethod != null) { if (!writeMethod.getReturnType().equals(void.class)) { writeMethod = null; diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/util/Locale.java --- a/jdk/src/share/classes/java/util/Locale.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/util/Locale.java Wed Oct 13 17:51:41 2010 -0700 @@ -569,6 +569,9 @@ * @exception NullPointerException thrown if any argument is null. */ public Locale(String language, String country, String variant) { + if (language== null || country == null || variant == null) { + throw new NullPointerException(); + } _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant); _extensions = getCompatibilityExtensions(language, "", country, variant); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/java/util/ResourceBundle.java --- a/jdk/src/share/classes/java/util/ResourceBundle.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/java/util/ResourceBundle.java Wed Oct 13 17:51:41 2010 -0700 @@ -293,16 +293,6 @@ = new ConcurrentHashMap(INITIAL_CACHE_SIZE); /** - * This ConcurrentMap is used to keep multiple threads from loading the - * same bundle concurrently. The table entries are - * where CacheKey is the key for the bundle that is under construction - * and Thread is the thread that is constructing the bundle. - * This list is manipulated in findBundleInCache and putBundleInCache. - */ - private static final ConcurrentMap underConstruction - = new ConcurrentHashMap(); - - /** * Queue for reference objects referring to class loaders or bundles. */ private static final ReferenceQueue referenceQueue = new ReferenceQueue(); @@ -1381,7 +1371,7 @@ boolean expiredBundle = false; // First, look up the cache to see if it's in the cache, without - // declaring beginLoading. + // attempting to load bundle. cacheKey.setLocale(targetLocale); ResourceBundle bundle = findBundleInCache(cacheKey, control); if (isValidBundle(bundle)) { @@ -1408,56 +1398,25 @@ CacheKey constKey = (CacheKey) cacheKey.clone(); try { - // Try declaring loading. If beginLoading() returns true, - // then we can proceed. Otherwise, we need to take a look - // at the cache again to see if someone else has loaded - // the bundle and put it in the cache while we've been - // waiting for other loading work to complete. - while (!beginLoading(constKey)) { - bundle = findBundleInCache(cacheKey, control); - if (bundle == null) { - continue; + bundle = loadBundle(cacheKey, formats, control, expiredBundle); + if (bundle != null) { + if (bundle.parent == null) { + bundle.setParent(parent); } - if (bundle == NONEXISTENT_BUNDLE) { - // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist. - return parent; - } - expiredBundle = bundle.expired; - if (!expiredBundle) { - if (bundle.parent == parent) { - return bundle; - } - BundleReference bundleRef = cacheList.get(cacheKey); - if (bundleRef != null && bundleRef.get() == bundle) { - cacheList.remove(cacheKey, bundleRef); - } - } + bundle.locale = targetLocale; + bundle = putBundleInCache(cacheKey, bundle, control); + return bundle; } - try { - bundle = loadBundle(cacheKey, formats, control, expiredBundle); - if (bundle != null) { - if (bundle.parent == null) { - bundle.setParent(parent); - } - bundle.locale = targetLocale; - bundle = putBundleInCache(cacheKey, bundle, control); - return bundle; - } - - // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle - // instance for the locale. - putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); - } finally { - endLoading(constKey); - } + // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle + // instance for the locale. + putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control); } finally { if (constKey.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } - assert underConstruction.get(cacheKey) != Thread.currentThread(); return parent; } @@ -1465,7 +1424,6 @@ List formats, Control control, boolean reload) { - assert underConstruction.get(cacheKey) == Thread.currentThread(); // Here we actually load the bundle in the order of formats // specified by the getFormats() value. @@ -1498,7 +1456,6 @@ break; } } - assert underConstruction.get(cacheKey) == Thread.currentThread(); return bundle; } @@ -1530,57 +1487,6 @@ } /** - * Declares the beginning of actual resource bundle loading. This method - * returns true if the declaration is successful and the current thread has - * been put in underConstruction. If someone else has already begun - * loading, this method waits until that loading work is complete and - * returns false. - */ - private static final boolean beginLoading(CacheKey constKey) { - Thread me = Thread.currentThread(); - Thread worker; - // We need to declare by putting the current Thread (me) to - // underConstruction that we are working on loading the specified - // resource bundle. If we are already working the loading, it means - // that the resource loading requires a recursive call. In that case, - // we have to proceed. (4300693) - if (((worker = underConstruction.putIfAbsent(constKey, me)) == null) - || worker == me) { - return true; - } - - // If someone else is working on the loading, wait until - // the Thread finishes the bundle loading. - synchronized (worker) { - while (underConstruction.get(constKey) == worker) { - try { - worker.wait(); - } catch (InterruptedException e) { - // record the interruption - constKey.setCause(e); - } - } - } - return false; - } - - /** - * Declares the end of the bundle loading. This method calls notifyAll - * for those who are waiting for this completion. - */ - private static final void endLoading(CacheKey constKey) { - // Remove this Thread from the underConstruction map and wake up - // those who have been waiting for me to complete this bundle - // loading. - Thread me = Thread.currentThread(); - assert (underConstruction.get(constKey) == me); - underConstruction.remove(constKey); - synchronized (me) { - me.notifyAll(); - } - } - - /** * Throw a MissingResourceException with proper message */ private static final void throwMissingResourceException(String baseName, diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/GroupLayout.java --- a/jdk/src/share/classes/javax/swing/GroupLayout.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/GroupLayout.java Wed Oct 13 17:51:41 2010 -0700 @@ -1464,8 +1464,8 @@ * <= {@code pref} <= {@code max}. *

* Similarly any methods that take a {@code Component} throw a - * {@code NullPointerException} if passed {@code null} and any methods - * that take a {@code Group} throw an {@code IllegalArgumentException} if + * {@code IllegalArgumentException} if passed {@code null} and any methods + * that take a {@code Group} throw an {@code NullPointerException} if * passed {@code null}. * * @see #createSequentialGroup diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/JComponent.java --- a/jdk/src/share/classes/javax/swing/JComponent.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/JComponent.java Wed Oct 13 17:51:41 2010 -0700 @@ -4787,6 +4787,17 @@ * @see RepaintManager#addDirtyRegion */ public void repaint(long tm, int x, int y, int width, int height) { + Container p = this; + while ((p = p.getParent()) instanceof JComponent) { + JComponent jp = (JComponent) p; + if (jp.isPaintingOrigin()) { + Rectangle rectangle = SwingUtilities.convertRectangle( + this, new Rectangle(x, y, width, height), jp); + jp.repaint(tm, + rectangle.x, rectangle.y, rectangle.width, rectangle.height); + return; + } + } RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/JDesktopPane.java --- a/jdk/src/share/classes/javax/swing/JDesktopPane.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/JDesktopPane.java Wed Oct 13 17:51:41 2010 -0700 @@ -215,7 +215,8 @@ /** * Sets the DesktopManger that will handle - * desktop-specific UI actions. + * desktop-specific UI actions. This may be overridden by + * {@code LookAndFeel}. * * @param d the DesktopManager to use * diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/JLayer.java --- a/jdk/src/share/classes/javax/swing/JLayer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/JLayer.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,17 +25,17 @@ package javax.swing; +import sun.awt.AWTAccessor; + import javax.swing.plaf.LayerUI; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; import java.security.AccessController; import java.security.PrivilegedAction; @@ -156,8 +156,6 @@ private LayerUI layerUI; private JPanel glassPane; private boolean isPainting; - private static final DefaultLayerLayout sharedLayoutInstance = - new DefaultLayerLayout(); private long eventMask; private static final LayerEventController eventController = @@ -165,7 +163,7 @@ /** * Creates a new {@code JLayer} object with a {@code null} view component - * and {@code null} {@link javax.swing.plaf.LayerUI}. + * and default {@link javax.swing.plaf.LayerUI}. * * @see #setView * @see #setUI @@ -176,14 +174,14 @@ /** * Creates a new {@code JLayer} object - * with {@code null} {@link javax.swing.plaf.LayerUI}. + * with default {@link javax.swing.plaf.LayerUI}. * * @param view the component to be decorated by this {@code JLayer} * * @see #setUI */ public JLayer(V view) { - this(view, null); + this(view, new LayerUI()); } /** @@ -195,7 +193,6 @@ * to be used by this {@code JLayer} */ public JLayer(V view, LayerUI ui) { - setLayout(sharedLayoutInstance); setGlassPane(createGlassPane()); setView(view); setUI(ui); @@ -279,10 +276,15 @@ */ public void setGlassPane(JPanel glassPane) { Component oldGlassPane = getGlassPane(); + boolean isGlassPaneVisible = false; if (oldGlassPane != null) { + isGlassPaneVisible = oldGlassPane.isVisible(); super.remove(oldGlassPane); } if (glassPane != null) { + AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane, + new Rectangle()); + glassPane.setVisible(isGlassPaneVisible); super.addImpl(glassPane, null, 0); } this.glassPane = glassPane; @@ -303,6 +305,40 @@ } /** + * Sets the layout manager for this container. This method is + * overridden to prevent the layout manager from being set. + *

Note: If {@code mgr} is non-{@code null}, this + * method will throw an exception as layout managers are not supported on + * a {@code JLayer}. + * + * @param mgr the specified layout manager + * @exception IllegalArgumentException this method is not supported + */ + public void setLayout(LayoutManager mgr) { + if (mgr != null) { + throw new IllegalArgumentException("JLayer.setLayout() not supported"); + } + } + + /** + * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry + * of this component from becoming complex enough to inhibit + * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, + * add it to a {@code JPanel} that has a border. + *

Note: If {@code border} is non-{@code null}, this + * method will throw an exception as borders are not supported on + * a {@code JLayer}. + * + * @param border the {@code Border} to set + * @exception IllegalArgumentException this method is not supported + */ + public void setBorder(Border border) { + if (border != null) { + throw new IllegalArgumentException("JLayer.setBorder() not supported"); + } + } + + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} * @@ -341,6 +377,32 @@ } /** + * Always returns {@code true} to cause painting to originate from {@code JLayer}, + * or one of its ancestors. + * + * @return true + * @see JComponent#isPaintingOrigin() + */ + boolean isPaintingOrigin() { + return true; + } + + /** + * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + */ + public void repaint(long tm, int x, int y, int width, int height) { + if (getUI() != null) { + getUI().repaint(tm, x, y, width, height, this); + } + } + + /** * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object. * * @param g the {@code Graphics} to render to @@ -364,14 +426,18 @@ } /** - * To enable the correct painting of the {@code glassPane} and view component, - * the {@code JLayer} overrides the default implementation of - * this method to return {@code false} when the {@code glassPane} is visible. + * The {@code JLayer} overrides the default implementation of + * this method (in {@code JComponent}) to return {@code false}. + * This ensures + * that the drawing machinery will call the {@code JLayer}'s + * {@code paint} + * implementation rather than messaging the {@code JLayer}'s + * children directly. * - * @return false if {@code JLayer}'s {@code glassPane} is visible + * @return false */ public boolean isOptimizedDrawingEnabled() { - return glassPane == null || !glassPane.isVisible(); + return false; } /** @@ -461,17 +527,16 @@ /** * Returns the preferred size of the viewport for a view component. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the preferred size of the viewport for a view component * * @see Scrollable - * @see LayerUI#getPreferredScrollableViewportSize(JLayer) */ public Dimension getPreferredScrollableViewportSize() { - if (getUI() != null) { - return getUI().getPreferredScrollableViewportSize(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getPreferredScrollableViewportSize(); } return getPreferredSize(); } @@ -481,18 +546,17 @@ * that display logical rows or columns in order to completely expose * one block of rows or columns, depending on the value of orientation. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return the "block" increment for scrolling in the specified direction * * @see Scrollable - * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int) */ public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableBlockIncrement(this, visibleRect, + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect, orientation, direction); } return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : @@ -504,17 +568,16 @@ * determine the height of the layer, unless the preferred height * of the layer is smaller than the height of the viewport. *

- * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the height of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportHeight(JLayer) */ public boolean getScrollableTracksViewportHeight() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportHeight(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportHeight(); } return false; } @@ -524,17 +587,16 @@ * determine the width of the layer, unless the preferred width * of the layer is smaller than the width of the viewport. *

- * If the ui delegate of this layer is not null, this method delegates its - * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return whether the layer should track the width of the viewport * * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) */ public boolean getScrollableTracksViewportWidth() { - if (getUI() != null) { - return getUI().getScrollableTracksViewportWidth(this); + if (getView() instanceof Scrollable) { + return ((Scrollable)getView()).getScrollableTracksViewportWidth(); } return false; } @@ -549,20 +611,19 @@ * Scrolling containers, like {@code JScrollPane}, will use this method * each time the user requests a unit scroll. *

- * If the ui delegate of this layer is not {@code null}, this method delegates its - * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)} + * If the view component of this layer implements {@link Scrollable}, this method delegates its + * implementation to the view component. * * @return The "unit" increment for scrolling in the specified direction. * This value should always be positive. * * @see Scrollable - * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int) */ public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { - if (getUI() != null) { - return getUI().getScrollableUnitIncrement( - this, visibleRect, orientation, direction); + if (getView() instanceof Scrollable) { + return ((Scrollable) getView()).getScrollableUnitIncrement( + visibleRect, orientation, direction); } return 1; } @@ -595,6 +656,16 @@ } /** + * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method, + * if {@code LayerUI} is set. + */ + public void doLayout() { + if (getUI() != null) { + getUI().doLayout(this); + } + } + + /** * static AWTEventListener to be shared with all AbstractLayerUIs */ private static class LayerEventController implements AWTEventListener { @@ -625,8 +696,8 @@ JLayer l = (JLayer) component; LayerUI ui = l.getUI(); if (ui != null && - isEventEnabled(l.getLayerEventMask(), - event.getID())) { + isEventEnabled(l.getLayerEventMask(), event.getID()) && + (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) { ui.eventDispatched(event, l); } } @@ -758,82 +829,4 @@ return super.contains(x, y); } } - - /** - * The default layout manager for the {@link javax.swing.JLayer}.
- * It places the glassPane on top of the view component - * and makes it the same size as {@code JLayer}, - * it also makes the view component the same size but minus layer's insets
- */ - private static class DefaultLayerLayout implements LayoutManager, Serializable { - /** - * {@inheritDoc} - */ - public void layoutContainer(Container parent) { - JLayer layer = (JLayer) parent; - Component view = layer.getView(); - Component glassPane = layer.getGlassPane(); - if (view != null) { - Insets insets = layer.getInsets(); - view.setLocation(insets.left, insets.top); - view.setSize(layer.getWidth() - insets.left - insets.right, - layer.getHeight() - insets.top - insets.bottom); - } - if (glassPane != null) { - glassPane.setLocation(0, 0); - glassPane.setSize(layer.getWidth(), layer.getHeight()); - } - } - - /** - * {@inheritDoc} - */ - public Dimension minimumLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getMinimumSize(); - ret.width += size.width; - ret.height += size.height; - } - if (ret.width == 0 || ret.height == 0) { - ret.width = ret.height = 4; - } - return ret; - } - - /** - * {@inheritDoc} - */ - public Dimension preferredLayoutSize(Container parent) { - JLayer layer = (JLayer) parent; - Insets insets = layer.getInsets(); - Dimension ret = new Dimension(insets.left + insets.right, - insets.top + insets.bottom); - Component view = layer.getView(); - if (view != null) { - Dimension size = view.getPreferredSize(); - if (size.width > 0 && size.height > 0) { - ret.width += size.width; - ret.height += size.height; - } - } - return ret; - } - - /** - * {@inheritDoc} - */ - public void addLayoutComponent(String name, Component comp) { - } - - /** - * {@inheritDoc} - */ - public void removeLayoutComponent(Component comp) { - } - } } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/JTable.java --- a/jdk/src/share/classes/javax/swing/JTable.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/JTable.java Wed Oct 13 17:51:41 2010 -0700 @@ -4574,9 +4574,8 @@ * @see TableColumnModelListener */ public void columnMoved(TableColumnModelEvent e) { - // If I'm currently editing, then I should stop editing - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } repaint(); } @@ -4593,8 +4592,8 @@ * @see TableColumnModelListener */ public void columnMarginChanged(ChangeEvent e) { - if (isEditing()) { - removeEditor(); + if (isEditing() && !getCellEditor().stopCellEditing()) { + getCellEditor().cancelCellEditing(); } TableColumn resizingColumn = getResizingColumn(); // Need to do this here, before the parent's diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/ToolTipManager.java --- a/jdk/src/share/classes/javax/swing/ToolTipManager.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java Wed Oct 13 17:51:41 2010 -0700 @@ -459,7 +459,7 @@ if (insideComponent == null) { // Drag exit } - if (window != null && event.getSource() == window) { + if (window != null && event.getSource() == window && insideComponent != null) { // if we get an exit and have a heavy window // we need to check if it if overlapping the inside component Container insideComponentWindow = insideComponent.getTopLevelAncestor(); diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/plaf/LayerUI.java --- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Wed Oct 13 17:51:41 2010 -0700 @@ -600,104 +600,6 @@ } /** - * Returns the preferred size of the viewport for a view component. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return the preferred size of the viewport for a view component - * @see Scrollable#getPreferredScrollableViewportSize() - */ - public Dimension getPreferredScrollableViewportSize(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getPreferredScrollableViewportSize(); - } - return l.getPreferredSize(); - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one block of rows or columns, depending on the value of orientation. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return the "block" increment for scrolling in the specified direction - * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int) - */ - public int getScrollableBlockIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableBlockIncrement( - visibleRect,orientation, direction); - } - return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : - visibleRect.width; - } - - /** - * Returns {@code false} to indicate that the height of the viewport does not - * determine the height of the layer, unless the preferred height - * of the layer is smaller than the height of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the height of the viewport - * @see Scrollable#getScrollableTracksViewportHeight() - */ - public boolean getScrollableTracksViewportHeight(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportHeight(); - } - return false; - } - - /** - * Returns {@code false} to indicate that the width of the viewport does not - * determine the width of the layer, unless the preferred width - * of the layer is smaller than the width of the viewport. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @return whether the layer should track the width of the viewport - * @see Scrollable - * @see LayerUI#getScrollableTracksViewportWidth(JLayer) - */ - public boolean getScrollableTracksViewportWidth(JLayer l) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableTracksViewportWidth(); - } - return false; - } - - /** - * Returns a scroll increment, which is required for components - * that display logical rows or columns in order to completely expose - * one new row or column, depending on the value of orientation. - * Ideally, components should handle a partially exposed row or column - * by returning the distance required to completely expose the item. - *

- * Scrolling containers, like JScrollPane, will use this method - * each time the user requests a unit scroll. - * - * @param l the {@code JLayer} component where this UI delegate is being installed - * @param visibleRect The view area visible within the viewport - * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL. - * @param direction Less than zero to scroll up/left, greater than zero for down/right. - * @return The "unit" increment for scrolling in the specified direction. - * This value should always be positive. - * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) - */ - public int getScrollableUnitIncrement(JLayer l, - Rectangle visibleRect, - int orientation, int direction) { - if (l.getView() instanceof Scrollable) { - return ((Scrollable)l.getView()).getScrollableUnitIncrement( - visibleRect, orientation, direction); - } - return 1; - } - - /** * If the {@code JLayer}'s view component is not {@code null}, * this calls the view's {@code getBaseline()} method. * Otherwise, the default implementation is called. @@ -718,7 +620,7 @@ /** * If the {@code JLayer}'s view component is not {@code null}, - * this calls the view's {@code getBaselineResizeBehavior()} method. + * this returns the result of the view's {@code getBaselineResizeBehavior()} method. * Otherwise, the default implementation is called. * * @param c {@code JLayer} to return baseline resize behavior for @@ -732,4 +634,90 @@ } return super.getBaselineResizeBehavior(c); } + + /** + * Causes the passed instance of {@code JLayer} to lay out its components. + * + * @param l the {@code JLayer} component where this UI delegate is being installed + */ + public void doLayout(JLayer l) { + Component view = l.getView(); + if (view != null) { + view.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + Component glassPane = l.getGlassPane(); + if (glassPane != null) { + glassPane.setBounds(0, 0, l.getWidth(), l.getHeight()); + } + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getPreferredSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return preferred size for the passed {@code JLayer} + */ + public Dimension getPreferredSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getPreferredSize(); + } + return super.getPreferredSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMinimalSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return minimal size for the passed {@code JLayer} + */ + public Dimension getMinimumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMinimumSize(); + } + return super.getMinimumSize(c); + } + + /** + * If the {@code JLayer}'s view component is not {@code null}, + * this returns the result of the view's {@code getMaximumSize()} method. + * Otherwise, the default implementation is used. + * + * @param c {@code JLayer} to return preferred size for + * @return maximun size for the passed {@code JLayer} + */ + public Dimension getMaximumSize(JComponent c) { + JLayer l = (JLayer) c; + Component view = l.getView(); + if (view != null) { + return view.getMaximumSize(); + } + return super.getMaximumSize(c); + } + + /** + * Adds the specified region to the dirty region list if the component + * is showing. The component will be repainted after all of the + * currently pending events have been dispatched. + *

+ * This method is to be overridden when the dirty region needs to be changed. + * + * @param tm this parameter is not used + * @param x the x value of the dirty region + * @param y the y value of the dirty region + * @param width the width of the dirty region + * @param height the height of the dirty region + * @see java.awt.Component#isShowing + * @see RepaintManager#addDirtyRegion + */ + public void repaint(long tm, int x, int y, int width, int height, JLayer l) { + RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height); + } } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java Wed Oct 13 17:51:41 2010 -0700 @@ -1603,6 +1603,7 @@ BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue(); oldModel.removeChangeListener(modelListener); newModel.addChangeListener(modelListener); + scrollBarValue = scrollbar.getValue(); scrollbar.repaint(); scrollbar.revalidate(); } else if ("orientation" == propertyName) { diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java --- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java Wed Oct 13 17:51:41 2010 -0700 @@ -144,7 +144,7 @@ */ public int getBaseline(JComponent c, int width, int height) { int baseline; - if (MetalLookAndFeel.usingOcean()) { + if (MetalLookAndFeel.usingOcean() && height >= 4) { height -= 4; baseline = super.getBaseline(c, width, height); if (baseline >= 0) { diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java Wed Oct 13 17:51:41 2010 -0700 @@ -115,6 +115,9 @@ return new SynthTabbedPaneUI(); } + private SynthTabbedPaneUI() { + } + private boolean scrollableTabLayoutEnabled() { return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/sun/awt/AWTAccessor.java --- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Wed Oct 13 17:51:41 2010 -0700 @@ -344,6 +344,11 @@ * Removes the last focus request for the heavyweight from the queue. */ void removeLastFocusRequest(Component heavyweight); + + /* + * Sets the most recent focus owner in the window. + */ + void setMostRecentFocusOwner(Window window, Component component); } /* diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/sun/awt/EmbeddedFrame.java --- a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java Wed Oct 13 17:51:41 2010 -0700 @@ -70,7 +70,10 @@ // JDK 1.1 compatibility private static final long serialVersionUID = 2967042741780317130L; - // Use these in traverseOut method to determine directions + /* + * The constants define focus traversal directions. + * Use them in {@code traverseIn}, {@code traverseOut} methods. + */ protected static final boolean FORWARD = true; protected static final boolean BACKWARD = false; @@ -284,6 +287,41 @@ } /** + * This method is called by the embedder when we should receive focus as element + * of the traversal chain. The method requests focus on: + * 1. the first Component of this EmbeddedFrame if user moves focus forward + * in the focus traversal cycle. + * 2. the last Component of this EmbeddedFrame if user moves focus backward + * in the focus traversal cycle. + * + * The direction parameter specifies which of the two mentioned cases is + * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class + * to avoid confusing boolean values. + * + * A concrete implementation of this method is defined in the platform-dependent + * subclasses. + * + * @param direction FORWARD or BACKWARD + * @return true, if the EmbeddedFrame wants to get focus, false otherwise. + */ + public boolean traverseIn(boolean direction) { + Component comp = null; + + if (direction == FORWARD) { + comp = getFocusTraversalPolicy().getFirstComponent(this); + } else { + comp = getFocusTraversalPolicy().getLastComponent(this); + } + if (comp != null) { + // comp.requestFocus(); - Leads to a hung. + + AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp); + synthesizeWindowActivation(true); + } + return (null != comp); + } + + /** * This method is called from dispatchKeyEvent in the following two cases: * 1. The focus is on the first Component of this EmbeddedFrame and we are * about to transfer the focus backward. diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/classes/sun/util/locale/BaseLocale.java --- a/jdk/src/share/classes/sun/util/locale/BaseLocale.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/share/classes/sun/util/locale/BaseLocale.java Wed Oct 13 17:51:41 2010 -0700 @@ -64,12 +64,14 @@ public static BaseLocale getInstance(String language, String script, String region, String variant) { // JDK uses deprecated ISO639.1 language codes for he, yi and id - if (AsciiUtil.caseIgnoreMatch(language, "he")) { - language = "iw"; - } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { - language = "ji"; - } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { - language = "in"; + if (language != null) { + if (AsciiUtil.caseIgnoreMatch(language, "he")) { + language = "iw"; + } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) { + language = "ji"; + } else if (AsciiUtil.caseIgnoreMatch(language, "id")) { + language = "in"; + } } Key key = new Key(language, script, region, variant); diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/Demo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/Demo.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,664 @@ +/* + * 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 [-cp .../zipfs.jar:./] Demo action ZipfileName [...] + * + * To deploy the provider, either copy the zipfs.jar into JDK/JRE + * extensions directory or add + * /demo/nio/ZipFileSystem/zipfs.jar + * into your class path as showed above. + * + * @author Xueming Shen + */ + +public class Demo { + + static enum Action { + rename, // + // rename entry src to dst inside zipfile + + movein, // + // move an external src file into zipfile + // as entry dst + + moveout, // + // move a zipfile entry src out to dst + + copy, // + // copy entry src to dst inside zipfile + + copyin, // + // copy an external src file into zipfile + // as entry dst + + copyout, // + // copy zipfile entry src" out to file dst + + zzmove, // + // move entry path/dir from zfsrc to zfdst + + zzcopy, // + // copy path from zipfile zfsrc to zipfile + // zfdst + + attrs, // + // printout the attributes of entry path + + attrsspace, // + // printout the storespace attrs of entry path + + setmtime, // + // set the lastModifiedTime of entry path + + lsdir, // + // list dir's direct child files/dirs + + mkdir, // + + mkdirs, // + + rmdirs, // + + list, // + // recursively list all entries of dir + // via DirectoryStream + + tlist, // + // list with buildDirTree=true + + vlist, // + // recursively verbose list all entries of + // dir via DirectoryStream + + walk, // + // recursively walk all entries of dir + // via Files.walkFileTree + + twalk, // + // walk with buildDirTree=true + + extract, // + + update, // + + delete, // + + add, // + + create, // + // create a new zipfile if it doesn't exit + // and then add the file(s) into it. + + attrs2, // + // test different ways to print attrs + } + + public static void main(String[] args) throws Throwable { + + Action action = Action.valueOf(args[0]);; + Map env = env = new HashMap(); + if (action == Action.create) + env.put("createNew", true); + if (action == Action.tlist || action == Action.twalk) + env.put("buildDirTree", true); + + FileSystem fs = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)), + 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 zzmove: + fs2 = FileSystems.newFileSystem( + URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)), + 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); + //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( + 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 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 ds = path.newDirectoryStream( + new DirectoryStream.Filter() { + 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.println("-------(1)---------"); + System.out.println( + Attributes.readBasicFileAttributes(path).toString()); + System.out.println("-------(2)---------"); + Map map = path.readAttributes("zip:*"); + for (Map.Entry 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 e : map.entrySet()) { + System.out.printf(" %s : %s%n", e.getKey(), e.getValue()); + } + } + break; + } + } 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() { + 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 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 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 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() { + + @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 (verbose) + System.out.println(Attributes.readBasicFileAttributes(path).toString()); + else + System.out.printf(" %s%n", path.toString()); + if (path.notExists()) + return; + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream 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 read = new HashSet<>(); + read.add(READ); + Set 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 read = new HashSet<>(); + read.add(READ); + Set 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(); + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,3 @@ +com.sun.nio.zipfs.ZipFileSystemProvider +com.sun.nio.zipfs.JarFileSystemProvider + diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/README.txt Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,29 @@ +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 /demo/nio/ZipFileSystem/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: + + // use file type detection + Map env = Collections.emptyMap(); + Path jarfile = Path.get("foo.jar"); + FileSystem fs = FileSystems.newFileSystem(jarfile, env); + +-or + + // locate file system by URI + Map env = Collections.emptyMap(); + URI uri = URI.create("zip:///mydir/foo.jar"); + FileSystem fs = FileSystems.newFileSystem(uri, env); + +Once a FileSystem is created then classes in the java.nio.file package +can be used to access files in the zip/JAR file, eg: + + Path mf = fs.getPath("/META-INF/MANIFEST.MF"); + InputStream in = mf.newInputStream(); + + diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,71 @@ +/* + * 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 + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 decTL = new ThreadLocal<>(); + private final ThreadLocal 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; + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,261 @@ +/* + * 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; + +/** + * + * @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; + + /* + * 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 + + + /* + * 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 + + ////////////////////////////////////////// + static final int CH(ByteBuffer b, int pos) { + return b.get(pos) & 0xff; + } + static final int SH(ByteBuffer b, int pos) { + return b.getShort(pos) & 0xffff; + } + static final long LG(ByteBuffer b, int pos) { + return b.getInt(pos) & 0xffffffffL; + } + + // central directory header (END) fields + static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); } + static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); } + static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); } + static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); } + static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);} + static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);} + static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);} + static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);} + static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);} + static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);} + static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);} + static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);} + static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);} + static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);} + static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);} + static final long CENOFF(ByteBuffer 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; +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,109 @@ +/* + * 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; +import static com.sun.nio.zipfs.ZipUtils.*; + +/** + * + * @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal + */ + +public class ZipDirectoryStream implements DirectoryStream { + + private final ZipFileSystem zipfs; + private final byte[] path; + private final DirectoryStream.Filter filter; + private volatile boolean isClosed; + private volatile Iterator itr; + + ZipDirectoryStream(ZipPath zipPath, + DirectoryStream.Filter 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 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; + } + + +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,185 @@ +/* + * 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.ReadOnlyFileSystemException; +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 get(ZipPath path, Class 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); + 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 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; + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,156 @@ +/* + * 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(dosToJavaTime(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(dosToJavaTime(e.atime)); + return null; + } + + @Override + public FileTime lastModifiedTime() { + return FileTime.fromMillis(dosToJavaTime(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 byte[] name() { + return Arrays.copyOf(e.name, e.name.length); + } + + 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(); + Formatter fm = new Formatter(sb); + fm.format("[/%s]%n", new String(e.name)); // TBD encoding + fm.format(" creationTime : %s%n", creationTime()); + 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(); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 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 getFileStoreAttributeView(Class 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(); + } + }; + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,2257 @@ +/* + * 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.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.MappedByteBuffer; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.*; +import java.net.URI; +import java.util.*; +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; + + private final Object lock = new Object(); + + // 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 + + ZipFileSystem(ZipFileSystemProvider provider, + Path zfpath, + Map env) + throws IOException + { + // configurable env setup + this.buildDirTree = TRUE.equals(env.get("buildDirTree")); + 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)); + initZipFile(); + } + + @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 getRootDirectories() { + ArrayList 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 getFileStores() { + ArrayList list = new ArrayList(1); + list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'}))); + return list; + } + + private static final Set supportedFileAttributeViews = + Collections.unmodifiableSet( + new HashSet(Arrays.asList("basic", "zip"))); + + @Override + public Set 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 { + synchronized (lock) { + if (!isOpen) + return; + isOpen = false; + if (!streams.isEmpty()) { + synchronized(streams) { + for (InputStream is: streams) + is.close(); + } + } + sync(); + ch.close(); + } + synchronized (inflaters) { + for (Inflater inf : inflaters) + inf.end(); + } + synchronized (deflaters) { + for (Deflater def : deflaters) + def.end(); + } + for (Path p: tmppaths) { + try { + p.deleteIfExists(); + } catch (IOException x) { + x.printStackTrace(); + } + } + provider.removeFileSystem(zfpath); + } + + ZipFileAttributes[] getAllAttributes() throws IOException { + ensureOpen(); + int n = inodes.size(); + ZipFileAttributes[] zes = new ZipFileAttributes[n]; + Iterator itr = inodes.values().iterator(); + int i = 0; + while(itr.hasNext()) { + zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos)); + } + return zes; + } + + EntryName[] getEntryNames() throws IOException { + ensureOpen(); + return inodes.keySet().toArray(new EntryName[0]); + } + + ZipFileAttributes getFileAttributes(byte[] path) + throws IOException + { + synchronized (lock) { + Entry e = getEntry0(path); + if (e == null) { + if (path.length == 0) { + e = new Entry(new byte[0]); // root + } else if (buildDirTree) { + IndexNode inode = getDirs().get(new EntryName(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 = javaToDosTime(bfas.lastModifiedTime().toMillis()); + if (bfas.lastAccessTime() != null) + e.atime = javaToDosTime(bfas.lastAccessTime().toMillis()); + if (bfas.creationTime() != null) + e.ctime = javaToDosTime(bfas.creationTime().toMillis()); + } + return new ZipFileAttributes(e); + } + } + + void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime) + throws IOException + { + checkWritable(); + synchronized (lock) { + 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 = javaToDosTime(mtime.toMillis()); + if (atime != null) + e.atime = javaToDosTime(atime.toMillis()); + if (ctime != null) + e.ctime = javaToDosTime(ctime.toMillis()); + update(e); + } + } + + boolean exists(byte[] path) + throws IOException + { + return getEntry0(path) != null; + } + + boolean isDirectory(byte[] path) + throws IOException + { + synchronized (lock) { + if (buildDirTree) { + return getDirs().containsKey(new EntryName(path)); + } + Entry e = getEntry0(path); + return (e != null && e.isDir()) || path.length == 0; + } + } + + 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 iteratorOf(byte[] path, + DirectoryStream.Filter filter) + throws IOException + { + synchronized (lock) { + if (buildDirTree) { + IndexNode inode = getDirs().get(new EntryName(path)); + if (inode == null) + throw new NotDirectoryException(getString(path)); + List 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 list = new ArrayList(); + EntryName[] entries = getEntryNames(); + path = toDirectoryPath(path); + for (EntryName en :entries) { + if (!isParentOf(path, en.name)) // is "path" the parent of "name" + continue; + int off = path.length; + while (off < en.name.length) { + if (en.name[off] == '/') + break; + off++; + } + if (off < (en.name.length - 1)) + continue; + ZipPath zp = toZipPath(en.name); + if (filter == null || filter.accept(zp)) + list.add(zp); + } + return list.iterator(); + } + } + + void createDirectory(byte[] dir, FileAttribute... attrs) + throws IOException + { + checkWritable(); + dir = toDirectoryPath(dir); + synchronized (lock) { + ensureOpen(); + // pseudo root dir, or exiting dir + if (dir.length == 0 || exists(dir)) + throw new FileAlreadyExistsException(getString(dir)); + checkParents(dir); + + Entry e = new Entry(dir, Entry.NEW); + e.method = METHOD_STORED; // STORED for dir + update(e); + } + } + + 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 + synchronized (lock) { + 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 + // don't touch the "nlen and elen" here. writeLOC() always + // re-calculate from "name" and "extra" for the correct length, + // copyLOCEntry however needs the original lengths to skip the + // loc header. + // u.nlen = dst.length; + 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 = javaToDosTime(System.currentTimeMillis()); + update(u); + if (deletesrc) + updateDelete(eSrc); + } + } + + // 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; + } + synchronized (lock) { + 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)); + } + } + } + + // Returns an input stream for reading the contents of the specified + // file entry. + InputStream newInputStream(byte[] path) throws IOException { + synchronized (lock) { + 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); + } + } + + private void checkOptions(Set 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 options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + if (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)) { + checkWritable(); + 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(); + } + }; + } else { + 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(); + } + }; + } + } + + // 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 options, + FileAttribute... attrs) + throws IOException + { + checkOptions(options); + final boolean forWrite = (options.contains(StandardOpenOption.WRITE) || + options.contains(StandardOpenOption.APPEND)); + 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 = javaToDosTime(System.currentTimeMillis()); + u.size = Attributes.readBasicFileAttributes(u.file).size(); + update(u); + } else { + if (!isFCH) // if this is a new fch for reading + removeTempPathForEntry(tmpfile); + } + } + }; + } + + // the outstanding input streams that need to be closed + private Set streams = + Collections.synchronizedSet(new HashSet()); + + // the ex-channel and ex-path that need to close when their outstanding + // input streams are all closed by the obtainers. + private Set exChClosers = new HashSet<>(); + + private Set tmppaths = new HashSet<>(); + private Path getTempPathForEntry(byte[] path) throws IOException { + Path tmpPath = createTempFileInSameDirectoryAs(zfpath); + tmppaths.add(tmpPath); + + 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 { + while ((path = getParent(path)) != null) { + if (!inodes.containsKey(new EntryName(path))) + throw new NoSuchFileException(getString(path)); + } + } + + 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 void initZipFile() throws IOException { + ch = zfpath.newByteChannel(READ); + initCEN(); + } + + private volatile boolean isOpen = true; + private SeekableByteChannel ch; // channel to the zipfile + ByteBuffer cen; // CEN & ENDHDR + private END end; + private long locpos; // position of first LOC header (usually 0) + + // name -> pos (in cen), package private for ZipInfo + LinkedHashMap inodes; + + byte[] getBytes(String name) { + return zc.getBytes(name); + } + 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). + private 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 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 long initCEN() throws IOException { + end = findEND(); + if (end.endpos == 0) { + inodes = new LinkedHashMap(10); + locpos = 0; + return 0; // 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 + cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR)); + if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) { + zerror("read CEN tables failed"); + } + cen.order(ByteOrder.LITTLE_ENDIAN).flip(); + + // Iterate through the entries in the central directory + inodes = new LinkedHashMap(end.centot + 1); + int pos = 0; + int limit = cen.remaining() - ENDHDR; + int i = 0; + byte[] bBuf = new byte[1024]; + 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 (bad compression method: " + method + ")"); + if (pos + CENHDR + nlen > limit) + zerror("invalid CEN header (bad header size)"); + if (bBuf.length < nlen) + bBuf = new byte[nlen]; + cen.position(pos + CENHDR); + byte[] name = new byte[nlen]; + cen.get(name); + inodes.put(new EntryName(name), new IndexNode(name, pos)); + // skip ext and comment + cen.position(pos += (CENHDR + nlen + elen + clen)); + i++; + } + if (cen.remaining() != ENDHDR) { + zerror("invalid CEN header (bad header size)"); + } + dirs = null; // clear the dir map + return cenpos; + } + + 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 static Path createTempFileInSameDirectoryAs(Path path) + throws IOException + { + Path parent = path.toAbsolutePath().getParent(); + String dir = (parent == null)? "." : parent.toString(); + return File.createTempFile("zipfstmp", null, new File(dir)).toPath(); + } + + ////////////////////update & sync ////////////////////////////////////// + + private boolean hasUpdate = false; + private void updateDelete(Entry e) { + EntryName en = new EntryName(e.name); + inodes.remove(en); + hasUpdate = true; + } + + private void update(Entry e) { + EntryName en = new EntryName(e.name); + inodes.put(en, e); + hasUpdate = true; + } + + // 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; + } + if (updateHeader) { // if we need update the loc header + locoff += LOCHDR + e.nlen + e.elen; // skip header + size += e.csize; + written = e.writeLOC(os) + size; + } else { + size += LOCHDR + e.nlen + e.elen + e.csize; + written = 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 { + assert Thread.holdsLock(this); + + // 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 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(cen, 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()) { + // 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()); + } else { + ch.close(); + zfpath.delete(); + } + tmpFile.moveTo(zfpath, REPLACE_EXISTING); + hasUpdate = false; // clear + + if (isOpen) { + ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen" + initCEN(); + } + //System.out.println("->sync() done!"); + } + + private Entry getEntry0(byte[] path) throws IOException { + assert Thread.holdsLock(this); + + if (path == null) + throw new NullPointerException("path"); + if (path.length == 0) + return null; + EntryName en = new EntryName(path); + IndexNode inode = null; + synchronized (lock) { + ensureOpen(); + if ((inode = inodes.get(en)) == null) { + if (path[path.length -1] == '/') // already has a slash + return null; + path = Arrays.copyOf(path, path.length + 1); + path[path.length - 1] = '/'; + en.name(path); + if ((inode = inodes.get(en)) == null) + return null; + } + if (inode instanceof Entry) + return (Entry)inode; + return Entry.readCEN(cen, inode.pos); + } + } + + // Test if the "name" a parent directory of any entry (dir empty) + boolean isAncestor(byte[] name) { + for (Map.Entry 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(); + synchronized(lock) { + 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 { + + ensureOpen(); + if (e.mtime == -1) + e.mtime = javaToDosTime(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; + } + } + // 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) { + 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 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 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); + } + } + + private 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 List 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 List 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); + } + } + } + + // wrapper for the byte[] name + static class EntryName { + byte[] name; + int hashcode; // node is hashable/hashed by its name + + public EntryName (byte[] name) { + name(name); + } + + void name(byte[] name) { + this.name = name; + this.hashcode = Arrays.hashCode(name); + } + + public boolean equals(Object other) { + if (!(other instanceof EntryName)) + return false; + return Arrays.equals(name, ((EntryName)other).name); + } + + public int hashCode() { + return hashcode; + } + } + + // can simply use Integer instead, if we don't use it to + // build a internal node tree. + static class IndexNode { + byte[] name; + int pos = -1; // postion in cen table, -1 menas the + // entry does not exists in zip file + IndexNode(byte[] name, int pos) { + this.name = name; + this.pos = pos; + } + + 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 + int nlen; + int elen; + byte[] extra; + + // loc + long startPos; + long endPos; // exclusive + + // cen + int versionMade; + int disk; + int attrs; + long attrsEx; + long locoff; + + int clen; + byte[] comment; + + // ZIP64 flag + boolean hasZip64; + + Entry() {} + + Entry(byte[] name) { + this.name = name; + //this.nlen = name.length; + this.mtime = javaToDosTime(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 (byte[] name, Path file, int type) { + this(name, type); + this.file = file; + this.method = METHOD_STORED; + } + + Entry(Entry e) { + this.version = e.version; + this.name = e.name; // copyOf? + this.nlen = e.nlen; + 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 == null)? + null:Arrays.copyOf(e.extra, e.extra.length); + this.elen = e.elen; + this.versionMade = e.versionMade; + this.disk = e.disk; + this.attrs = e.attrs; + this.attrsEx = e.attrsEx; + this.locoff = e.locoff; + this.clen = e.clen; + this.comment = (e.comment == null)? + null:Arrays.copyOf(e.comment, e.comment.length); + this.startPos = e.startPos; + this.endPos = e.endPos; + this.hasZip64 = e.hasZip64;; + } + + Entry (Entry e, int type) { + this(e); + this.type = type; + } + + 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(ByteBuffer cen, int pos) throws IOException + { + return new Entry().cen(cen, pos); + } + + private Entry cen(ByteBuffer cen, int pos) throws IOException + { + 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 = CENTIM(cen, pos); + crc = CENCRC(cen, pos); + csize = CENSIZ(cen, pos); + size = CENLEN(cen, pos); + nlen = CENNAM(cen, pos); + elen = CENEXT(cen, pos); + clen = CENCOM(cen, pos); + disk = CENDSK(cen, pos); + attrs = CENATT(cen, pos); + attrsEx = CENATX(cen, pos); + locoff = CENOFF(cen, pos); + + cen.position(pos + CENHDR); + name = new byte[nlen]; + cen.get(name); + + if (elen > 0) { + extra = new byte[elen]; + cen.get(extra); + if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL || + locoff == ZIP64_MINVAL) { + int off = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + if (SH(extra, off) == EXTID_ZIP64) { + off += 4; + if (size == ZIP64_MINVAL) { + // if invalid zip64 extra fields, just skip + if (sz < 8 || (off + 8) > elen) + break; + size = LL(extra, off); + sz -= 8; + off += 8; + } + if (csize == ZIP64_MINVAL) { + if (sz < 8 || (off + 8) > elen) + break; + csize = LL(extra, off); + sz -= 8; + off += 8; + } + if (locoff == ZIP64_MINVAL) { + if (sz < 8 || (off + 8) > elen) + break; + locoff = LL(extra, off); + sz -= 8; + off += 8; + } + break; + } + off += (sz + 4); + } + } + } + if (clen > 0) { + comment = new byte[clen]; + cen.get(comment); + } + return this; + } + + int writeCEN(OutputStream os) throws IOException + { + int written = CENHDR; + int version0 = version(); + + long csize0 = csize; + long size0 = size; + long locoff0 = locoff; + int e64len = 0; + + // confirm size/length + nlen = (name != null) ? name.length : 0; + elen = (extra != null) ? extra.length : 0; + clen = (comment != null) ? comment.length : 0; + + boolean hasZip64 = false; + if (csize >= ZIP64_MINVAL) { + csize0 = ZIP64_MINVAL; + e64len += 8; // csize(8) + hasZip64 = true; + } + if (size >= ZIP64_MINVAL) { + size0 = ZIP64_MINVAL; // size(8) + e64len += 8; + hasZip64 = true; + } + if (locoff >= ZIP64_MINVAL) { + locoff0 = ZIP64_MINVAL; + e64len += 8; // offset(8) + hasZip64 = true; + } + writeInt(os, CENSIG); // CEN header signature + if (hasZip64) { + 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 + writeInt(os, mtime); // last modification time + writeInt(os, crc); // crc-32 + writeInt(os, csize0); // compressed size + writeInt(os, size0); // uncompressed size + writeShort(os, name.length); + + if (hasZip64) { + // + headid(2) + datasize(2) + writeShort(os, e64len + 4 + elen); + } else { + writeShort(os, elen); + } + 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 (hasZip64) { + writeShort(os, EXTID_ZIP64);// Zip64 extra + writeShort(os, e64len); + if (size0 == ZIP64_MINVAL) + writeLong(os, size); + if (csize0 == ZIP64_MINVAL) + writeLong(os, csize); + if (locoff0 == ZIP64_MINVAL) + writeLong(os, locoff); + } + if (extra != null) { + writeBytes(os, extra); + } + if (comment != null) { + //TBD: 0, Math.min(commentBytes.length, 0xffff)); + writeBytes(os, comment); + } + return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0); + } + + ///////////////////// LOC ////////////////////// + static Entry readLOC(ZipFileSystem zf, long pos) + throws IOException + { + return readLOC(zf, pos, new byte[1024]); + } + + static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf) + throws IOException + { + return new Entry().loc(zf, pos, buf); + } + + Entry loc(ZipFileSystem zf, long pos, byte[] buf) + throws IOException + { + assert (buf.length >= LOCHDR); + if (zf.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 = LOCTIM(buf); + crc = LOCCRC(buf); + csize = LOCSIZ(buf); + size = LOCLEN(buf); + nlen = LOCNAM(buf); + elen = LOCEXT(buf); + + name = new byte[nlen]; + if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) { + throw new ZipException("loc: name reading failed"); + } + if (elen > 0) { + extra = new byte[elen]; + if (zf.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 = zf.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 { + boolean hasZip64 = false; + 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); + hasZip64 = true; + break; + } + off += (sz + 4); + } + } + pos += (method == METHOD_STORED ? size : csize); + } + endPos = pos; + return this; + } + + int writeLOC(OutputStream os) + throws IOException + { + writeInt(os, LOCSIG); // LOC header signature + + int version = version(); + if ((flag & FLAG_DATADESCR) != 0) { + 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 + + // 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) { + hasZip64 = true; + 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 (hasZip64) { + writeInt(os, ZIP64_MINVAL); + writeInt(os, ZIP64_MINVAL); + //TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8) + } else { + writeInt(os, csize); // compressed size + writeInt(os, size); // uncompressed size + } + } + writeShort(os, name.length); + writeShort(os, elen + (hasZip64 ? 20 : 0)); + writeBytes(os, name); + if (hasZip64) { + // TBD: should we update extra directory? + writeShort(os, EXTID_ZIP64); + writeShort(os, 16); + writeLong(os, size); + writeLong(os, csize); + } + if (extra != null) { + writeBytes(os, extra); + } + return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0); + } + + // 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() { + if (extra == null) + return; + int elen = extra.length; + int off = 0; + while (off + 4 < elen) { + // extra spec: HeaderID+DataSize+Data + int sz = SH(extra, off + 2); + int tag = SH(extra, off); + off += 4; + int pos = off; + 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; + mtime = LL(extra, pos + 4); + atime = LL(extra, pos + 12); + ctime = LL(extra, pos + 20); + break; + case EXTID_UNIX: + atime = LG(extra, pos); + mtime = LG(extra, pos + 4); + break; + default: // unknow + } + off += sz; + } + } + } + + private static class ExChannelCloser { + Path path; + SeekableByteChannel ch; + Set streams; + ExChannelCloser(Path path, + SeekableByteChannel ch, + Set 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 dirs; + private IndexNode root; + private IndexNode addToDir(EntryName 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(new EntryName(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 getDirs() + throws IOException + { + if (hasUpdate) + sync(); + if (dirs != null) + return dirs; + dirs = new HashMap(); + byte[] empty = new byte[0]; + root = new IndexNode(empty, -1); + dirs.put(new EntryName(empty), root); + + EntryName[] names = inodes.keySet().toArray(new EntryName[0]); + int i = names.length; + while (--i >= 0) { + addToDir(names[i]); + } + // for (int i EntryName en : inodes.keySet()) { + // addToDir(en); + // } + return dirs; + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,152 @@ +/* + * 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 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 env) + throws IOException + { + return newFileSystem(uriToPath(uri), env); + } + + @Override + public FileSystem newFileSystem(FileRef file, Map 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 env) + throws IOException + { + synchronized(filesystems) { + if (filesystems.containsKey(path)) + throw new FileSystemAlreadyExistsException(); + ZipFileSystem zipfs = new ZipFileSystem(this, path, env); + filesystems.put(path, 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 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 = filesystems.get(uriToPath(uri)); + if (zipfs == null) + throw new FileSystemNotFoundException(); + return zipfs; + } + } + + void removeFileSystem(Path zfpath) { + synchronized (filesystems) { + filesystems.remove(zfpath); + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,132 @@ +/* + * 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.PrintStream; +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 the loc and cen tables of the ZIP file + * + * @author Xueming Shen + */ + +public class ZipInfo { + + public static void main(String[] args) throws Throwable { + if (args.length < 2) { + print("Usage: java ZipInfo [cen|loc] zfname"); + } else { + Map env = Collections.emptyMap(); + ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider() + .newFileSystem(Paths.get(args[1]), env)); + + long pos = 0; + + if ("loc".equals(args[0])) { + print("[Local File Header]%n"); + byte[] buf = new byte[1024]; + for (int i = 0; i < zfs.getEntryNames().length; i++) { + Entry loc = Entry.readLOC(zfs, pos, buf); + print("--------loc[%x]--------%n", pos); + printLOC(loc); + pos = loc.endPos; + } + } if ("cen".equals(args[0])) { + int i = 0; + Iterator itr = zfs.inodes.values().iterator(); + print("[Central Directory Header]%n"); + while (itr.hasNext()) { + Entry cen = Entry.readCEN(zfs.cen, itr.next().pos); + print("--------cen[%d]--------%n", i); + printCEN(cen); + i++; + } + } + zfs.close(); + } + } + + static void print(String fmt, Object... objs) { + System.out.printf(fmt, objs); + } + + static void printLOC(Entry loc) { + print(" [%x, %x]%n", loc.startPos, loc.endPos); + print(" Signature : %8x%n", LOCSIG); + print(" Version : %4x [%d.%d]%n", + loc.version, loc. version/10, loc. version%10); + print(" Flag : %4x%n", loc.flag); + print(" Method : %4x%n", loc. method); + print(" LastMTime : %8x [%tc]%n", + loc.mtime, dosToJavaTime(loc.mtime)); + print(" CRC : %8x%n", loc.crc); + print(" CSize : %8x%n", loc.csize); + print(" Size : %8x%n", loc.size); + print(" NameLength : %4x [%s]%n", + loc.nlen, new String(loc.name)); + print(" ExtraLength : %4x%n", loc.elen); + if (loc.hasZip64) + print(" *ZIP64*%n"); + } + + static void printCEN(Entry cen) { + print(" Signature : %08x%n", CENSIG); + print(" VerMadeby : %4x [%d.%d]%n", + cen.versionMade, cen.versionMade/10, cen.versionMade%10); + print(" VerExtract : %4x [%d.%d]%n", + cen.version, cen.version/10, cen.version%10); + print(" Flag : %4x%n", cen.flag); + print(" Method : %4x%n", cen.method); + print(" LastMTime : %8x [%tc]%n", + cen.mtime, dosToJavaTime(cen.mtime)); + print(" CRC : %8x%n", cen.crc); + print(" CSize : %8x%n", cen.csize); + print(" Size : %8x%n", cen.size); + print(" NameLen : %4x [%s]%n", + cen.nlen, new String(cen.name)); + print(" ExtraLen : %4x%n", cen.elen); + print(" CommentLen : %4x%n", cen.clen); + print(" DiskStart : %4x%n", cen.disk); + print(" Attrs : %4x%n", cen.attrs); + print(" AttrsEx : %8x%n", cen.attrsEx); + print(" LocOff : %8x%n", cen.locoff); + if (cen.hasZip64) + print(" *ZIP64*%n"); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,964 @@ +/* + * 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.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.*; +import java.nio.file.DirectoryStream.Filter; +import java.nio.file.spi.FileSystemProvider; +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 java.util.regex.Matcher; +import java.util.regex.Pattern; +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 acceptAllFilter = + new DirectoryStream.Filter() { + @Override public boolean accept(Path entry) { return true; } + }; + + @Override + public final DirectoryStream newDirectoryStream() throws IOException { + return newDirectoryStream(acceptAllFilter); + } + + @Override + public DirectoryStream newDirectoryStream(Filter filter) + throws IOException + { + return new ZipDirectoryStream(this, filter); + } + + @Override + public final DirectoryStream 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 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 getFileAttributeView(Class 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 readAttributes(String attribute, LinkOption... options) + throws IOException + { + return (Map)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 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 options, + FileAttribute... attrs) + throws IOException + { + return zfs.newByteChannel(getResolvedPath(), options, attrs); + } + + + FileChannel newFileChannel(Set options, + FileAttribute... attrs) + throws IOException + { + return zfs.newFileChannel(getResolvedPath(), options, attrs); + } + + @Override + public SeekableByteChannel newByteChannel(OpenOption... options) + throws IOException { + Set 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 = false; + } + // 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(), null, null); + } catch (IOException x) { + // rollback? + try { + target.delete(); + } catch (IOException ignore) { } + throw x; + } + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,289 @@ +/* + * 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; + +/** + * + * @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 >>> 0) & 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 >>> 0) & 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 >>> 0) & 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; + } + + 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(); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java Wed Oct 13 17:51:41 2010 -0700 @@ -64,7 +64,10 @@ accessor.setFile(fd, null); accessor.setFiles(fd, null, null); } else { - accessor.setDirectory(fd, directory); + // Fix 6987233: add the trailing slash if it's absent + accessor.setDirectory(fd, directory + + (directory.endsWith(File.separator) ? + "" : File.separator)); accessor.setFile(fd, filenames[0]); accessor.setFiles(fd, directory, filenames); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java --- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Wed Oct 13 17:51:41 2010 -0700 @@ -705,12 +705,8 @@ throw new IllegalStateException("Attempt to resize uncreated window"); } insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height); - if (width <= 0) { - width = 1; - } - if (height <= 0) { - height = 1; - } + width = Math.max(MIN_SIZE, width); + height = Math.max(MIN_SIZE, height); XToolkit.awtLock(); try { XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height); diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Wed Oct 13 17:51:41 2010 -0700 @@ -763,12 +763,8 @@ } private void checkShellRectSize(Rectangle shellRect) { - if (shellRect.width < 0) { - shellRect.width = 1; - } - if (shellRect.height < 0) { - shellRect.height = 1; - } + shellRect.width = Math.max(MIN_SIZE, shellRect.width); + shellRect.height = Math.max(MIN_SIZE, shellRect.height); } private void checkShellRectPos(Rectangle shellRect) { diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java Wed Oct 13 17:51:41 2010 -0700 @@ -28,9 +28,12 @@ import sun.awt.EmbeddedFrame; import java.awt.*; import java.awt.AWTKeyStroke; +import java.util.logging.Logger; public class XEmbeddedFrame extends EmbeddedFrame { + private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName()); + long handle; public XEmbeddedFrame() { } @@ -70,6 +73,21 @@ this(handle, supportsXEmbed, false); } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public boolean traverseIn(boolean direction) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + return super.traverseIn(direction); + } + } + return false; + } + protected boolean traverseOut(boolean direction) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (direction == FORWARD) { @@ -81,6 +99,20 @@ return true; } + /* + * The method shouldn't be called in case of active XEmbed. + */ + public void synthesizeWindowActivation(boolean doActivate) { + XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer(); + if (peer != null) { + if (peer.supportsXEmbed() && peer.isXEmbedActive()) { + log.fine("The method shouldn't be called when XEmbed is active!"); + } else { + peer.synthesizeFocusInOut(doActivate); + } + } + } + public void registerAccelerator(AWTKeyStroke stroke) { XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer(); if (xefp != null) { diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Wed Oct 13 17:51:41 2010 -0700 @@ -35,6 +35,8 @@ import sun.awt.EmbeddedFrame; import sun.awt.SunToolkit; +import static sun.awt.X11.XConstants.*; + public class XEmbeddedFramePeer extends XFramePeer { private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer"); @@ -305,4 +307,20 @@ EmbeddedFrame frame = (EmbeddedFrame)target; frame.notifyModalBlocked(blocker, blocked); } + + public void synthesizeFocusInOut(boolean doFocus) { + XFocusChangeEvent xev = new XFocusChangeEvent(); + + XToolkit.awtLock(); + try { + xev.set_type(doFocus ? FocusIn : FocusOut); + xev.set_window(getFocusProxy().getWindow()); + xev.set_mode(NotifyNormal); + XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false, + NoEventMask, xev.pData); + } finally { + XToolkit.awtUnlock(); + xev.dispose(); + } + } } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/classes/sun/awt/X11/XToolkit.java --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Wed Oct 13 17:51:41 2010 -0700 @@ -1482,8 +1482,19 @@ try { if (numberOfButtons == 0) { numberOfButtons = getNumberOfButtonsImpl(); + numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons; + //4th and 5th buttons are for wheel and shouldn't be reported as buttons. + //If we have more than 3 physical buttons and a wheel, we report N-2 buttons. + //If we have 3 physical buttons and a wheel, we report 3 buttons. + //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively. + if (numberOfButtons >=5) { + numberOfButtons -= 2; + } else if (numberOfButtons == 4 || numberOfButtons ==5){ + numberOfButtons = 3; + } } - return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons; + //Assume don't have to re-query the number again and again. + return numberOfButtons; } finally { awtUnlock(); } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/solaris/native/sun/awt/awt_InputMethod.c --- a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c Wed Oct 13 17:51:41 2010 -0700 @@ -1473,6 +1473,10 @@ static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) { /* mark that XIM server was destroyed */ X11im = NULL; + JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + /* free the old pX11IMData and set it to null. this also avoids crashing + * the jvm if the XIM server reappears */ + X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance); } /* diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Wed Oct 13 17:51:41 2010 -0700 @@ -556,24 +556,26 @@ Component target = (Component)getTarget(); Window window = SunToolkit.getContainingWindow(target); - if (window != null && !window.isOpaque()) { - // Non-opaque windows do not support heavyweight children. - // Redirect all painting to the Window's Graphics instead. - // The caller is responsible for calling the - // WindowPeer.updateWindow() after painting has finished. - int x = 0, y = 0; - for (Component c = target; c != window; c = c.getParent()) { - x += c.getX(); - y += c.getY(); - } - + if (window != null) { Graphics g = ((WWindowPeer)window.getPeer()).getTranslucentGraphics(); + // getTranslucentGraphics() returns non-null value for non-opaque windows only + if (g != null) { + // Non-opaque windows do not support heavyweight children. + // Redirect all painting to the Window's Graphics instead. + // The caller is responsible for calling the + // WindowPeer.updateWindow() after painting has finished. + int x = 0, y = 0; + for (Component c = target; c != window; c = c.getParent()) { + x += c.getX(); + y += c.getY(); + } - g.translate(x, y); - g.clipRect(0, 0, target.getWidth(), target.getHeight()); + g.translate(x, y); + g.clipRect(0, 0, target.getWidth(), target.getHeight()); - return g; + return g; + } } SurfaceData surfaceData = this.surfaceData; diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java --- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java Wed Oct 13 17:51:41 2010 -0700 @@ -191,9 +191,20 @@ public void activateEmbeddingTopLevel() { } - public void synthesizeWindowActivation(boolean doActivate) { - ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + public void synthesizeWindowActivation(final boolean doActivate) { + if (!doActivate || EventQueue.isDispatchThread()) { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate); + } else { + // To avoid focus concurrence b/w IE and EmbeddedFrame + // activation is postponed by means of posting it to EDT. + EventQueue.invokeLater(new Runnable() { + public void run() { + ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true); + } + }); + } } + public void registerAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Oct 13 17:51:41 2010 -0700 @@ -595,16 +595,6 @@ } @Override - public Graphics getGraphics() { - synchronized (getStateLock()) { - if (!isOpaque) { - return getTranslucentGraphics(); - } - } - return super.getGraphics(); - } - - @Override public void setBackground(Color c) { super.setBackground(c); synchronized (getStateLock()) { diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/lib/tzmappings --- a/jdk/src/windows/lib/tzmappings Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/lib/tzmappings Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,4 @@ # -# # This file describes mapping information between Windows and Java # time zones. # Format: Each line should include a colon separated fields of Windows @@ -11,7 +10,7 @@ # NOTE # This table format is not a public interface of any Java # platforms. No applications should depend on this file in any form. -# +# # This table has been generated by a program and should not be edited # manually. # @@ -84,8 +83,8 @@ Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg: West Asia:10,11:UZ:Asia/Tashkent: West Asia Standard Time:10,11:UZ:Asia/Tashkent: -Central Asia:12,13::Asia/Dhaka: -Central Asia Standard Time:12,13::Asia/Dhaka: +Central Asia:12,13::Asia/Almaty: +Central Asia Standard Time:12,13::Asia/Almaty: N. Central Asia Standard Time:12,13::Asia/Novosibirsk: Bangkok:14,15::Asia/Bangkok: Bangkok Standard Time:14,15::Asia/Bangkok: @@ -167,22 +166,27 @@ Greenwich Standard Time:88,89::GMT: Argentina Standard Time:900,900::America/Buenos_Aires: Azerbaijan Standard Time:901,901:AZ:Asia/Baku: -Central Brazilian Standard Time:902,902:BR:America/Manaus: -Central Standard Time (Mexico):903,903::America/Mexico_City: -Georgian Standard Time:904,904:GE:Asia/Tbilisi: -Jordan Standard Time:905,905:JO:Asia/Amman: -Mauritius Standard Time:906,906:MU:Indian/Mauritius: -Middle East Standard Time:907,907:LB:Asia/Beirut: -Montevideo Standard Time:908,908:UY:America/Montevideo: -Morocco Standard Time:909,909:MA:Africa/Casablanca: -Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua: -Namibia Standard Time:911,911:NA:Africa/Windhoek: -Pacific Standard Time (Mexico):912,912:MX:America/Tijuana: -Pakistan Standard Time:913,913::Asia/Karachi: -UTC:914,914::UTC: -Venezuela Standard Time:915,915::America/Caracas: -Kamchatka Standard Time:916,916:RU:Asia/Kamchatka: -Paraguay Standard Time:917,917:PY:America/Asuncion: -Western Brazilian Standard Time:918,918:BR:America/Rio_Branco: -Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar: -Armenian Standard Time:920,920:AM:Asia/Yerevan: +Bangladesh Standard Time:902,902::Asia/Dhaka: +Central Brazilian Standard Time:903,903:BR:America/Manaus: +Central Standard Time (Mexico):904,904::America/Mexico_City: +Georgian Standard Time:905,905:GE:Asia/Tbilisi: +Jordan Standard Time:906,906:JO:Asia/Amman: +Kamchatka Standard Time:907,907:RU:Asia/Kamchatka: +Mauritius Standard Time:908,908:MU:Indian/Mauritius: +Middle East Standard Time:909,909:LB:Asia/Beirut: +Montevideo Standard Time:910,910:UY:America/Montevideo: +Morocco Standard Time:911,911:MA:Africa/Casablanca: +Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua: +Namibia Standard Time:913,913:NA:Africa/Windhoek: +Pacific Standard Time (Mexico):914,914:MX:America/Tijuana: +Pakistan Standard Time:915,915::Asia/Karachi: +Paraguay Standard Time:916,916:PY:America/Asuncion: +Syria Standard Time:917,917:SY:Asia/Damascus: +UTC:918,918::UTC: +UTC+12:919,919::GMT+1200: +UTC-02:920,920::GMT-0200: +UTC-11:921,921::GMT-1100: +Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar: +Venezuela Standard Time:923,923::America/Caracas: +Western Brazilian Standard Time:924,924:BR:America/Rio_Branco: +Armenian Standard Time:925,925:AM:Asia/Yerevan: diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/native/sun/windows/awt_Component.cpp --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Wed Oct 13 17:51:41 2010 -0700 @@ -2329,6 +2329,19 @@ MSG msg; InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y); + AwtWindow *toplevel = GetContainer(); + if (toplevel && !toplevel->IsSimpleWindow()) { + /* + * The frame should be focused by click in case it is + * the active window but not the focused window. See 6886678. + */ + if (toplevel->GetHWnd() == ::GetActiveWindow() && + toplevel->GetHWnd() != AwtComponent::GetFocusedWindow()) + { + toplevel->AwtSetActiveWindow(); + } + } + SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y, GetJavaModifiers(), clickCount, JNI_FALSE, GetButton(button), &msg); diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/native/sun/windows/awt_Desktop.cpp --- a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp Wed Oct 13 17:51:41 2010 -0700 @@ -59,15 +59,17 @@ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - GetLastError(), + (int)retval, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&buffer, 0, NULL ); - jstring errmsg = JNU_NewStringPlatform(env, buffer, len); - LocalFree(buffer); - return errmsg; + if (buffer) { + jstring errmsg = JNU_NewStringPlatform(env, buffer); + LocalFree(buffer); + return errmsg; + } } return NULL; diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp --- a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp Wed Oct 13 17:51:41 2010 -0700 @@ -505,7 +505,8 @@ SetIntegerProperty(TEXT("win.drag.width"), cxdrag); SetIntegerProperty(TEXT("win.drag.height"), cydrag); SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2); - SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS)); + SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons()); + SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime()); // BEGIN cross-platform properties diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/native/sun/windows/awt_Toolkit.cpp --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Wed Oct 13 17:51:41 2010 -0700 @@ -133,6 +133,8 @@ static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit"); +static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2. + UINT AwtToolkit::GetMouseKeyState() { static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON); @@ -2310,5 +2312,9 @@ JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl (JNIEnv *, jobject self) { - return GetSystemMetrics(SM_CMOUSEBUTTONS); + return AwtToolkit::GetNumberOfButtons(); } + +UINT AwtToolkit::GetNumberOfButtons() { + return MOUSE_BUTTONS_WINDOWS_SUPPORTED; +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/src/windows/native/sun/windows/awt_Toolkit.h --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h Wed Oct 13 17:51:41 2010 -0700 @@ -185,6 +185,7 @@ BOOL IsDynamicLayoutActive(); BOOL areExtraMouseButtonsEnabled(); void setExtraMouseButtonsEnabled(BOOL enable); + static UINT GetNumberOfButtons(); INLINE BOOL localPump() { return m_localPump; } INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/demo/zipfs/Basic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/demo/zipfs/Basic.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,159 @@ +/* + * 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 + * 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.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.file.spi.FileSystemProvider; +import java.util.*; +import java.net.URI; +import java.io.IOException; + +/** + * Basic test for zip provider + */ + +public class Basic { + public static void main(String[] args) throws Exception { + Path zipfile = Paths.get(args[0]); + + // Test: zip should should be returned in provider list + boolean found = false; + + for (FileSystemProvider provider: FileSystemProvider.installedProviders()) { + if (provider.getScheme().equalsIgnoreCase("zip")) { + found = true; + break; + } + } + if (!found) + throw new RuntimeException("'zip' provider not installed"); + + // Test: FileSystems#newFileSystem(FileRef) + Map env = new HashMap(); + FileSystems.newFileSystem(zipfile, env, null).close(); + + // Test: FileSystems#newFileSystem(URI) + URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4)); + FileSystem fs = FileSystems.newFileSystem(uri, env, null); + + // Test: exercise toUri method + String expected = uri.toString() + "#/foo"; + String actual = fs.getPath("/foo").toUri().toString(); + if (!actual.equals(expected)) { + throw new RuntimeException("toUri returned '" + actual + + "', expected '" + expected + "'"); + } + + // Test: exercise directory iterator and retrieval of basic attributes + Files.walkFileTree(fs.getPath("/"), new FileTreePrinter()); + + // Test: DirectoryStream + found = false; + DirectoryStream stream = fs.getPath("/").newDirectoryStream(); + try { + for (Path entry: stream) { + found = entry.toString().equals("/META-INF/"); + if (found) break; + } + } finally { + stream.close(); + } + + if (!found) + throw new RuntimeException("Expected file not found"); + + // Test: copy file from zip file to current (scratch) directory + Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider"); + if (source.exists()) { + Path target = Paths.get(source.getName().toString()); + source.copyTo(target, StandardCopyOption.REPLACE_EXISTING); + try { + long s1 = Attributes.readBasicFileAttributes(source).size(); + long s2 = Attributes.readBasicFileAttributes(target).size(); + if (s2 != s1) + throw new RuntimeException("target size != source size"); + } finally { + target.delete(); + } + } + + // Test: FileStore + FileStore store = fs.getPath("/").getFileStore(); + if (!store.supportsFileAttributeView("basic")) + throw new RuntimeException("BasicFileAttributeView should be supported"); + + // Test: ClosedFileSystemException + fs.close(); + if (fs.isOpen()) + throw new RuntimeException("FileSystem should be closed"); + try { + fs.getPath("/missing").checkAccess(AccessMode.READ); + } catch (ClosedFileSystemException x) { } + } + + // FileVisitor that pretty prints a file tree + static class FileTreePrinter extends SimpleFileVisitor { + private int indent = 0; + + private void indent() { + StringBuilder sb = new StringBuilder(indent); + for (int i=0; i %s", s, path); + } catch (Exception x) { + exc = x; + out.format("%s -> %s", s, x); + } + out.println(); + } + + Path path() { + return path; + } + + void fail() { + throw new RuntimeException("PathOps failed"); + } + + void checkPath() { + if (path == null) { + throw new InternalError("path is null"); + } + } + + void check(Object result, String expected) { + out.format("\tExpected: %s\n", expected); + out.format("\tActual: %s\n", result); + if (result == null) { + if (expected == null) return; + } else { + // compare string representations + if (expected != null && result.toString().equals(expected.toString())) + return; + } + fail(); + } + + void check(Object result, boolean expected) { + check(result, Boolean.toString(expected)); + } + + PathOps root(String expected) { + out.println("check root"); + checkPath(); + check(path.getRoot(), expected); + return this; + } + + PathOps parent(String expected) { + out.println("check parent"); + checkPath(); + check(path.getParent(), expected); + return this; + } + + PathOps name(String expected) { + out.println("check name"); + checkPath(); + check(path.getName(), expected); + return this; + } + + PathOps element(int index, String expected) { + out.format("check element %d\n", index); + checkPath(); + check(path.getName(index), expected); + return this; + } + + PathOps subpath(int startIndex, int endIndex, String expected) { + out.format("test subpath(%d,%d)\n", startIndex, endIndex); + checkPath(); + check(path.subpath(startIndex, endIndex), expected); + return this; + } + + PathOps starts(String prefix) { + out.format("test startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), true); + return this; + } + + PathOps notStarts(String prefix) { + out.format("test not startsWith with %s\n", prefix); + checkPath(); + Path s = fs.getPath(prefix); + check(path.startsWith(s), false); + return this; + } + + PathOps ends(String suffix) { + out.format("test endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), true); + return this; + } + + PathOps notEnds(String suffix) { + out.format("test not endsWith %s\n", suffix); + checkPath(); + Path s = fs.getPath(suffix); + check(path.endsWith(s), false); + return this; + } + + PathOps absolute() { + out.println("check path is absolute"); + checkPath(); + check(path.isAbsolute(), true); + return this; + } + + PathOps notAbsolute() { + out.println("check path is not absolute"); + checkPath(); + check(path.isAbsolute(), false); + return this; + } + + PathOps resolve(String other, String expected) { + out.format("test resolve %s\n", other); + checkPath(); + check(path.resolve(other), expected); + return this; + } + + PathOps relativize(String other, String expected) { + out.format("test relativize %s\n", other); + checkPath(); + Path that = fs.getPath(other); + check(path.relativize(that), expected); + return this; + } + + PathOps normalize(String expected) { + out.println("check normalized path"); + checkPath(); + check(path.normalize(), expected); + return this; + } + + PathOps string(String expected) { + out.println("check string representation"); + checkPath(); + check(path, expected); + return this; + } + + PathOps invalid() { + if (!(exc instanceof InvalidPathException)) { + out.println("InvalidPathException not thrown as expected"); + fail(); + } + return this; + } + + static PathOps test(String s) { + return new PathOps(s); + } + + // -- PathOpss -- + + static void header(String s) { + out.println(); + out.println(); + out.println("-- " + s + " --"); + } + + static void doPathOpTests() { + header("Path operations"); + + // all components + test("/a/b/c") + .root("/") + .parent("/a/b") + .name("c"); + + // root component only + test("/") + .root("/") + .parent(null) + .name(null); + + // no root component + test("a/b") + .root(null) + .parent("a") + .name("b"); + + // name component only + test("foo") + .root(null) + .parent(null) + .name("foo"); + + // startsWith + test("/") + .starts("/") + .notStarts("/foo"); + test("/foo") + .starts("/") + .starts("/foo") + .notStarts("/f"); + test("/foo/bar") + .starts("/") + .starts("/foo") + .starts("/foo/bar") + .notStarts("/f") + .notStarts("foo") + .notStarts("foo/bar"); + test("foo") + .starts("foo") + .notStarts("f"); + test("foo/bar") + .starts("foo") + .starts("foo/bar") + .notStarts("f") + .notStarts("/foo") + .notStarts("/foo/bar"); + + // endsWith + test("/") + .ends("/") + .notEnds("foo") + .notEnds("/foo"); + test("/foo") + .ends("foo") + .ends("/foo") + .notEnds("/"); + test("/foo/bar") + .ends("bar") + .ends("foo/bar") + .ends("/foo/bar") + .notEnds("/bar"); + test("foo") + .ends("foo"); + test("foo/bar") + .ends("bar") + .ends("foo/bar"); + + // elements + test("a/b/c") + .element(0,"a") + .element(1,"b") + .element(2,"c"); + + // isAbsolute + test("/") + .absolute(); + test("/tmp") + .absolute(); + test("tmp") + .notAbsolute(); + + // resolve + test("/tmp") + .resolve("foo", "/tmp/foo") + .resolve("/foo", "/foo"); + test("tmp") + .resolve("foo", "tmp/foo") + .resolve("/foo", "/foo"); + + // relativize + test("/a/b/c") + .relativize("/a/b/c", null) + .relativize("/a/b/c/d/e", "d/e") + .relativize("/a/x", "../../x"); + + // normalize + test("/") + .normalize("/"); + test("foo") + .normalize("foo"); + test("/foo") + .normalize("/foo"); + test(".") + .normalize(null); + test("..") + .normalize(".."); + test("/..") + .normalize("/"); + test("/../..") + .normalize("/"); + test("foo/.") + .normalize("foo"); + test("./foo") + .normalize("foo"); + test("foo/..") + .normalize(null); + test("../foo") + .normalize("../foo"); + test("../../foo") + .normalize("../../foo"); + test("foo/bar/..") + .normalize("foo"); + test("foo/bar/gus/../..") + .normalize("foo"); + test("/foo/bar/gus/../..") + .normalize("/foo"); + + // invalid + test("foo\u0000bar") + .invalid(); + test("\u0000foo") + .invalid(); + test("bar\u0000") + .invalid(); + test("//foo\u0000bar") + .invalid(); + test("//\u0000foo") + .invalid(); + test("//bar\u0000") + .invalid(); + + // normalization + test("//foo//bar") + .string("/foo/bar") + .root("/") + .parent("/foo") + .name("bar"); + } + + static void npes() { + header("NullPointerException"); + + Path path = fs.getPath("foo"); + + try { + path.resolve((String)null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.relativize(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.compareTo(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.startsWith(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + path.endsWith(null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + } + + public static void main(String[] args) throws Throwable { + + Path zipfile = Paths.get(args[0]); + Map env = new HashMap(); + fs = FileSystems.newFileSystem(zipfile, env, null); + npes(); + doPathOpTests(); + fs.close(); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/demo/zipfs/ZipFSTester.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/demo/zipfs/ZipFSTester.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,633 @@ +/* + * 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.*; +import java.nio.*; +import java.nio.channels.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.net.*; +import java.util.*; + +import static java.nio.file.StandardOpenOption.*; +import static java.nio.file.StandardCopyOption.*; + +/* + * Tests various zipfs operations. + */ + +public class ZipFSTester { + + public static void main(String[] args) throws Throwable { + FileSystem fs = null; + try { + fs = newZipFileSystem(Paths.get(args[0]), new HashMap()); + test(fs); + test2(fs); // more tests + } finally { + if (fs != null) + fs.close(); + } + } + + static void test(FileSystem fs) + throws Exception + { + Random rdm = new Random(); + + // clone a fs and test on it + Path tmpfsPath = getTempPath(); + Map env = new HashMap(); + env.put("createNew", true); + FileSystem fs0 = newZipFileSystem(tmpfsPath, env); + z2zcopy(fs, fs0, "/", 0); + fs0.close(); // sync to file + + fs = newZipFileSystem(tmpfsPath, new HashMap()); + + try { + // prepare a src + Path src = getTempPath(); + String tmpName = src.toString(); + OutputStream os = src.newOutputStream(); + byte[] bits = new byte[12345]; + rdm.nextBytes(bits); + os.write(bits); + os.close(); + + // copyin + Path dst = getPathWithParents(fs, tmpName); + src.copyTo(dst); + checkEqual(src, dst); + + // copy + Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + + "/efg" + rdm.nextInt(100) + "/foo.class"); + dst.copyTo(dst2); + //dst.moveTo(dst2); + checkEqual(src, dst2); + + // delete + dst.delete(); + if (dst.exists()) + throw new RuntimeException("Failed!"); + + // moveout + Path dst3 = Paths.get(tmpName + "_Tmp"); + dst2.moveTo(dst3); + checkEqual(src, dst3); + + // delete + if (dst2.exists()) + throw new RuntimeException("Failed!"); + dst3.delete(); + if (dst3.exists()) + throw new RuntimeException("Failed!"); + + // newInputStream on dir + Path parent = dst2.getParent(); + try { + parent.newInputStream(); + throw new RuntimeException("Failed"); + } catch (FileSystemException e) { + e.printStackTrace(); // expected fse + } + + // rmdirs + try { + rmdirs(parent); + } catch (IOException x) { + x.printStackTrace(); + } + + // newFileChannel() copy in, out and verify via fch + fchCopy(src, dst); // in + checkEqual(src, dst); + Path tmp = Paths.get(tmpName + "_Tmp"); + fchCopy(dst, tmp); // out + checkEqual(src, tmp); + tmp.delete(); + + // test channels + channel(fs, dst); + dst.delete(); + src.delete(); + } finally { + if (fs != null) + fs.close(); + if (tmpfsPath.exists()) + tmpfsPath.delete(); + } + } + + static void test2(FileSystem fs) throws Exception { + + Path fs1Path = getTempPath(); + Path fs2Path = getTempPath(); + Path fs3Path = getTempPath(); + + if (fs1Path.exists()) + fs1Path.delete(); + if (fs2Path.exists()) + fs2Path.delete(); + if (fs3Path.exists()) + fs3Path.delete(); + + // create a new filesystem, copy everything from fs + Map env = new HashMap(); + env.put("createNew", true); + FileSystem fs0 = newZipFileSystem(fs1Path, env); + + final FileSystem fs2 = newZipFileSystem(fs2Path, env); + final FileSystem fs3 = newZipFileSystem(fs3Path, env); + + System.out.println("copy src: fs -> fs0..."); + z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 + fs0.close(); // dump to file + + System.out.println("open fs0 as fs1"); + env = new HashMap(); + final FileSystem fs1 = newZipFileSystem(fs1Path, env); + + System.out.println("listing..."); + final ArrayList files = new ArrayList<>(); + final ArrayList dirs = new ArrayList<>(); + list(fs1.getPath("/"), files, dirs); + + Thread t0 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 0); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t1 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 1); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(dirs); + Collections.shuffle(list); + for (String path : list) { + try { + z2zcopy(fs1, fs2, path, 2); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + + }); + + Thread t3 = new Thread(new Runnable() { + public void run() { + List list = new ArrayList<>(files); + Collections.shuffle(list); + while (!list.isEmpty()) { + Iterator itr = list.iterator(); + while (itr.hasNext()) { + String path = itr.next(); + try { + if (fs2.getPath(path).exists()) { + z2zmove(fs2, fs3, path); + itr.remove(); + } + } catch (FileAlreadyExistsException x){ + itr.remove(); + } catch (Exception x) { + x.printStackTrace(); + } + } + } + } + + }); + + System.out.println("copying/removing..."); + t0.start(); t1.start(); t2.start(); t3.start(); + t0.join(); t1.join(); t2.join(); t3.join(); + + System.out.println("closing: fs1, fs2"); + fs1.close(); + fs2.close(); + + int failed = 0; + System.out.println("checkEqual: fs vs fs3"); + for (String path : files) { + try { + checkEqual(fs.getPath(path), fs3.getPath(path)); + } catch (IOException x) { + //x.printStackTrace(); + failed++; + } + } + System.out.println("closing: fs3"); + fs3.close(); + + System.out.println("opening: fs3 as fs4"); + FileSystem fs4 = newZipFileSystem(fs3Path, env); + + + ArrayList files2 = new ArrayList<>(); + ArrayList dirs2 = new ArrayList<>(); + list(fs4.getPath("/"), files2, dirs2); + + System.out.println("checkEqual: fs vs fs4"); + for (String path : files2) { + checkEqual(fs.getPath(path), fs4.getPath(path)); + } + System.out.println("walking: fs4"); + walk(fs4.getPath("/")); + System.out.println("closing: fs4"); + fs4.close(); + + System.out.printf("failed=%d%n", failed); + + fs1Path.delete(); + fs2Path.delete(); + fs3Path.delete(); + } + + private static FileSystem newZipFileSystem(Path path, Map env) + throws IOException + { + return FileSystems.newFileSystem( + URI.create("zip" + + path.toUri().toString().substring(4)), + env, + null); + } + + private static Path getTempPath() throws IOException + { + File tmp = File.createTempFile("testzipfs_", "zip"); + tmp.delete(); // we need a clean path, no file + return tmp.toPath(); + } + + private static void list(Path path, List files, List dirs ) + throws IOException + { + if (Attributes.readBasicFileAttributes(path).isDirectory()) { + DirectoryStream ds = path.newDirectoryStream(); + for (Path child : ds) + list(child, files, dirs); + ds.close(); + dirs.add(path.toString()); + } else { + files.add(path.toString()); + } + } + + private static void z2zcopy(FileSystem src, FileSystem dst, String path, + int method) + 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 ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zcopy(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName(), + method); + } + ds.close(); + } else { + try { + if (dstPath.exists()) + return; + switch (method) { + case 0: + srcPath.copyTo(dstPath); + break; + case 1: + chCopy(srcPath, dstPath); + break; + case 2: + //fchCopy(srcPath, dstPath); + streamCopy(srcPath, dstPath); + break; + } + } catch (FileAlreadyExistsException x) {} + } + } + + private static void z2zmove(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()) + mkdirs(dstPath); + DirectoryStream ds = srcPath.newDirectoryStream(); + for (Path child : ds) { + z2zmove(src, dst, + path + (path.endsWith("/")?"":"/") + child.getName()); + } + ds.close(); + } else { + //System.out.println("moving..." + path); + Path parent = dstPath.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + srcPath.moveTo(dstPath); + } + } + + private static void walk(Path path) throws IOException + { + Files.walkFileTree( + path, + new SimpleFileVisitor() { + 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) + throws IOException + { + indent -= 2; + 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(); + } + } + + // 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 read = new HashSet<>(); + read.add(READ); + Set 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 read = new HashSet<>(); + read.add(READ); + Set 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(); + } + } + + static void channel(FileSystem fs, Path path) + throws Exception + { + System.out.println("test ByteChannel..."); + SeekableByteChannel sbc = path.newByteChannel(); + Set read = new HashSet<>(); + read.add(READ); + System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size()); + ByteBuffer bb = ByteBuffer.allocate((int)sbc.size()); + int n = sbc.read(bb); + System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size()); + int N = 120; + sbc.close(); + + // sbc.position(pos) is not supported in current version + // try the FileChannel + sbc = fs.provider().newFileChannel(path, read); + sbc.position(N); + System.out.printf(" sbc[2]: pos=%d, size=%d%n", + sbc.position(), sbc.size()); + bb2.limit(100); + n = sbc.read(bb2); + System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n", + n, sbc.position(), sbc.size()); + System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n", + N, bb.get(N) & 0xff, bb2.get(0) & 0xff); + sbc.close(); + } + + // create parents if does not exist + static Path getPathWithParents(FileSystem fs, String name) + throws Exception + { + Path path = fs.getPath(name); + Path parent = path.getParent(); + if (parent != null && parent.notExists()) + mkdirs(parent); + return path; + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/demo/zipfs/basic.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/demo/zipfs/basic.sh Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,73 @@ +# +# 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 +# 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 6990846 +# @summary Test ZipFileSystem demo +# @build Basic PathOps ZipFSTester +# @run shell basic.sh + +if [ -z "${TESTJAVA}" ]; then + echo "Test must be run with jtreg" + exit 0 +fi + +ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar" +if [ ! -r "${ZIPFS}" ]; then + echo "${ZIPFS} not found" + exit 0 +fi + +OS=`uname -s` +case "$OS" in + Windows_* ) + CLASSPATH="${TESTCLASSES};${ZIPFS}" + ;; + * ) + CLASSPATH="${TESTCLASSES}:${ZIPFS}" + ;; +esac +export CLASSPATH + +failures=0 + +go() { + echo "" + ${TESTJAVA}/bin/java $1 $2 $3 2>&1 + if [ $? != 0 ]; then failures=`expr $failures + 1`; fi +} + +# Run the tests + +go Basic "${ZIPFS}" +go PathOps "${ZIPFS}" +go ZipFSTester "${ZIPFS}" + +# +# Results +# + +if [ $failures -gt 0 ]; +then echo "$failures tests failed"; +else echo "All tests passed"; +fi +exit $failures diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1995, 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 FocusOwnerFrameOnClick.java %W% %E% + @bug 6886678 + @summary Tests that clicking an owner frame switches focus from its owned window. + @author Anton Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main FocusOwnerFrameOnClick +*/ + +import java.awt.*; +import java.awt.event.*; +import java.applet.Applet; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.reflect.InvocationTargetException; +import test.java.awt.regtesthelpers.Util; + +public class FocusOwnerFrameOnClick extends Applet { + Robot robot; + Frame frame = new Frame("Frame"); + Window window = new Window(frame); + Button fButton = new Button("fButton"); + Button wButton = new Button("wButton"); + + AtomicBoolean focused = new AtomicBoolean(false); + + public static void main(String[] args) { + FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick(); + app.init(); + app.start(); + } + + public void init() { + robot = Util.createRobot(); + + frame.setLayout(new FlowLayout()); + frame.setSize(200, 200); + frame.add(fButton); + + window.setLocation(300, 0); + window.add(wButton); + window.pack(); + } + + public void start() { + frame.setVisible(true); + Util.waitForIdle(robot); + + window.setVisible(true); + Util.waitForIdle(robot); + + if (!wButton.hasFocus()) { + if (!Util.trackFocusGained(wButton, new Runnable() { + public void run() { + Util.clickOnComp(wButton, robot); + } + }, 2000, false)) + { + throw new TestErrorException("wButton didn't gain focus on showing"); + } + } + + Runnable clickAction = new Runnable() { + public void run() { + Point loc = fButton.getLocationOnScreen(); + Dimension dim = fButton.getSize(); + + robot.mouseMove(loc.x, loc.y + dim.height + 20); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + } + }; + + if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) { + throw new TestFailedException("The frame wasn't focused on click"); + } + + System.out.println("Test passed."); + } +} + +/** + * Thrown when the behavior being verified is found wrong. + */ +class TestFailedException extends RuntimeException { + TestFailedException(String msg) { + super("Test failed: " + msg); + } +} + +/** + * Thrown when an error not related to the behavior being verified is encountered. + */ +class TestErrorException extends RuntimeException { + TestErrorException(String msg) { + super("Unexpected error: " + msg); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java --- a/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java Wed Oct 13 17:51:41 2010 -0700 @@ -21,16 +21,15 @@ static final int SHIFT = 1; static final int CTRL = 2; static final int ALT = 3; - static CheckingModifierAdapter adapterTest1; - static CheckingModifierAdapter adapterTest2; - static CheckingModifierAdapter adapterTest3; - static CheckingModifierAdapter adapterTest4; + static CheckingModifierAdapterExtra adapterTest1; + static CheckingModifierAdapterExtra adapterTest2; + static CheckingModifierAdapterExtra adapterTest3; + static CheckingModifierAdapterExtra adapterTest4; static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception static boolean autorun = false; //use robot or manual run static int testModifier = NONE; - static int [] mouseButtons; static int [] mouseButtonDownMasks; //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them @@ -39,7 +38,6 @@ static int [] modifiersExStandardCTRL; static int [] modifiersExStandardALT; - // final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK}; // BUTTON1, 2, 3 press-release. final static int modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK; @@ -56,7 +54,7 @@ if (modifiersEx != curStandardExModifiers[index]){ // System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers"); - MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -168,7 +166,7 @@ } if (modifiersEx != curStandardExModifiers[index]){ - MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -191,7 +189,7 @@ } if (modifiersEx != curStandardExModifiers[index]){ - MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers"); + MessageLogger.reportError("Test failed : Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]); } //check event.paramString() output @@ -275,11 +273,11 @@ this.addMouseListener(adapterTest1); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ - System.out.println("testNONE() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + for (int i = 3; i< mouseButtonDownMasks.length; i++){ + System.out.println("testNONE() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); } robot.delay(1000); this.removeMouseListener(adapterTest1); @@ -289,12 +287,12 @@ this.addMouseListener(adapterTest2); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_SHIFT); - System.out.println("testSHIFT() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_SHIFT); } robot.delay(1000); @@ -305,12 +303,12 @@ this.addMouseListener(adapterTest3); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_CONTROL); - System.out.println("testCTRL() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testCTRL() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_CONTROL); } robot.delay(1000); @@ -321,12 +319,12 @@ this.addMouseListener(adapterTest4); robot.delay(1000); robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2); - for (int i = 3; i< mouseButtons.length; i++){ + for (int i = 3; i< mouseButtonDownMasks.length; i++){ robot.keyPress(KeyEvent.VK_ALT); - System.out.println("testALT() => " +mouseButtons[i] ); - robot.mousePress(mouseButtons[i]); + System.out.println("testALT() => " +mouseButtonDownMasks[i] ); + robot.mousePress(mouseButtonDownMasks[i]); robot.delay(100); - robot.mouseRelease(mouseButtons[i]); + robot.mouseRelease(mouseButtonDownMasks[i]); robot.keyRelease(KeyEvent.VK_ALT); } robot.delay(1000); @@ -368,52 +366,52 @@ } public static void initAdapters(){ - adapterTest1 = new CheckingModifierAdapter(NONE); - adapterTest2 = new CheckingModifierAdapter(SHIFT); - adapterTest3 = new CheckingModifierAdapter(CTRL); - adapterTest4 = new CheckingModifierAdapter(ALT); + adapterTest1 = new CheckingModifierAdapterExtra(NONE); + adapterTest2 = new CheckingModifierAdapterExtra(SHIFT); + adapterTest3 = new CheckingModifierAdapterExtra(CTRL); + adapterTest4 = new CheckingModifierAdapterExtra(ALT); } public static void initVars(){ - int [] tmp = new int [MouseInfo.getNumberOfButtons()]; - for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ - tmp[i] = InputEvent.getMaskForButton(i+1); - // System.out.println("TEST: "+tmp[i]); + //Init the array of the mouse button masks. It will be used for generating mouse events. + mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()]; + for (int i = 0; i < mouseButtonDownMasks.length; i++){ + mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1); + System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]); } - mouseButtons = Arrays.copyOf(tmp, tmp.length); - - for (int i = 0; i < mouseButtons.length; i++){ - System.out.println("MouseArray [i] == "+mouseButtons[i]); - } - - mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length); - // So we need to get the number of extra buttons on the mouse: "MouseInfo.getNumberOfButtons() - 3" // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK. - tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; + int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3]; + + //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys) Arrays.fill(tmp, 0); - for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ tmp[i] = mouseButtonDownMasks[j]; } modifiersExStandard = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length); + //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK); - for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){ - tmp[i] = tmp[j] | mouseButtonDownMasks[j]; + for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){ + System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]); + tmp[i] = tmp[i] | mouseButtonDownMasks[j]; } modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length); } @@ -436,9 +434,9 @@ /* A class that invoke appropriate verification * routine with current modifier. */ -class CheckingModifierAdapter extends MouseAdapter{ +class CheckingModifierAdapterExtra extends MouseAdapter{ int modifier; - public CheckingModifierAdapter(int modifier){ + public CheckingModifierAdapterExtra(int modifier){ this.modifier = modifier; } diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java --- a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java Wed Oct 13 17:51:41 2010 -0700 @@ -90,7 +90,7 @@ int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks(); for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ buttonMasks[i] = InputEvent.getMaskForButton(i+1); - System.out.println("TEST: "+buttonMasks[i]); + System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]); } for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){ diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/java/awt/image/GetSamplesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/image/GetSamplesTest.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,121 @@ +/* + * 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 6735275 + * @summary Test verifies that SampleModel.getSamples() throws an appropriate + * exception if coordinates are not in bounds. + * + * @run main GetSamplesTest + */ + +import java.awt.image.BandedSampleModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.MultiPixelPackedSampleModel; +import java.awt.image.PixelInterleavedSampleModel; +import java.awt.image.SampleModel; +import java.awt.image.SinglePixelPackedSampleModel; +import java.util.Vector; + +public class GetSamplesTest { + + public static int width = 100; + public static int height = 100; + public static int dataType = DataBuffer.TYPE_BYTE; + public static int numBands = 4; + + public static void main(String[] args) { + Vector> classes = new Vector>(); + + classes.add(ComponentSampleModel.class); + classes.add(MultiPixelPackedSampleModel.class); + classes.add(SinglePixelPackedSampleModel.class); + classes.add(BandedSampleModel.class); + classes.add(PixelInterleavedSampleModel.class); + + for (Class c : classes) { + doTest(c); + } + } + private static void doTest(Class c) { + System.out.println("Test for: " + c.getName()); + SampleModel sm = createSampleModel(c); + + DataBuffer db = sm.createDataBuffer(); + + int[] iArray = new int[ width * height + numBands]; + float[] fArray = new float[ width * height + numBands]; + double[] dArray = new double[ width * height + numBands]; + + boolean iOk = false; + boolean fOk = false; + boolean dOk = false; + + try { + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + iOk = true; + } + + try { + sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + fOk = true; + } + + try { + sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + dOk = true; + } + if (!iOk || !fOk || !dOk) { + throw new RuntimeException("Test for " + c.getSimpleName() + + " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk); + } + } + + private static SampleModel createSampleModel(Class cls) { + SampleModel res = null; + + if (cls == ComponentSampleModel.class) { + res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } ); + } else if (cls == MultiPixelPackedSampleModel.class) { + res = new MultiPixelPackedSampleModel(dataType, width, height, 4); + } else if (cls == SinglePixelPackedSampleModel.class) { + res = new SinglePixelPackedSampleModel(dataType, width, height, + new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }); + } else if (cls == BandedSampleModel.class) { + res = new BandedSampleModel(dataType, width, height, numBands); + } else if (cls == PixelInterleavedSampleModel.class) { + res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 }); + } else { + throw new RuntimeException("Unknown class " + cls); + } + return res; + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/java/beans/Introspector/6976577/Test6976577.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/beans/Introspector/6976577/Test6976577.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 6976577 + * @summary Tests public methods in non-public beans + * @author Sergey Malenkov + */ + +import test.Accessor; + +import java.beans.EventSetDescriptor; +import java.beans.IndexedPropertyDescriptor; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +public class Test6976577 { + + public static void main(String[] args) throws Exception { + Class bt = Accessor.getBeanType(); + Class lt = Accessor.getListenerType(); + + // test PropertyDescriptor + PropertyDescriptor pd = new PropertyDescriptor("boolean", bt); + test(pd.getReadMethod()); + test(pd.getWriteMethod()); + + // test IndexedPropertyDescriptor + IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt); + test(ipd.getReadMethod()); + test(ipd.getWriteMethod()); + test(ipd.getIndexedReadMethod()); + test(ipd.getIndexedWriteMethod()); + + // test EventSetDescriptor + EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process"); + test(esd.getAddListenerMethod()); + test(esd.getRemoveListenerMethod()); + test(esd.getGetListenerMethod()); + test(esd.getListenerMethods()); + } + + private static void test(Method... methods) { + for (Method method : methods) { + if (method == null) { + throw new Error("public method is not found"); + } + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/java/beans/Introspector/6976577/test/Accessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/beans/Introspector/6976577/test/Accessor.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,81 @@ +package test; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.EventListener; +import java.util.TooManyListenersException; + +public class Accessor { + + public static Class getBeanType() { + return Bean.class; + } + + public static Class getListenerType() { + return TestListener.class; + } +} + +interface TestEvent { +} + +interface TestListener extends EventListener { + void process(TestEvent event); +} + +class Bean { + + private boolean b; + private int[] indexed; + private TestListener listener; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + + public void addPropertyChangeListener(PropertyChangeListener listener) { + this.pcs.addPropertyChangeListener(listener); + } + + public void addTestListener(TestListener listener) throws TooManyListenersException { + if (listener != null) { + if (this.listener != null) { + throw new TooManyListenersException(); + } + this.listener = listener; + } + } + + public void removeTestListener(TestListener listener) { + if (this.listener == listener) { + this.listener = null; + } + } + + public TestListener[] getTestListeners() { + return (this.listener != null) + ? new TestListener[] { this.listener } + : new TestListener[0]; + } + + public boolean isBoolean() { + return this.b; + } + + public void setBoolean(boolean b) { + this.b = b; + } + + public int[] getIndexed() { + return this.indexed; + } + + public void setIndexed(int[] values) { + this.indexed = values; + } + + public int getIndexed(int index) { + return this.indexed[index]; + } + + public void setIndexed(int index, int value) { + this.indexed[index] = value; + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/javax/swing/JComboBox/6632953/bug6632953.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,44 @@ +/* + * 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 6632953 + * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height + * @author Alexander Potochkin + */ + +import javax.swing.JComboBox; +import javax.swing.plaf.metal.MetalComboBoxUI; + +public class bug6632953 { + + public static void main(String... args) throws Exception { + MetalComboBoxUI ui = new MetalComboBoxUI(); + ui.installUI(new JComboBox()); + ui.getBaseline(new JComboBox(), 0, 0); + ui.getBaseline(new JComboBox(), 1, 1); + ui.getBaseline(new JComboBox(), 2, 2); + ui.getBaseline(new JComboBox(), 3, 3); + ui.getBaseline(new JComboBox(), 4, 4); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,92 @@ +/* + * 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 6542335 + @summary different behavior on knob of scroll bar between 1.4.2 and 5.0 + @author Alexander Potochkin + @run main bug6542335 +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicScrollBarUI; +import java.awt.*; +import java.awt.event.InputEvent; + +public class bug6542335 { + private static JScrollBar sb; + private static MyScrollBarUI ui; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(10); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + final JFrame frame = new JFrame("bug6542335"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + sb = new JScrollBar(0, 0, 1, 0, 1); + + ui = new MyScrollBarUI(); + sb.setUI(ui); + + sb.setPreferredSize(new Dimension(200, 17)); + DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel(); + rangeModel.setMaximum(100); + rangeModel.setMinimum(0); + rangeModel.setExtent(50); + rangeModel.setValue(50); + + sb.setModel(rangeModel); + frame.add(sb); + + frame.setSize(200, 100); + frame.setVisible(true); + } + }); + + Rectangle thumbBounds = new Rectangle(ui.getThumbBounds()); + + toolkit.realSync(); + Point l = sb.getLocationOnScreen(); + robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (!thumbBounds.equals(ui.getThumbBounds())) { + throw new RuntimeException("Test failed"); + } + } + + static class MyScrollBarUI extends BasicScrollBarUI { + public Rectangle getThumbBounds() { + return super.getThumbBounds(); + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/javax/swing/JTable/Test6888156.java --- a/jdk/test/javax/swing/JTable/Test6888156.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/test/javax/swing/JTable/Test6888156.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 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 @@ -71,14 +71,14 @@ table = new JTable(model); } - public void test(final LookAndFeel laf) throws Exception { + public void test(final String laf) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { try { + System.out.println(laf); UIManager.setLookAndFeel(laf); - } catch (UnsupportedLookAndFeelException e) { - System.err.println(laf.getDescription() + - " is unsupported; continuing"); + } catch (Exception e) { + System.err.println(laf + " is unsupported; continuing"); return; } SwingUtilities.updateComponentTreeUI(table); @@ -92,8 +92,10 @@ public static void main(String[] args) throws Exception { Test6888156 t = new Test6888156(); - t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel()); - t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel()); + t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel"); + t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + t.test(laf.getClassName()); + } } } - diff -r 43cb79a6b123 -r d954b585d3a1 jdk/test/javax/swing/JTextArea/6940863/bug6940863.java --- a/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java Tue Oct 12 17:05:28 2010 -0700 +++ b/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java Wed Oct 13 17:51:41 2010 -0700 @@ -56,6 +56,7 @@ public static void main(String[] args) throws Exception { if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { System.out.println("The test is suitable only for Windows OS. Skipped"); + return; } UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/.hgtags --- a/langtools/.hgtags Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/.hgtags Wed Oct 13 17:51:41 2010 -0700 @@ -86,3 +86,5 @@ 4826378eaade4c6676c452efe954be4ee113cc11 jdk7-b109 32da0f38d2fe96c558492b8707b40da24643d41e jdk7-b110 8bec624274ef8535720cff553374347c2f4f5fb2 jdk7-b111 +fd2579b80b83bf5d4289426016c7d29174ba5dd9 jdk7-b112 +6dbd2d869b0573fa5b799a23cccff47d20c12696 jdk7-b113 diff -r 43cb79a6b123 -r d954b585d3a1 langtools/make/netbeans/langtools/build.xml --- a/langtools/make/netbeans/langtools/build.xml Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/make/netbeans/langtools/build.xml Wed Oct 13 17:51:41 2010 -0700 @@ -31,44 +31,44 @@ --> - - - - - - + + - - - + - + - + - + Must set property 'includes' - - - - - + - + Must set property 'run.classname' - + - - - + @@ -118,7 +118,7 @@ - + @@ -127,36 +127,36 @@ - + Some tests failed; see report for details. - + - + - + Must set property 'debug.classname' - + Must set property 'jtreg.tests' - + - + Must set property 'class' @@ -169,16 +169,16 @@ - + - - - + @@ -187,7 +187,7 @@ - + @@ -196,26 +196,26 @@ - + - + - + - - + - @@ -236,7 +236,7 @@ - + @@ -251,28 +251,29 @@ - - + - + diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java --- a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -99,9 +99,6 @@ private static Context preRegister(Context context) { Bark.preRegister(context); - // force the use of the scanner that captures Javadoc comments - DocCommentScanner.Factory.preRegister(context); - if (context.get(JavaFileManager.class) == null) JavacFileManager.preRegister(context); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -96,9 +96,6 @@ args.getClass(); context.getClass(); fileObjects.getClass(); - - // force the use of the scanner that captures Javadoc comments - com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context); } JavacTaskImpl(JavacTool tool, @@ -337,9 +334,13 @@ ListBuffer elements = new ListBuffer(); for (JCCompilationUnit unit : units) { - for (JCTree node : unit.defs) - if (node.getTag() == JCTree.CLASSDEF) - elements.append(((JCTree.JCClassDecl) node).sym); + for (JCTree node : unit.defs) { + if (node.getTag() == JCTree.CLASSDEF) { + JCClassDecl cdef = (JCClassDecl) node; + if (cdef.sym != null) // maybe null if errors in anno processing + elements.append(cdef.sym); + } + } } return elements.toList(); } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -56,7 +56,6 @@ import com.sun.tools.javac.comp.MemberEnter; import com.sun.tools.javac.comp.Resolve; import com.sun.tools.javac.model.JavacElements; -import com.sun.tools.javac.processing.JavacMessager; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree; @@ -81,14 +80,15 @@ */ public class JavacTrees extends Trees { - private final Resolve resolve; - private final Enter enter; - private final Log log; - private final MemberEnter memberEnter; - private final Attr attr; - private final TreeMaker treeMaker; - private final JavacElements elements; - private final JavacTaskImpl javacTaskImpl; + // in a world of a single context per compilation, these would all be final + private Resolve resolve; + private Enter enter; + private Log log; + private MemberEnter memberEnter; + private Attr attr; + private TreeMaker treeMaker; + private JavacElements elements; + private JavacTaskImpl javacTaskImpl; public static JavacTrees instance(JavaCompiler.CompilationTask task) { if (!(task instanceof JavacTaskImpl)) @@ -111,6 +111,14 @@ private JavacTrees(Context context) { context.put(JavacTrees.class, this); + init(context); + } + + public void updateContext(Context context) { + init(context); + } + + private void init(Context context) { attr = Attr.instance(context); enter = Enter.instance(context); elements = JavacElements.instance(context); @@ -337,6 +345,7 @@ super(M); } + @Override public T copy(T t, JCTree leaf) { T t2 = super.copy(t, leaf); if (t == leaf) diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/code/Scope.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Wed Oct 13 17:51:41 2010 -0700 @@ -70,6 +70,45 @@ */ public int nelems = 0; + /** A timestamp - useful to quickly check whether a scope has changed or not + */ + public ScopeCounter scopeCounter; + + static ScopeCounter dummyCounter = new ScopeCounter() { + @Override + public void inc() { + //do nothing + } + }; + + public static class ScopeCounter { + protected static final Context.Key scopeCounterKey = + new Context.Key(); + + public static ScopeCounter instance(Context context) { + ScopeCounter instance = context.get(scopeCounterKey); + if (instance == null) + instance = new ScopeCounter(context); + return instance; + } + + protected ScopeCounter(Context context) { + context.put(scopeCounterKey, this); + } + + private ScopeCounter() {}; + + private long val = 0; + + public void inc() { + val++; + } + + public long val() { + return val; + } + } + /** Every hash bucket is a list of Entry's which ends in sentinel. */ private static final Entry sentinel = new Entry(null, null, null, null); @@ -80,12 +119,12 @@ /** A value for the empty scope. */ - public static final Scope emptyScope = new Scope(null, null, new Entry[]{}); + public static final Scope emptyScope = new Scope(null, null, new Entry[]{}, dummyCounter); /** Construct a new scope, within scope next, with given owner, using * given table. The table's length must be an exponent of 2. */ - Scope(Scope next, Symbol owner, Entry[] table) { + private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { this.next = next; assert emptyScope == null || owner != null; this.owner = owner; @@ -94,13 +133,18 @@ this.elems = null; this.nelems = 0; this.shared = 0; + this.scopeCounter = scopeCounter; } /** Construct a new scope, within scope next, with given owner, * using a fresh table of length INITIAL_SIZE. */ public Scope(Symbol owner) { - this(null, owner, new Entry[INITIAL_SIZE]); + this(owner, dummyCounter); + } + + 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; } @@ -110,7 +154,7 @@ * of fresh tables. */ public Scope dup() { - Scope result = new Scope(this, this.owner, this.table); + 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); @@ -123,7 +167,7 @@ * of fresh tables. */ public Scope dup(Symbol newOwner) { - Scope result = new Scope(this, newOwner, this.table); + Scope result = new Scope(this, newOwner, this.table, scopeCounter); shared++; // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode()); // new Error().printStackTrace(System.out); @@ -135,7 +179,7 @@ * the table of its outer scope. */ public Scope dupUnshared() { - return new Scope(this, this.owner, this.table.clone()); + return new Scope(this, this.owner, this.table.clone(), scopeCounter); } /** Remove all entries of this scope from its table, if shared @@ -211,6 +255,7 @@ table[hash] = e; elems = e; nelems++; + scopeCounter.inc(); } Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) { @@ -226,6 +271,8 @@ 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]; if (te == e) @@ -472,7 +519,7 @@ public static final Entry[] emptyTable = new Entry[0]; public DelegatedScope(Scope outer) { - super(outer, outer.owner, emptyTable); + super(outer, outer.owner, emptyTable, outer.scopeCounter); delegatee = outer; } public Scope dup() { @@ -498,10 +545,22 @@ } } + /** A class scope, for which a scope counter should be provided */ + public static class ClassScope extends Scope { + + ClassScope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { + super(next, owner, table, scopeCounter); + } + + public ClassScope(Symbol owner, ScopeCounter scopeCounter) { + super(owner, scopeCounter); + } + } + /** An error scope, for which the owner should be an error symbol. */ public static class ErrorScope extends Scope { ErrorScope(Scope next, Symbol errSymbol, Entry[] table) { - super(next, /*owner=*/errSymbol, table); + super(next, /*owner=*/errSymbol, table, dummyCounter); } public ErrorScope(Symbol errSymbol) { super(errSymbol); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/code/Source.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,11 +25,14 @@ package com.sun.tools.javac.code; +import java.util.*; +import javax.lang.model.SourceVersion; +import static javax.lang.model.SourceVersion.*; + import com.sun.tools.javac.util.*; import com.sun.tools.javac.jvm.Target; -import javax.lang.model.SourceVersion; -import static javax.lang.model.SourceVersion.*; -import java.util.*; + +import static com.sun.tools.javac.main.OptionName.*; /** The source language version accepted. * @@ -71,7 +74,7 @@ Source instance = context.get(sourceKey); if (instance == null) { Options options = Options.instance(context); - String sourceString = options.get("-source"); + String sourceString = options.get(SOURCE); if (sourceString != null) instance = lookup(sourceString); if (instance == null) instance = DEFAULT; context.put(sourceKey, instance); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -960,6 +960,8 @@ return ElementKind.ENUM_CONSTANT; } else if (owner.kind == TYP || owner.kind == ERR) { return ElementKind.FIELD; + } else if (isResourceVariable()) { + return ElementKind.RESOURCE_VARIABLE; } else { return ElementKind.LOCAL_VARIABLE; } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Wed Oct 13 17:51:41 2010 -0700 @@ -74,6 +74,7 @@ public final JCNoType voidType = new JCNoType(TypeTags.VOID); private final Names names; + private final Scope.ScopeCounter scopeCounter; private final ClassReader reader; private final Target target; @@ -340,6 +341,7 @@ context.put(symtabKey, this); names = Names.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); target = Target.instance(context); // Create the unknown type @@ -386,7 +388,7 @@ // Create class to hold all predefined constants and operations. predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); - Scope scope = new Scope(predefClass); + Scope scope = new Scope.ClassScope(predefClass, scopeCounter); predefClass.members_field = scope; // Enter symbols for basic types. @@ -476,7 +478,7 @@ proprietarySymbol.completer = null; proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; proprietarySymbol.erasure_field = proprietaryType; - proprietarySymbol.members_field = new Scope(proprietarySymbol); + proprietarySymbol.members_field = new Scope.ClassScope(proprietarySymbol, scopeCounter); proprietaryType.typarams_field = List.nil(); proprietaryType.allparams_field = List.nil(); proprietaryType.supertype_field = annotationType; @@ -488,7 +490,7 @@ ClassType arrayClassType = (ClassType)arrayClass.type; arrayClassType.supertype_field = objectType; arrayClassType.interfaces_field = List.of(cloneableType, serializableType); - arrayClass.members_field = new Scope(arrayClass); + arrayClass.members_field = new Scope.ClassScope(arrayClass, scopeCounter); lengthVar = new VarSymbol( PUBLIC | FINAL, names.length, diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Oct 13 17:51:41 2010 -0700 @@ -69,6 +69,7 @@ new Context.Key(); final Symtab syms; + final Scope.ScopeCounter scopeCounter; final JavacMessages messages; final Names names; final boolean allowBoxing; @@ -89,6 +90,7 @@ protected Types(Context context) { context.put(typesKey, this); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); names = Names.instance(context); allowBoxing = Source.instance(context).allowBoxing(); reader = ClassReader.instance(context); @@ -1984,22 +1986,26 @@ final MethodSymbol cachedImpl; final Filter implFilter; final boolean checkResult; + final Scope.ScopeCounter scopeCounter; public Entry(MethodSymbol cachedImpl, Filter scopeFilter, - boolean checkResult) { + boolean checkResult, + Scope.ScopeCounter scopeCounter) { this.cachedImpl = cachedImpl; this.implFilter = scopeFilter; this.checkResult = checkResult; + this.scopeCounter = scopeCounter; } - boolean matches(Filter scopeFilter, boolean checkResult) { + boolean matches(Filter scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) { return this.implFilter == scopeFilter && - this.checkResult == checkResult; + this.checkResult == checkResult && + this.scopeCounter.val() >= scopeCounter.val(); } } - MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter) { + MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter, Scope.ScopeCounter scopeCounter) { SoftReference> ref_cache = _map.get(ms); Map cache = ref_cache != null ? ref_cache.get() : null; if (cache == null) { @@ -2008,9 +2014,9 @@ } Entry e = cache.get(origin); if (e == null || - !e.matches(implFilter, checkResult)) { + !e.matches(implFilter, checkResult, scopeCounter)) { MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter); - cache.put(origin, new Entry(impl, implFilter, checkResult)); + cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter)); return impl; } else { @@ -2038,7 +2044,7 @@ private ImplementationCache implCache = new ImplementationCache(); public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter implFilter) { - return implCache.get(ms, origin, checkResult, implFilter); + return implCache.get(ms, origin, checkResult, implFilter, scopeCounter); } // diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Oct 13 17:51:41 2010 -0700 @@ -119,10 +119,10 @@ allowAnonOuterThis = source.allowAnonOuterThis(); allowStringsInSwitch = source.allowStringsInSwitch(); sourceName = source.name; - relax = (options.get("-retrofit") != null || - options.get("-relax") != null); - useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; - enableSunApiLintControl = options.get("enableSunApiLintControl") != null; + relax = (options.isSet("-retrofit") || + options.isSet("-relax")); + useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); + enableSunApiLintControl = options.isSet("enableSunApiLintControl"); } /** Switch: relax some constraints for retrofit mode. @@ -1422,7 +1422,8 @@ // Compute the result type. Type restype = mtype.getReturnType(); - assert restype.tag != WILDCARD : mtype; + if (restype.tag == WILDCARD) + throw new AssertionError(mtype); // as a special case, array.clone() has a result that is // the same as static type of the array being cloned diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,7 +25,6 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.AssignmentTree; import java.util.*; import java.util.Set; @@ -46,6 +45,8 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; +import static com.sun.tools.javac.main.OptionName.*; + /** Type checking helper class for the attribution phase. * *

This is NOT part of any supported API. @@ -60,6 +61,7 @@ private final Names names; private final Log log; private final Symtab syms; + private final Enter enter; private final Infer infer; private final Types types; private final JCDiagnostic.Factory diags; @@ -86,6 +88,7 @@ names = Names.instance(context); log = Log.instance(context); syms = Symtab.instance(context); + enter = Enter.instance(context); infer = Infer.instance(context); this.types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); @@ -97,10 +100,10 @@ allowGenerics = source.allowGenerics(); allowAnnotations = source.allowAnnotations(); allowCovariantReturns = source.allowCovariantReturns(); - complexInference = options.get("-complexinference") != null; - skipAnnotations = options.get("skipAnnotations") != null; - warnOnSyntheticConflicts = options.get("warnOnSyntheticConflicts") != null; - suppressAbortOnBadClassFile = options.get("suppressAbortOnBadClassFile") != null; + complexInference = options.isSet(COMPLEXINFERENCE); + skipAnnotations = options.isSet("skipAnnotations"); + warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); + suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); Target target = Target.instance(context); syntheticNameChar = target.syntheticNameChar(); @@ -1727,6 +1730,113 @@ return undef; } + void checkNonCyclicDecl(JCClassDecl tree) { + CycleChecker cc = new CycleChecker(); + cc.scan(tree); + if (!cc.errorFound && !cc.partialCheck) { + tree.sym.flags_field |= ACYCLIC; + } + } + + class CycleChecker extends TreeScanner { + + List seenClasses = List.nil(); + boolean errorFound = false; + boolean partialCheck = false; + + private void checkSymbol(DiagnosticPosition pos, Symbol sym) { + if (sym != null && sym.kind == TYP) { + Env classEnv = enter.getEnv((TypeSymbol)sym); + if (classEnv != null) { + DiagnosticSource prevSource = log.currentSource(); + try { + log.useSource(classEnv.toplevel.sourcefile); + scan(classEnv.tree); + } + finally { + log.useSource(prevSource.getFile()); + } + } else if (sym.kind == TYP) { + checkClass(pos, sym, List.nil()); + } + } else { + //not completed yet + partialCheck = true; + } + } + + @Override + public void visitSelect(JCFieldAccess tree) { + super.visitSelect(tree); + checkSymbol(tree.pos(), tree.sym); + } + + @Override + public void visitIdent(JCIdent tree) { + checkSymbol(tree.pos(), tree.sym); + } + + @Override + public void visitTypeApply(JCTypeApply tree) { + scan(tree.clazz); + } + + @Override + public void visitTypeArray(JCArrayTypeTree tree) { + scan(tree.elemtype); + } + + @Override + public void visitClassDef(JCClassDecl tree) { + List supertypes = List.nil(); + if (tree.getExtendsClause() != null) { + supertypes = supertypes.prepend(tree.getExtendsClause()); + } + if (tree.getImplementsClause() != null) { + for (JCTree intf : tree.getImplementsClause()) { + supertypes = supertypes.prepend(intf); + } + } + checkClass(tree.pos(), tree.sym, supertypes); + } + + void checkClass(DiagnosticPosition pos, Symbol c, List supertypes) { + if ((c.flags_field & ACYCLIC) != 0) + return; + if (seenClasses.contains(c)) { + errorFound = true; + noteCyclic(pos, (ClassSymbol)c); + } else if (!c.type.isErroneous()) { + try { + seenClasses = seenClasses.prepend(c); + if (c.type.tag == CLASS) { + if (supertypes.nonEmpty()) { + scan(supertypes); + } + else { + ClassType ct = (ClassType)c.type; + if (ct.supertype_field == null || + ct.interfaces_field == null) { + //not completed yet + partialCheck = true; + return; + } + checkSymbol(pos, ct.supertype_field.tsym); + for (Type intf : ct.interfaces_field) { + checkSymbol(pos, intf.tsym); + } + } + if (c.owner.kind == TYP) { + checkSymbol(pos, c.owner); + } + } + } finally { + seenClasses = seenClasses.tail; + } + } + } + } + /** Check for cyclic references. Issue an error if the * symbol of the type referred to has a LOCKED flag set. * diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Oct 13 17:51:41 2010 -0700 @@ -94,6 +94,7 @@ Log log; Symtab syms; + Scope.ScopeCounter scopeCounter; Check chk; TreeMaker make; ClassReader reader; @@ -121,6 +122,7 @@ reader = ClassReader.instance(context); make = TreeMaker.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); chk = Check.instance(context); memberEnter = MemberEnter.instance(context); types = Types.instance(context); @@ -189,7 +191,7 @@ */ public Env classEnv(JCClassDecl tree, Env env) { Env localEnv = - env.dup(tree, env.info.dup(new Scope(tree.sym))); + env.dup(tree, env.info.dup(new Scope.ClassScope(tree.sym, scopeCounter))); localEnv.enclClass = tree; localEnv.outer = env; localEnv.info.isSelfCall = false; @@ -325,7 +327,7 @@ c.flatname = names.fromString(tree.packge + "." + name); c.sourcefile = tree.sourcefile; c.completer = null; - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); tree.packge.package_info = c; } classEnter(tree.defs, topEnv); @@ -393,7 +395,7 @@ c.completer = memberEnter; c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree); c.sourcefile = env.toplevel.sourcefile; - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); ClassType ct = (ClassType)c.type; if (owner.kind != PCK && (c.flags_field & STATIC) == 0) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Oct 13 17:51:41 2010 -0700 @@ -80,25 +80,12 @@ } - public static class InferenceException extends RuntimeException { + public static class InferenceException extends Resolve.InapplicableMethodException { private static final long serialVersionUID = 0; - JCDiagnostic diagnostic; - JCDiagnostic.Factory diags; - InferenceException(JCDiagnostic.Factory diags) { - this.diagnostic = null; - this.diags = diags; + super(diags); } - - InferenceException setMessage(String key, Object... args) { - this.diagnostic = diags.fragment(key, args); - return this; - } - - public JCDiagnostic getDiagnostic() { - return diagnostic; - } } public static class NoInstanceException extends InferenceException { @@ -320,7 +307,7 @@ Type qtype1 = types.subst(that.qtype, that.tvars, undetvars); if (!types.isSubtype(qtype1, to)) { throw unambiguousNoInstanceException - .setMessage("no.conforming.instance.exists", + .setMessage("infer.no.conforming.instance.exists", that.tvars, that.qtype, to); } for (List l = undetvars; l.nonEmpty(); l = l.tail) @@ -378,6 +365,11 @@ // instantiate all polymorphic argument types and // set up lower bounds constraints for undetvars Type varargsFormal = useVarargs ? formals.last() : null; + if (varargsFormal == null && + actuals.size() != formals.size()) { + throw unambiguousNoInstanceException + .setMessage("infer.arg.length.mismatch"); + } while (actuals.nonEmpty() && formals.head != varargsFormal) { Type formal = formals.head; Type actual = actuals.head.baseType(); @@ -390,19 +382,16 @@ : types.isSubtypeUnchecked(actual, undetFormal, warn); if (!works) { throw unambiguousNoInstanceException - .setMessage("no.conforming.assignment.exists", + .setMessage("infer.no.conforming.assignment.exists", tvars, actualNoCapture, formal); } formals = formals.tail; actuals = actuals.tail; actualsNoCapture = actualsNoCapture.tail; } - if (formals.head != varargsFormal || // not enough args - !useVarargs && actuals.nonEmpty()) { // too many args - // argument lists differ in length - throw unambiguousNoInstanceException - .setMessage("arg.length.mismatch"); - } + + if (formals.head != varargsFormal) // not enough args + throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch"); // for varargs arguments as well if (useVarargs) { @@ -416,7 +405,7 @@ boolean works = types.isConvertible(actual, elemUndet, warn); if (!works) { throw unambiguousNoInstanceException - .setMessage("no.conforming.assignment.exists", + .setMessage("infer.no.conforming.assignment.exists", tvars, actualNoCapture, elemType); } actuals = actuals.tail; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Oct 13 17:51:41 2010 -0700 @@ -68,6 +68,7 @@ private Names names; private Log log; private Symtab syms; + private Scope.ScopeCounter scopeCounter; private Resolve rs; private Check chk; private Attr attr; @@ -90,6 +91,7 @@ names = Names.instance(context); log = Log.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); rs = Resolve.instance(context); chk = Check.instance(context); attr = Attr.instance(context); @@ -107,7 +109,7 @@ types = Types.instance(context); Options options = Options.instance(context); - debugLower = options.get("debuglower") != null; + debugLower = options.isSet("debuglower"); pkginfoOpt = PkgInfo.get(options); } @@ -569,7 +571,7 @@ c.flatname = chk.localClassName(c); c.sourcefile = owner.sourcefile; c.completer = null; - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); c.flags_field = flags; ClassType ctype = (ClassType) c.type; ctype.supertype_field = syms.objectType; @@ -2677,7 +2679,8 @@ } //where private JCTree convert(JCTree tree, Type pt) { - if (tree.type == pt) return tree; + if (tree.type == pt || tree.type.tag == TypeTags.BOT) + return tree; JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree); result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt) : pt; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Oct 13 17:51:41 2010 -0700 @@ -67,6 +67,7 @@ private final Check chk; private final Attr attr; private final Symtab syms; + private final Scope.ScopeCounter scopeCounter; private final TreeMaker make; private final ClassReader reader; private final Todo todo; @@ -92,6 +93,7 @@ chk = Check.instance(context); attr = Attr.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); make = TreeMaker.instance(context); reader = ClassReader.instance(context); todo = Todo.instance(context); @@ -100,7 +102,7 @@ diags = JCDiagnostic.Factory.instance(context); target = Target.instance(context); Options options = Options.instance(context); - skipAnnotations = options.get("skipAnnotations") != null; + skipAnnotations = options.isSet("skipAnnotations"); } /** A queue for classes whose members still need to be entered into the @@ -925,7 +927,7 @@ tp.accept(new TypeAnnotate(baseEnv)); tree.accept(new TypeAnnotate(env)); - chk.checkNonCyclic(tree.pos(), c.type); + chk.checkNonCyclicDecl(tree); attr.attribTypeVariables(tree.typarams, baseEnv); @@ -1087,7 +1089,7 @@ private Env baseEnv(JCClassDecl tree, Env env) { - Scope baseScope = new Scope(tree.sym); + Scope baseScope = new Scope.ClassScope(tree.sym, scopeCounter); //import already entered local classes into base scope for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) { if (e.sym.isLocal()) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Oct 13 17:51:41 2010 -0700 @@ -110,15 +110,17 @@ boxingEnabled = source.allowBoxing(); varargsEnabled = source.allowVarargs(); Options options = Options.instance(context); - debugResolve = options.get("debugresolve") != null; - allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null; + debugResolve = options.isSet("debugresolve"); + allowTransitionalJSR292 = options.isSet("allowTransitionalJSR292"); Target target = Target.instance(context); allowMethodHandles = allowTransitionalJSR292 || target.hasMethodHandles(); allowInvokeDynamic = (allowTransitionalJSR292 || target.hasInvokedynamic()) && - options.get("invokedynamic") != null; + options.isSet("invokedynamic"); polymorphicSignatureScope = new Scope(syms.noSymbol); + + inapplicableMethodException = new InapplicableMethodException(diags); } /** error symbols, which are returned when resolution fails @@ -318,7 +320,8 @@ throws Infer.InferenceException { boolean polymorphicSignature = (m.isPolymorphicSignatureGeneric() && allowMethodHandles) || isTransitionalDynamicCallSite(site, m); - if (useVarargs && (m.flags() & VARARGS) == 0) return null; + if (useVarargs && (m.flags() & VARARGS) == 0) + throw inapplicableMethodException.setMessage(null); Type mt = types.memberType(site, m); // tvars is the list of formal type variables for which type arguments @@ -334,7 +337,7 @@ } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) { ForAll pmt = (ForAll) mt; if (typeargtypes.length() != pmt.tvars.length()) - return null; + throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args // Check type arguments are within bounds List formals = pmt.tvars; List actuals = typeargtypes; @@ -343,7 +346,7 @@ pmt.tvars, typeargtypes); for (; bounds.nonEmpty(); bounds = bounds.tail) if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) - return null; + throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds); formals = formals.tail; actuals = actuals.tail; } @@ -375,11 +378,10 @@ allowBoxing, useVarargs, warn); - return - argumentsAcceptable(argtypes, mt.getParameterTypes(), - allowBoxing, useVarargs, warn) - ? mt - : null; + + checkRawArgumentsAcceptable(argtypes, mt.getParameterTypes(), + allowBoxing, useVarargs, warn); + return mt; } boolean isTransitionalDynamicCallSite(Type site, Symbol sym) { @@ -403,7 +405,7 @@ try { return rawInstantiate(env, site, m, argtypes, typeargtypes, allowBoxing, useVarargs, warn); - } catch (Infer.InferenceException ex) { + } catch (InapplicableMethodException ex) { return null; } } @@ -415,26 +417,76 @@ boolean allowBoxing, boolean useVarargs, Warner warn) { + try { + checkRawArgumentsAcceptable(argtypes, formals, allowBoxing, useVarargs, warn); + return true; + } catch (InapplicableMethodException ex) { + return false; + } + } + void checkRawArgumentsAcceptable(List argtypes, + List formals, + boolean allowBoxing, + boolean useVarargs, + Warner warn) { Type varargsFormal = useVarargs ? formals.last() : null; + if (varargsFormal == null && + argtypes.size() != formals.size()) { + throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args + } + while (argtypes.nonEmpty() && formals.head != varargsFormal) { boolean works = allowBoxing ? types.isConvertible(argtypes.head, formals.head, warn) : types.isSubtypeUnchecked(argtypes.head, formals.head, warn); - if (!works) return false; + if (!works) + throw inapplicableMethodException.setMessage("no.conforming.assignment.exists", + argtypes.head, + formals.head); argtypes = argtypes.tail; formals = formals.tail; } - if (formals.head != varargsFormal) return false; // not enough args - if (!useVarargs) - return argtypes.isEmpty(); - Type elt = types.elemtype(varargsFormal); - while (argtypes.nonEmpty()) { - if (!types.isConvertible(argtypes.head, elt, warn)) - return false; - argtypes = argtypes.tail; + + if (formals.head != varargsFormal) + throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args + + if (useVarargs) { + Type elt = types.elemtype(varargsFormal); + while (argtypes.nonEmpty()) { + if (!types.isConvertible(argtypes.head, elt, warn)) + throw inapplicableMethodException.setMessage("varargs.argument.mismatch", + argtypes.head, + elt); + argtypes = argtypes.tail; + } } - return true; + return; } + // where + public static class InapplicableMethodException extends RuntimeException { + private static final long serialVersionUID = 0; + + JCDiagnostic diagnostic; + JCDiagnostic.Factory diags; + + InapplicableMethodException(JCDiagnostic.Factory diags) { + this.diagnostic = null; + this.diags = diags; + } + InapplicableMethodException setMessage(String key) { + this.diagnostic = key != null ? diags.fragment(key) : null; + return this; + } + InapplicableMethodException setMessage(String key, Object... args) { + this.diagnostic = key != null ? diags.fragment(key, args) : null; + return this; + } + + public JCDiagnostic getDiagnostic() { + return diagnostic; + } + } + private final InapplicableMethodException inapplicableMethodException; /* *************************************************************************** * Symbol lookup @@ -595,6 +647,7 @@ * @param allowBoxing Allow boxing conversions of arguments. * @param useVarargs Box trailing arguments into an array for varargs. */ + @SuppressWarnings("fallthrough") Symbol selectBest(Env env, Type site, List argtypes, @@ -608,21 +661,16 @@ if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; assert sym.kind < AMBIGUOUS; try { - if (rawInstantiate(env, site, sym, argtypes, typeargtypes, - allowBoxing, useVarargs, Warner.noWarnings) == null) { - // inapplicable - switch (bestSoFar.kind) { - case ABSENT_MTH: return wrongMethod.setWrongSym(sym); - case WRONG_MTH: return wrongMethods; - default: return bestSoFar; - } - } - } catch (Infer.InferenceException ex) { + rawInstantiate(env, site, sym, argtypes, typeargtypes, + allowBoxing, useVarargs, Warner.noWarnings); + } catch (InapplicableMethodException ex) { switch (bestSoFar.kind) { case ABSENT_MTH: return wrongMethod.setWrongSym(sym, ex.getDiagnostic()); case WRONG_MTH: - return wrongMethods; + wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation); + case WRONG_MTHS: + return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic()); default: return bestSoFar; } @@ -631,7 +679,7 @@ return (bestSoFar.kind == ABSENT_MTH) ? new AccessError(env, site, sym) : bestSoFar; - } + } return (bestSoFar.kind > AMBIGUOUS) ? sym : mostSpecific(sym, bestSoFar, env, site, @@ -1253,11 +1301,12 @@ Name name, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = findFun(env, name, argtypes, typeargtypes, steps.head.isBoxingRequired, env.info.varArgs = steps.head.isVarargsRequired); @@ -1274,6 +1323,12 @@ return sym; } + private Symbol startResolution() { + wrongMethod.clear(); + wrongMethods.clear(); + return methodNotFound; + } + /** Resolve a qualified method identifier * @param pos The position to use for error reporting. * @param env The environment current at the method invocation. @@ -1286,11 +1341,12 @@ Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env env, Type site, Name name, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = findMethod(env, site, name, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired(), false); @@ -1404,11 +1460,12 @@ Type site, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired()); @@ -1439,26 +1496,22 @@ Type site, List argtypes, List typeargtypes) { - Symbol sym = methodNotFound; - JCDiagnostic explanation = null; + Symbol sym = startResolution(); List steps = methodResolutionSteps; while (steps.nonEmpty() && steps.head.isApplicable(boxingEnabled, varargsEnabled) && sym.kind >= ERRONEOUS) { + currentStep = steps.head; sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, steps.head.isBoxingRequired(), env.info.varArgs = steps.head.isVarargsRequired()); methodResolutionCache.put(steps.head, sym); - if (sym.kind == WRONG_MTH && - ((InapplicableSymbolError)sym).explanation != null) { - //if the symbol is an inapplicable method symbol, then the - //explanation contains the reason for which inference failed - explanation = ((InapplicableSymbolError)sym).explanation; - } steps = steps.tail; } if (sym.kind >= AMBIGUOUS) { - final JCDiagnostic details = explanation; + final JCDiagnostic details = sym.kind == WRONG_MTH ? + ((InapplicableSymbolError)sym).explanation : + null; Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") { @Override JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Type site, Name name, List argtypes, List typeargtypes) { @@ -1860,7 +1913,8 @@ */ InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) { this.sym = sym; - this.explanation = explanation; + if (this.sym == sym && explanation != null) + this.explanation = explanation; //update the details return this; } @@ -1868,7 +1922,6 @@ */ InapplicableSymbolError setWrongSym(Symbol sym) { this.sym = sym; - this.explanation = null; return this; } @@ -1905,6 +1958,10 @@ } } + void clear() { + explanation = null; + } + @Override public Symbol access(Name name, TypeSymbol location) { return types.createErrorType(name, location, syms.errSymbol.type).tsym; @@ -1917,6 +1974,9 @@ * given an actual arguments/type argument list. */ class InapplicableSymbolsError extends ResolveError { + + private List candidates = List.nil(); + InapplicableSymbolsError(Symbol sym) { super(WRONG_MTHS, "inapplicable symbols"); } @@ -1928,8 +1988,85 @@ Name name, List argtypes, List typeargtypes) { - return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, + if (candidates.nonEmpty()) { + JCDiagnostic err = diags.create(dkind, + log.currentSource(), + pos, + "cant.apply.symbols", + name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), + getName(), + argtypes); + return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); + } else { + return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, site, name, argtypes, typeargtypes); + } + } + + //where + List candidateDetails(Type site) { + List details = List.nil(); + for (Candidate c : candidates) + details = details.prepend(c.getDiagnostic(site)); + return details.reverse(); + } + + Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) { + Candidate c = new Candidate(currentStep, sym, details); + if (c.isValid() && !candidates.contains(c)) + candidates = candidates.append(c); + return this; + } + + void clear() { + candidates = List.nil(); + } + + private Name getName() { + Symbol sym = candidates.head.sym; + return sym.name == names.init ? + sym.owner.name : + sym.name; + } + + private class Candidate { + + final MethodResolutionPhase step; + final Symbol sym; + final JCDiagnostic details; + + private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details) { + this.step = step; + this.sym = sym; + this.details = details; + } + + JCDiagnostic getDiagnostic(Type site) { + return diags.fragment("inapplicable.method", + Kinds.kindName(sym), + sym.location(site, types), + sym.asMemberOf(site, types), + details); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Candidate) { + Symbol s1 = this.sym; + Symbol s2 = ((Candidate)o).sym; + if ((s1 != s2 && + (s1.overrides(s2, s1.owner.type.tsym, types, false) || + (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || + ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) + return true; + } + return false; + } + + boolean isValid() { + return (((sym.flags() & VARARGS) != 0 && step == VARARITY) || + (sym.flags() & VARARGS) == 0 && step == (boxingEnabled ? BOX : BASIC)); + } } } @@ -2093,6 +2230,8 @@ final List methodResolutionSteps = List.of(BASIC, BOX, VARARITY); + private MethodResolutionPhase currentStep = null; + private MethodResolutionPhase firstErroneousResolutionPhase() { MethodResolutionPhase bestSoFar = BASIC; Symbol sym = methodNotFound; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,8 +150,8 @@ useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; - mmappedIO = options.get("mmappedIO") != null; - ignoreSymbolFile = options.get("ignore.symbol.file") != null; + mmappedIO = options.isSet("mmappedIO"); + ignoreSymbolFile = options.isSet("ignore.symbol.file"); } public JavaFileObject getFileForInput(String name) { @@ -435,7 +435,7 @@ zdir = new ZipFile(zipFileName); } else { - usePreindexedCache = options.get("usezipindex") != null; + usePreindexedCache = options.isSet("usezipindex"); preindexCacheLocation = options.get("java.io.tmpdir"); String optCacheLoc = options.get("cachezipindexdir"); @@ -469,7 +469,7 @@ null, usePreindexedCache, preindexCacheLocation, - options.get("writezipindexfiles") != null)); + options.isSet("writezipindexfiles"))); } } else { @@ -482,7 +482,7 @@ symbolFilePrefix, usePreindexedCache, preindexCacheLocation, - options.get("writezipindexfiles") != null)); + options.isSet("writezipindexfiles"))); } } } catch (FileNotFoundException ex) { @@ -605,7 +605,7 @@ nullCheck(className); nullCheck(kind); if (!sourceOrClass.contains(kind)) - throw new IllegalArgumentException("Invalid kind " + kind); + throw new IllegalArgumentException("Invalid kind: " + kind); return getFileForInput(location, RelativeFile.forClass(className, kind)); } @@ -658,7 +658,7 @@ nullCheck(className); nullCheck(kind); if (!sourceOrClass.contains(kind)) - throw new IllegalArgumentException("Invalid kind " + kind); + throw new IllegalArgumentException("Invalid kind: " + kind); return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling); } @@ -672,7 +672,7 @@ // validatePackageName(packageName); nullCheck(packageName); if (!isRelativeUri(relativeName)) - throw new IllegalArgumentException("relativeName is invalid"); + throw new IllegalArgumentException("Invalid relative name: " + relativeName); RelativeFile name = packageName.length() == 0 ? new RelativeFile(relativeName) : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName); @@ -806,6 +806,8 @@ String path = uri.normalize().getPath(); if (path.length() == 0 /* isEmpty() is mustang API */) return false; + if (!path.equals(uri.getPath())) // implicitly checks for embedded . and .. + return false; char first = path.charAt(0); return first != '.' && first != '/'; } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 13 17:51:41 2010 -0700 @@ -56,6 +56,8 @@ import static com.sun.tools.javac.jvm.ClassFile.*; import static com.sun.tools.javac.jvm.ClassFile.Version.*; +import static com.sun.tools.javac.main.OptionName.*; + /** This class provides operations to read a classfile into an internal * representation. The internal representation is anchored in a * ClassSymbol which contains in its scope symbol representations @@ -122,6 +124,9 @@ /** The symbol table. */ Symtab syms; + /** The scope counter */ + Scope.ScopeCounter scopeCounter; + Types types; /** The name table. */ @@ -244,6 +249,7 @@ names = Names.instance(context); syms = Symtab.instance(context); + scopeCounter = Scope.ScopeCounter.instance(context); types = Types.instance(context); fileManager = context.get(JavaFileManager.class); if (fileManager == null) @@ -255,23 +261,23 @@ Options options = Options.instance(context); annotate = Annotate.instance(context); - verbose = options.get("-verbose") != null; - checkClassFile = options.get("-checkclassfile") != null; + verbose = options.isSet(VERBOSE); + checkClassFile = options.isSet("-checkclassfile"); Source source = Source.instance(context); allowGenerics = source.allowGenerics(); allowVarargs = source.allowVarargs(); allowAnnotations = source.allowAnnotations(); - saveParameterNames = options.get("save-parameter-names") != null; - cacheCompletionFailure = options.get("dev") == null; + saveParameterNames = options.isSet("save-parameter-names"); + cacheCompletionFailure = options.isUnset("dev"); preferSource = "source".equals(options.get("-Xprefer")); completionFailureName = - (options.get("failcomplete") != null) + options.isSet("failcomplete") ? names.fromString(options.get("failcomplete")) : null; typevars = new Scope(syms.noSymbol); - debugJSR308 = options.get("TA:reader") != null; + debugJSR308 = options.isSet("TA:reader"); initAttributeReaders(); } @@ -1984,7 +1990,7 @@ ClassType ct = (ClassType)c.type; // allocate scope for members - c.members_field = new Scope(c); + c.members_field = new Scope.ClassScope(c, scopeCounter); // prepare type variable table typevars = typevars.dup(currentOwner); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Oct 13 17:51:41 2010 -0700 @@ -45,8 +45,10 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.UninitializedType.*; +import static com.sun.tools.javac.main.OptionName.*; import static javax.tools.StandardLocation.CLASS_OUTPUT; + /** This class provides operations to map an internal symbol table graph * rooted in a ClassSymbol into a classfile. * @@ -178,15 +180,16 @@ types = Types.instance(context); fileManager = context.get(JavaFileManager.class); - debugJSR308 = options.get("TA:writer") != null; - verbose = options.get("-verbose") != null; - scramble = options.get("-scramble") != null; - scrambleAll = options.get("-scrambleAll") != null; - retrofit = options.get("-retrofit") != null; - genCrt = options.get("-Xjcov") != null; - debugstackmap = options.get("debugstackmap") != null; + debugJSR308 = options.isSet("TA:writer"); + verbose = options.isSet(VERBOSE); + scramble = options.isSet("-scramble"); + scrambleAll = options.isSet("-scrambleAll"); + retrofit = options.isSet("-retrofit"); + genCrt = options.isSet(XJCOV); + debugstackmap = options.isSet("debugstackmap"); - emitSourceFile = options.get("-g:")==null || options.get("-g:source")!=null; + emitSourceFile = options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "source"); String dumpModFlags = options.get("dumpmodifiers"); dumpClassModifiers = diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Oct 13 17:51:41 2010 -0700 @@ -46,6 +46,7 @@ import static com.sun.tools.javac.code.TypeTags.*; import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.CRTFlags.*; +import static com.sun.tools.javac.main.OptionName.*; /** This pass maps flat Java (i.e. without inner classes) to bytecodes. * @@ -113,19 +114,19 @@ Options options = Options.instance(context); lineDebugInfo = - options.get("-g:") == null || - options.get("-g:lines") != null; + options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "lines"); varDebugInfo = - options.get("-g:") == null - ? options.get("-g") != null - : options.get("-g:vars") != null; - genCrt = options.get("-Xjcov") != null; - debugCode = options.get("debugcode") != null; - allowInvokedynamic = target.hasInvokedynamic() || options.get("invokedynamic") != null; + options.isUnset(G_CUSTOM) + ? options.isSet(G) + : options.isSet(G_CUSTOM, "vars"); + genCrt = options.isSet(XJCOV); + debugCode = options.isSet("debugcode"); + allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic"); generateIproxies = target.requiresIproxy() || - options.get("miranda") != null; + options.isSet("miranda"); if (target.generateStackMapTable()) { // ignore cldc because we cannot have both stackmap formats diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java Wed Oct 13 17:51:41 2010 -0700 @@ -31,6 +31,8 @@ import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.util.*; +import static com.sun.tools.javac.main.OptionName.*; + /** The classfile version target. * *

This is NOT part of any supported API. @@ -73,7 +75,7 @@ Target instance = context.get(targetKey); if (instance == null) { Options options = Options.instance(context); - String targetString = options.get("-target"); + String targetString = options.get(TARGET); if (targetString != null) instance = lookup(targetString); if (instance == null) instance = DEFAULT; context.put(targetKey, instance); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 @@ -26,48 +26,44 @@ package com.sun.tools.javac.main; import java.io.*; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.MissingResourceException; +import java.util.Queue; import java.util.ResourceBundle; import java.util.Set; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.processing.Processor; +import javax.lang.model.SourceVersion; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.DiagnosticListener; -import com.sun.tools.javac.file.JavacFileManager; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; +import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.*; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.*; +import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.parser.*; import com.sun.tools.javac.comp.*; import com.sun.tools.javac.jvm.*; - -import com.sun.tools.javac.code.Symbol.*; -import com.sun.tools.javac.tree.JCTree.*; - import com.sun.tools.javac.processing.*; -import javax.annotation.processing.Processor; import static javax.tools.StandardLocation.CLASS_OUTPUT; +import static com.sun.tools.javac.main.OptionName.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; import static com.sun.tools.javac.util.ListBuffer.lb; -// TEMP, until we have a more efficient way to save doc comment info -import com.sun.tools.javac.parser.DocCommentScanner; - -import java.util.HashMap; -import java.util.Queue; -import javax.lang.model.SourceVersion; /** This class could be the main entry point for GJC when GJC is used as a * component in a larger software system. It provides operations to @@ -359,22 +355,22 @@ Options options = Options.instance(context); - verbose = options.get("-verbose") != null; - sourceOutput = options.get("-printsource") != null; // used to be -s - stubOutput = options.get("-stubs") != null; - relax = options.get("-relax") != null; - printFlat = options.get("-printflat") != null; - attrParseOnly = options.get("-attrparseonly") != null; - encoding = options.get("-encoding"); - lineDebugInfo = options.get("-g:") == null || - options.get("-g:lines") != null; - genEndPos = options.get("-Xjcov") != null || + verbose = options.isSet(VERBOSE); + sourceOutput = options.isSet(PRINTSOURCE); // used to be -s + stubOutput = options.isSet("-stubs"); + relax = options.isSet("-relax"); + printFlat = options.isSet("-printflat"); + attrParseOnly = options.isSet("-attrparseonly"); + encoding = options.get(ENCODING); + lineDebugInfo = options.isUnset(G_CUSTOM) || + options.isSet(G_CUSTOM, "lines"); + genEndPos = options.isSet(XJCOV) || context.get(DiagnosticListener.class) != null; - devVerbose = options.get("dev") != null; - processPcks = options.get("process.packages") != null; - werror = options.get("-Werror") != null; + devVerbose = options.isSet("dev"); + processPcks = options.isSet("process.packages"); + werror = options.isSet(WERROR); - verboseCompilePolicy = options.get("verboseCompilePolicy") != null; + verboseCompilePolicy = options.isSet("verboseCompilePolicy"); if (attrParseOnly) compilePolicy = CompilePolicy.ATTR_ONLY; @@ -384,15 +380,15 @@ implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit")); completionFailureName = - (options.get("failcomplete") != null) + options.isSet("failcomplete") ? names.fromString(options.get("failcomplete")) : null; shouldStopPolicy = - (options.get("shouldStopPolicy") != null) + options.isSet("shouldStopPolicy") ? CompileState.valueOf(options.get("shouldStopPolicy")) : null; - if (options.get("oldDiags") == null) + if (options.isUnset("oldDiags")) log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context)); } @@ -957,18 +953,17 @@ // Process annotations if processing is not disabled and there // is at least one Processor available. Options options = Options.instance(context); - if (options.get("-proc:none") != null) { + if (options.isSet(PROC, "none")) { processAnnotations = false; } else if (procEnvImpl == null) { procEnvImpl = new JavacProcessingEnvironment(context, processors); processAnnotations = procEnvImpl.atLeastOneProcessor(); if (processAnnotations) { - if (context.get(Scanner.Factory.scannerFactoryKey) == null) - DocCommentScanner.Factory.preRegister(context); options.put("save-parameter-names", "save-parameter-names"); reader.saveParameterNames = true; keepComments = true; + genEndPos = true; if (taskListener != null) taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING)); log.deferDiagnostics = true; @@ -1017,7 +1012,7 @@ // annotation processing is to occur with compilation, // emit a warning. Options options = Options.instance(context); - if (options.get("-proc:only") != null) { + if (options.isSet(PROC, "only")) { log.warning("proc.proc-only.requested.no.procs"); todo.clear(); } @@ -1105,10 +1100,10 @@ Options options = Options.instance(context); return explicitAnnotationProcessingRequested || - options.get("-processor") != null || - options.get("-processorpath") != null || - options.get("-proc:only") != null || - options.get("-Xprint") != null; + options.isSet(PROCESSOR) || + options.isSet(PROCESSORPATH) || + options.isSet(PROC, "only") || + options.isSet(XPRINT); } /** @@ -1587,6 +1582,7 @@ } public void initRound(JavaCompiler prev) { + genEndPos = prev.genEndPos; keepComments = prev.keepComments; start_msec = prev.start_msec; hasBeenUsed = true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Wed Oct 13 17:51:41 2010 -0700 @@ -32,6 +32,9 @@ import java.security.DigestInputStream; import java.security.MessageDigest; import java.util.MissingResourceException; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.annotation.processing.Processor; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.file.CacheFSInfo; @@ -41,9 +44,8 @@ import com.sun.tools.javac.main.RecognizedOptions.OptionHelper; import com.sun.tools.javac.util.*; import com.sun.tools.javac.processing.AnnotationProcessingError; -import javax.tools.JavaFileManager; -import javax.tools.JavaFileObject; -import javax.annotation.processing.Processor; + +import static com.sun.tools.javac.main.OptionName.*; /** This class provides a commandline interface to the GJC compiler. * @@ -239,16 +241,16 @@ } } - if (!checkDirectory("-d")) + if (!checkDirectory(D)) return null; - if (!checkDirectory("-s")) + if (!checkDirectory(S)) return null; - String sourceString = options.get("-source"); + String sourceString = options.get(SOURCE); Source source = (sourceString != null) ? Source.lookup(sourceString) : Source.DEFAULT; - String targetString = options.get("-target"); + String targetString = options.get(TARGET); Target target = (targetString != null) ? Target.lookup(targetString) : Target.DEFAULT; @@ -285,7 +287,7 @@ // phase this out with JSR 292 PFD if ("no".equals(options.get("allowTransitionalJSR292"))) { options.put("allowTransitionalJSR292", null); - } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) { + } else if (target.hasInvokedynamic() && options.isUnset("allowTransitionalJSR292")) { options.put("allowTransitionalJSR292", "allowTransitionalJSR292"); } @@ -300,7 +302,7 @@ return filenames.toList(); } // where - private boolean checkDirectory(String optName) { + private boolean checkDirectory(OptionName optName) { String value = options.get(optName); if (value == null) return true; @@ -367,10 +369,10 @@ return EXIT_CMDERR; } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) { // it is allowed to compile nothing if just asking for help or version info - if (options.get("-help") != null - || options.get("-X") != null - || options.get("-version") != null - || options.get("-fullversion") != null) + if (options.isSet(HELP) + || options.isSet(X) + || options.isSet(VERSION) + || options.isSet(FULLVERSION)) return EXIT_OK; error("err.no.source.files"); return EXIT_CMDERR; @@ -382,7 +384,7 @@ return EXIT_SYSERR; } - boolean forceStdOut = options.get("stdout") != null; + boolean forceStdOut = options.isSet("stdout"); if (forceStdOut) { out.flush(); out = new PrintWriter(System.out, true); @@ -391,7 +393,7 @@ context.put(Log.outKey, out); // allow System property in following line as a Mustang legacy - boolean batchMode = (options.get("nonBatchMode") == null + boolean batchMode = (options.isUnset("nonBatchMode") && System.getProperty("nonBatchMode") == null); if (batchMode) CacheFSInfo.preRegister(context); @@ -455,7 +457,7 @@ // for buggy compiler error recovery by swallowing thrown // exceptions. if (comp == null || comp.errorCount() == 0 || - options == null || options.get("dev") != null) + options == null || options.isSet("dev")) bugMessage(ex); return EXIT_ABNORMAL; } finally { @@ -478,7 +480,7 @@ */ void feMessage(Throwable ex) { Log.printLines(out, ex.getMessage()); - if (ex.getCause() != null && options.get("dev") != null) { + if (ex.getCause() != null && options.isSet("dev")) { ex.getCause().printStackTrace(out); } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java --- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Wed Oct 13 17:51:41 2010 -0700 @@ -366,11 +366,11 @@ // } // } int maxDepth = (recurse ? Integer.MAX_VALUE : 1); - Set opts = EnumSet.of(DETECT_CYCLES, FOLLOW_LINKS); + Set opts = EnumSet.of(FOLLOW_LINKS); Files.walkFileTree(packageDir, opts, maxDepth, new SimpleFileVisitor() { @Override - public FileVisitResult preVisitDirectory(Path dir) { + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292? return FileVisitResult.CONTINUE; else diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -42,50 +42,17 @@ */ public class DocCommentScanner extends Scanner { - /** A factory for creating scanners. */ - public static class Factory extends Scanner.Factory { - - public static void preRegister(final Context context) { - context.put(scannerFactoryKey, new Context.Factory() { - public Factory make() { - return new Factory(context); - } - }); - } - - /** Create a new scanner factory. */ - protected Factory(Context context) { - super(context); - } - - @Override - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new DocCommentScanner(this, (CharBuffer)input); - } else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - } - - @Override - public Scanner newScanner(char[] input, int inputLength) { - return new DocCommentScanner(this, input, inputLength); - } - } - - /** Create a scanner from the input buffer. buffer must implement * array() and compact(), and remaining() must be less than limit(). */ - protected DocCommentScanner(Factory fac, CharBuffer buffer) { + protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) { super(fac, buffer); } /** Create a scanner from the input array. The array must have at * least a single character of extra space. */ - protected DocCommentScanner(Factory fac, char[] input, int inputLength) { + protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) { super(fac, input, inputLength); } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 @@ -2473,6 +2473,11 @@ defs.append(importDeclaration()); } else { JCTree def = typeDeclaration(mods); + if (keepDocComments && dc != null && docComments.get(def) == dc) { + // If the first type declaration has consumed the first doc + // comment, then don't use it for the top level comment as well. + dc = null; + } if (def instanceof JCExpressionStatement) def = ((JCExpressionStatement)def).expr; defs.append(def); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 @@ -59,7 +59,7 @@ final Source source; final Names names; final Options options; - final Scanner.Factory scannerFactory; + final ScannerFactory scannerFactory; protected ParserFactory(Context context) { super(); @@ -70,11 +70,11 @@ this.keywords = Keywords.instance(context); this.source = Source.instance(context); this.options = Options.instance(context); - this.scannerFactory = Scanner.Factory.instance(context); + this.scannerFactory = ScannerFactory.instance(context); } public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) { - Lexer lexer = scannerFactory.newScanner(input); + Lexer lexer = scannerFactory.newScanner(input, keepDocComments); if (keepEndPos) { return new EndPosParser(this, lexer, keepDocComments, keepLineMap); } else { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 @@ -47,48 +47,6 @@ private static boolean scannerDebug = false; - /** A factory for creating scanners. */ - public static class Factory { - /** The context key for the scanner factory. */ - public static final Context.Key scannerFactoryKey = - new Context.Key(); - - /** Get the Factory instance for this context. */ - public static Factory instance(Context context) { - Factory instance = context.get(scannerFactoryKey); - if (instance == null) - instance = new Factory(context); - return instance; - } - - final Log log; - final Names names; - final Source source; - final Keywords keywords; - - /** Create a new scanner factory. */ - protected Factory(Context context) { - context.put(scannerFactoryKey, this); - this.log = Log.instance(context); - this.names = Names.instance(context); - this.source = Source.instance(context); - this.keywords = Keywords.instance(context); - } - - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new Scanner(this, (CharBuffer)input); - } else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - } - - public Scanner newScanner(char[] input, int inputLength) { - return new Scanner(this, input, inputLength); - } - } - /* Output variables; set by nextToken(): */ @@ -177,7 +135,7 @@ private final Keywords keywords; /** Common code for constructors. */ - private Scanner(Factory fac) { + private Scanner(ScannerFactory fac) { log = fac.log; names = fac.names; keywords = fac.keywords; @@ -201,7 +159,7 @@ /** Create a scanner from the input buffer. buffer must implement * array() and compact(), and remaining() must be less than limit(). */ - protected Scanner(Factory fac, CharBuffer buffer) { + protected Scanner(ScannerFactory fac, CharBuffer buffer) { this(fac, JavacFileManager.toArray(buffer), buffer.limit()); } @@ -216,7 +174,7 @@ * @param inputLength the size of the input. * Must be positive and less than or equal to input.length. */ - protected Scanner(Factory fac, char[] input, int inputLength) { + protected Scanner(ScannerFactory fac, char[] input, int inputLength) { this(fac); eofPos = inputLength; if (inputLength == input.length) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,90 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.parser; + +import java.nio.CharBuffer; + +import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; + + +/** + * A factory for creating scanners. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own + * risk. This code and its internal interfaces are subject to change + * or deletion without notice. + */ +public class ScannerFactory { + /** The context key for the scanner factory. */ + public static final Context.Key scannerFactoryKey = + new Context.Key(); + + /** Get the Factory instance for this context. */ + public static ScannerFactory instance(Context context) { + ScannerFactory instance = context.get(scannerFactoryKey); + if (instance == null) + instance = new ScannerFactory(context); + return instance; + } + + final Log log; + final Names names; + final Source source; + final Keywords keywords; + + /** Create a new scanner factory. */ + protected ScannerFactory(Context context) { + context.put(scannerFactoryKey, this); + this.log = Log.instance(context); + this.names = Names.instance(context); + this.source = Source.instance(context); + this.keywords = Keywords.instance(context); + } + + public Scanner newScanner(CharSequence input, boolean keepDocComments) { + if (input instanceof CharBuffer) { + CharBuffer buf = (CharBuffer) input; + if (keepDocComments) + return new DocCommentScanner(this, buf); + else + return new Scanner(this, buf); + } else { + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length, keepDocComments); + } + } + + public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { + if (keepDocComments) + return new DocCommentScanner(this, input, inputLength); + else + return new Scanner(this, input, inputLength); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,14 +25,6 @@ package com.sun.tools.javac.processing; -import com.sun.tools.javac.util.*; -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.NestingKind; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.Element; -import java.util.*; - import java.io.Closeable; import java.io.FileNotFoundException; import java.io.InputStream; @@ -43,14 +35,26 @@ import java.io.FilterWriter; import java.io.PrintWriter; import java.io.IOException; +import java.util.*; -import javax.tools.*; import static java.util.Collections.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.NestingKind; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Element; +import javax.tools.*; import javax.tools.JavaFileManager.Location; + import static javax.tools.StandardLocation.SOURCE_OUTPUT; import static javax.tools.StandardLocation.CLASS_OUTPUT; +import com.sun.tools.javac.code.Lint; +import com.sun.tools.javac.util.*; + +import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; + /** * The FilerImplementation class must maintain a number of * constraints. First, multiple attempts to open the same path within @@ -366,7 +370,7 @@ aggregateGeneratedSourceNames = new LinkedHashSet(); aggregateGeneratedClassNames = new LinkedHashSet(); - lint = (Options.instance(context)).lint("processing"); + lint = (Lint.instance(context)).isEnabled(PROCESSING); } public JavaFileObject createSourceFile(CharSequence name, diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -49,6 +49,7 @@ import javax.tools.JavaFileObject; import javax.tools.DiagnosticListener; +import com.sun.tools.javac.api.JavacTrees; import com.sun.source.util.AbstractTypeProcessor; import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; @@ -78,6 +79,8 @@ import static javax.tools.StandardLocation.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; +import static com.sun.tools.javac.main.OptionName.*; +import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; /** * Objects of this class hold and manage the state needed to support @@ -159,15 +162,14 @@ source = Source.instance(context); diags = JCDiagnostic.Factory.instance(context); options = Options.instance(context); - printProcessorInfo = options.get("-XprintProcessorInfo") != null; - printRounds = options.get("-XprintRounds") != null; - verbose = options.get("-verbose") != null; - lint = options.lint("processing"); - procOnly = options.get("-proc:only") != null || - options.get("-Xprint") != null; - fatalErrors = options.get("fatalEnterError") != null; - showResolveErrors = options.get("showResolveErrors") != null; - werror = options.get("-Werror") != null; + printProcessorInfo = options.isSet(XPRINTPROCESSORINFO); + printRounds = options.isSet(XPRINTROUNDS); + verbose = options.isSet(VERBOSE); + lint = Lint.instance(context).isEnabled(PROCESSING); + procOnly = options.isSet(PROC, "only") || options.isSet(XPRINT); + fatalErrors = options.isSet("fatalEnterError"); + showResolveErrors = options.isSet("showResolveErrors"); + werror = options.isSet(WERROR); platformAnnotations = initPlatformAnnotations(); foundTypeProcessors = false; @@ -199,7 +201,7 @@ Log log = Log.instance(context); Iterator processorIterator; - if (options.get("-Xprint") != null) { + if (options.isSet(XPRINT)) { try { Processor processor = PrintingProcessor.class.newInstance(); processorIterator = List.of(processor).iterator(); @@ -212,7 +214,7 @@ } else if (processors != null) { processorIterator = processors.iterator(); } else { - String processorNames = options.get("-processor"); + String processorNames = options.get(PROCESSOR); JavaFileManager fileManager = context.get(JavaFileManager.class); try { // If processorpath is not explicitly set, use the classpath. @@ -263,7 +265,7 @@ ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH) : standardFileManager.getLocation(CLASS_PATH); - if (needClassLoader(options.get("-processor"), workingPath) ) + if (needClassLoader(options.get(PROCESSOR), workingPath) ) handleException(key, e); } else { @@ -744,7 +746,7 @@ psi.runContributingProcs(renv); // Debugging - if (options.get("displayFilerState") != null) + if (options.isSet("displayFilerState")) filer.displayState(); } @@ -1104,6 +1106,12 @@ task.updateContext(next); } + JavacTrees trees = context.get(JavacTrees.class); + if (trees != null) { + next.put(JavacTrees.class, trees); + trees.updateContext(next); + } + context.clear(); return next; } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Oct 13 17:51:41 2010 -0700 @@ -93,6 +93,8 @@ required: {2}\n\ found: {3}\n\ reason: {6} +compiler.err.cant.apply.symbols=\ + no suitable {0} found for {1}({2}) compiler.err.cant.assign.val.to.final.var=\ cannot assign a value to final variable {0} compiler.err.cant.deref=\ @@ -1075,11 +1077,11 @@ no unique maximal instance exists for type variable {0} with upper bounds {1} compiler.misc.no.unique.minimal.instance.exists=\ no unique minimal instance exists for type variable {0} with lower bounds {1} -compiler.misc.no.conforming.instance.exists=\ +compiler.misc.infer.no.conforming.instance.exists=\ no instance(s) of type variable(s) {0} exist so that {1} conforms to {2} -compiler.misc.no.conforming.assignment.exists=\ +compiler.misc.infer.no.conforming.assignment.exists=\ no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to formal parameter type {2} -compiler.misc.arg.length.mismatch=\ +compiler.misc.infer.arg.length.mismatch=\ cannot instantiate from arguments because actual and formal argument lists differ in length compiler.misc.inferred.do.not.conform.to.bounds=\ inferred type does not conform to declared bound(s)\n\ @@ -1095,6 +1097,16 @@ type argument {0} inferred for {1} is not allowed in this context compiler.misc.diamond.invalid.args=\ type arguments {0} inferred for {1} are not allowed in this context + +compiler.misc.explicit.param.do.not.conform.to.bounds=\ + explicit type argument {0} does not conform to declared bound(s) {1} + +compiler.misc.arg.length.mismatch=\ + actual and formal argument lists differ in length +compiler.misc.no.conforming.assignment.exists=\ + actual argument {0} cannot be converted to {1} by method invocation conversion +compiler.misc.varargs.argument.mismatch=\ + argument type {0} does not conform to vararg element type {1} ##### ## The first argument ({0}) is a "kindname". @@ -1232,6 +1244,10 @@ compiler.misc.non.denotable.type=\ Non-denotable type {0} not allowed here +compiler.misc.inapplicable.method=\ + {0} {1}.{2} is not applicable\n\ + ({3}) + ######################################## # Diagnostics for language feature changes ######################################## diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java Wed Oct 13 17:51:41 2010 -0700 @@ -65,8 +65,6 @@ */ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter { - protected int currentIndentation = 0; - /** * Create a basic formatter based on the supplied options. * @@ -107,33 +105,28 @@ } public String formatMessage(JCDiagnostic d, Locale l) { - int prevIndentation = currentIndentation; - try { - StringBuilder buf = new StringBuilder(); - Collection args = formatArguments(d, l); - String msg = localize(l, d.getCode(), args.toArray()); - String[] lines = msg.split("\n"); - if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) { - currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY); - buf.append(indent(lines[0], currentIndentation)); //summary + int currentIndentation = 0; + StringBuilder buf = new StringBuilder(); + Collection args = formatArguments(d, l); + String msg = localize(l, d.getCode(), args.toArray()); + String[] lines = msg.split("\n"); + if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) { + currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY); + buf.append(indent(lines[0], currentIndentation)); //summary + } + if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) { + currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS); + for (int i = 1;i < lines.length; i++) { + buf.append("\n" + indent(lines[i], currentIndentation)); } - if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) { - currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS); - for (int i = 1;i < lines.length; i++) { - buf.append("\n" + indent(lines[i], currentIndentation)); - } - } - if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) { - currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS); + } + if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) { + currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS); for (String sub : formatSubdiagnostics(d, l)) { - buf.append("\n" + sub); - } + buf.append("\n" + indent(sub, currentIndentation)); } - return buf.toString(); } - finally { - currentIndentation = prevIndentation; - } + return buf.toString(); } protected String addSourceLineIfNeeded(JCDiagnostic d, String msg) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/util/Log.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Wed Oct 13 17:51:41 2010 -0700 @@ -35,11 +35,14 @@ import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; +import com.sun.tools.javac.api.DiagnosticFormatter; +import com.sun.tools.javac.main.OptionName; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.api.DiagnosticFormatter; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; +import static com.sun.tools.javac.main.OptionName.*; + /** A class for error logs. Reports errors and warnings, and * keeps track of error numbers and positions. * @@ -129,14 +132,14 @@ this.noticeWriter = noticeWriter; Options options = Options.instance(context); - this.dumpOnError = options.get("-doe") != null; - this.promptOnError = options.get("-prompt") != null; - this.emitWarnings = options.get("-Xlint:none") == null; - this.suppressNotes = options.get("suppressNotes") != null; - this.MaxErrors = getIntOption(options, "-Xmaxerrs", getDefaultMaxErrors()); - this.MaxWarnings = getIntOption(options, "-Xmaxwarns", getDefaultMaxWarnings()); + this.dumpOnError = options.isSet(DOE); + this.promptOnError = options.isSet(PROMPT); + this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none"); + this.suppressNotes = options.isSet("suppressNotes"); + this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors()); + this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings()); - boolean rawDiagnostics = options.get("rawDiagnostics") != null; + boolean rawDiagnostics = options.isSet("rawDiagnostics"); messages = JavacMessages.instance(context); this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) : new BasicDiagnosticFormatter(options, messages); @@ -150,7 +153,7 @@ expectDiagKeys = new HashSet(Arrays.asList(ek.split(", *"))); } // where - private int getIntOption(Options options, String optionName, int defaultValue) { + private int getIntOption(Options options, OptionName optionName, int defaultValue) { String s = options.get(optionName); try { if (s != null) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/util/Names.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java Wed Oct 13 17:51:41 2010 -0700 @@ -271,7 +271,7 @@ } protected Name.Table createTable(Options options) { - boolean useUnsharedTable = options.get("useUnsharedTable") != null; + boolean useUnsharedTable = options.isSet("useUnsharedTable"); if (useUnsharedTable) return new UnsharedNameTable(this); else diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javac/util/Options.java --- a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,8 +25,9 @@ package com.sun.tools.javac.util; +import java.util.*; import com.sun.tools.javac.main.OptionName; -import java.util.*; +import static com.sun.tools.javac.main.OptionName.*; /** A table of all command-line options. * If an option has an argument, the option name is mapped to the argument. @@ -60,14 +61,62 @@ context.put(optionsKey, this); } + /** + * Get the value for an undocumented option. + */ public String get(String name) { return values.get(name); } + /** + * Get the value for an option. + */ public String get(OptionName name) { return values.get(name.optionName); } + /** + * Check if the value for an undocumented option has been set. + */ + public boolean isSet(String name) { + return (values.get(name) != null); + } + + /** + * Check if the value for an option has been set. + */ + public boolean isSet(OptionName name) { + return (values.get(name.optionName) != null); + } + + /** + * Check if the value for a choice option has been set to a specific value. + */ + public boolean isSet(OptionName name, String value) { + return (values.get(name.optionName + value) != null); + } + + /** + * Check if the value for an undocumented option has not been set. + */ + public boolean isUnset(String name) { + return (values.get(name) == null); + } + + /** + * Check if the value for an option has not been set. + */ + public boolean isUnset(OptionName name) { + return (values.get(name.optionName) == null); + } + + /** + * Check if the value for a choice option has not been set to a specific value. + */ + public boolean isUnset(OptionName name, String value) { + return (values.get(name.optionName + value) == null); + } + public void put(String name, String value) { values.put(name, value); } @@ -92,16 +141,14 @@ return values.size(); } - static final String LINT = "-Xlint"; - /** Check for a lint suboption. */ public boolean lint(String s) { // return true if either the specific option is enabled, or // they are all enabled without the specific one being // disabled return - get(LINT + ":" + s)!=null || - (get(LINT)!=null || get(LINT + ":all")!=null) && - get(LINT+":-"+s)==null; + isSet(XLINT_CUSTOM, s) || + (isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) && + isUnset(XLINT_CUSTOM, "-" + s); } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -107,9 +107,6 @@ // force the use of Messager as a Log messager = Messager.instance0(context); - // force the use of the scanner that captures Javadoc comments - DocCommentScanner.Factory.preRegister(context); - return new JavadocTool(context); } catch (CompletionFailure ex) { messager.error(Position.NOPOS, ex.getMessage()); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javah/JavahTask.java --- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -526,15 +526,17 @@ } private void showVersion(boolean full) { - log.println(version(full ? "full" : "release")); + log.println(version(full)); } private static final String versionRBName = "com.sun.tools.javah.resources.version"; private static ResourceBundle versionRB; - private String version(String key) { - // key=version: mm.nn.oo[-milestone] - // key=full: mm.mm.oo[-milestone]-build + private String version(boolean full) { + String msgKey = (full ? "javah.fullVersion" : "javah.version"); + String versionKey = (full ? "full" : "release"); + // versionKey=product: mm.nn.oo[-milestone] + // versionKey=full: mm.mm.oo[-milestone]-build if (versionRB == null) { try { versionRB = ResourceBundle.getBundle(versionRBName); @@ -543,7 +545,7 @@ } } try { - return versionRB.getString(key); + return getMessage(msgKey, "javah", versionRB.getString(versionKey)); } catch (MissingResourceException e) { return getMessage("version.unknown", System.getProperty("java.version")); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 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,8 @@ # # Version string. # -javah.version=javah version "{0}" +javah.version={0} version "{1}" +javah.fullVersion={0} full version "{1}" # # These should have better diagnostics. diff -r 43cb79a6b123 -r d954b585d3a1 langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,28 @@ +# +# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# 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. +# + +jdk=$(JDK_VERSION) +full=$(FULL_VERSION) +release=$(RELEASE) diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6302184/T6302184.out --- a/langtools/test/tools/javac/6302184/T6302184.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/6302184/T6302184.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,4 +1,7 @@ +/** + * This is a test that uses ISO 8859 encoding. + */ class T6302184 { T6302184() { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6304921/TestLog.java --- a/langtools/test/tools/javac/6304921/TestLog.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/6304921/TestLog.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -35,7 +35,6 @@ import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.parser.Parser; import com.sun.tools.javac.parser.ParserFactory; -import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; @@ -60,7 +59,6 @@ log.multipleErrors = true; JavacFileManager.preRegister(context); - Scanner.Factory sfac = Scanner.Factory.instance(context); ParserFactory pfac = ParserFactory.instance(context); final String text = diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6758789/T6758789a.out --- a/langtools/test/tools/javac/6758789/T6758789a.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/6758789/T6758789a.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ -T6758789a.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, null -T6758789a.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, null +T6758789a.java:14:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, (compiler.misc.arg.length.mismatch) +T6758789a.java:15:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, (compiler.misc.arg.length.mismatch) 2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6840059/T6840059.out --- a/langtools/test/tools/javac/6840059/T6840059.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/6840059/T6840059.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ -T6840059.java:15:9: compiler.err.cant.apply.symbol: kindname.constructor, T6840059, java.lang.Integer, java.lang.String, kindname.class, T6840059, null -T6840059.java:15:25: compiler.err.cant.apply.symbol: kindname.constructor, T6840059, java.lang.Integer, compiler.misc.no.args, kindname.class, T6840059, null +T6840059.java:15:9: compiler.err.cant.apply.symbol.1: kindname.constructor, T6840059, java.lang.Integer, java.lang.String, kindname.class, T6840059, (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer) +T6840059.java:15:25: compiler.err.cant.apply.symbol.1: kindname.constructor, T6840059, java.lang.Integer, compiler.misc.no.args, kindname.class, T6840059, (compiler.misc.arg.length.mismatch) 2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6857948/T6857948.out --- a/langtools/test/tools/javac/6857948/T6857948.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/6857948/T6857948.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ T6857948.java:16:32: compiler.err.cant.resolve.location.args: kindname.method, nosuchfunction, , , kindname.class, Test -T6857948.java:16:50: compiler.err.cant.apply.symbol: kindname.constructor, Foo, java.lang.String, compiler.misc.no.args, kindname.class, Foo, null +T6857948.java:16:50: compiler.err.cant.apply.symbol.1: kindname.constructor, Foo, java.lang.String, compiler.misc.no.args, kindname.class, Foo, (compiler.misc.arg.length.mismatch) 2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465a.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465a.out -XDrawDiagnostics T6863465a.java + */ + +class T6863465a { + static class a { static interface b {} } + static class c extends a implements z.y {} + static class x { static interface y {} } + static class z extends x implements c.b {} +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465a.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465a.out Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,2 @@ +T6863465a.java:11:12: compiler.err.cyclic.inheritance: T6863465a.c +1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465b.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465b.out -XDrawDiagnostics T6863465b.java + */ + +class T6863465b { + static class a { static interface b { static interface d {} } } + static class c extends a implements z.y, z.d {} + static class x { static interface y {} } + static class z extends x implements c.b {} +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465b.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465b.out Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,2 @@ +T6863465b.java:11:12: compiler.err.cyclic.inheritance: T6863465b.c +1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465c.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465c.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465c.out -XDrawDiagnostics T6863465c.java + */ + +class T6863465c { + static class x { static interface y {} } + static class z extends x implements c.b {} + static class a { static interface b { static interface d {} } } + static class c extends a implements z.y, z.d {} +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465c.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465c.out Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,3 @@ +T6863465c.java:13:47: compiler.err.cant.resolve.location: kindname.class, d, , , kindname.class, T6863465c.z +T6863465c.java:11:12: compiler.err.cyclic.inheritance: T6863465c.z +2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465d.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465d.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,14 @@ +/** + * @test /nodynamiccopyright/ + * @bug 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @author Maurizio Cimadamore + * @compile/fail/ref=T6863465d.out -XDrawDiagnostics T6863465d.java + */ + +class T6863465d { + static class a { static interface b { static interface d {} } } + static class c extends a implements z.y, z.d {} + static class x { static interface y { static interface w {} } } + static class z extends x implements c.b, c.w {} +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/T6863465d.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/T6863465d.out Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,3 @@ +T6863465d.java:13:47: compiler.err.cant.resolve.location: kindname.class, w, , , kindname.class, T6863465d.c +T6863465d.java:11:12: compiler.err.cyclic.inheritance: T6863465d.c +2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/6863465/TestCircularClassfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6863465/TestCircularClassfile.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,123 @@ +/* + * 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 6863465 + * @summary javac doesn't detect circular subclass dependencies via qualified names + * @run main TestCircularClassfile + */ + +import java.io.*; +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; + +import com.sun.source.util.JavacTask; +import java.util.EnumSet; + +public class TestCircularClassfile { + + enum ClassName { + A("A"), + B("B"), + C("C"), + OBJECT("Object"); + + String name; + + ClassName(String name) { + this.name = name; + } + } + + static class JavaSource extends SimpleJavaFileObject { + + final static String sourceStub = "class #C extends #S {}"; + + String source; + + public JavaSource(ClassName clazz, ClassName sup) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + source = sourceStub.replace("#C", clazz.name).replace("#S", sup.name); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + public static void main(String... args) throws Exception { + int count = 0; + for (ClassName clazz : EnumSet.of(ClassName.A, ClassName.B, ClassName.C)) { + for (ClassName sup : EnumSet.of(ClassName.A, ClassName.B, ClassName.C)) { + if (sup.ordinal() < clazz.ordinal()) continue; + check("sub_"+count++, clazz, sup); + } + } + } + + static JavaSource[] initialSources = new JavaSource[] { + new JavaSource(ClassName.A, ClassName.OBJECT), + new JavaSource(ClassName.B, ClassName.A), + new JavaSource(ClassName.C, ClassName.B) + }; + + static String workDir = System.getProperty("user.dir"); + + static void check(String destPath, ClassName clazz, ClassName sup) throws Exception { + File destDir = new File(workDir, destPath); destDir.mkdir(); + final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); + JavacTask ct = (JavacTask)tool.getTask(null, null, null, + Arrays.asList("-d", destPath), null, Arrays.asList(initialSources)); + ct.generate(); + File fileToRemove = new File(destPath, clazz.name + ".class"); + fileToRemove.delete(); + JavaSource newSource = new JavaSource(clazz, sup); + DiagnosticChecker checker = new DiagnosticChecker(); + ct = (JavacTask)tool.getTask(null, null, checker, + Arrays.asList("-cp", destPath), null, Arrays.asList(newSource)); + ct.analyze(); + if (!checker.errorFound) { + throw new AssertionError(newSource.source); + } + } + + static class DiagnosticChecker implements DiagnosticListener { + + boolean errorFound = false; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR && + diagnostic.getCode().equals("compiler.err.cyclic.inheritance")) { + errorFound = true; + } + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/CyclicInheritance.out --- a/langtools/test/tools/javac/CyclicInheritance.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/CyclicInheritance.out Wed Oct 13 17:51:41 2010 -0700 @@ -4,6 +4,6 @@ CyclicInheritance.java:22:1: compiler.err.cyclic.inheritance: I11 CyclicInheritance.java:27:1: compiler.err.cyclic.inheritance: C211 CyclicInheritance.java:31:1: compiler.err.cyclic.inheritance: C212 -CyclicInheritance.java:36:27: compiler.err.report.access: C221.I, private, C221 -CyclicInheritance.java:40:24: compiler.err.report.access: C222.C, private, C222 +CyclicInheritance.java:36:1: compiler.err.cyclic.inheritance: C221 +CyclicInheritance.java:40:1: compiler.err.cyclic.inheritance: C222 8 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6722234a.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, null +T6722234a.java:12:9: compiler.err.cant.apply.symbol.1: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1) 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ -T6722234a.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, null +T6722234a.java:12:9: compiler.err.cant.apply.symbol.1: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1) - compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T6722234a),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, java.lang.Integer, kindname.method, test(compiler.misc.type.var: T, 2))} 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6722234b.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, List,List, List,List, kindname.class, T6722234b, null +T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List,List, List,List, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List, List) 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,4 +1,4 @@ -T6722234b.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, List,List, List,List, kindname.class, T6722234b, null +T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List,List, List,List, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List, List) - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, Object, kindname.method, m(List,List))} - compiler.misc.where.description.captured.1: compiler.misc.captured.type: 1,compiler.misc.captured.type: 2,{(compiler.misc.where.captured.1: compiler.misc.captured.type: 1, T6722234b, compiler.misc.type.null, ? extends T6722234b),(compiler.misc.where.captured.1: compiler.misc.captured.type: 2, T6722234b, compiler.misc.type.null, ? extends T6722234b)} 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out --- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6722234c.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, null +T6722234c.java:14:9: compiler.err.cant.apply.symbol.1: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, (compiler.misc.infer.no.conforming.assignment.exists: T, java.lang.String, T6722234c.String) 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6799605/T6799605.out --- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,4 +1,4 @@ -T6799605.java:17:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605, kindname.class, T6799605 -T6799605.java:18:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605,T6799605, kindname.class, T6799605 -T6799605.java:19:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605,T6799605,T6799605, kindname.class, T6799605 +T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.inferred.do.not.conform.to.bounds: compiler.misc.type.captureof: 1, ?, T6799605))} +T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605, T6799605)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch))} +T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605, T6799605)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch))} 3 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out --- a/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ -T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator +T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, compound(java.lang.Iterable>))} 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out --- a/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ -T6862608b.java:11:7: compiler.err.cant.apply.symbol: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b, null +T6862608b.java:11:7: compiler.err.cant.apply.symbol.1: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1) - compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,compiler.misc.type.var: S, 1,compiler.misc.type.var: S, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T66862608b),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, compiler.misc.type.var: S, 1, kindname.method, foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 1, java.lang.Object, kindname.method, foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 2, java.lang.Object, kindname.class, T66862608b)} 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/NameCollision.out --- a/langtools/test/tools/javac/NameCollision.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/NameCollision.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,3 @@ NameCollision.java:13:31: compiler.err.intf.expected.here -1 error +NameCollision.java:13:5: compiler.err.cyclic.inheritance: NameCollision.Runnable +2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/T6326754.out --- a/langtools/test/tools/javac/T6326754.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/T6326754.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,7 +1,7 @@ T6326754.java:44:12: compiler.err.name.clash.same.erasure: TestConstructor(T), TestConstructor(K) T6326754.java:52:17: compiler.err.name.clash.same.erasure: setT(K), setT(T) T6326754.java:64:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types), T, T -T6326754.java:70:11: compiler.err.cant.apply.symbol: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC, null +T6326754.java:70:11: compiler.err.cant.apply.symbol.1: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC, (compiler.misc.arg.length.mismatch) - compiler.note.unchecked.filename: T6326754.java - compiler.note.unchecked.recompile 4 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/T6587674.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/T6587674.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 6587674 + * @summary NoClassdefFound when anonymously extending a class. + */ + +import java.util.Vector; + +public class T6587674 { + private static final Vector list = + true ? null : new Vector() { }; + + public static void main(String[] args) { + System.out.println("T6587674 runs fine!"); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/api/TestJavacTaskScanner.java --- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,8 +31,8 @@ */ import com.sun.tools.javac.api.JavacTaskImpl; -import com.sun.tools.javac.parser.*; // XXX -import com.sun.tools.javac.util.*; // XXX +import com.sun.tools.javac.parser.*; +import com.sun.tools.javac.util.*; import java.io.*; import java.net.*; import java.nio.*; @@ -65,7 +65,7 @@ fm.getJavaFileObjects(new File[] {file}); StandardJavaFileManager fm = getLocalFileManager(tool, null, null); task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits); - task.getContext().put(Scanner.Factory.scannerFactoryKey, + task.getContext().put(ScannerFactory.scannerFactoryKey, new MyScanner.Factory(task.getContext(), this)); elements = task.getElements(); types = task.getTypes(); @@ -170,34 +170,36 @@ class MyScanner extends Scanner { - public static class Factory extends Scanner.Factory { + public static class Factory extends ScannerFactory { public Factory(Context context, TestJavacTaskScanner test) { super(context); this.test = test; } @Override - public Scanner newScanner(CharSequence input) { + public Scanner newScanner(CharSequence input, boolean keepDocComments) { + assert !keepDocComments; if (input instanceof CharBuffer) { return new MyScanner(this, (CharBuffer)input, test); } else { char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); + return newScanner(array, array.length, keepDocComments); } } @Override - public Scanner newScanner(char[] input, int inputLength) { + public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { + assert !keepDocComments; return new MyScanner(this, input, inputLength, test); } private TestJavacTaskScanner test; } - protected MyScanner(Factory fac, CharBuffer buffer, TestJavacTaskScanner test) { + protected MyScanner(ScannerFactory fac, CharBuffer buffer, TestJavacTaskScanner test) { super(fac, buffer); this.test = test; } - protected MyScanner(Factory fac, char[] input, int inputLength, TestJavacTaskScanner test) { + protected MyScanner(ScannerFactory fac, char[] input, int inputLength, TestJavacTaskScanner test) { super(fac, input, inputLength); this.test = test; } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/Example.java --- a/langtools/test/tools/javac/diags/Example.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/Example.java Wed Oct 13 17:51:41 2010 -0700 @@ -401,7 +401,7 @@ } } for (JCDiagnostic sd: d.getSubdiagnostics()) - scanForKeys(d, keys); + scanForKeys(sd, keys); } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples.not-yet.txt --- a/langtools/test/tools/javac/diags/examples.not-yet.txt Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Oct 13 17:51:41 2010 -0700 @@ -3,7 +3,7 @@ compiler.err.annotation.value.not.allowable.type # cannot happen: precluded by complete type-specific tests compiler.err.assignment.from.super-bound # DEAD compiler.err.assignment.to.extends-bound # DEAD -compiler.err.cant.apply.symbol.1 +compiler.err.cant.apply.symbol compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.select.static.class.from.param.type compiler.err.illegal.char.for.encoding @@ -43,7 +43,6 @@ compiler.err.unexpected.type compiler.err.unknown.enum.constant # in bad class file compiler.err.unsupported.cross.fp.lit # Scanner: host system dependent -compiler.misc.arg.length.mismatch compiler.misc.assignment.from.super-bound compiler.misc.assignment.to.extends-bound compiler.misc.bad.class.file.header # bad class file @@ -73,7 +72,6 @@ compiler.misc.kindname.type.variable compiler.misc.kindname.type.variable.bound compiler.misc.kindname.value -compiler.misc.no.conforming.assignment.exists compiler.misc.non.denotable.type compiler.misc.no.unique.minimal.instance.exists compiler.misc.resume.abort # prompt for a response diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/ExplicitParamsDoNotConformToBounds.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/ExplicitParamsDoNotConformToBounds.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,30 @@ +/* + * 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.cant.apply.symbol.1 +// key: compiler.misc.explicit.param.do.not.conform.to.bounds + +class ExplicitParamsDoNotConformToBounds { + void m() {} + { this.m(); } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/InapplicableSymbols.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/InapplicableSymbols.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,32 @@ +/* + * 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.cant.apply.symbols +// key: compiler.misc.arg.length.mismatch +// key: compiler.misc.inapplicable.method + +class ExplicitParamsDoNotConformToBounds { + void m(int i1) {} + void m(int i1, int i2) {} + { this.m(); } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java --- a/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java Wed Oct 13 17:51:41 2010 -0700 @@ -22,7 +22,7 @@ */ // key: compiler.misc.incompatible.types.1 -// key: compiler.misc.no.conforming.instance.exists +// key: compiler.misc.infer.no.conforming.instance.exists // key: compiler.err.prob.found.req class IncompatibleTypes1 { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/InferArgsLengthMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/InferArgsLengthMismatch.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,30 @@ +/* + * 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.cant.apply.symbol.1 +// key: compiler.misc.infer.arg.length.mismatch + +class InferArgsLengthMismatch { + void m(X x1, X x2) {} + { this.m(1); } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/KindnameConstructor.java --- a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java Wed Oct 13 17:51:41 2010 -0700 @@ -24,7 +24,9 @@ // key: compiler.misc.kindname.constructor // key: compiler.misc.kindname.class // key: compiler.misc.no.args -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.arg.length.mismatch +// key: compiler.misc.no.conforming.assignment.exists // key: compiler.misc.count.error.plural // run: backdoor diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/NoArgs.java --- a/langtools/test/tools/javac/diags/examples/NoArgs.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples/NoArgs.java Wed Oct 13 17:51:41 2010 -0700 @@ -22,7 +22,8 @@ */ // key: compiler.misc.no.args -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.arg.length.mismatch // run: simple class X { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,30 @@ +/* + * 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.cant.apply.symbol.1 +// key: compiler.misc.varargs.argument.mismatch + +class VarargsArgumentMismatch { + void m(String s, Integer... is) {} + { this.m("1", "2", "3"); } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/WhereCaptured.java --- a/langtools/test/tools/javac/diags/examples/WhereCaptured.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples/WhereCaptured.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,7 +25,8 @@ // key: compiler.misc.where.description.captured.1 // key: compiler.misc.where.description.typevar // key: compiler.misc.where.typevar -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.infer.no.conforming.assignment.exists // key: compiler.misc.captured.type // options: -XDdiags=where,simpleNames // run: simple diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/WhereCaptured1.java --- a/langtools/test/tools/javac/diags/examples/WhereCaptured1.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples/WhereCaptured1.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,7 +25,8 @@ // key: compiler.misc.where.description.captured.1 // key: compiler.misc.where.description.typevar // key: compiler.misc.where.typevar -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.infer.no.conforming.assignment.exists // key: compiler.misc.captured.type // key: compiler.misc.type.null // options: -XDdiags=where,simpleNames diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/diags/examples/WhereTypeVar.java --- a/langtools/test/tools/javac/diags/examples/WhereTypeVar.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/diags/examples/WhereTypeVar.java Wed Oct 13 17:51:41 2010 -0700 @@ -24,7 +24,8 @@ // key: compiler.misc.where.typevar // key: compiler.misc.where.description.typevar.1 // key: compiler.misc.type.var -// key: compiler.err.cant.apply.symbol +// key: compiler.err.cant.apply.symbol.1 +// key: compiler.misc.no.conforming.assignment.exists // options: -XDdiags=where,disambiguateTvars // run: simple diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/diamond/neg/Neg06.out --- a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,4 +1,4 @@ -Neg06.java:18:36: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.IFoo, Neg06.ISuperFoo) -Neg06.java:19:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) -Neg06.java:20:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) +Neg06.java:18:36: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.IFoo, Neg06.ISuperFoo) +Neg06.java:19:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) +Neg06.java:20:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo, Neg06.CSuperFoo) 3 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6315770/T6315770.out --- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,3 +1,3 @@ T6315770.java:16:42: compiler.err.undetermined.type.1: T6315770, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable) -T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T6315770, T6315770)), T6315770, T6315770 +T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770, T6315770)), T6315770, T6315770 2 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6611449/T6611449.out --- a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ -T6611449.java:18:9: compiler.err.cant.resolve.location.args: kindname.constructor, T6611449, , int, kindname.class, T6611449 -T6611449.java:19:9: compiler.err.cant.resolve.location.args: kindname.constructor, T6611449, , int,int, kindname.class, T6611449 -T6611449.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, T, int, kindname.class, T6611449, null -T6611449.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, T,T, int,int, kindname.class, T6611449, null +T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S))} +T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.infer.arg.length.mismatch))} +T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S) +T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S) 4 errors diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6638712/T6638712a.out --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator +T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator, java.util.Comparator)), java.util.Comparator, java.util.Comparator 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6638712/T6638712b.out --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T, java.lang.String)), T, java.lang.String +T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)), T, java.lang.String 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6638712/T6638712c.out --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6638712c.java:16:9: compiler.err.cant.apply.symbol: kindname.method, sort, T[],java.util.Comparator, java.lang.Enum[],java.util.Comparator>, kindname.class, T6638712c, null +T6638712c.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, sort, T[],java.util.Comparator, java.lang.Enum[],java.util.Comparator>, kindname.class, T6638712c, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Enum[],java.util.Comparator, java.lang.Enum[],java.util.Comparator>) 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6638712/T6638712d.out --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List>, int,java.util.List>, kindname.class, T6638712d, null +T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List>, int,java.util.List>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.params: java.lang.String,java.util.List>, int,java.util.List>) 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/generics/inference/6638712/T6638712e.out --- a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out Wed Oct 13 17:51:41 2010 -0700 @@ -1,2 +1,2 @@ -T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: X, T6638712e.Foo, T6638712e.Foo)), T6638712e.Foo, T6638712e.Foo +T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo, T6638712e.Foo)), T6638712e.Foo, T6638712e.Foo 1 error diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,100 @@ +/* + * 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.util.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import static javax.lang.model.SourceVersion.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; + +/** + * An abstract annotation processor tailored to javac regression testing. + */ +public abstract class JavacTestingAbstractProcessor extends AbstractProcessor { + private static final Set allAnnotations; + + static { + Set tmp = new HashSet<>(); + tmp.add("*"); + allAnnotations = Collections.unmodifiableSet(tmp); + } + + protected Elements eltUtils; + protected Elements elements; + protected Types typeUtils; + protected Types types; + protected Filer filer; + protected Messager messager; + protected Map options; + + /** + * Constructor for subclasses to call. + */ + protected JavacTestingAbstractProcessor() { + super(); + } + + /** + * Return the latest source version. Unless this method is + * overridden, an {@code IllegalStateException} will be thrown if a + * subclass has a {@code SupportedSourceVersion} annotation. + */ + @Override + public SourceVersion getSupportedSourceVersion() { + SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class); + if (ssv != null) + throw new IllegalStateException("SupportedSourceVersion annotation not supported here."); + + return SourceVersion.latest(); + } + + /** + * If the processor class is annotated with {@link + * SupportedAnnotationTypes}, return an unmodifiable set with the + * same set of strings as the annotation. If the class is not so + * annotated, a one-element set containing {@code "*"} is returned + * to indicate all annotations are processed. + * + * @return the names of the annotation types supported by this + * processor, or an empty set if none + */ + @Override + public Set getSupportedAnnotationTypes() { + SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class); + if (sat != null) + return super.getSupportedAnnotationTypes(); + else + return allAnnotations; + } + + @Override + public void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + elements = eltUtils = processingEnv.getElementUtils(); + types = typeUtils = processingEnv.getTypeUtils(); + filer = processingEnv.getFiler(); + messager = processingEnv.getMessager(); + options = processingEnv.getOptions(); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6348499/A.java --- a/langtools/test/tools/javac/processing/6348499/A.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6348499/A.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -27,10 +27,8 @@ import javax.lang.model.*; import javax.lang.model.element.*; -@SupportedAnnotationTypes("*") -public class A extends AbstractProcessor { +public class A extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment renv) { - Filer filer = processingEnv.getFiler(); try { OutputStream out = filer.createClassFile(getClass().getName()+"_0").openOutputStream(); out.close(); @@ -39,8 +37,4 @@ } return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6348499/T6348499.java --- a/langtools/test/tools/javac/processing/6348499/T6348499.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6348499/T6348499.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +25,8 @@ * @test * @bug 6441871 * @summary javac crashes at com.sun.tools.javac.jvm.ClassReader$BadClassFile - * @build A + * @library ../../lib + * @build JavacTestingAbstractProcessor A * @run main T6348499 */ @@ -54,7 +55,6 @@ fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java"))); Iterable opts = Arrays.asList("-proc:only", "-processor", "A", - "-source", "1.6", "-processorpath", testClasses); StringWriter out = new StringWriter(); JavacTask task = tool.getTask(out, fm, dl, opts, null, files); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6359313/T6359313.java --- a/langtools/test/tools/javac/processing/6359313/T6359313.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6359313/T6359313.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6359313 * @summary error compiling annotated package * @author Peter von der Ah\u00e9 + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6359313.java * @compile -processor T6359313 package-info.java Foo.java */ @@ -37,7 +39,7 @@ import javax.lang.model.element.TypeElement; @SupportedAnnotationTypes("Foo") -public class T6359313 extends AbstractProcessor { +public class T6359313 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { return true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6365040/ProcBar.java --- a/langtools/test/tools/javac/processing/6365040/ProcBar.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6365040/ProcBar.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,13 +31,11 @@ /** * Second of several processors to run. */ -@SupportedAnnotationTypes("*") -public class ProcBar extends AbstractProcessor { +public class ProcBar extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from ProcBar"); + messager.printMessage(NOTE, "Hello from ProcBar"); return false; } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6365040/ProcFoo.java --- a/langtools/test/tools/javac/processing/6365040/ProcFoo.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6365040/ProcFoo.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,13 +31,11 @@ /** * First of several processors to run. */ -@SupportedAnnotationTypes("*") -public class ProcFoo extends AbstractProcessor { +public class ProcFoo extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from ProcFoo"); + messager.printMessage(NOTE, "Hello from ProcFoo"); return false; } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6365040/T6365040.java --- a/langtools/test/tools/javac/processing/6365040/T6365040.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6365040/T6365040.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6365040 6358129 * @summary Test -processor foo,bar,baz * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile ProcFoo.java * @compile ProcBar.java * @compile T6365040.java @@ -43,13 +45,11 @@ import javax.lang.model.element.TypeElement; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6365040 extends AbstractProcessor { +public class T6365040 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { if (!roundEnvironment.processingOver()) - processingEnv.getMessager().printMessage(NOTE, - "Hello from T6365040"); + messager.printMessage(NOTE, "Hello from T6365040"); return true; } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6413690/T6413690.java --- a/langtools/test/tools/javac/processing/6413690/T6413690.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6413690/T6413690.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6413690 6380018 * @summary JavacProcessingEnvironment does not enter trees from preceding rounds * @author Peter von der Ah\u00e9 + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6413690.java * @compile -XDfatalEnterError -verbose -processor T6413690 src/Super.java TestMe.java */ @@ -42,11 +44,9 @@ import javax.lang.model.util.Elements; @SupportedAnnotationTypes("TestMe") -public class T6413690 extends AbstractProcessor { +public class T6413690 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - Elements elements = processingEnv.getElementUtils(); - Filer filer = processingEnv.getFiler(); TypeElement testMe = elements.getTypeElement(TestMe.class.getName()); Set supers = roundEnvironment.getElementsAnnotatedWith(testMe); try { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6414633/A.java --- a/langtools/test/tools/javac/processing/6414633/A.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6414633/A.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,8 @@ import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class A extends AbstractProcessor { - +@SuppressWarnings("") +public class A extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { Messager m = processingEnv.getMessager(); for (TypeElement anno: annotations) { @@ -42,8 +41,6 @@ return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } + @SuppressWarnings("") + private void foo() {} } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6414633/T6414633.java --- a/langtools/test/tools/javac/processing/6414633/T6414633.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6414633/T6414633.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +25,8 @@ * @test * @bug 6414633 6440109 * @summary Only the first processor message at a source location is reported - * @build A T6414633 + * @library ../../lib + * @build JavacTestingAbstractProcessor A T6414633 * @run main T6414633 */ @@ -55,8 +56,7 @@ fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java"))); String[] opts = { "-proc:only", "-processor", A.class.getName(), - "-source", "1.6", - "-classpath", testClasses }; + "-classpath", testClasses + System.getProperty("path.separator") + "../../lib" }; JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files); task.call(); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6430209/T6430209.java --- a/langtools/test/tools/javac/processing/6430209/T6430209.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6430209/T6430209.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +25,8 @@ * @test * @bug 6441871 * @summary spurious compiler error elicited by packageElement.getEnclosedElements() - * @build b6341534 + * @library ../../lib + * @build JavacTestingAbstractProcessor b6341534 * @run main T6430209 */ @@ -54,7 +55,7 @@ // run annotation processor b6341534 so we can check diagnostics // -proc:only -processor b6341534 -cp . ./src/*.java String testSrc = System.getProperty("test.src", "."); - String testClasses = System.getProperty("test.classes"); + String testClasses = System.getProperty("test.classes") + System.getProperty("path.separator") + "../../lib"; JavacTool tool = JavacTool.create(); MyDiagListener dl = new MyDiagListener(); StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6430209/b6341534.java --- a/langtools/test/tools/javac/processing/6430209/b6341534.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6430209/b6341534.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -30,16 +30,9 @@ import java.util.*; import java.util.Set; -@SupportedAnnotationTypes({"*"}) -public class b6341534 extends AbstractProcessor { +public class b6341534 extends JavacTestingAbstractProcessor { static int r = 0; - static Elements E = null; - static Messager msgr = null; - public void init(ProcessingEnvironment penv) { - processingEnv = penv; - msgr = penv.getMessager(); - E = penv.getElementUtils(); - } + //Create directory 'dir1' and a test class in dir1 public boolean process(Set tes, RoundEnvironment renv) { @@ -49,13 +42,13 @@ System.out.println("Round"+r+ ": " + t.toString()); try { - PackageElement PE = E.getPackageElement("dir1"); + PackageElement PE = eltUtils.getPackageElement("dir1"); List LEE = PE.getEnclosedElements(); /* <=This line elicits the error message. */ for(Element e : LEE) System.out.println("found " + e.toString() + " in dir1."); } catch(NullPointerException npe) { - msgr.printMessage(ERROR,npe.toString()); + messager.printMessage(ERROR,npe.toString()); //npe.printStackTrace(); return false; } @@ -63,13 +56,8 @@ // on round 1, expect errorRaised == false && processingOver == false // on round 2, expect errorRaised == true && processingOver == true if( renv.errorRaised() != renv.processingOver()) { - msgr.printMessage(ERROR, "FAILED"); + messager.printMessage(ERROR, "FAILED"); } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6499119/ClassProcessor.java --- a/langtools/test/tools/javac/processing/6499119/ClassProcessor.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6499119/ClassProcessor.java Wed Oct 13 17:51:41 2010 -0700 @@ -32,20 +32,17 @@ * @test * @bug 6499119 * @summary Created package-info class file modeled improperly + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile ClassProcessor.java package-info.java * @compile/process -cp . -processor ClassProcessor -Akind=java java.lang.Object * @compile/process -cp . -processor ClassProcessor -Akind=class java.lang.Object */ @SupportedOptions({ "gen", "expect" }) -@SupportedAnnotationTypes({"*"}) -public class ClassProcessor extends AbstractProcessor { +public class ClassProcessor extends JavacTestingAbstractProcessor { int round = 1; - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (round == 1) { System.out.println("-- Round 1 --"); @@ -71,8 +68,6 @@ } private void createPackageFile() { - Filer filer = processingEnv.getFiler(); - String kind = processingEnv.getOptions().get("kind"); File pkgInfo; @@ -125,7 +120,6 @@ } private void error(String msg) { - Messager messager = processingEnv.getMessager(); messager.printMessage(Kind.ERROR, msg); } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6511613/DummyProcessor.java --- a/langtools/test/tools/javac/processing/6511613/DummyProcessor.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java Wed Oct 13 17:51:41 2010 -0700 @@ -26,15 +26,10 @@ import javax.lang.model.element.*; import java.util.Set; -@SupportedAnnotationTypes("*") -public class DummyProcessor extends AbstractProcessor { +public class DummyProcessor extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6511613/clss41701.java --- a/langtools/test/tools/javac/processing/6511613/clss41701.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6511613/clss41701.java Wed Oct 13 17:51:41 2010 -0700 @@ -26,7 +26,8 @@ * @bug 6511613 * @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified * - * @build DummyProcessor + * @library ../../lib + * @build JavacTestingAbstractProcessor DummyProcessor * @compile/fail clss41701.java * @compile/fail -processor DummyProcessor clss41701.java */ diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6512707/T6512707.java --- a/langtools/test/tools/javac/processing/6512707/T6512707.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6512707/T6512707.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -26,8 +26,9 @@ * @bug 6512707 * @summary "incompatible types" after (unrelated) annotation processing * @author Peter Runge + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6512707.java - * * @compile -processor T6512707 TestAnnotation.java */ @@ -41,16 +42,10 @@ * Dummy processor to force bug 6512707 to show - it does not matter what * the annotation processor does for this bug. */ -@SupportedAnnotationTypes("*") -public class T6512707 extends AbstractProcessor { +public class T6512707 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { - return(false); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); + return false; } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/6634138/T6634138.java --- a/langtools/test/tools/javac/processing/6634138/T6634138.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/6634138/T6634138.java Wed Oct 13 17:51:41 2010 -0700 @@ -26,6 +26,8 @@ * @bug 6634138 * @author Joseph D. Darcy * @summary Verify source files output after processing is over are compiled + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile T6634138.java * @compile -processor T6634138 Dummy.java * @run main ExerciseDependency @@ -44,10 +46,7 @@ import javax.lang.model.element.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class T6634138 extends AbstractProcessor { - private Filer filer; - +public class T6634138 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { // Write out files *after* processing is over. @@ -77,16 +76,6 @@ } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/T6439826.java --- a/langtools/test/tools/javac/processing/T6439826.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/T6439826.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -48,8 +48,7 @@ StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); Iterable files = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java"))); - Iterable opts = Arrays.asList("-source","1.6", - "-proc:only", + Iterable opts = Arrays.asList("-proc:only", "-processor", "T6439826", "-processorpath", testClasses); StringWriter out = new StringWriter(); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/T6920317.java --- a/langtools/test/tools/javac/processing/T6920317.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/T6920317.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,6 +25,7 @@ * @test * @bug 6920317 * @summary package-info.java file has to be specified on the javac cmdline, else it will not be avail + * @library ../lib */ import java.io.*; @@ -349,12 +350,7 @@ /** Annotation processor used to verify the expected value for the package annotations found by javac. */ @SupportedOptions({ "gen", "expect" }) - @SupportedAnnotationTypes({"*"}) - public static class Processor extends AbstractProcessor { - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - + public static class Processor extends JavacTestingAbstractProcessor { public boolean process(Set annots, RoundEnvironment renv) { round++; System.err.println("Round " + round + " annots:" + annots + " rootElems:" + renv.getRootElements()); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/Xprint.java --- a/langtools/test/tools/javac/processing/Xprint.java Tue Oct 12 17:05:28 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. - * 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 6266828 - * @summary JSR 269: Java Language Model API - * @author Peter von der Ah\u00e9 - */ -import javax.tools.JavaCompiler; -import javax.tools.ToolProvider; - -public class Xprint { - public static void main(String[] args) { - JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); - javac.run(System.in, null, null, - "-Xprint", - "com.sun.tools.javac.code.Types", - "com.sun.tools.javac.parser.Parser", - "java.util.EnumSet"); - } -} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/environment/TestSourceVersion.java --- a/langtools/test/tools/javac/processing/environment/TestSourceVersion.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/environment/TestSourceVersion.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6402506 * @summary Test that getSourceVersion works properly * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestSourceVersion.java * @compile -processor TestSourceVersion -proc:only -source 1.2 -AExpectedVersion=RELEASE_2 HelloWorld.java * @compile -processor TestSourceVersion -proc:only -source 1.3 -AExpectedVersion=RELEASE_3 HelloWorld.java @@ -52,9 +54,8 @@ * This processor checks that ProcessingEnvironment.getSourceVersion() * is consistent with the setting of the -source option. */ -@SupportedAnnotationTypes("*") @SupportedOptions("ExpectedVersion") -public class TestSourceVersion extends AbstractProcessor { +public class TestSourceVersion extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { @@ -68,9 +69,4 @@ return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java --- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 * @summary Tests that getElementsAnnotatedWith works properly. * @author Joseph D. Darcy + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile TestElementsAnnotatedWith.java * @compile InheritedAnnotation.java * @compile -processor TestElementsAnnotatedWith -proc:only SurfaceAnnotations.java @@ -57,16 +59,13 @@ * getElementsAnnotatedWith is consistent with the expected results * stored in an AnnotatedElementInfo annotation. */ -@SupportedAnnotationTypes("*") @AnnotatedElementInfo(annotationName="java.lang.SuppressWarnings", expectedSize=0, names={}) -public class TestElementsAnnotatedWith extends AbstractProcessor { +public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - Elements elementUtils = processingEnv.getElementUtils(); - TypeElement annotatedElementInfoElement = - elementUtils.getTypeElement("AnnotatedElementInfo"); + elements.getTypeElement("AnnotatedElementInfo"); Set resultsMeta = Collections.emptySet(); Set resultsBase = Collections.emptySet(); @@ -93,9 +92,7 @@ resultsMeta = roundEnvironment. - getElementsAnnotatedWith(elementUtils. - getTypeElement(annotatedElementInfo. - annotationName())) ; + getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName())); System.err.println("Results: " + resultsMeta); @@ -167,9 +164,4 @@ throw new RuntimeException("Illegal argument exception not thrown"); } catch(IllegalArgumentException iae) {} } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java --- a/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,9 @@ * @bug 6403459 * @summary Test that generating programs with syntax errors is a fatal condition * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor + * @compile TestReturnCode.java * @compile TestFatalityOfParseErrors.java * @compile/fail -XprintRounds -processor TestFatalityOfParseErrors -proc:only TestFatalityOfParseErrors.java */ @@ -45,11 +48,8 @@ * Write out an incomplete source file and observe that the next round * is marked as an error. */ -@SupportedAnnotationTypes("*") -public class TestFatalityOfParseErrors extends AbstractProcessor { +public class TestFatalityOfParseErrors extends JavacTestingAbstractProcessor { int round = 0; - Messager messager; - Filer filer; public boolean process(Set annotations, RoundEnvironment roundEnvironment) { @@ -87,14 +87,4 @@ } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java --- a/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6406212 * @summary Test that annotation processor options with illegal syntax are rejected * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestOptionSyntaxErrors.java * @compile/fail -A TestOptionSyntaxErrors.java * @compile/fail -A8adOption TestOptionSyntaxErrors.java @@ -46,14 +48,9 @@ /** * No-op processor; should not be run. */ -@SupportedAnnotationTypes("*") -public class TestOptionSyntaxErrors extends AbstractProcessor { +public class TestOptionSyntaxErrors extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/errors/TestReturnCode.java --- a/langtools/test/tools/javac/processing/errors/TestReturnCode.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/errors/TestReturnCode.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6403468 * @summary Test that an erroneous return code results from raising an error. * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestReturnCode.java * * @compile -processor TestReturnCode -proc:only Foo.java @@ -60,20 +62,17 @@ * This processor raises errors or throws exceptions on different * rounds to allow the return code to be test. */ -@SupportedAnnotationTypes("*") @SupportedOptions({"ErrorOnFirst", "ErrorOnLast", "ExceptionOnFirst", "ExceptionOnLast"}) -public class TestReturnCode extends AbstractProcessor { +public class TestReturnCode extends JavacTestingAbstractProcessor { private boolean errorOnFirst; private boolean errorOnLast; private boolean exceptionOnFirst; private boolean exceptionOnLast; - private Messager messager; - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -103,11 +102,5 @@ errorOnLast = keySet.contains("ErrorOnLast"); exceptionOnFirst = keySet.contains("ExceptionOnFirst"); exceptionOnLast = keySet.contains("ExceptionOnLast"); - messager = processingEnv.getMessager(); - } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/filer/TestFilerConstraints.java --- a/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,7 @@ * @bug 6380018 6453386 6457283 * @summary Test that the constraints guaranteed by the Filer and maintained * @author Joseph D. Darcy + * @library ../../lib * @build TestFilerConstraints * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java */ @@ -69,11 +70,8 @@ * * */ -@SupportedAnnotationTypes("*") -public class TestFilerConstraints extends AbstractProcessor { +public class TestFilerConstraints extends JavacTestingAbstractProcessor { private int round = 0; - private Messager messager; - private Filer filer; private PrintWriter pw_src1 = null; private PrintWriter pw_src2 = null; @@ -167,17 +165,6 @@ return true; } - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - - } - /** * Test that the single expected expected type, name, is the root * element. diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/filer/TestGetResource.java --- a/langtools/test/tools/javac/processing/filer/TestGetResource.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/filer/TestGetResource.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6380018 6449798 * @summary Test Filer.getResource * @author Joseph D. Darcy - * @build TestGetResource + * @library ../../lib + * @build JavacTestingAbstractProcessor TestGetResource * @compile -processor TestGetResource -proc:only -Aphase=write TestGetResource.java * @compile -processor TestGetResource -proc:only -Aphase=read TestGetResource.java */ @@ -49,13 +50,8 @@ * first run of the annotation processor, write out a resource file * and on the second run read it in. */ -@SupportedAnnotationTypes("*") @SupportedOptions("phase") -public class TestGetResource extends AbstractProcessor { - private Messager messager; - private Filer filer; - private Map options; - +public class TestGetResource extends JavacTestingAbstractProcessor { private static String CONTENTS = "Hello World."; private static String PKG = ""; private static String RESOURCE_NAME = "Resource1"; @@ -92,15 +88,4 @@ } return false; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - options = processingEnv.getOptions(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/filer/TestGetResource2.java --- a/langtools/test/tools/javac/processing/filer/TestGetResource2.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/filer/TestGetResource2.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -24,6 +24,7 @@ /* @test * @bug 6929404 * @summary Filer.getResource(SOURCE_PATH, ...) does not work when -sourcepath contains >1 entry + * @library ../../lib */ import java.io.*; @@ -114,8 +115,7 @@ throw new Exception(errors + " errors occurred"); } - @SupportedAnnotationTypes("*") - static class AnnoProc extends AbstractProcessor { + static class AnnoProc extends JavacTestingAbstractProcessor { public @Override boolean process(Set annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { @@ -123,27 +123,23 @@ } try { - FileObject resource = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt"); + FileObject resource = filer.getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt"); try { resource.openInputStream().close(); - processingEnv.getMessager().printMessage(Kind.NOTE, "found: " + resource.toUri()); + messager.printMessage(Kind.NOTE, "found: " + resource.toUri()); return true; } catch (IOException x) { - processingEnv.getMessager().printMessage(Kind.ERROR, "could not read: " + resource.toUri()); + messager.printMessage(Kind.ERROR, "could not read: " + resource.toUri()); x.printStackTrace(); } } catch (IOException x) { - processingEnv.getMessager().printMessage(Kind.ERROR, "did not find resource"); + messager.printMessage(Kind.ERROR, "did not find resource"); x.printStackTrace(); } return false; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } private File write(File dir, String path, String contents) throws IOException { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,100 @@ +/* + * 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 6502392 + * @summary Invalid relative names for Filer.createResource and Filer.getResource + * @library ../../lib + * @build JavacTestingAbstractProcessor + * @compile TestInvalidRelativeNames.java + * @compile/process -processor TestInvalidRelativeNames java.lang.Object + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.Diagnostic; +import javax.tools.StandardLocation; + +public class TestInvalidRelativeNames extends JavacTestingAbstractProcessor { + enum Kind { CREATE_WRITER, GET_READER, CREATE_OUTPUT_STREAM, GET_INPUT_STREAM }; + + static final String[] invalidRelativeNames = { + "/boo", "goo/../hoo", "./ioo", "" + }; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + for (String relative: invalidRelativeNames) { + for (Kind kind: Kind.values()) { + test(relative, kind); + } + } + } + return true; + } + + void test(String relative, Kind kind) { + System.out.println("test relative path: " + relative + ", kind: " + kind); + try { + switch (kind) { + case CREATE_WRITER: + Writer writer = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openWriter(); + writer.close(); + break; + + case GET_READER: + Reader reader = filer.getResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openReader(true); + reader.close(); + break; + + case CREATE_OUTPUT_STREAM: + OutputStream out = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openOutputStream(); + out.close(); + break; + + case GET_INPUT_STREAM: + InputStream in = filer.createResource( + StandardLocation.SOURCE_OUTPUT, "", relative).openInputStream(); + in.close(); + break; + } + } catch (IllegalArgumentException expected) { + System.out.println("expected exception thrown: " + expected); + return; + } catch (Exception e) { + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e); + return; + } + messager.printMessage(Diagnostic.Kind.ERROR, + "relative path: " + relative + ", kind: " + kind + ", no exception thrown"); + } +} + diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/filer/TestLastRound.java --- a/langtools/test/tools/javac/processing/filer/TestLastRound.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/filer/TestLastRound.java Wed Oct 13 17:51:41 2010 -0700 @@ -24,6 +24,8 @@ /* * @test 6966604 * @summary JavacFiler not correctly notified of lastRound + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestLastRound.java * @compile/fail/ref=TestLastRound.out -XDrawDiagnostics -Werror -proc:only -processor TestLastRound TestLastRound.java */ @@ -35,12 +37,10 @@ import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class TestLastRound extends AbstractProcessor { +public class TestLastRound extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Filer filer = processingEnv.getFiler(); if (roundEnv.processingOver()) { try { JavaFileObject fo = filer.createSourceFile("LastRound.java"); @@ -52,9 +52,4 @@ } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/filer/TestPackageInfo.java --- a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6380018 6392177 * @summary Test the ability to create and process package-info.java files * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile TestPackageInfo.java * @compile -processor TestPackageInfo -proc:only foo/bar/package-info.java TestPackageInfo.java */ @@ -49,13 +51,7 @@ * 1) Visibility of package-info files from the command line * 2) Visibility of generated package-info.java source files */ -@SupportedAnnotationTypes("*") -public class TestPackageInfo extends AbstractProcessor { - private Elements eltUtils; - private Messager messager; - private Filer filer; - private Map options; - +public class TestPackageInfo extends JavacTestingAbstractProcessor { private int round = 0; public boolean process(Set annotations, @@ -64,11 +60,7 @@ // Verify annotations are as expected Set expectedAnnotations = new HashSet(); - if (round == 1) - expectedAnnotations.add(eltUtils. - getTypeElement("javax.annotation.processing.SupportedAnnotationTypes")); - expectedAnnotations.add(eltUtils. - getTypeElement("java.lang.SuppressWarnings")); + expectedAnnotations.add(eltUtils.getTypeElement("java.lang.SuppressWarnings")); if (!roundEnv.processingOver()) { System.out.println("\nRound " + round); @@ -127,16 +119,4 @@ } return false; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - messager = processingEnv.getMessager(); - filer = processingEnv.getFiler(); - options = processingEnv.getOptions(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/messager/6362067/T6362067.java --- a/langtools/test/tools/javac/processing/messager/6362067/T6362067.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/messager/6362067/T6362067.java Wed Oct 13 17:51:41 2010 -0700 @@ -2,39 +2,34 @@ * @test /nodynamiccopyright/ * @bug 6362067 * @summary Messager methods do not print out source position information - * @build T6362067 + * @library ../../../lib + * @build JavacTestingAbstractProcessor T6362067 * @compile -processor T6362067 -proc:only T6362067.java * @compile/ref=T6362067.out -XDrawDiagnostics -processor T6362067 -proc:only T6362067.java */ - import java.util.Set; import javax.annotation.processing.*; import javax.lang.model.element.*; import static javax.tools.Diagnostic.Kind.*; -@Deprecated // convenient test annotation -@SupportedAnnotationTypes("*") -public class T6362067 extends AbstractProcessor { +@Deprecated // convenient test annotations +@SuppressWarnings({""}) +public class T6362067 extends JavacTestingAbstractProcessor { public boolean process(Set annos, RoundEnvironment roundEnv) { - Messager msgr = processingEnv.getMessager(); + for (Element e: roundEnv.getRootElements()) { - msgr.printMessage(NOTE, "note:elem", e); + messager.printMessage(NOTE, "note:elem", e); for (AnnotationMirror a: e.getAnnotationMirrors()) { - msgr.printMessage(NOTE, "note:anno", e, a); + messager.printMessage(NOTE, "note:anno", e, a); for (AnnotationValue v: a.getElementValues().values()) { - msgr.printMessage(NOTE, "note:value", e, a, v); + messager.printMessage(NOTE, "note:value", e, a, v); } - } } + if (roundEnv.processingOver()) - msgr.printMessage(NOTE, "note:nopos"); + messager.printMessage(NOTE, "note:nopos"); return true; } - - @Override - public javax.lang.model.SourceVersion getSupportedSourceVersion() { - return javax.lang.model.SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/messager/MessagerBasics.java --- a/langtools/test/tools/javac/processing/messager/MessagerBasics.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/messager/MessagerBasics.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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,6 +26,8 @@ * @bug 6341173 6341072 * @summary Test presence of Messager methods * @author Joseph D. Darcy + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile MessagerBasics.java * @compile -processor MessagerBasics -proc:only MessagerBasics.java * @compile/fail -processor MessagerBasics -proc:only -AfinalError MessagerBasics.java @@ -39,18 +41,16 @@ import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") @SupportedOptions("finalError") -public class MessagerBasics extends AbstractProcessor { +public class MessagerBasics extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager m = processingEnv.getMessager(); if (roundEnv.processingOver()) { if (processingEnv.getOptions().containsKey("finalError")) - m.printMessage(ERROR, "Does not compute"); + messager.printMessage(ERROR, "Does not compute"); else { - m.printMessage(NOTE, "Post no bills"); - m.printMessage(WARNING, "Beware the ides of March!"); + messager.printMessage(NOTE, "Post no bills"); + messager.printMessage(WARNING, "Beware the ides of March!"); } } return true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/6194785/T6194785.java --- a/langtools/test/tools/javac/processing/model/6194785/T6194785.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/6194785/T6194785.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6194785 * @summary ParameterDeclaration.getSimpleName does not return actual name from class files * @author Peter von der Ah\u00e9 + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g T6194785.java T6194785a.java * @compile -processor T6194785 foo.T6194785a T6194785.java */ @@ -36,13 +38,10 @@ import javax.lang.model.util.*; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6194785 extends AbstractProcessor { +public class T6194785 extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnvironment) { - final Messager log = processingEnv.getMessager(); - final Elements elements = processingEnv.getElementUtils(); class Scan extends ElementScanner7 { @Override public Void visitExecutable(ExecutableElement e, Void ignored) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/6341534/T6341534.java --- a/langtools/test/tools/javac/processing/model/6341534/T6341534.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/6341534/T6341534.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -27,6 +27,8 @@ * @summary PackageElement.getEnclosedElements results in NullPointerException from parse(JavaCompiler.java:429) * @author Steve Sides * @author Peter von der Ahe + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile T6341534.java * @compile -proc:only -processor T6341534 dir/package-info.java * @compile -processor T6341534 dir/package-info.java @@ -40,20 +42,11 @@ import java.util.Set; import static javax.tools.Diagnostic.Kind.*; -@SupportedAnnotationTypes("*") -public class T6341534 extends AbstractProcessor { - Elements elements; - Messager messager; - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - messager = processingEnv.getMessager(); - } - +public class T6341534 extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment renv) { messager.printMessage(NOTE, - String.valueOf(elements.getPackageElement("no.such.package"))); - PackageElement dir = elements.getPackageElement("dir"); + String.valueOf(eltUtils.getPackageElement("no.such.package"))); + PackageElement dir = eltUtils.getPackageElement("dir"); messager.printMessage(NOTE, dir.getQualifiedName().toString()); for (Element e : dir.getEnclosedElements()) messager.printMessage(NOTE, e.toString()); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java --- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java Wed Oct 13 17:51:41 2010 -0700 @@ -26,7 +26,8 @@ * @bug 6449781 * @summary Test that reported names of anonymous classes are non-null. * @author Joseph D. Darcy - * @build TestAnonSourceNames + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestAnonSourceNames * @compile -processor TestAnonSourceNames TestAnonClassNames.java * @run main TestAnonClassNames */ @@ -141,8 +142,7 @@ /** * Probe at the various kinds of names of a type element. */ -@SupportedAnnotationTypes("*") -class ClassNameProber extends AbstractProcessor { +class ClassNameProber extends JavacTestingAbstractProcessor { public ClassNameProber(){super();} private boolean classesFound=false; @@ -174,8 +174,4 @@ } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java --- a/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java Wed Oct 13 17:51:41 2010 -0700 @@ -36,8 +36,7 @@ * Using the tree API, retrieve element representations of anonymous * classes and verify their names are as specified. */ -@SupportedAnnotationTypes("*") -public class TestAnonSourceNames extends AbstractProcessor { +public class TestAnonSourceNames extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -84,9 +83,4 @@ return super.visitClass(node, cu); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestElement.java --- a/langtools/test/tools/javac/processing/model/element/TestElement.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestElement.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6453386 * @summary Test basic properties of javax.lang.element.Element * @author Joseph D. Darcy - * @build TestElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestElement * @compile -processor TestElement -proc:only TestElement.java */ @@ -43,8 +44,7 @@ /** * Test basic workings of javax.lang.element.Element */ -@SupportedAnnotationTypes("*") -public class TestElement extends AbstractProcessor { +public class TestElement extends JavacTestingAbstractProcessor { /** * For now, just check that constructors have a simple name of * "". @@ -66,9 +66,4 @@ } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestNames.java --- a/langtools/test/tools/javac/processing/model/element/TestNames.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestNames.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6380016 * @summary Test that the constraints guaranteed by the Filer and maintained * @author Joseph D. Darcy - * @build TestNames + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestNames * @compile -processor TestNames -proc:only TestNames.java */ @@ -45,11 +46,8 @@ /** * Basic tests of semantics of javax.lang.model.element.Name */ -@SupportedAnnotationTypes("*") -public class TestNames extends AbstractProcessor { +public class TestNames extends JavacTestingAbstractProcessor { private int round = 0; - private Filer filer; - private Elements eltUtils; String stringStringName = "java.lang.String"; Name stringName = null; @@ -106,16 +104,6 @@ return true; } - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - eltUtils = processingEnv.getElementUtils(); - } - private static class Pseudonym implements Name { private String name; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestPackageElement.java --- a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6449798 6399404 * @summary Test basic workings of PackageElement * @author Joseph D. Darcy - * @build TestPackageElement + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestPackageElement * @compile -processor TestPackageElement -proc:only TestPackageElement.java */ @@ -43,11 +44,7 @@ /** * Test basic workings of PackageElement. */ -@SupportedAnnotationTypes("*") -public class TestPackageElement extends AbstractProcessor { - private Filer filer; - private Elements eltUtils; - +public class TestPackageElement extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -71,15 +68,4 @@ } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - filer = processingEnv.getFiler(); - eltUtils = processingEnv.getElementUtils(); - } - } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestResourceElement.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,91 @@ +/* + * 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 6967842 + * @summary Element not returned from tree API for ARM resource variables. + * @author A. Sundararajan + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestResourceElement + * @compile -processor TestResourceElement -proc:only TestResourceElement.java + */ + +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import java.util.*; +import com.sun.source.tree.*; +import com.sun.source.util.*; + +public class TestResourceElement extends JavacTestingAbstractProcessor implements AutoCloseable { + public boolean process(Set annotations, + RoundEnvironment roundEnv) { + if (!roundEnv.processingOver()) { + Trees trees = Trees.instance(processingEnv); + + for(Element rootElement : roundEnv.getRootElements()) { + TreePath treePath = trees.getPath(rootElement); + + VariableScanner varScanner = new VariableScanner(trees); + varScanner.scan(trees.getTree(rootElement), + treePath.getCompilationUnit()); + if (varScanner.getTrvElement() == null) { + throw new AssertionError("Element is null for 'trv'"); + } + } + } + return true; + } + + @Override + public void close() {} + + private void test1() { + // The resource variable "trv"'s Element is checked. + // Do not change the name of the variable. + try(TestResourceElement trv = this) {} + } + + class VariableScanner extends TreeScanner { + private Trees trees; + private Element trvElement; + + public VariableScanner(Trees trees) { + super(); + this.trees = trees; + } + @Override + public Void visitVariable(VariableTree node, CompilationUnitTree cu) { + // if this is "trv", get it's element. + if (node.getName().contentEquals("trv")) { + trvElement = trees.getElement(trees.getPath(cu, node)); + } + return super.visitVariable(node, cu); + } + + Element getTrvElement() { + return trvElement; + } + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TestResourceVariable.java --- a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java Wed Oct 13 17:51:41 2010 -0700 @@ -23,11 +23,12 @@ /* * @test - * @bug 6911256 6964740 + * @bug 6911256 6964740 6967842 * @summary Test that the resource variable kind is appropriately set * @author Joseph D. Darcy - * @build TestResourceVariable - * @compile/fail -processor TestResourceVariable -proc:only TestResourceVariable.java + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestResourceVariable + * @compile -processor TestResourceVariable -proc:only TestResourceVariable.java */ // Bug should be filed for this misbehavior @@ -48,8 +49,7 @@ * resource of an ARM block and verify their kind tags are set * appropriately. */ -@SupportedAnnotationTypes("*") -public class TestResourceVariable extends AbstractProcessor implements AutoCloseable { +public class TestResourceVariable extends JavacTestingAbstractProcessor implements AutoCloseable { int resourceVariableCount = 0; public boolean process(Set annotations, @@ -105,9 +105,4 @@ return super.visitVariable(node, cu); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/element/TypeParamBounds.java --- a/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6423972 * @summary Tests TypeParameter.getBounds. * @author Scott Seligman - * @build TypeParamBounds + * @library ../../../lib + * @build JavacTestingAbstractProcessor TypeParamBounds * @compile -processor TypeParamBounds -proc:only TypeParamBounds.java */ @@ -40,18 +41,7 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class TypeParamBounds extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class TypeParamBounds extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -59,11 +49,6 @@ return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { TypeElement gen = elements.getTypeElement("TypeParamBounds.Gen"); @@ -91,7 +76,6 @@ // Fodder for the processor - static class Gen { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java --- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6362178 * @summary MirroredType[s]Exception shouldn't be created too eagerly * @author Scott Seligman + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile -g OverEager.java * @compile -processor OverEager -proc:only OverEager.java */ @@ -40,17 +42,7 @@ @SupportedAnnotationTypes("IAm") @IAm(OverEager.class) -public class OverEager extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class OverEager extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -58,11 +50,6 @@ return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { for (TypeElement t : typesIn(round.getRootElements())) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java --- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java Wed Oct 13 17:51:41 2010 -0700 @@ -25,6 +25,8 @@ * @test * @bug 6519115 * @summary Verify MirroredTypeException vs MirroredTypesException is thrown + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile Plurality.java * @compile -processor Plurality -proc:only Plurality.java * @author Joseph D. Darcy @@ -38,25 +40,13 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") @P0 @P1 @P2 @S1 -public class Plurality extends AbstractProcessor { +public class Plurality extends JavacTestingAbstractProcessor { private boolean executed = false; - Elements elements; - Types types; - - @Override - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - - public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -164,11 +154,6 @@ toStringName); } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } @Retention(RetentionPolicy.RUNTIME) diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/type/NoTypes.java --- a/langtools/test/tools/javac/processing/model/type/NoTypes.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/type/NoTypes.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6418666 6423973 6453386 * @summary Test the NoTypes: VOID, PACKAGE, NONE * @author Scott Seligman + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g NoTypes.java * @compile -processor NoTypes -proc:only NoTypes.java */ @@ -39,18 +41,7 @@ import static javax.lang.model.type.TypeKind.*; -@SupportedAnnotationTypes("*") -public class NoTypes extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class NoTypes extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -58,11 +49,6 @@ return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/BinaryName.java --- a/langtools/test/tools/javac/processing/model/util/BinaryName.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/BinaryName.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6346251 * @summary Test Elements.getBinaryName * @author Scott Seligman - * @build BinaryName + * @library ../../../lib + * @build JavacTestingAbstractProcessor BinaryName * @compile -processor BinaryName -proc:only BinaryName.java */ @@ -38,17 +39,8 @@ import static javax.lang.model.util.ElementFilter.typesIn; -@SupportedAnnotationTypes("*") @HelloIm("BinaryName") -public class BinaryName extends AbstractProcessor { - - Elements elements; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - } - +public class BinaryName extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java --- a/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6346506 6408241 * @summary getTypeElement should tolerate a type that can't be found * @author Scott Seligman - * @build GetTypeElemBadArg + * @library ../../../lib + * @build JavacTestingAbstractProcessor GetTypeElemBadArg * @compile -processor GetTypeElemBadArg -proc:only GetTypeElemBadArg.java */ @@ -37,16 +38,7 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class GetTypeElemBadArg extends AbstractProcessor { - - Elements elements; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - } - +public class GetTypeElemBadArg extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; @@ -63,12 +55,6 @@ return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private static void tellAbout(TypeElement t) { System.out.println(t); System.out.println(t.getClass()); diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/NoSupers.java --- a/langtools/test/tools/javac/processing/model/util/NoSupers.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/NoSupers.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6346453 * @summary directSupertypes should return empty list if arg has no supertypes * @author Scott Seligman - * @build NoSupers + * @library ../../../lib + * @build JavacTestingAbstractProcessor NoSupers * @compile -processor NoSupers -proc:only NoSupers.java */ @@ -36,16 +37,7 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class NoSupers extends AbstractProcessor { - - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - types = penv.getTypeUtils(); - } - +public class NoSupers extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java --- a/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6453386 * @summary Verify that example code in Elements.overrides works as spec'ed. * @author Scott Seligman + * @library ../../../lib + * @build JavacTestingAbstractProcessor * @compile -g OverridesSpecEx.java * @compile -processor OverridesSpecEx -proc:only OverridesSpecEx.java */ @@ -39,19 +41,7 @@ import static javax.lang.model.util.ElementFilter.*; - -@SupportedAnnotationTypes("*") -public class OverridesSpecEx extends AbstractProcessor { - - Elements elements; - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - elements = penv.getElementUtils(); - types = penv.getTypeUtils(); - } - +public class OverridesSpecEx extends JavacTestingAbstractProcessor { public boolean process(Set annoTypes, RoundEnvironment round) { if (!round.processingOver()) @@ -59,11 +49,6 @@ return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - private void doit(Set annoTypes, RoundEnvironment round) { TypeElement string = elements.getTypeElement("java.lang.String"); @@ -113,9 +98,7 @@ throw new AssertionError("Bogus result"); } - // Fodder for the processor - class A { public void m() {} } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/TypesBadArg.java --- a/langtools/test/tools/javac/processing/model/util/TypesBadArg.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/TypesBadArg.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6345812 * @summary Validate argument kinds in Types utilities * @author Scott Seligman - * @build TypesBadArg + * @library ../../../lib + * @build JavacTestingAbstractProcessor TypesBadArg * @compile -processor TypesBadArg -proc:only TypesBadArg.java */ @@ -36,15 +37,9 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; -@SupportedAnnotationTypes("*") -public class TypesBadArg extends AbstractProcessor { - +public class TypesBadArg extends JavacTestingAbstractProcessor { boolean success = true; - public void init(ProcessingEnvironment penv) { - super.init(penv); - } - public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java --- a/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6392818 * @summary Tests Elements.isDeprecated(Element) * @author Joseph D. Darcy + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile TestDeprecation.java * @compile -processor TestDeprecation -proc:only Dep1.java * @compile Dep1.java @@ -47,8 +49,7 @@ * getElementsAnnotatedWith is consistent with the expected results * stored in an AnnotatedElementInfo annotation. */ -@SupportedAnnotationTypes("*") -public class TestDeprecation extends AbstractProcessor { +public class TestDeprecation extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { @@ -98,9 +99,4 @@ return failure; } } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java --- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6346973 * @summary directSupertypes(t) should not return t * @author Scott Seligman - * @build DirectSupersOfErr + * @library ../../../../lib + * @build JavacTestingAbstractProcessor DirectSupersOfErr * @compile -processor DirectSupersOfErr -proc:only C1.java */ @@ -37,16 +38,7 @@ import javax.lang.model.util.*; import static javax.lang.model.util.ElementFilter.*; -@SupportedAnnotationTypes("*") -public class DirectSupersOfErr extends AbstractProcessor { - - Types types; - - public void init(ProcessingEnvironment penv) { - super.init(penv); - types = penv.getTypeUtils(); - } - +public class DirectSupersOfErr extends JavacTestingAbstractProcessor { public boolean process(Set tes, RoundEnvironment round) { if (round.processingOver()) return true; diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java --- a/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 @@ -26,7 +26,8 @@ * @bug 6471577 6517779 * @summary Test Elements.getConstantExpression * @author Joseph D. Darcy - * @build TestGetConstantExpression + * @library ../../../../lib + * @build JavacTestingAbstractProcessor TestGetConstantExpression * @compile -processor TestGetConstantExpression Foo.java */ @@ -44,10 +45,7 @@ /** * Test basic workings of Elements.getConstantExpression. */ -@SupportedAnnotationTypes("*") -public class TestGetConstantExpression extends AbstractProcessor { - private Elements eltUtils; - private Filer filer; +public class TestGetConstantExpression extends JavacTestingAbstractProcessor { private int round = 1; /** @@ -130,14 +128,4 @@ return 0; } } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - filer = processingEnv.getFiler(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java --- a/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,7 +26,8 @@ * @bug 6453386 * @summary Test Elements.getPackageOf * @author Joseph D. Darcy - * @build TestGetPackageOf + * @library ../../../../lib + * @build JavacTestingAbstractProcessor TestGetPackageOf * @compile -processor TestGetPackageOf -proc:only TestGetPackageOf.java */ @@ -43,10 +44,7 @@ /** * Test basic workings of Elements.getPackageOf */ -@SupportedAnnotationTypes("*") -public class TestGetPackageOf extends AbstractProcessor { - private Elements eltUtils; - +public class TestGetPackageOf extends JavacTestingAbstractProcessor { /** * Check expected behavior on classes and packages. */ @@ -69,13 +67,4 @@ } return true; } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - eltUtils = processingEnv.getElementUtils(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,310 @@ +/* + * 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 6877202 6986246 + * @summary Elements.getDocComment() is not getting JavaDocComments + */ + +import com.sun.source.tree.*; +import com.sun.source.util.*; +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.util.*; +import javax.tools.*; + +/* + * For a mixture of pre-existing and generated source files, ensure that we can + * get the doc comments. + * The test uses both a standard ElementScanner to find all the elements being + * processed, and a TreeScanner to find all the local and anonymous inner classes + * as well. + * And, because the relevant code paths in the compiler are different for + * command line and JSR 199 invocation, the test covers both ways of invoking the + * compiler. + */ + +@SupportedOptions("scan") +@SupportedAnnotationTypes("*") +public class TestDocComments extends AbstractProcessor { + enum CompileKind { API, CMD }; + enum ScanKind { TREE, ELEMENT }; + + // ----- Main test driver: invoke compiler for the various test cases ------ + + public static void main(String... args) throws Exception { + for (CompileKind ck: CompileKind.values()) { + for (ScanKind sk: ScanKind.values()) { + try { + test(ck, sk); + } catch (IOException e) { + error(e.toString()); + } + } + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + static void test(CompileKind ck, ScanKind sk) throws IOException { + String testClasses = System.getProperty("test.classes"); + String testSrc = System.getProperty("test.src"); + File testDir = new File("test." + ck + "." + sk); + testDir.mkdirs(); + String[] opts = { + "-d", testDir.getPath(), + "-implicit:none", + "-processor", TestDocComments.class.getName(), + "-processorpath", testClasses, + //"-XprintRounds", + "-Ascan=" + sk + }; + File[] files = { + new File(testSrc, "a/First.java") + }; + + if (ck == CompileKind.API) + test_javac_api(opts, files); + else + test_javac_cmd(opts, files); + } + + static void test_javac_api(String[] opts, File[] files) throws IOException { + System.err.println("test javac api: " + Arrays.asList(opts) + " " + Arrays.asList(files)); + DiagnosticListener dl = new DiagnosticListener() { + public void report(Diagnostic diagnostic) { + error(diagnostic.toString()); + } + }; + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + Iterable units = fm.getJavaFileObjects(files); + JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units); + t.parse(); + t.analyze(); + } + + static void test_javac_cmd(String[] opts, File[] files) { + System.err.println("test javac cmd: " + Arrays.asList(opts) + " " + Arrays.asList(files)); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + List args = new ArrayList(Arrays.asList(opts)); + for (File f: files) + args.add(f.getPath()); + int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc > 0) + error("Compilation failed: rc=" + rc); + } + + static void error(String msg) { + System.err.println(msg); + errors++; + //throw new Error(msg); + } + + static int errors; + + // ----- Annotation processor: scan for elements and check doc comments ---- + + Map options; + Filer filer; + Messager messager; + Elements elements; + Trees trees; + ScanKind skind; + + int round = 0; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + options = pEnv.getOptions(); + filer = pEnv.getFiler(); + messager = pEnv.getMessager(); + elements = pEnv.getElementUtils(); + trees = Trees.instance(processingEnv); + skind = ScanKind.valueOf(options.get("scan")); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + // Scan elements using an appropriate scanner, and for each element found, + // call check(Element e) to verify the doc comment on that element + for (Element e: roundEnv.getRootElements()) { + System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName()); + if (skind == ScanKind.TREE) { + new TestTreeScanner().scan(trees.getPath(e), trees); + } else + new TestElementScanner().scan(e); + } + + // For a few rounds, generate new source files, so that we can check whether + // doc comments are correctly handled in subsequent processing rounds + final int MAX_ROUNDS = 3; + if (round <= MAX_ROUNDS) { + String pkg = "p"; + String currClass = "Gen" + round; + String curr = pkg + "." + currClass; + String next = (round < MAX_ROUNDS) ? (pkg + ".Gen" + (round + 1)) : "z.Last"; + StringBuilder text = new StringBuilder(); + text.append("package ").append(pkg).append(";\n"); + text.append("/** CLASS ").append(currClass).append(" */\n"); + text.append("public class ").append(currClass).append(" {\n"); + text.append(" /** CONSTRUCTOR **/\n"); + text.append(" ").append(currClass).append("() { }\n"); + text.append(" /** FIELD x */\n"); + text.append(" ").append(next).append(" x;\n"); + text.append(" /** METHOD m */\n"); + text.append(" void m() { }\n"); + text.append("}\n"); + + try { + JavaFileObject fo = filer.createSourceFile(curr); + Writer out = fo.openWriter(); + try { + out.write(text.toString()); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } + + return true; + } + + /* + * Check that the doc comment on an element is as expected. + * This method is invoked for each element found by the scanners run by process. + */ + void check(Element e) { + System.err.println("Checking " + e); + + String dc = elements.getDocComment(e); + System.err.println(" found " + dc); + + String expect = (e.getKind() + " " + e.getSimpleName()); // default + + Name name = e.getSimpleName(); + Element encl = e.getEnclosingElement(); + Name enclName = encl.getSimpleName(); + ElementKind enclKind = encl.getKind(); + switch (e.getKind()) { + case PARAMETER: + case LOCAL_VARIABLE: + // doc comments not retained for these elements + expect = null; + break; + + case CONSTRUCTOR: + if (enclName.length() == 0 || enclKind == ElementKind.ENUM) { + // Enum constructor is synthetic + expect = null; + } + break; + + case METHOD: + if (enclKind == ElementKind.ENUM + && (name.contentEquals("values") || name.contentEquals("valueOf"))) { + // synthetic enum methods + expect = null; + } + break; + + case CLASS: + if (e.getSimpleName().length() == 0) { + // anon inner class + expect = null; + } + break; + } + + System.err.println(" expect " + expect); + + if (dc == null ? expect == null : dc.trim().equals(expect)) + return; + + if (dc == null) + messager.printMessage(Diagnostic.Kind.ERROR, "doc comment is null", e); + else { + messager.printMessage(Diagnostic.Kind.ERROR, + "unexpected comment: \"" + dc + "\", expected \"" + expect + "\"", e); + } + } + + // ----- Scanners to find elements ----------------------------------------- + + class TestElementScanner extends ElementScanner7 { + @Override + public Void visitExecutable(ExecutableElement e, Void _) { + check(e); + return super.visitExecutable(e, _); + } + @Override + public Void visitType(TypeElement e, Void _) { + check(e); + return super.visitType(e, _); + } + @Override + public Void visitVariable(VariableElement e, Void _) { + check(e); + return super.visitVariable(e, _); + } + } + + class TestTreeScanner extends TreePathScanner { + @Override + public Void visitClass(ClassTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitClass(tree, trees); + } + @Override + public Void visitMethod(MethodTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitMethod(tree, trees); + } + @Override + public Void visitVariable(VariableTree tree, Trees trees) { + check(trees.getElement(getCurrentPath())); + return super.visitVariable(tree, trees); + } + } + +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,54 @@ +/* + * 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 a; + +/** CLASS First */ +public class First { + /** CONSTRUCTOR */ + First() { } + + /** FIELD x */ + p.Gen1 x; + + /** METHOD m **/ + void m(int i) { + /** CLASS Local */ + class Local { + /** CONSTRUCTOR */ + Local() { } + } + + Runnable r = new Runnable() { + /** METHOD run **/ + public void run() { } + }; + + } + + /** ENUM E */ + enum E { + /** ENUM_CONSTANT e1 */ + e1 + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,30 @@ +/* + * 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 z; + +// This class should be read last, implicitly. Therefore it should not +// be subject to anno processing. If it is, the lack of doc comments should +// be detected and will flag an error. +public class Last { +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/model/util/filter/TestIterables.java --- a/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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,6 +26,8 @@ * @bug 6406164 * @summary Test that ElementFilter iterable methods behave properly. * @author Joseph D. Darcy + * @library ../../../../lib + * @build JavacTestingAbstractProcessor * @compile TestIterables.java * @compile -processor TestIterables -proc:only Foo1.java * @compile Foo1.java @@ -51,9 +53,8 @@ * results. */ @SupportedAnnotationTypes("ExpectedElementCounts") -@ExpectedElementCounts(methods=3) -public class TestIterables extends AbstractProcessor { - +@ExpectedElementCounts(methods=2) +public class TestIterables extends JavacTestingAbstractProcessor { public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { @@ -118,10 +119,4 @@ return count1; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/options/Xprint.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/options/Xprint.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, 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 6266828 + * @summary JSR 269: Java Language Model API + * @author Peter von der Ah\u00e9 + */ +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; + +public class Xprint { + public static void main(String[] args) { + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + javac.run(System.in, null, null, + "-Xprint", + "com.sun.tools.javac.code.Types", + "com.sun.tools.javac.parser.Parser", + "java.util.EnumSet"); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/options/XprintDocComments.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/options/XprintDocComments.java Wed Oct 13 17:51:41 2010 -0700 @@ -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 6861094 + * @summary javac -Xprint does not print comments + * @compile/ref=XprintDocComments.out -Xprint XprintDocComments.java + */ + +/** + * CLASS XprintDocComments + */ +class XPrintDocComments { + /** + * FIELD i; + */ + int i; +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/options/XprintDocComments.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/options/XprintDocComments.out Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,12 @@ + +/** + * CLASS XprintDocComments + */ +class XPrintDocComments { + + XPrintDocComments(); + /** + * FIELD i; + */ + int i; +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java --- a/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java Wed Oct 13 17:51:41 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -50,7 +50,8 @@ /** * This processor returns the supported source level as indicated by - * the "SourceLevel" option. + * the "SourceLevel" option; therefore, don't use + * JavacTestingAbstractProcessor which returns the latest source level. */ @SupportedAnnotationTypes("*") @SupportedOptions("SourceVersion") diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/werror/WError1.java --- a/langtools/test/tools/javac/processing/werror/WError1.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/werror/WError1.java Wed Oct 13 17:51:41 2010 -0700 @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WError1.java * @compile -proc:only -processor WError1 WError1.java * @compile/fail/ref=WError1.out -XDrawDiagnostics -Werror -proc:only -processor WError1 WError1.java @@ -36,22 +38,15 @@ import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WError1 extends AbstractProcessor { +public class WError1 extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); if (++round == 1) { messager.printMessage(Diagnostic.Kind.WARNING, "round 1"); } return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - int round = 0; } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/werror/WErrorGen.java --- a/langtools/test/tools/javac/processing/werror/WErrorGen.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/werror/WErrorGen.java Wed Oct 13 17:51:41 2010 -0700 @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WErrorGen.java * @compile -proc:only -processor WErrorGen WErrorGen.java * @compile/fail/ref=WErrorGen.out -XDrawDiagnostics -Werror -Xlint:rawtypes -processor WErrorGen WErrorGen.java @@ -36,12 +38,10 @@ import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WErrorGen extends AbstractProcessor { +public class WErrorGen extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Filer filer = processingEnv.getFiler(); if (++round == 1) { try { JavaFileObject fo = filer.createSourceFile("Gen"); @@ -54,10 +54,5 @@ return true; } - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } - int round = 0; } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/processing/werror/WErrorLast.java --- a/langtools/test/tools/javac/processing/werror/WErrorLast.java Tue Oct 12 17:05:28 2010 -0700 +++ b/langtools/test/tools/javac/processing/werror/WErrorLast.java Wed Oct 13 17:51:41 2010 -0700 @@ -24,6 +24,8 @@ /* * @test 6403456 * @summary -Werror should work with annotation processing + * @library ../../lib + * @build JavacTestingAbstractProcessor * @compile WErrorLast.java * @compile -proc:only -processor WErrorLast WErrorLast.java * @compile/fail/ref=WErrorLast.out -XDrawDiagnostics -Werror -proc:only -processor WErrorLast WErrorLast.java @@ -36,20 +38,13 @@ import javax.lang.model.element.*; import javax.tools.*; -@SupportedAnnotationTypes("*") -public class WErrorLast extends AbstractProcessor { +public class WErrorLast extends JavacTestingAbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); if (roundEnv.processingOver()) { messager.printMessage(Diagnostic.Kind.WARNING, "last round"); } return true; } - - @Override - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } } diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javac/tree/TreePosRoundsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/tree/TreePosRoundsTest.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,205 @@ +/* + * 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 6985205 6986246 + * @summary access to tree positions and doc comments may be lost across annotation processing rounds + * @build TreePosRoundsTest + * @compile -proc:only -processor TreePosRoundsTest TreePosRoundsTest.java + * @run main TreePosRoundsTest + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.*; + +import com.sun.source.tree.*; +import com.sun.source.util.*; +import javax.tools.JavaCompiler.CompilationTask; + +// This test is an annotation processor that performs multiple rounds of +// processing, and on each round, it checks that source positions are +// available and correct. +// +// The test can be run directly as a processor from the javac command line +// or via JSR 199 by invoking the main program. + +@SupportedAnnotationTypes("*") +public class TreePosRoundsTest extends AbstractProcessor { + public static void main(String... args) throws Exception { + String testSrc = System.getProperty("test.src"); + String testClasses = System.getProperty("test.classes"); + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + String thisName = TreePosRoundsTest.class.getName(); + File thisFile = new File(testSrc, thisName + ".java"); + Iterable files = fm.getJavaFileObjects(thisFile); + List options = Arrays.asList( + "-proc:only", + "-processor", thisName, + "-processorpath", testClasses); + CompilationTask t = c.getTask(null, fm, null, options, null, files); + boolean ok = t.call(); + if (!ok) + throw new Exception("processing failed"); + } + + Filer filer; + Messager messager; + Trees trees; + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + filer = pEnv.getFiler(); + messager = pEnv.getMessager(); + trees = Trees.instance(pEnv); + } + + int round = 0; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + // Scan trees for elements, verifying source tree positions + for (Element e: roundEnv.getRootElements()) { + try { + TreePath p = trees.getPath(e); + new TestTreeScanner(p.getCompilationUnit(), trees).scan(trees.getPath(e), null); + } catch (IOException ex) { + messager.printMessage(Diagnostic.Kind.ERROR, + "Cannot get source: " + ex, e); + } + } + + final int MAXROUNDS = 3; + if (round < MAXROUNDS) + generateSource("Gen" + round); + + return true; + } + + void generateSource(String name) { + StringBuilder text = new StringBuilder(); + text.append("class ").append(name).append("{\n"); + text.append(" int one = 1;\n"); + text.append(" int two = 2;\n"); + text.append(" int three = one + two;\n"); + text.append("}\n"); + + try { + JavaFileObject fo = filer.createSourceFile(name); + Writer out = fo.openWriter(); + try { + out.write(text.toString()); + } finally { + out.close(); + } + } catch (IOException e) { + throw new Error(e); + } + } + + class TestTreeScanner extends TreePathScanner { + TestTreeScanner(CompilationUnitTree unit, Trees trees) throws IOException { + this.unit = unit; + JavaFileObject sf = unit.getSourceFile(); + source = sf.getCharContent(true).toString(); + sourcePositions = trees.getSourcePositions(); + } + + @Override + public Void visitVariable(VariableTree tree, Void _) { + check(getCurrentPath()); + return super.visitVariable(tree, _); + } + + void check(TreePath tp) { + Tree tree = tp.getLeaf(); + + String expect = tree.toString(); + if (tree.getKind() == Tree.Kind.VARIABLE) { + // tree.toString() does not know enough context to add ";", + // so deal with that manually... + Tree.Kind enclKind = tp.getParentPath().getLeaf().getKind(); + //System.err.println(" encl: " +enclKind); + if (enclKind == Tree.Kind.CLASS || enclKind == Tree.Kind.BLOCK) + expect += ";"; + } + //System.err.println("expect: " + expect); + + int start = (int)sourcePositions.getStartPosition(unit, tree); + if (start == Diagnostic.NOPOS) { + messager.printMessage(Diagnostic.Kind.ERROR, "start pos not set for " + trim(tree)); + return; + } + + int end = (int)sourcePositions.getEndPosition(unit, tree); + if (end == Diagnostic.NOPOS) { + messager.printMessage(Diagnostic.Kind.ERROR, "end pos not set for " + trim(tree)); + return; + } + + String found = source.substring(start, end); + //System.err.println(" found: " + found); + + // allow for long lines, in which case just compare beginning and + // end of the strings + boolean equal; + if (found.contains("\n")) { + String head = found.substring(0, found.indexOf("\n")); + String tail = found.substring(found.lastIndexOf("\n")).trim(); + equal = expect.startsWith(head) && expect.endsWith(tail); + } else { + equal = expect.equals(found); + } + + if (!equal) { + messager.printMessage(Diagnostic.Kind.ERROR, + "unexpected value found: '" + found + "'; expected: '" + expect + "'"); + } + } + + String trim(Tree tree) { + final int MAXLEN = 32; + String s = tree.toString().replaceAll("\\s+", " ").trim(); + return (s.length() < MAXLEN) ? s : s.substring(0, MAXLEN); + + } + + CompilationUnitTree unit; + SourcePositions sourcePositions; + String source; + } + +} diff -r 43cb79a6b123 -r d954b585d3a1 langtools/test/tools/javah/VersionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javah/VersionTest.java Wed Oct 13 17:51:41 2010 -0700 @@ -0,0 +1,59 @@ +/* + * 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 6890226 + * @summary javah -version is broken + */ + +import java.io.*; +import java.util.Locale; + +public class VersionTest { + public static void main(String... args) { + Locale prev = Locale.getDefault(); + try { + Locale.setDefault(Locale.ENGLISH); + System.err.println(Locale.getDefault()); + test("-version", "\\S+ version \"\\S+\""); + test("-fullversion", "\\S+ full version \"\\S+\""); + } finally { + Locale.setDefault(prev); + } + } + + static void test(String option, String regex) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { option }; + int rc = com.sun.tools.javah.Main.run(args, pw); + pw.close(); + if (rc != 0) + throw new Error("javah failed: rc=" + rc); + String out = sw.toString().trim(); + System.err.println(out); + if (!out.matches(regex)) + throw new Error("output does not match pattern: " + regex); + } +} diff -r 43cb79a6b123 -r d954b585d3a1 make/jprt.properties --- a/make/jprt.properties Tue Oct 12 17:05:28 2010 -0700 +++ b/make/jprt.properties Wed Oct 13 17:51:41 2010 -0700 @@ -25,49 +25,310 @@ # Properties for jprt -# Use whatever release that the submitted job requests +# At submit time, the release supplied will be in jprt.submit.release +# and will be one of the official release names defined in jprt. +# jprt supports property value expansion using ${property.name} syntax. + +# This tells jprt what default release we want to build jprt.tools.default.release=${jprt.submit.release} # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug -# Shortened list of vm tests -jprt.test.targets= \ - *-product-*-jvm98, \ - *-product-*-scimark, \ - *-product-*-runThese, \ - *-product-*-GCBasher_default, \ - *-product-*-GCOld_default, \ - *-product-*-jbb_default +# Define the Windows we want (temporary) +jprt.my.windows.i586.jdk7b107=windows_i586_5.0 +jprt.my.windows.i586.jdk7temp=windows_i586_5.0 +jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} + +# Standard list of jprt build targets for this source tree +jprt.build.targets= \ + solaris_sparc_5.10-{product|fastdebug}, \ + solaris_sparcv9_5.10-{product|fastdebug}, \ + solaris_i586_5.10-{product|fastdebug}, \ + solaris_x64_5.10-{product|fastdebug}, \ + linux_i586_2.6-{product|fastdebug}, \ + linux_x64_2.6-{product|fastdebug}, \ + ${jprt.my.windows.i586}-{product|fastdebug}, \ + windows_x64_5.2-{product|fastdebug} + +# User can select the test set with jprt submit "-testset name" option +jprt.my.test.set=${jprt.test.set} + +# Default vm test targets (no fastdebug & limited c2 testing) +jprt.vm.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-jvm98, \ + solaris_sparcv9_5.10-product-c2-jvm98, \ + solaris_i586_5.10-product-c1-jvm98, \ + solaris_x64_5.10-product-c2-jvm98, \ + linux_i586_2.6-product-{c1|c2}-jvm98, \ + linux_x64_2.6-product-c2-jvm98, \ + ${jprt.my.windows.i586}-product-c1-jvm98, \ + windows_x64_5.2-product-c2-jvm98, \ + \ + solaris_sparc_5.10-product-c1-scimark, \ + solaris_sparcv9_5.10-product-c2-scimark, \ + solaris_i586_5.10-product-c1-scimark, \ + solaris_x64_5.10-product-c2-scimark, \ + linux_i586_2.6-product-{c1|c2}-scimark, \ + linux_x64_2.6-product-c2-scimark, \ + ${jprt.my.windows.i586}-product-c1-scimark, \ + windows_x64_5.2-product-c2-scimark -# Test targets in test/Makefile -jprt.make.rule.test.targets= \ - *-product-*-langtools_jtreg, \ - *-product-*-jdk_beans1, \ - *-product-*-jdk_beans2, \ - *-product-*-jdk_beans3, \ - *-product-*-jdk_io, \ - *-product-*-jdk_lang, \ - *-product-*-jdk_management1, \ - *-product-*-jdk_management2, \ - *-product-*-jdk_math, \ - *-product-*-jdk_misc, \ - *-product-*-jdk_net, \ - *-product-*-jdk_nio1, \ - *-product-*-jdk_nio2, \ - *-product-*-jdk_nio3, \ - *-product-*-jdk_security1, \ - *-product-*-jdk_security2, \ - *-product-*-jdk_security3, \ - *-product-*-jdk_text, \ - *-product-*-jdk_tools1, \ - *-product-*-jdk_tools2, \ - *-product-*-jdk_util +# Default jdk test targets in test/Makefile (no fastdebug & limited c2 testing) +jprt.make.rule.default.test.targets= \ + \ + solaris_sparc_5.10-product-c1-langtools_jtreg, \ + solaris_sparcv9_5.10-product-c2-langtools_jtreg, \ + solaris_i586_5.10-product-c1-langtools_jtreg, \ + solaris_x64_5.10-product-c2-langtools_jtreg, \ + linux_i586_2.6-product-{c1|c2}-langtools_jtreg, \ + linux_x64_2.6-product-c2-langtools_jtreg, \ + ${jprt.my.windows.i586}-product-c1-langtools_jtreg, \ + windows_x64_5.2-product-c2-langtools_jtreg, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans1, \ + solaris_sparcv9_5.10-product-c2-jdk_beans1, \ + solaris_i586_5.10-product-c1-jdk_beans1, \ + solaris_x64_5.10-product-c2-jdk_beans1, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ + linux_x64_2.6-product-c2-jdk_beans1, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans1, \ + windows_x64_5.2-product-c2-jdk_beans1, \ + \ + solaris_sparc_5.10-product-c1-jdk_io, \ + solaris_sparcv9_5.10-product-c2-jdk_io, \ + solaris_i586_5.10-product-c1-jdk_io, \ + solaris_x64_5.10-product-c2-jdk_io, \ + linux_i586_2.6-product-{c1|c2}-jdk_io, \ + linux_x64_2.6-product-c2-jdk_io, \ + ${jprt.my.windows.i586}-product-c1-jdk_io, \ + windows_x64_5.2-product-c2-jdk_io, \ + \ + solaris_sparc_5.10-product-c1-jdk_lang, \ + solaris_sparcv9_5.10-product-c2-jdk_lang, \ + solaris_i586_5.10-product-c1-jdk_lang, \ + solaris_x64_5.10-product-c2-jdk_lang, \ + linux_i586_2.6-product-{c1|c2}-jdk_lang, \ + linux_x64_2.6-product-c2-jdk_lang, \ + ${jprt.my.windows.i586}-product-c1-jdk_lang, \ + windows_x64_5.2-product-c2-jdk_lang, \ + \ + solaris_sparc_5.10-product-c1-jdk_math, \ + solaris_sparcv9_5.10-product-c2-jdk_math, \ + solaris_i586_5.10-product-c1-jdk_math, \ + solaris_x64_5.10-product-c2-jdk_math, \ + linux_i586_2.6-product-{c1|c2}-jdk_math, \ + linux_x64_2.6-product-c2-jdk_math, \ + ${jprt.my.windows.i586}-product-c1-jdk_math, \ + windows_x64_5.2-product-c2-jdk_math, \ + \ + solaris_sparc_5.10-product-c1-jdk_misc, \ + solaris_sparcv9_5.10-product-c2-jdk_misc, \ + solaris_i586_5.10-product-c1-jdk_misc, \ + solaris_x64_5.10-product-c2-jdk_misc, \ + linux_i586_2.6-product-{c1|c2}-jdk_misc, \ + linux_x64_2.6-product-c2-jdk_misc, \ + ${jprt.my.windows.i586}-product-c1-jdk_misc, \ + windows_x64_5.2-product-c2-jdk_misc, \ + \ + solaris_sparc_5.10-product-c1-jdk_net, \ + solaris_sparcv9_5.10-product-c2-jdk_net, \ + solaris_i586_5.10-product-c1-jdk_net, \ + solaris_x64_5.10-product-c2-jdk_net, \ + linux_i586_2.6-product-{c1|c2}-jdk_net, \ + linux_x64_2.6-product-c2-jdk_net, \ + ${jprt.my.windows.i586}-product-c1-jdk_net, \ + windows_x64_5.2-product-c2-jdk_net, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio1, \ + solaris_sparcv9_5.10-product-c2-jdk_nio1, \ + solaris_i586_5.10-product-c1-jdk_nio1, \ + solaris_x64_5.10-product-c2-jdk_nio1, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ + linux_x64_2.6-product-c2-jdk_nio1, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio1, \ + windows_x64_5.2-product-c2-jdk_nio1, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio2, \ + solaris_sparcv9_5.10-product-c2-jdk_nio2, \ + solaris_i586_5.10-product-c1-jdk_nio2, \ + solaris_x64_5.10-product-c2-jdk_nio2, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ + linux_x64_2.6-product-c2-jdk_nio2, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio2, \ + windows_x64_5.2-product-c2-jdk_nio2, \ + \ + solaris_sparc_5.10-product-c1-jdk_nio3, \ + solaris_sparcv9_5.10-product-c2-jdk_nio3, \ + solaris_i586_5.10-product-c1-jdk_nio3, \ + solaris_x64_5.10-product-c2-jdk_nio3, \ + linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ + linux_x64_2.6-product-c2-jdk_nio3, \ + ${jprt.my.windows.i586}-product-c1-jdk_nio3, \ + windows_x64_5.2-product-c2-jdk_nio3, \ + \ + solaris_sparc_5.10-product-c1-jdk_security1, \ + solaris_sparcv9_5.10-product-c2-jdk_security1, \ + solaris_i586_5.10-product-c1-jdk_security1, \ + solaris_x64_5.10-product-c2-jdk_security1, \ + linux_i586_2.6-product-{c1|c2}-jdk_security1, \ + linux_x64_2.6-product-c2-jdk_security1, \ + ${jprt.my.windows.i586}-product-c1-jdk_security1, \ + windows_x64_5.2-product-c2-jdk_security1, \ + \ + solaris_sparc_5.10-product-c1-jdk_text, \ + solaris_sparcv9_5.10-product-c2-jdk_text, \ + solaris_i586_5.10-product-c1-jdk_text, \ + solaris_x64_5.10-product-c2-jdk_text, \ + linux_i586_2.6-product-{c1|c2}-jdk_text, \ + linux_x64_2.6-product-c2-jdk_text, \ + ${jprt.my.windows.i586}-product-c1-jdk_text, \ + windows_x64_5.2-product-c2-jdk_text, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools1, \ + solaris_sparcv9_5.10-product-c2-jdk_tools1, \ + solaris_i586_5.10-product-c1-jdk_tools1, \ + solaris_x64_5.10-product-c2-jdk_tools1, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ + linux_x64_2.6-product-c2-jdk_tools1, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools1, \ + windows_x64_5.2-product-c2-jdk_tools1, \ + \ + solaris_sparc_5.10-product-c1-jdk_util, \ + solaris_sparcv9_5.10-product-c2-jdk_util, \ + solaris_i586_5.10-product-c1-jdk_util, \ + solaris_x64_5.10-product-c2-jdk_util, \ + linux_i586_2.6-product-{c1|c2}-jdk_util, \ + linux_x64_2.6-product-c2-jdk_util, \ + ${jprt.my.windows.i586}-product-c1-jdk_util, \ + windows_x64_5.2-product-c2-jdk_util -# Not Ready Yet: -# *-product-*-jdk_awt -# *-product-*-jdk_rmi -# *-product-*-jdk_swing +# All vm test targets (but still no fastdebug & limited c2 testing) +jprt.vm.all.test.targets= \ + \ + ${jprt.vm.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-runThese, \ + solaris_sparcv9_5.10-product-c2-runThese, \ + solaris_i586_5.10-product-c1-runThese, \ + solaris_x64_5.10-product-c2-runThese, \ + linux_i586_2.6-product-{c1|c2}-runThese, \ + linux_x64_2.6-product-c2-runThese, \ + ${jprt.my.windows.i586}-product-c1-runThese, \ + windows_x64_5.2-product-c2-runThese, \ + \ + solaris_sparc_5.10-product-c1-jbb_default, \ + solaris_sparcv9_5.10-product-c2-jbb_default, \ + solaris_i586_5.10-product-c1-jbb_default, \ + solaris_x64_5.10-product-c2-jbb_default, \ + linux_i586_2.6-product-{c1|c2}-jbb_default, \ + linux_x64_2.6-product-c2-jbb_default, \ + ${jprt.my.windows.i586}-product-c1-jbb_default, \ + windows_x64_5.2-product-c2-jbb_default + +# All jdk test targets (but still no fastdebug & limited c2 testing) +jprt.make.rule.all.test.targets= \ + \ + ${jprt.make.rule.default.test.targets}, \ + \ + solaris_sparc_5.10-product-c1-jdk_awt, \ + solaris_sparcv9_5.10-product-c2-jdk_awt, \ + solaris_i586_5.10-product-c1-jdk_awt, \ + solaris_x64_5.10-product-c2-jdk_awt, \ + linux_i586_2.6-product-{c1|c2}-jdk_awt, \ + linux_x64_2.6-product-c2-jdk_awt, \ + ${jprt.my.windows.i586}-product-c1-jdk_awt, \ + windows_x64_5.2-product-c2-jdk_awt, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans2, \ + solaris_sparcv9_5.10-product-c2-jdk_beans2, \ + solaris_i586_5.10-product-c1-jdk_beans2, \ + solaris_x64_5.10-product-c2-jdk_beans2, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ + linux_x64_2.6-product-c2-jdk_beans2, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans2, \ + windows_x64_5.2-product-c2-jdk_beans2, \ + \ + solaris_sparc_5.10-product-c1-jdk_beans3, \ + solaris_sparcv9_5.10-product-c2-jdk_beans3, \ + solaris_i586_5.10-product-c1-jdk_beans3, \ + solaris_x64_5.10-product-c2-jdk_beans3, \ + linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ + linux_x64_2.6-product-c2-jdk_beans3, \ + ${jprt.my.windows.i586}-product-c1-jdk_beans3, \ + windows_x64_5.2-product-c2-jdk_beans3, \ + \ + solaris_sparc_5.10-product-c1-jdk_management1, \ + solaris_sparcv9_5.10-product-c2-jdk_management1, \ + solaris_i586_5.10-product-c1-jdk_management1, \ + solaris_x64_5.10-product-c2-jdk_management1, \ + linux_i586_2.6-product-{c1|c2}-jdk_management1, \ + linux_x64_2.6-product-c2-jdk_management1, \ + ${jprt.my.windows.i586}-product-c1-jdk_management1, \ + windows_x64_5.2-product-c2-jdk_management1, \ + \ + solaris_sparc_5.10-product-c1-jdk_management2, \ + solaris_sparcv9_5.10-product-c2-jdk_management2, \ + solaris_i586_5.10-product-c1-jdk_management2, \ + solaris_x64_5.10-product-c2-jdk_management2, \ + linux_i586_2.6-product-{c1|c2}-jdk_management2, \ + linux_x64_2.6-product-c2-jdk_management2, \ + ${jprt.my.windows.i586}-product-c1-jdk_management2, \ + windows_x64_5.2-product-c2-jdk_management2, \ + \ + solaris_sparc_5.10-product-c1-jdk_rmi, \ + solaris_sparcv9_5.10-product-c2-jdk_rmi, \ + solaris_i586_5.10-product-c1-jdk_rmi, \ + solaris_x64_5.10-product-c2-jdk_rmi, \ + linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ + linux_x64_2.6-product-c2-jdk_rmi, \ + ${jprt.my.windows.i586}-product-c1-jdk_rmi, \ + windows_x64_5.2-product-c2-jdk_rmi, \ + \ + solaris_sparc_5.10-product-c1-jdk_security2, \ + solaris_sparcv9_5.10-product-c2-jdk_security2, \ + solaris_i586_5.10-product-c1-jdk_security2, \ + solaris_x64_5.10-product-c2-jdk_security2, \ + linux_i586_2.6-product-{c1|c2}-jdk_security2, \ + linux_x64_2.6-product-c2-jdk_security2, \ + ${jprt.my.windows.i586}-product-c1-jdk_security2, \ + windows_x64_5.2-product-c2-jdk_security2, \ + \ + solaris_sparc_5.10-product-c1-jdk_security3, \ + solaris_sparcv9_5.10-product-c2-jdk_security3, \ + solaris_i586_5.10-product-c1-jdk_security3, \ + solaris_x64_5.10-product-c2-jdk_security3, \ + linux_i586_2.6-product-{c1|c2}-jdk_security3, \ + linux_x64_2.6-product-c2-jdk_security3, \ + ${jprt.my.windows.i586}-product-c1-jdk_security3, \ + windows_x64_5.2-product-c2-jdk_security3, \ + \ + solaris_sparc_5.10-product-c1-jdk_swing, \ + solaris_sparcv9_5.10-product-c2-jdk_swing, \ + solaris_i586_5.10-product-c1-jdk_swing, \ + solaris_x64_5.10-product-c2-jdk_swing, \ + linux_i586_2.6-product-{c1|c2}-jdk_swing, \ + linux_x64_2.6-product-c2-jdk_swing, \ + ${jprt.my.windows.i586}-product-c1-jdk_swing, \ + windows_x64_5.2-product-c2-jdk_swing, \ + \ + solaris_sparc_5.10-product-c1-jdk_tools2, \ + solaris_sparcv9_5.10-product-c2-jdk_tools2, \ + solaris_i586_5.10-product-c1-jdk_tools2, \ + solaris_x64_5.10-product-c2-jdk_tools2, \ + linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ + linux_x64_2.6-product-c2-jdk_tools2, \ + ${jprt.my.windows.i586}-product-c1-jdk_tools2, \ + windows_x64_5.2-product-c2-jdk_tools2 + +# Select list to use (allow for testset to be empty too) +jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} +jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} +jprt.vm..test.targets=${jprt.vm.default.test.targets} +jprt.vm.test.targets=${jprt.vm.${jprt.my.test.set}.test.targets} +jprt.test.targets=${jprt.vm.test.targets} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev