From 99c5ea5368b2a58c6e93d4c76fccf5707c9469f8 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 29 Apr 2009 20:03:09 +0400 Subject: [PATCH 001/102] 6660539: Introspector shares cache of mutable BeanInfo between AppContexts Reviewed-by: peterz --- .../classes/java/beans/Introspector.java | 29 ++++++-- .../java/beans/Introspector/Test6660539.java | 68 +++++++++++++++++++ 2 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 jdk/test/java/beans/Introspector/Test6660539.java diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java index 6a50cbe7f7d..2a49db1794c 100644 --- a/jdk/src/share/classes/java/beans/Introspector.java +++ b/jdk/src/share/classes/java/beans/Introspector.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ import java.util.EventListener; import java.util.List; import java.util.WeakHashMap; import java.util.TreeMap; +import sun.awt.AppContext; import sun.reflect.misc.ReflectUtil; /** @@ -111,8 +112,8 @@ public class Introspector { // Static Caches to speed up introspection. private static Map declaredMethodCache = Collections.synchronizedMap(new WeakHashMap()); - private static Map beanInfoCache = - Collections.synchronizedMap(new WeakHashMap()); + + private static final Object BEANINFO_CACHE = new Object(); private Class beanClass; private BeanInfo explicitBeanInfo; @@ -175,10 +176,18 @@ public class Introspector { if (!ReflectUtil.isPackageAccessible(beanClass)) { return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); } - BeanInfo bi = (BeanInfo)beanInfoCache.get(beanClass); + Map, BeanInfo> map; + synchronized (BEANINFO_CACHE) { + map = (Map, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE); + if (map == null) { + map = Collections.synchronizedMap(new WeakHashMap, BeanInfo>()); + AppContext.getAppContext().put(BEANINFO_CACHE, map); + } + } + BeanInfo bi = map.get(beanClass); if (bi == null) { bi = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); - beanInfoCache.put(beanClass, bi); + map.put(beanClass, bi); } return bi; } @@ -351,7 +360,10 @@ public class Introspector { */ public static void flushCaches() { - beanInfoCache.clear(); + Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); + if (map != null) { + map.clear(); + } declaredMethodCache.clear(); } @@ -374,7 +386,10 @@ public class Introspector { if (clz == null) { throw new NullPointerException(); } - beanInfoCache.remove(clz); + Map map = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); + if (map != null) { + map.remove(clz); + } declaredMethodCache.remove(clz); } diff --git a/jdk/test/java/beans/Introspector/Test6660539.java b/jdk/test/java/beans/Introspector/Test6660539.java new file mode 100644 index 00000000000..b0678a5a04b --- /dev/null +++ b/jdk/test/java/beans/Introspector/Test6660539.java @@ -0,0 +1,68 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6660539 + * @summary Tests changeable BeanInfo cache in different application contexts + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; + +public class Test6660539 implements Runnable { + private static final String NAME = "$$$"; + + public static void main(String[] args) throws Exception { + for (PropertyDescriptor pd : getPropertyDescriptors()) { + pd.setDisplayName(NAME); + } + ThreadGroup group = new ThreadGroup(NAME); + Thread thread = new Thread(group, new Test6660539()); + thread.start(); + thread.join(); + } + + public void run() { + SunToolkit.createNewAppContext(); + for (PropertyDescriptor pd : getPropertyDescriptors()) { + if (pd.getDisplayName().equals(NAME)) + throw new Error("shared BeanInfo cache"); + } + } + + private static PropertyDescriptor[] getPropertyDescriptors() { + try { + BeanInfo info = Introspector.getBeanInfo(Test6660539.class); + return info.getPropertyDescriptors(); + } + catch (IntrospectionException exception) { + throw new Error("unexpected", exception); + } + } +} From de6e2fb6e267b377c94c9179cd474d1689b4a0e6 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 29 Apr 2009 20:55:13 +0400 Subject: [PATCH 002/102] 6777487: Encoder allows reading private variables with certain names Reviewed-by: peterz --- .../share/classes/java/beans/MetaData.java | 83 ++++++++++--------- .../beans/XMLEncoder/6777487/TestBox.java | 52 ++++++++++++ .../6777487/TestCheckedCollection.java | 48 +++++++++++ .../XMLEncoder/6777487/TestCheckedList.java | 48 +++++++++++ .../XMLEncoder/6777487/TestCheckedMap.java | 49 +++++++++++ .../6777487/TestCheckedRandomAccessList.java | 48 +++++++++++ .../XMLEncoder/6777487/TestCheckedSet.java | 48 +++++++++++ .../6777487/TestCheckedSortedMap.java | 49 +++++++++++ .../6777487/TestCheckedSortedSet.java | 48 +++++++++++ .../beans/XMLEncoder/6777487/TestEncoder.java | 60 ++++++++++++++ .../beans/XMLEncoder/6777487/TestEnumMap.java | 47 +++++++++++ .../beans/XMLEncoder/6777487/TestEnumSet.java | 47 +++++++++++ 12 files changed, 589 insertions(+), 38 deletions(-) create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestBox.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java create mode 100644 jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index defd196457e..75c3945106d 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -333,31 +333,6 @@ abstract class java_util_Collections extends PersistenceDelegate { return (oldC.size() == newC.size()) && oldC.containsAll(newC); } - static Object getPrivateField(final Object instance, final String name) { - return AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - Class type = instance.getClass(); - while ( true ) { - try { - Field field = type.getDeclaredField(name); - field.setAccessible(true); - return field.get( instance ); - } - catch (NoSuchFieldException exception) { - type = type.getSuperclass(); - if (type == null) { - throw new IllegalStateException("Could not find field " + name, exception); - } - } - catch (Exception exception) { - throw new IllegalStateException("Could not get value " + type.getName() + '.' + name, exception); - } - } - } - } ); - } - static final class EmptyList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { return new Expression(oldInstance, Collections.class, "emptyList", null); @@ -498,7 +473,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedCollection_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); List list = new ArrayList((Collection) oldInstance); return new Expression(oldInstance, Collections.class, "checkedCollection", new Object[]{list, type}); } @@ -506,7 +481,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); List list = new LinkedList((Collection) oldInstance); return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type}); } @@ -514,7 +489,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedRandomAccessList_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); List list = new ArrayList((Collection) oldInstance); return new Expression(oldInstance, Collections.class, "checkedList", new Object[]{list, type}); } @@ -522,7 +497,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedSet_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); Set set = new HashSet((Set) oldInstance); return new Expression(oldInstance, Collections.class, "checkedSet", new Object[]{set, type}); } @@ -530,7 +505,7 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedSortedSet_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object type = getPrivateField(oldInstance, "type"); + Object type = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedCollection.type"); SortedSet set = new TreeSet((SortedSet) oldInstance); return new Expression(oldInstance, Collections.class, "checkedSortedSet", new Object[]{set, type}); } @@ -538,8 +513,8 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedMap_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object keyType = getPrivateField(oldInstance, "keyType"); - Object valueType = getPrivateField(oldInstance, "valueType"); + Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); + Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); Map map = new HashMap((Map) oldInstance); return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType}); } @@ -547,8 +522,8 @@ abstract class java_util_Collections extends PersistenceDelegate { static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections { protected Expression instantiate(Object oldInstance, Encoder out) { - Object keyType = getPrivateField(oldInstance, "keyType"); - Object valueType = getPrivateField(oldInstance, "valueType"); + Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); + Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); SortedMap map = new TreeMap((SortedMap) oldInstance); return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType}); } @@ -570,7 +545,7 @@ class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { } private static Object getType(Object instance) { - return java_util_Collections.getPrivateField(instance, "keyType"); + return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType"); } } @@ -589,7 +564,7 @@ class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { } private static Object getType(Object instance) { - return java_util_Collections.getPrivateField(instance, "elementType"); + return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType"); } } @@ -1280,7 +1255,7 @@ class javax_swing_Box_PersistenceDelegate extends DefaultPersistenceDelegate { private Integer getAxis(Object object) { Box box = (Box) object; - return (Integer) java_util_Collections.getPrivateField(box.getLayout(), "axis"); + return (Integer) MetaData.getPrivateFieldValue(box.getLayout(), "javax.swing.BoxLayout.axis"); } } @@ -1363,6 +1338,7 @@ final class sun_swing_PrintColorUIResource_PersistenceDelegate extends Persisten } class MetaData { + private static final Map fields = Collections.synchronizedMap(new WeakHashMap()); private static Hashtable internalPersistenceDelegates = new Hashtable(); private static PersistenceDelegate nullPersistenceDelegate = new NullPersistenceDelegate(); @@ -1501,4 +1477,35 @@ class MetaData { return null; } } + + static Object getPrivateFieldValue(Object instance, String name) { + Field field = fields.get(name); + if (field == null) { + int index = name.lastIndexOf('.'); + final String className = name.substring(0, index); + final String fieldName = name.substring(1 + index); + field = AccessController.doPrivileged(new PrivilegedAction() { + public Field run() { + try { + Field field = Class.forName(className).getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } + catch (ClassNotFoundException exception) { + throw new IllegalStateException("Could not find class", exception); + } + catch (NoSuchFieldException exception) { + throw new IllegalStateException("Could not find field", exception); + } + } + }); + fields.put(name, field); + } + try { + return field.get(instance); + } + catch (IllegalAccessException exception) { + throw new IllegalStateException("Could not get value of the field", exception); + } + } } diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestBox.java b/jdk/test/java/beans/XMLEncoder/6777487/TestBox.java new file mode 100644 index 00000000000..1287f4414b5 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestBox.java @@ -0,0 +1,52 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for BoxLayout + * @author Sergey Malenkov + */ + +import java.awt.FlowLayout; +import javax.swing.Box; +import javax.swing.BoxLayout; + +public final class TestBox { + private static final Integer OBJECT = Integer.valueOf(-123); + + public static void main(String[] args) { + TestEncoder.test( + new Box(BoxLayout.LINE_AXIS), + new Box(BoxLayout.PAGE_AXIS) { + @Override + public FlowLayout getLayout() { + return new FlowLayout() { + private final Object axis = OBJECT; + }; + } + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java new file mode 100644 index 00000000000..805f05f4299 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedCollection.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedCollection + * @author Sergey Malenkov + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class TestCheckedCollection { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + List list = Collections.emptyList(); + TestEncoder.test( + Collections.checkedCollection(list, String.class), + new ArrayList() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java new file mode 100644 index 00000000000..69d6ca9c8ba --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedList.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedList + * @author Sergey Malenkov + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class TestCheckedList { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + List list = Collections.emptyList(); + TestEncoder.test( + Collections.checkedList(list, String.class), + new ArrayList() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java new file mode 100644 index 00000000000..7105782b179 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedMap.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedMap + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class TestCheckedMap { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + Map map = Collections.emptyMap(); + TestEncoder.test( + Collections.checkedMap(map, String.class, String.class), + new HashMap() { + private final Object keyType = OBJECT; + private final Object valueType = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java new file mode 100644 index 00000000000..5141bc80620 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedRandomAccessList.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedRandomAccessList + * @author Sergey Malenkov + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class TestCheckedRandomAccessList { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + List list = new ArrayList(); + TestEncoder.test( + Collections.checkedList(list, String.class), + new ArrayList() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java new file mode 100644 index 00000000000..d4dd04160b0 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSet.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedSet + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public final class TestCheckedSet { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + Set set = Collections.emptySet(); + TestEncoder.test( + Collections.checkedSet(set, String.class), + new HashSet() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java new file mode 100644 index 00000000000..f39e7e2e060 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedMap.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedSortedMap + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.SortedMap; +import java.util.TreeMap; + +public final class TestCheckedSortedMap { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + SortedMap map = new TreeMap(); + TestEncoder.test( + Collections.checkedSortedMap(map, String.class, String.class), + new TreeMap() { + private final Object keyType = OBJECT; + private final Object valueType = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java new file mode 100644 index 00000000000..f49c6ea3d94 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestCheckedSortedSet.java @@ -0,0 +1,48 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for CheckedSortedSet + * @author Sergey Malenkov + */ + +import java.util.Collections; +import java.util.SortedSet; +import java.util.TreeSet; + +public final class TestCheckedSortedSet { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + SortedSet set = new TreeSet(); + TestEncoder.test( + Collections.checkedSortedSet(set, String.class), + new TreeSet() { + private final Object type = OBJECT; + }, + OBJECT + ); + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java b/jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java new file mode 100644 index 00000000000..a06289c8738 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestEncoder.java @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.beans.Expression; +import java.beans.XMLEncoder; + +final class TestEncoder extends XMLEncoder { + private Expression expression; + + private TestEncoder() { + super(System.out); + } + + @Override + public void writeExpression(Expression expression) { + if (this.expression == null) { + this.expression = expression; + } + super.writeExpression(expression); + } + + public static void test(Object provider, Object object, Object value) { + System.setSecurityManager(new SecurityManager()); + + TestEncoder encoder = new TestEncoder(); + encoder.setPersistenceDelegate( + object.getClass(), + encoder.getPersistenceDelegate(provider.getClass())); + encoder.writeObject(object); + encoder.close(); + + if (encoder.expression != null) { + for (Object argument : encoder.expression.getArguments()) { + if (value.equals(argument)) { + throw new Error("Found private value!"); + } + } + } + } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java new file mode 100644 index 00000000000..1d046c63e88 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumMap.java @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for EnumMap + * @author Sergey Malenkov + */ + +import java.util.EnumMap; +import java.util.HashMap; + +public final class TestEnumMap { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + TestEncoder.test( + new EnumMap(Point.class), + new HashMap() { + private final Object keyType = OBJECT; + }, + OBJECT); + } + + public enum Point { X, Y, Z } +} diff --git a/jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java new file mode 100644 index 00000000000..b9f518d9979 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6777487/TestEnumSet.java @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6777487 + * @summary Tests private field access for EnumSet + * @author Sergey Malenkov + */ + +import java.util.EnumSet; +import java.util.HashSet; + +public final class TestEnumSet { + private static final Object OBJECT = new Object(); + + public static void main(String[] args) { + TestEncoder.test( + EnumSet.noneOf(Point.class), + new HashSet() { + private final Object elementType = OBJECT; + }, + OBJECT); + } + + public enum Point { X, Y, Z } +} From d663bac9312a84730da246fa8fcd8ce080e220fd Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Tue, 5 May 2009 12:07:37 +0400 Subject: [PATCH 003/102] 6837293: Reapply fix for 6588003 to JDK7 Reviewed-by: alexp --- .../classes/javax/swing/text/LayoutQueue.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/text/LayoutQueue.java b/jdk/src/share/classes/javax/swing/text/LayoutQueue.java index 38fd665c40e..f1d73ffc0d8 100644 --- a/jdk/src/share/classes/javax/swing/text/LayoutQueue.java +++ b/jdk/src/share/classes/javax/swing/text/LayoutQueue.java @@ -25,6 +25,7 @@ package javax.swing.text; import java.util.Vector; +import sun.awt.AppContext; /** * A queue of text layout tasks. @@ -35,10 +36,10 @@ import java.util.Vector; */ public class LayoutQueue { - Vector tasks; - Thread worker; + private static final Object DEFAULT_QUEUE = new Object(); - static LayoutQueue defaultQueue; + private Vector tasks; + private Thread worker; /** * Construct a layout queue. @@ -51,10 +52,15 @@ public class LayoutQueue { * Fetch the default layout queue. */ public static LayoutQueue getDefaultQueue() { - if (defaultQueue == null) { - defaultQueue = new LayoutQueue(); + AppContext ac = AppContext.getAppContext(); + synchronized (DEFAULT_QUEUE) { + LayoutQueue defaultQueue = (LayoutQueue) ac.get(DEFAULT_QUEUE); + if (defaultQueue == null) { + defaultQueue = new LayoutQueue(); + ac.put(DEFAULT_QUEUE, defaultQueue); + } + return defaultQueue; } - return defaultQueue; } /** @@ -63,7 +69,9 @@ public class LayoutQueue { * @param q the new queue. */ public static void setDefaultQueue(LayoutQueue q) { - defaultQueue = q; + synchronized (DEFAULT_QUEUE) { + AppContext.getAppContext().put(DEFAULT_QUEUE, q); + } } /** From b23fe07b43057fcb66d2a463e8e8371ce6b2069c Mon Sep 17 00:00:00 2001 From: Jean-Christophe Collet Date: Tue, 5 May 2009 11:02:51 +0200 Subject: [PATCH 004/102] 6801497: Proxy is assumed to be immutable but is non-final Cloned the proxy instance when necessary Reviewed-by: chegar --- jdk/src/share/classes/java/net/Socket.java | 13 +++++++++---- jdk/src/share/classes/java/net/URL.java | 8 +++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index e0769176af3..110a6a5f1a9 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -114,9 +114,14 @@ class Socket implements java.io.Closeable { * @since 1.5 */ public Socket(Proxy proxy) { - if (proxy != null && proxy.type() == Proxy.Type.SOCKS) { + // Create a copy of Proxy as a security measure + if (proxy == null) { + throw new IllegalArgumentException("Invalid Proxy"); + } + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + if (p.type() == Proxy.Type.SOCKS) { SecurityManager security = System.getSecurityManager(); - InetSocketAddress epoint = (InetSocketAddress) proxy.address(); + InetSocketAddress epoint = (InetSocketAddress) p.address(); if (security != null) { if (epoint.isUnresolved()) security.checkConnect(epoint.getHostName(), @@ -125,10 +130,10 @@ class Socket implements java.io.Closeable { security.checkConnect(epoint.getAddress().getHostAddress(), epoint.getPort()); } - impl = new SocksSocketImpl(proxy); + impl = new SocksSocketImpl(p); impl.setSocket(this); } else { - if (proxy == Proxy.NO_PROXY) { + if (p == Proxy.NO_PROXY) { if (factory == null) { impl = new PlainSocketImpl(); impl.setSocket(this); diff --git a/jdk/src/share/classes/java/net/URL.java b/jdk/src/share/classes/java/net/URL.java index bb934d9b745..73818e960d8 100644 --- a/jdk/src/share/classes/java/net/URL.java +++ b/jdk/src/share/classes/java/net/URL.java @@ -1004,16 +1004,18 @@ public final class URL implements java.io.Serializable { throw new IllegalArgumentException("proxy can not be null"); } + // Create a copy of Proxy as a security measure + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); SecurityManager sm = System.getSecurityManager(); - if (proxy.type() != Proxy.Type.DIRECT && sm != null) { - InetSocketAddress epoint = (InetSocketAddress) proxy.address(); + if (p.type() != Proxy.Type.DIRECT && sm != null) { + InetSocketAddress epoint = (InetSocketAddress) p.address(); if (epoint.isUnresolved()) sm.checkConnect(epoint.getHostName(), epoint.getPort()); else sm.checkConnect(epoint.getAddress().getHostAddress(), epoint.getPort()); } - return handler.openConnection(this, proxy); + return handler.openConnection(this, p); } /** From 2453a64fc4954f7a2b13cf20f13583cc542fa0a3 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 5 May 2009 17:47:04 +0400 Subject: [PATCH 005/102] 6805231: Security Warning Icon is missing in Windows 2000 Prof from Jdk build 6u12 The icon becomes layered only when the fading-out effect is being performed. Reviewed-by: art, dcherepanov --- .../windows/native/sun/windows/awt_Window.cpp | 36 ++++++++++++++----- .../windows/native/sun/windows/awt_Window.h | 3 ++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 88bcd8ecc45..3e31a1c8db8 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -524,7 +524,7 @@ void AwtWindow::CreateWarningWindow(JNIEnv *env) RegisterWarningWindowClass(); warningWindow = ::CreateWindowEx( - WS_EX_NOACTIVATE | WS_EX_LAYERED, + WS_EX_NOACTIVATE, GetWarningWindowClassName(), warningString, WS_POPUP, @@ -536,7 +536,7 @@ void AwtWindow::CreateWarningWindow(JNIEnv *env) NULL // lParam ); if (warningWindow == NULL) { - //XXX: actually this is bad... We didn't manage to create the widow. + //XXX: actually this is bad... We didn't manage to create the window. return; } @@ -836,6 +836,19 @@ void AwtWindow::RepaintWarningWindow() ::ReleaseDC(warningWindow, hdc); } +void AwtWindow::SetLayered(HWND window, bool layered) +{ + const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE); + ::SetWindowLong(window, GWL_EXSTYLE, layered ? + ex_style | WS_EX_LAYERED : ex_style & ~WS_EX_LAYERED); +} + +bool AwtWindow::IsLayered(HWND window) +{ + const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE); + return ex_style & WS_EX_LAYERED; +} + void AwtWindow::StartSecurityAnimation(AnimationKind kind) { if (!IsUntrusted()) { @@ -858,8 +871,14 @@ void AwtWindow::StartSecurityAnimation(AnimationKind kind) ::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0), 0xFF, LWA_ALPHA); + AwtWindow::SetLayered(warningWindow, false); ::RedrawWindow(warningWindow, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); + } else if (securityAnimationKind == akPreHide) { + // Pre-hiding means fading-out. We have to make the window layered. + // Note: Some VNC clients do not support layered windows, hence + // we dynamically turn it on and off. See 6805231. + AwtWindow::SetLayered(warningWindow, true); } } @@ -2528,8 +2547,6 @@ void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque) HWND hwnd = GetHWnd(); - LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - if (opaque != old_opaque) { ::EnterCriticalSection(&contentBitmapCS); if (hContentBitmap != NULL) { @@ -2541,21 +2558,22 @@ void AwtWindow::SetTranslucency(BYTE opacity, BOOL opaque) if (opaque && opacity == 0xff) { // Turn off all the effects - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED); + AwtWindow::SetLayered(hwnd, false); + // Ask the window to repaint itself and all the children RedrawWindow(); } else { // We're going to enable some effects - if (!(ex_style & WS_EX_LAYERED)) { - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED); + if (!AwtWindow::IsLayered(hwnd)) { + AwtWindow::SetLayered(hwnd, true); } else { if ((opaque && opacity < 0xff) ^ (old_opaque && old_opacity < 0xff)) { // _One_ of the modes uses the SetLayeredWindowAttributes. // Need to reset the style in this case. // If both modes are simple (i.e. just changing the opacity level), // no need to reset the style. - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style & ~WS_EX_LAYERED); - ::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED); + AwtWindow::SetLayered(hwnd, false); + AwtWindow::SetLayered(hwnd, true); } } diff --git a/jdk/src/windows/native/sun/windows/awt_Window.h b/jdk/src/windows/native/sun/windows/awt_Window.h index bf43150a7e8..40da9979bcd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.h +++ b/jdk/src/windows/native/sun/windows/awt_Window.h @@ -332,6 +332,9 @@ private: void RepositionSecurityWarning(JNIEnv *env); + static void SetLayered(HWND window, bool layered); + static bool IsLayered(HWND window); + public: void UpdateSecurityWarningVisibility(); static bool IsWarningWindow(HWND hWnd); From dfb6852a1624bfa42b89ad993ec832bfab0b5d89 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 5 May 2009 17:56:31 +0400 Subject: [PATCH 006/102] 6818787: It is possible to reposition the security icon too far from the border of the window on X11 The constraints for the position of the icon are moved to the shared code Reviewed-by: art, dcherepanov --- jdk/src/share/classes/java/awt/Window.java | 54 ++++++++++++++++--- .../windows/native/sun/windows/awt_Window.cpp | 25 --------- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 01d9ff59d00..faff2758726 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -3593,16 +3593,56 @@ public class Window extends Container implements Accessible { // ****************** END OF MIXING CODE ******************************** - // This method gets the window location/size as reported by the native - // system since the locally cached values may represent outdated data. - // NOTE: this method is invoked on the toolkit thread, and therefore - // is not supposed to become public/user-overridable. + /** + * Limit the given double value with the given range. + */ + private static double limit(double value, double min, double max) { + value = Math.max(value, min); + value = Math.min(value, max); + return value; + } + + /** + * Calculate the position of the security warning. + * + * This method gets the window location/size as reported by the native + * system since the locally cached values may represent outdated data. + * + * The method is used from the native code, or via AWTAccessor. + * + * NOTE: this method is invoked on the toolkit thread, and therefore is not + * supposed to become public/user-overridable. + */ private Point2D calculateSecurityWarningPosition(double x, double y, double w, double h) { - return new Point2D.Double( - x + w * securityWarningAlignmentX + securityWarningPointX, - y + h * securityWarningAlignmentY + securityWarningPointY); + // The position according to the spec of SecurityWarning.setPosition() + double wx = x + w * securityWarningAlignmentX + securityWarningPointX; + double wy = y + h * securityWarningAlignmentY + securityWarningPointY; + + // First, make sure the warning is not too far from the window bounds + wx = Window.limit(wx, + x - securityWarningWidth - 2, + x + w + 2); + wy = Window.limit(wy, + y - securityWarningHeight - 2, + y + h + 2); + + // Now make sure the warning window is visible on the screen + Rectangle screenBounds = graphicsConfig.getBounds(); + Insets screenInsets = + Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfig); + + wx = Window.limit(wx, + screenBounds.x + screenInsets.left, + screenBounds.x + screenBounds.width - screenInsets.right + - securityWarningWidth); + wy = Window.limit(wy, + screenBounds.y + screenInsets.top, + screenBounds.y + screenBounds.height - screenInsets.bottom + - securityWarningHeight); + + return new Point2D.Double(wx, wy); } static { diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 3e31a1c8db8..39f61bb7543 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -707,31 +707,6 @@ void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect) env->DeleteLocalRef(point2D); - //Make sure the warning is not far from the window bounds - x = max(x, windowBounds.left - (int)warningWindowWidth - 2); - x = min(x, windowBounds.right + (int)warningWindowWidth + 2); - - y = max(y, windowBounds.top - (int)warningWindowHeight - 2); - y = min(y, windowBounds.bottom + (int)warningWindowHeight + 2); - - // Now make sure the warning window is visible on the screen - HMONITOR hmon = MonitorFromWindow(GetHWnd(), MONITOR_DEFAULTTOPRIMARY); - DASSERT(hmon != NULL); - - RECT monitorBounds; - RECT monitorInsets; - - MonitorBounds(hmon, &monitorBounds); - if (!AwtToolkit::GetScreenInsets(m_screenNum, &monitorInsets)) { - ::ZeroMemory(&monitorInsets, sizeof(monitorInsets)); - } - - x = max(x, monitorBounds.left + monitorInsets.left); - x = min(x, monitorBounds.right - monitorInsets.right - (int)warningWindowWidth); - - y = max(y, monitorBounds.top + monitorInsets.top); - y = min(y, monitorBounds.bottom - monitorInsets.bottom - (int)warningWindowHeight); - rect->left = x; rect->top = y; rect->right = rect->left + warningWindowWidth; From f6e8569c858067188a8d84e91d91dafa4aaa0a71 Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Wed, 6 May 2009 15:17:22 +0400 Subject: [PATCH 007/102] 6656586: Cursor.predefined is protected static mutable (findbugs) Reviewed-by: hawtin, igor --- jdk/src/share/classes/java/awt/Cursor.java | 21 ++++++-- .../PredefinedPrivate/PredefinedPrivate.java | 49 +++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java diff --git a/jdk/src/share/classes/java/awt/Cursor.java b/jdk/src/share/classes/java/awt/Cursor.java index cc1b20b999a..0187eac69b9 100644 --- a/jdk/src/share/classes/java/awt/Cursor.java +++ b/jdk/src/share/classes/java/awt/Cursor.java @@ -118,8 +118,18 @@ public class Cursor implements java.io.Serializable { */ public static final int MOVE_CURSOR = 13; + /** + * @deprecated As of JDK version 1.7, the {@link #getPredefinedCursor()} + * method should be used instead. + */ + @Deprecated protected static Cursor predefined[] = new Cursor[14]; + /** + * This field is a private replacement for 'predefined' array. + */ + private final static Cursor[] predefinedPrivate = new Cursor[14]; + /* Localization names and default values */ static final String[][] cursorProperties = { { "AWT.DefaultCursor", "Default Cursor" }, @@ -253,10 +263,15 @@ public class Cursor implements java.io.Serializable { if (type < Cursor.DEFAULT_CURSOR || type > Cursor.MOVE_CURSOR) { throw new IllegalArgumentException("illegal cursor type"); } - if (predefined[type] == null) { - predefined[type] = new Cursor(type); + Cursor c = predefinedPrivate[type]; + if (c == null) { + predefinedPrivate[type] = c = new Cursor(type); } - return predefined[type]; + // fill 'predefined' array for backwards compatibility. + if (predefined[type] == null) { + predefined[type] = c; + } + return c; } /** diff --git a/jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java b/jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java new file mode 100644 index 00000000000..a4ba1daaca4 --- /dev/null +++ b/jdk/test/java/awt/Cursor/PredefinedPrivate/PredefinedPrivate.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6656586 + * @summary Test that Cursor.predefined array is not used in +Cursor.getPredefinedCursor() method + * @author Artem Ananiev + * @run main PredefinedPrivate + */ + +import java.awt.*; + +public class PredefinedPrivate { + public static void main(String args[]) { + new MyCursor(); + if (Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR) instanceof MyCursor) { + throw new RuntimeException("Test FAILED: getPredefinedCursor() returned modified cursor"); + } + } +} + +class MyCursor extends Cursor { + public MyCursor() { + super(DEFAULT_CURSOR); + Cursor.predefined[DEFAULT_CURSOR] = this; + } +} From ec41d4d0e931bf22dbfbcda44d506c9a44a3091d Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Thu, 7 May 2009 10:44:45 +0200 Subject: [PATCH 008/102] 6736293: OpenType checks can be bypassed through finalizer resurrection Reviewed-by: hawtin --- jdk/src/share/classes/java/awt/Window.java | 2 ++ .../openmbean/OpenMBeanAttributeInfoSupport.java | 8 ++++---- .../classes/javax/management/openmbean/OpenType.java | 5 +++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index faff2758726..920b499c9a3 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -3629,6 +3629,8 @@ public class Window extends Container implements Accessible { y + h + 2); // Now make sure the warning window is visible on the screen + GraphicsConfiguration graphicsConfig = + getGraphicsConfiguration_NoClientCode(); Rectangle screenBounds = graphicsConfig.getBounds(); Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfig); diff --git a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java index 3ad03ef58ae..f2f86e1bf72 100644 --- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java +++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java @@ -690,7 +690,7 @@ public class OpenMBeanAttributeInfoSupport private static T convertFromString(String s, OpenType openType) { Class c; try { - c = cast(Class.forName(openType.getClassName())); + c = cast(Class.forName(openType.safeGetClassName())); } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.toString()); // can't happen } @@ -711,7 +711,7 @@ public class OpenMBeanAttributeInfoSupport } catch (Exception e) { final String msg = "Could not convert \"" + s + "\" using method: " + valueOf; - throw new IllegalArgumentException(msg); + throw new IllegalArgumentException(msg, e); } } @@ -728,7 +728,7 @@ public class OpenMBeanAttributeInfoSupport } catch (Exception e) { final String msg = "Could not convert \"" + s + "\" using constructor: " + con; - throw new IllegalArgumentException(msg); + throw new IllegalArgumentException(msg, e); } } @@ -757,7 +757,7 @@ public class OpenMBeanAttributeInfoSupport stringArrayClass = Class.forName(squareBrackets + "Ljava.lang.String;"); targetArrayClass = - Class.forName(squareBrackets + "L" + baseType.getClassName() + + Class.forName(squareBrackets + "L" + baseType.safeGetClassName() + ";"); } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.toString()); // can't happen diff --git a/jdk/src/share/classes/javax/management/openmbean/OpenType.java b/jdk/src/share/classes/javax/management/openmbean/OpenType.java index 3f74c3cda60..b6d40d008c7 100644 --- a/jdk/src/share/classes/javax/management/openmbean/OpenType.java +++ b/jdk/src/share/classes/javax/management/openmbean/OpenType.java @@ -304,7 +304,12 @@ public abstract class OpenType implements Serializable { * @return the class name. */ public String getClassName() { + return className; + } + // A version of getClassName() that can only be called from within this + // package and that cannot be overridden. + String safeGetClassName() { return className; } From 10f62128a45fa6384621e57b86cc18475ee7fa27 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 8 May 2009 15:38:21 +0400 Subject: [PATCH 009/102] 6656625: ImageReaderSpi.STANDARD_INPUT_TYPE/ImageWriterSpi.STANDARD_OUTPUT_TYPE are mutable static (findbugs) Reviewed-by: prr --- .../sun/imageio/plugins/bmp/BMPImageReaderSpi.java | 2 +- .../sun/imageio/plugins/bmp/BMPImageWriterSpi.java | 3 ++- .../sun/imageio/plugins/gif/GIFImageReaderSpi.java | 2 +- .../sun/imageio/plugins/gif/GIFImageWriterSpi.java | 3 ++- .../imageio/plugins/jpeg/JPEGImageReaderSpi.java | 2 +- .../imageio/plugins/jpeg/JPEGImageWriterSpi.java | 3 ++- .../sun/imageio/plugins/png/PNGImageReaderSpi.java | 2 +- .../sun/imageio/plugins/png/PNGImageWriterSpi.java | 3 ++- .../imageio/plugins/wbmp/WBMPImageReaderSpi.java | 2 +- .../imageio/plugins/wbmp/WBMPImageWriterSpi.java | 3 ++- .../classes/javax/imageio/spi/ImageReaderSpi.java | 9 ++++++++- .../classes/javax/imageio/spi/ImageWriterSpi.java | 13 ++++++++++--- 12 files changed, 33 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java index 9cea55911f7..2966a4b883c 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageReaderSpi.java @@ -51,7 +51,7 @@ public class BMPImageReaderSpi extends ImageReaderSpi { entensions, mimeType, "com.sun.imageio.plugins.bmp.BMPImageReader", - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, false, null, null, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java index f5e322e01da..4ae73d4c897 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriterSpi.java @@ -32,6 +32,7 @@ import java.awt.image.SinglePixelPackedSampleModel; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageOutputStream; import javax.imageio.ImageWriter; import javax.imageio.ImageTypeSpecifier; import javax.imageio.IIOException; @@ -55,7 +56,7 @@ public class BMPImageWriterSpi extends ImageWriterSpi { entensions, mimeType, "com.sun.imageio.plugins.bmp.BMPImageWriter", - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, false, null, null, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java index 0dc0a40a6d7..3832b1eb923 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReaderSpi.java @@ -60,7 +60,7 @@ public class GIFImageReaderSpi extends ImageReaderSpi { suffixes, MIMETypes, readerClassName, - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, true, GIFStreamMetadata.nativeMetadataFormatName, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java index 796e3b2a458..42b81e4c8b8 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageWriterSpi.java @@ -31,6 +31,7 @@ import java.util.Locale; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriter; import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; import com.sun.imageio.plugins.common.PaletteBuilder; public class GIFImageWriterSpi extends ImageWriterSpi { @@ -59,7 +60,7 @@ public class GIFImageWriterSpi extends ImageWriterSpi { suffixes, MIMETypes, writerClassName, - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, true, GIFWritableStreamMetadata.NATIVE_FORMAT_NAME, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java index 13327e3ea9c..25aabe32e90 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java @@ -46,7 +46,7 @@ public class JPEGImageReaderSpi extends ImageReaderSpi { JPEG.suffixes, JPEG.MIMETypes, "com.sun.imageio.plugins.jpeg.JPEGImageReader", - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, true, JPEG.nativeStreamMetadataFormatName, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java index 717b4360794..02fade632ed 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java @@ -28,6 +28,7 @@ package com.sun.imageio.plugins.jpeg; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageOutputStream; import javax.imageio.ImageWriter; import javax.imageio.ImageTypeSpecifier; import javax.imageio.IIOException; @@ -49,7 +50,7 @@ public class JPEGImageWriterSpi extends ImageWriterSpi { JPEG.suffixes, JPEG.MIMETypes, "com.sun.imageio.plugins.jpeg.JPEGImageWriter", - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, true, JPEG.nativeStreamMetadataFormatName, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java index 44ee5b80101..6576b83df58 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageReaderSpi.java @@ -60,7 +60,7 @@ public class PNGImageReaderSpi extends ImageReaderSpi { suffixes, MIMETypes, readerClassName, - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, false, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java index 0dabd881816..4f69fcd70de 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGImageWriterSpi.java @@ -34,6 +34,7 @@ import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOMetadataFormat; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.stream.ImageOutputStream; public class PNGImageWriterSpi extends ImageWriterSpi { @@ -61,7 +62,7 @@ public class PNGImageWriterSpi extends ImageWriterSpi { suffixes, MIMETypes, writerClassName, - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, false, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java index 2d882ab6b2c..7e5e6e61e0e 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java @@ -51,7 +51,7 @@ public class WBMPImageReaderSpi extends ImageReaderSpi { entensions, mimeType, "com.sun.imageio.plugins.wbmp.WBMPImageReader", - STANDARD_INPUT_TYPE, + new Class[] { ImageInputStream.class }, writerSpiNames, true, null, null, null, null, diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java index 1da8420dc32..82106f981f5 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageWriterSpi.java @@ -28,6 +28,7 @@ package com.sun.imageio.plugins.wbmp; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.spi.ServiceRegistry; import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageOutputStream; import javax.imageio.ImageWriter; import javax.imageio.ImageTypeSpecifier; import javax.imageio.IIOException; @@ -54,7 +55,7 @@ public class WBMPImageWriterSpi extends ImageWriterSpi { entensions, mimeType, "com.sun.imageio.plugins.wbmp.WBMPImageWriter", - STANDARD_OUTPUT_TYPE, + new Class[] { ImageOutputStream.class }, readerSpiNames, true, null, null, null, null, diff --git a/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java b/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java index 4f0b7fa6ac5..0de66188ba8 100644 --- a/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java +++ b/jdk/src/share/classes/javax/imageio/spi/ImageReaderSpi.java @@ -77,7 +77,10 @@ public abstract class ImageReaderSpi extends ImageReaderWriterSpi { * A single-element array, initially containing * ImageInputStream.class, to be returned from * getInputTypes. + * @deprecated Instead of using this field, directly create + * the equivalent array { ImageInputStream.class }. */ + @Deprecated public static final Class[] STANDARD_INPUT_TYPE = { ImageInputStream.class }; @@ -227,7 +230,11 @@ public abstract class ImageReaderSpi extends ImageReaderWriterSpi { throw new IllegalArgumentException ("inputTypes.length == 0!"); } - this.inputTypes = (Class[])inputTypes.clone(); + + this.inputTypes = (inputTypes == STANDARD_INPUT_TYPE) ? + new Class[] { ImageInputStream.class } : + inputTypes.clone(); + // If length == 0, leave it null if (writerSpiNames != null && writerSpiNames.length > 0) { this.writerSpiNames = (String[])writerSpiNames.clone(); diff --git a/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java b/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java index 324c5cd3d05..f3ff947a4f4 100644 --- a/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java +++ b/jdk/src/share/classes/javax/imageio/spi/ImageWriterSpi.java @@ -77,9 +77,12 @@ public abstract class ImageWriterSpi extends ImageReaderWriterSpi { /** * A single-element array, initially containing - * ImageInputStream.class, to be returned from - * getInputTypes. + * ImageOutputStream.class, to be returned from + * getOutputTypes. + * @deprecated Instead of using this field, directly create + * the equivalent array { ImageOutputStream.class }. */ + @Deprecated public static final Class[] STANDARD_OUTPUT_TYPE = { ImageOutputStream.class }; @@ -228,7 +231,11 @@ public abstract class ImageWriterSpi extends ImageReaderWriterSpi { throw new IllegalArgumentException ("outputTypes.length == 0!"); } - this.outputTypes = (Class[])outputTypes.clone(); + + this.outputTypes = (outputTypes == STANDARD_OUTPUT_TYPE) ? + new Class[] { ImageOutputStream.class } : + outputTypes.clone(); + // If length == 0, leave it null if (readerSpiNames != null && readerSpiNames.length > 0) { this.readerSpiNames = (String[])readerSpiNames.clone(); From 8fdb1d367a6988246045d77dba7ce3e9b4eab893 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 8 May 2009 15:57:33 +0400 Subject: [PATCH 010/102] 6657133: Mutable statics in imageio plugins (findbugs) Reviewed-by: prr --- .../com/sun/imageio/stream/StreamCloser.java | 44 +++++++++++++------ .../plugins/bmp/BMPImageWriteParam.java | 2 +- .../stream/FileCacheImageInputStream.java | 10 ++++- .../stream/FileCacheImageOutputStream.java | 10 ++++- jdk/src/share/lib/security/java.security | 2 +- .../share/lib/security/java.security-solaris | 2 +- .../share/lib/security/java.security-windows | 2 +- 7 files changed, 51 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java b/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java index 03c6ce32364..96e5646f782 100644 --- a/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java +++ b/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java @@ -43,35 +43,35 @@ import javax.imageio.stream.ImageInputStream; */ public class StreamCloser { - private static WeakHashMap toCloseQueue; + private static WeakHashMap toCloseQueue; private static Thread streamCloser; - public static void addToQueue(ImageInputStream iis) { + public static void addToQueue(CloseAction ca) { synchronized (StreamCloser.class) { if (toCloseQueue == null) { toCloseQueue = - new WeakHashMap(); + new WeakHashMap(); } - toCloseQueue.put(iis, null); + toCloseQueue.put(ca, null); if (streamCloser == null) { final Runnable streamCloserRunnable = new Runnable() { public void run() { if (toCloseQueue != null) { synchronized (StreamCloser.class) { - Set set = + Set set = toCloseQueue.keySet(); // Make a copy of the set in order to avoid // concurrent modification (the is.close() // will in turn call removeFromQueue()) - ImageInputStream[] streams = - new ImageInputStream[set.size()]; - streams = set.toArray(streams); - for (ImageInputStream is : streams) { - if (is != null) { + CloseAction[] actions = + new CloseAction[set.size()]; + actions = set.toArray(actions); + for (CloseAction ca : actions) { + if (ca != null) { try { - is.close(); + ca.performAction(); } catch (IOException e) { } } @@ -106,10 +106,28 @@ public class StreamCloser { } } - public static void removeFromQueue(ImageInputStream iis) { + public static void removeFromQueue(CloseAction ca) { synchronized (StreamCloser.class) { if (toCloseQueue != null) { - toCloseQueue.remove(iis); + toCloseQueue.remove(ca); + } + } + } + + public static CloseAction createCloseAction(ImageInputStream iis) { + return new CloseAction(iis); + } + + public static final class CloseAction { + private ImageInputStream iis; + + private CloseAction(ImageInputStream iis) { + this.iis = iis; + } + + public void performAction() throws IOException { + if (iis != null) { + iis.close(); } } } diff --git a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java index ec3acf2e9db..e11057f2a48 100644 --- a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java +++ b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java @@ -78,7 +78,7 @@ public class BMPImageWriteParam extends ImageWriteParam { super(locale); // Set compression types ("BI_RGB" denotes uncompressed). - compressionTypes = BMPConstants.compressionTypeNames; + compressionTypes = BMPConstants.compressionTypeNames.clone(); // Set compression flag. canWriteCompressed = true; diff --git a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java index ad03d65c04d..1bff7746344 100644 --- a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java +++ b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java @@ -62,6 +62,10 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { /** The DisposerRecord that closes the underlying cache. */ private final DisposerRecord disposerRecord; + /** The CloseAction that closes the stream in + * the StreamCloser's shutdown hook */ + private final StreamCloser.CloseAction closeAction; + /** * Constructs a FileCacheImageInputStream that will read * from a given InputStream. @@ -96,7 +100,9 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { this.cacheFile = File.createTempFile("imageio", ".tmp", cacheDir); this.cache = new RandomAccessFile(cacheFile, "rw"); - StreamCloser.addToQueue(this); + + this.closeAction = StreamCloser.createCloseAction(this); + StreamCloser.addToQueue(closeAction); disposerRecord = new StreamDisposerRecord(cacheFile, cache); if (getClass() == FileCacheImageInputStream.class) { @@ -242,7 +248,7 @@ public class FileCacheImageInputStream extends ImageInputStreamImpl { stream = null; cache = null; cacheFile = null; - StreamCloser.removeFromQueue(this); + StreamCloser.removeFromQueue(closeAction); } /** diff --git a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java index f6387125499..f079e8e81fa 100644 --- a/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java +++ b/jdk/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java @@ -48,6 +48,10 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { // Pos after last (rightmost) byte written private long maxStreamPos = 0L; + /** The CloseAction that closes the stream in + * the StreamCloser's shutdown hook */ + private final StreamCloser.CloseAction closeAction; + /** * Constructs a FileCacheImageOutputStream that will write * to a given outputStream. @@ -82,7 +86,9 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { this.cacheFile = File.createTempFile("imageio", ".tmp", cacheDir); this.cache = new RandomAccessFile(cacheFile, "rw"); - StreamCloser.addToQueue(this); + + this.closeAction = StreamCloser.createCloseAction(this); + StreamCloser.addToQueue(closeAction); } public int read() throws IOException { @@ -227,7 +233,7 @@ public class FileCacheImageOutputStream extends ImageOutputStreamImpl { cacheFile = null; stream.flush(); stream = null; - StreamCloser.removeFromQueue(this); + StreamCloser.removeFromQueue(closeAction); } public void flushBefore(long pos) throws IOException { diff --git a/jdk/src/share/lib/security/java.security b/jdk/src/share/lib/security/java.security index eadfe715b51..c2a07506c15 100644 --- a/jdk/src/share/lib/security/java.security +++ b/jdk/src/share/lib/security/java.security @@ -127,7 +127,7 @@ system.scope=sun.security.provider.IdentityDatabase # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun. +package.access=sun.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris index 58fbc9d15cd..05dfcb17728 100644 --- a/jdk/src/share/lib/security/java.security-solaris +++ b/jdk/src/share/lib/security/java.security-solaris @@ -128,7 +128,7 @@ system.scope=sun.security.provider.IdentityDatabase # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun. +package.access=sun.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows index 25de17d5247..062b85b63c3 100644 --- a/jdk/src/share/lib/security/java.security-windows +++ b/jdk/src/share/lib/security/java.security-windows @@ -128,7 +128,7 @@ system.scope=sun.security.provider.IdentityDatabase # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun. +package.access=sun.,com.sun.imageio. # # List of comma-separated packages that start with or equal this string From 813ad65e9a7847816c206e194c4b8d297ed3ca17 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Fri, 8 May 2009 16:15:15 +0400 Subject: [PATCH 011/102] 6823373: [ZDI-CAN-460] Java Web Start JPEG header parsing needs more scruity Reviewed-by: igor --- .../sun/awt/splashscreen/splashscreen_jpeg.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c index 09d38fcb422..5d250e9e4b3 100644 --- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c +++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c @@ -139,21 +139,45 @@ SplashDecodeJpeg(Splash * splash, struct jpeg_decompress_struct *cinfo) splash->width = cinfo->output_width; splash->height = cinfo->output_height; + + if (!SAFE_TO_ALLOC(splash->imageFormat.depthBytes, splash->width)) { + return 0; + } stride = splash->width * splash->imageFormat.depthBytes; + if (!SAFE_TO_ALLOC(stride, splash->height)) { + return 0; + } + if (!SAFE_TO_ALLOC(cinfo->output_width, cinfo->output_components)) { + return 0; + } + splash->frameCount = 1; splash->frames = (SplashImage *) malloc(sizeof(SplashImage) * splash->frameCount); + if (splash->frames == NULL) { + return 0; + } memset(splash->frames, 0, sizeof(SplashImage) * splash->frameCount); + splash->loopCount = 1; - splash->frames[0].bitmapBits = malloc(stride * splash->height); splash->frames[0].delay = 0; + splash->frames[0].bitmapBits = malloc(stride * splash->height); + if (splash->frames[0].bitmapBits == NULL) { + free(splash->frames); + return 0; + } rowStride = cinfo->output_width * cinfo->output_components; buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, rowStride, 1); + if (buffer == NULL) { + free(splash->frames[0].bitmapBits); + free(splash->frames); + return 0; + } initFormat(&srcFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000); srcFormat.byteOrder = BYTE_ORDER_LSBFIRST; From ce7e28f3e6e44f6558968cb731d6fb5a90f29d9d Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 12 May 2009 16:32:34 +0100 Subject: [PATCH 012/102] 6801071: Remote sites can compromise user privacy and possibly hijack web sessions Reviewed-by: jccollet, hawtin --- jdk/make/sun/net/FILES_java.gmk | 1 + jdk/src/share/classes/java/net/Socket.java | 2 +- .../classes/java/net/SocksSocketImpl.java | 25 ++++++++--- jdk/src/share/classes/java/net/URL.java | 2 +- .../classes/sun/net/ApplicationProxy.java | 43 +++++++++++++++++++ .../www/protocol/http/HttpURLConnection.java | 18 +++++--- 6 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 jdk/src/share/classes/sun/net/ApplicationProxy.java diff --git a/jdk/make/sun/net/FILES_java.gmk b/jdk/make/sun/net/FILES_java.gmk index 1ab771a37f1..00b6223b8da 100644 --- a/jdk/make/sun/net/FILES_java.gmk +++ b/jdk/make/sun/net/FILES_java.gmk @@ -24,6 +24,7 @@ # FILES_java = \ + sun/net/ApplicationProxy.java \ sun/net/InetAddressCachePolicy.java \ sun/net/URLCanonicalizer.java \ sun/net/NetworkClient.java \ diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index 110a6a5f1a9..39dfebd4180 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -118,7 +118,7 @@ class Socket implements java.io.Closeable { if (proxy == null) { throw new IllegalArgumentException("Invalid Proxy"); } - Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); if (p.type() == Proxy.Type.SOCKS) { SecurityManager security = System.getSecurityManager(); InetSocketAddress epoint = (InetSocketAddress) p.address(); diff --git a/jdk/src/share/classes/java/net/SocksSocketImpl.java b/jdk/src/share/classes/java/net/SocksSocketImpl.java index e73b6c9467e..4561b6e1e56 100644 --- a/jdk/src/share/classes/java/net/SocksSocketImpl.java +++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java @@ -47,6 +47,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { private Socket cmdsock = null; private InputStream cmdIn = null; private OutputStream cmdOut = null; + /* true if the Proxy has been set programatically */ + private boolean applicationSetProxy; /* false */ + SocksSocketImpl() { // Nothing needed @@ -64,6 +67,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // Use getHostString() to avoid reverse lookups server = ad.getHostString(); port = ad.getPort(); + applicationSetProxy = true; } } @@ -165,8 +169,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { throw (IOException) pae.getException(); } } else { - userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + userName = getUserName(); } } if (userName == null) @@ -267,8 +270,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { out.write((endpoint.getPort() >> 8) & 0xff); out.write((endpoint.getPort() >> 0) & 0xff); out.write(endpoint.getAddress().getAddress()); - String userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + String userName = getUserName(); try { out.write(userName.getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { @@ -588,8 +590,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { out.write((super.getLocalPort() >> 8) & 0xff); out.write((super.getLocalPort() >> 0) & 0xff); out.write(addr1); - String userName = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("user.name")); + String userName = getUserName(); try { out.write(userName.getBytes("ISO-8859-1")); } catch (java.io.UnsupportedEncodingException uee) { @@ -1052,4 +1053,16 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { super.close(); } + private String getUserName() { + String userName = ""; + if (applicationSetProxy) { + try { + userName = System.getProperty("user.name"); + } catch (SecurityException se) { /* swallow Exception */ } + } else { + userName = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("user.name")); + } + return userName; + } } diff --git a/jdk/src/share/classes/java/net/URL.java b/jdk/src/share/classes/java/net/URL.java index 73818e960d8..33cfe039654 100644 --- a/jdk/src/share/classes/java/net/URL.java +++ b/jdk/src/share/classes/java/net/URL.java @@ -1005,7 +1005,7 @@ public final class URL implements java.io.Serializable { } // Create a copy of Proxy as a security measure - Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : new Proxy(proxy.type(), proxy.address()); + Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); SecurityManager sm = System.getSecurityManager(); if (p.type() != Proxy.Type.DIRECT && sm != null) { InetSocketAddress epoint = (InetSocketAddress) p.address(); diff --git a/jdk/src/share/classes/sun/net/ApplicationProxy.java b/jdk/src/share/classes/sun/net/ApplicationProxy.java new file mode 100644 index 00000000000..2c84e3649e3 --- /dev/null +++ b/jdk/src/share/classes/sun/net/ApplicationProxy.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.net; + +import java.net.Proxy; +import java.net.SocketAddress; + +/** + * Proxy wrapper class so that we can determine application set + * proxies by type. + */ +public final class ApplicationProxy extends Proxy { + private ApplicationProxy(Proxy proxy) { + super(proxy.type(), proxy.address()); + } + + public static ApplicationProxy create(Proxy proxy) { + return new ApplicationProxy(proxy); + } +} diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 6f3250b30eb..9f5d7303abc 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -575,12 +575,20 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses = new MessageHeader(); this.handler = handler; instProxy = p; - cookieHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + if (instProxy instanceof sun.net.ApplicationProxy) { + /* Application set Proxies should not have access to cookies + * in a secure environment unless explicitly allowed. */ + try { + cookieHandler = CookieHandler.getDefault(); + } catch (SecurityException se) { /* swallow exception */ } + } else { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public CookieHandler run() { - return CookieHandler.getDefault(); - } - }); + return CookieHandler.getDefault(); + } + }); + } cacheHandler = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public ResponseCache run() { From 28848d3300bdbb324ab81bdf4b4d9d14d349ed1a Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 13 May 2009 13:52:52 +0400 Subject: [PATCH 013/102] 6657625: RmfFileReader/StandardMidiFileWriter.types are public mutable statics (findbugs) Reviewed-by: hawtin --- .../classes/com/sun/media/sound/StandardMidiFileWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java b/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java index 533104fa707..fce29478ada 100644 --- a/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java +++ b/jdk/src/share/classes/com/sun/media/sound/StandardMidiFileWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ public class StandardMidiFileWriter extends MidiFileWriter { /** * MIDI parser types */ - public static final int types[] = { + private static final int types[] = { MIDI_TYPE_0, MIDI_TYPE_1 }; From 00b701fedae519097ea4f8c3b1f5f95c6d2cd117 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 13 May 2009 14:32:14 +0400 Subject: [PATCH 014/102] 6738524: JDK13Services allows read access to system properties from untrusted code Reviewed-by: hawtin --- .../com/sun/media/sound/JDK13Services.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java index 2b588ceef8d..fd477285770 100644 --- a/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java +++ b/jdk/src/share/classes/com/sun/media/sound/JDK13Services.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,15 @@ import javax.sound.midi.spi.MidiFileWriter; import javax.sound.midi.spi.SoundbankReader; import javax.sound.midi.spi.MidiDeviceProvider; +import javax.sound.midi.Receiver; +import javax.sound.midi.Sequencer; +import javax.sound.midi.Synthesizer; +import javax.sound.midi.Transmitter; +import javax.sound.sampled.Clip; +import javax.sound.sampled.Port; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + /** * JDK13Services uses the Service class in JDK 1.3 @@ -186,6 +195,16 @@ public class JDK13Services { If the property is not set, null is returned. */ private static synchronized String getDefaultProvider(Class typeClass) { + if (!SourceDataLine.class.equals(typeClass) + && !TargetDataLine.class.equals(typeClass) + && !Clip.class.equals(typeClass) + && !Port.class.equals(typeClass) + && !Receiver.class.equals(typeClass) + && !Transmitter.class.equals(typeClass) + && !Synthesizer.class.equals(typeClass) + && !Sequencer.class.equals(typeClass)) { + return null; + } String value; String propertyName = typeClass.getName(); value = JSSecurityManager.getProperty(propertyName); From 272f5e12f9e369834173681913c17b7e5c23a3c3 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 13 May 2009 14:32:33 +0400 Subject: [PATCH 015/102] 6777448: JDK13Services.getProviders creates instances with full privileges [hawtin, alexp] Reviewed-by: hawtin, alexp --- .../sun/media/sound/JSSecurityManager.java | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java b/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java index 253d22c1e93..064e5c4ba04 100644 --- a/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -283,28 +283,37 @@ class JSSecurityManager { static List getProviders(final Class providerClass) { - PrivilegedAction action = new PrivilegedAction() { - public Object run() { - List p = new ArrayList(); - Iterator ps = Service.providers(providerClass); - while (ps.hasNext()) { - try { - Object provider = ps.next(); - if (providerClass.isInstance(provider)) { - // $$mp 2003-08-22 - // Always adding at the beginning reverses the - // order of the providers. So we no longer have - // to do this in AudioSystem and MidiSystem. - p.add(0, provider); - } - } catch (Throwable t) { - //$$fb 2002-11-07: do not fail on SPI not found - if (Printer.err) t.printStackTrace(); - } } - return p; + List p = new ArrayList(); + // Service.providers(Class) just creates "lazy" iterator instance, + // so it doesn't require do be called from privileged section + final Iterator ps = Service.providers(providerClass); + + // the iterator's hasNext() method looks through classpath for + // the provider class names, so it requires read permissions + PrivilegedAction hasNextAction = new PrivilegedAction() { + public Boolean run() { + return ps.hasNext(); + } + }; + + while (AccessController.doPrivileged(hasNextAction)) { + try { + // the iterator's next() method creates instances of the + // providers and it should be called in the current security + // context + Object provider = ps.next(); + if (providerClass.isInstance(provider)) { + // $$mp 2003-08-22 + // Always adding at the beginning reverses the + // order of the providers. So we no longer have + // to do this in AudioSystem and MidiSystem. + p.add(0, provider); } - }; - List providers = (List) AccessController.doPrivileged(action); - return providers; + } catch (Throwable t) { + //$$fb 2002-11-07: do not fail on SPI not found + if (Printer.err) t.printStackTrace(); + } + } + return p; } } From 0681d1454c1758bbb76ba3073b2f4116a66109da Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 18 Jun 2009 14:08:07 +0400 Subject: [PATCH 016/102] 6660049: Synth Region.uiToRegionMap/lowerCaseNameMap are mutable statics Reviewed-by: hawtin --- .../javax/swing/plaf/synth/Region.java | 288 ++++++++++-------- .../javax/swing/plaf/synth/Test6660049.java | 123 ++++++++ 2 files changed, 287 insertions(+), 124 deletions(-) create mode 100644 jdk/test/javax/swing/plaf/synth/Test6660049.java diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/Region.java b/jdk/src/share/classes/javax/swing/plaf/synth/Region.java index c7de782ba59..1ecd999896d 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/Region.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/Region.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved. * 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,8 +24,13 @@ */ package javax.swing.plaf.synth; -import javax.swing.*; -import java.util.*; +import sun.awt.AppContext; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import javax.swing.JComponent; +import javax.swing.UIDefaults; /** * A distinct rendering area of a Swing component. A component may @@ -67,8 +72,8 @@ import java.util.*; * @author Scott Violet */ public class Region { - private static final Map uiToRegionMap = new HashMap(); - private static final Map lowerCaseNameMap = new HashMap(); + private static final Object UI_TO_REGION_MAP_KEY = new Object(); + private static final Object LOWER_CASE_NAME_MAP_KEY = new Object(); /** * ArrowButton's are special types of buttons that also render a @@ -77,396 +82,433 @@ public class Region { * To bind a style to this Region use the name * ArrowButton. */ - public static final Region ARROW_BUTTON = new Region("ArrowButton", - "ArrowButtonUI"); + public static final Region ARROW_BUTTON = new Region("ArrowButton", false); /** * Button region. To bind a style to this Region use the name * Button. */ - public static final Region BUTTON = new Region("Button", - "ButtonUI"); + public static final Region BUTTON = new Region("Button", false); /** * CheckBox region. To bind a style to this Region use the name * CheckBox. */ - public static final Region CHECK_BOX = new Region("CheckBox", - "CheckBoxUI"); + public static final Region CHECK_BOX = new Region("CheckBox", false); /** * CheckBoxMenuItem region. To bind a style to this Region use * the name CheckBoxMenuItem. */ - public static final Region CHECK_BOX_MENU_ITEM = new Region( - "CheckBoxMenuItem", "CheckBoxMenuItemUI"); + public static final Region CHECK_BOX_MENU_ITEM = new Region("CheckBoxMenuItem", false); /** * ColorChooser region. To bind a style to this Region use * the name ColorChooser. */ - public static final Region COLOR_CHOOSER = new Region( - "ColorChooser", "ColorChooserUI"); + public static final Region COLOR_CHOOSER = new Region("ColorChooser", false); /** * ComboBox region. To bind a style to this Region use * the name ComboBox. */ - public static final Region COMBO_BOX = new Region( - "ComboBox", "ComboBoxUI"); + public static final Region COMBO_BOX = new Region("ComboBox", false); /** * DesktopPane region. To bind a style to this Region use * the name DesktopPane. */ - public static final Region DESKTOP_PANE = new Region("DesktopPane", - "DesktopPaneUI"); + public static final Region DESKTOP_PANE = new Region("DesktopPane", false); + /** * DesktopIcon region. To bind a style to this Region use * the name DesktopIcon. */ - public static final Region DESKTOP_ICON = new Region("DesktopIcon", - "DesktopIconUI"); + public static final Region DESKTOP_ICON = new Region("DesktopIcon", false); /** * EditorPane region. To bind a style to this Region use * the name EditorPane. */ - public static final Region EDITOR_PANE = new Region("EditorPane", - "EditorPaneUI"); + public static final Region EDITOR_PANE = new Region("EditorPane", false); /** * FileChooser region. To bind a style to this Region use * the name FileChooser. */ - public static final Region FILE_CHOOSER = new Region("FileChooser", - "FileChooserUI"); + public static final Region FILE_CHOOSER = new Region("FileChooser", false); /** * FormattedTextField region. To bind a style to this Region use * the name FormattedTextField. */ - public static final Region FORMATTED_TEXT_FIELD = new Region( - "FormattedTextField", "FormattedTextFieldUI"); + public static final Region FORMATTED_TEXT_FIELD = new Region("FormattedTextField", false); /** * InternalFrame region. To bind a style to this Region use * the name InternalFrame. */ - public static final Region INTERNAL_FRAME = new Region("InternalFrame", - "InternalFrameUI"); + public static final Region INTERNAL_FRAME = new Region("InternalFrame", false); + /** * TitlePane of an InternalFrame. The TitlePane typically * shows a menu, title, widgets to manipulate the internal frame. * To bind a style to this Region use the name * InternalFrameTitlePane. */ - public static final Region INTERNAL_FRAME_TITLE_PANE = - new Region("InternalFrameTitlePane", - "InternalFrameTitlePaneUI"); + public static final Region INTERNAL_FRAME_TITLE_PANE = new Region("InternalFrameTitlePane", false); /** * Label region. To bind a style to this Region use the name * Label. */ - public static final Region LABEL = new Region("Label", "LabelUI"); + public static final Region LABEL = new Region("Label", false); /** * List region. To bind a style to this Region use the name * List. */ - public static final Region LIST = new Region("List", "ListUI"); + public static final Region LIST = new Region("List", false); /** * Menu region. To bind a style to this Region use the name * Menu. */ - public static final Region MENU = new Region("Menu", "MenuUI"); + public static final Region MENU = new Region("Menu", false); /** * MenuBar region. To bind a style to this Region use the name * MenuBar. */ - public static final Region MENU_BAR = new Region("MenuBar", "MenuBarUI"); + public static final Region MENU_BAR = new Region("MenuBar", false); /** * MenuItem region. To bind a style to this Region use the name * MenuItem. */ - public static final Region MENU_ITEM = new Region("MenuItem","MenuItemUI"); + public static final Region MENU_ITEM = new Region("MenuItem", false); /** * Accelerator region of a MenuItem. To bind a style to this * Region use the name MenuItemAccelerator. */ - public static final Region MENU_ITEM_ACCELERATOR = new Region( - "MenuItemAccelerator"); + public static final Region MENU_ITEM_ACCELERATOR = new Region("MenuItemAccelerator", true); /** * OptionPane region. To bind a style to this Region use * the name OptionPane. */ - public static final Region OPTION_PANE = new Region("OptionPane", - "OptionPaneUI"); + public static final Region OPTION_PANE = new Region("OptionPane", false); /** * Panel region. To bind a style to this Region use the name * Panel. */ - public static final Region PANEL = new Region("Panel", "PanelUI"); + public static final Region PANEL = new Region("Panel", false); /** * PasswordField region. To bind a style to this Region use * the name PasswordField. */ - public static final Region PASSWORD_FIELD = new Region("PasswordField", - "PasswordFieldUI"); + public static final Region PASSWORD_FIELD = new Region("PasswordField", false); /** * PopupMenu region. To bind a style to this Region use * the name PopupMenu. */ - public static final Region POPUP_MENU = new Region("PopupMenu", - "PopupMenuUI"); + public static final Region POPUP_MENU = new Region("PopupMenu", false); /** * PopupMenuSeparator region. To bind a style to this Region * use the name PopupMenuSeparator. */ - public static final Region POPUP_MENU_SEPARATOR = new Region( - "PopupMenuSeparator", "PopupMenuSeparatorUI"); + public static final Region POPUP_MENU_SEPARATOR = new Region("PopupMenuSeparator", false); /** * ProgressBar region. To bind a style to this Region * use the name ProgressBar. */ - public static final Region PROGRESS_BAR = new Region("ProgressBar", - "ProgressBarUI"); + public static final Region PROGRESS_BAR = new Region("ProgressBar", false); /** * RadioButton region. To bind a style to this Region * use the name RadioButton. */ - public static final Region RADIO_BUTTON = new Region( - "RadioButton", "RadioButtonUI"); + public static final Region RADIO_BUTTON = new Region("RadioButton", false); /** * RegionButtonMenuItem region. To bind a style to this Region * use the name RadioButtonMenuItem. */ - public static final Region RADIO_BUTTON_MENU_ITEM = new Region( - "RadioButtonMenuItem", "RadioButtonMenuItemUI"); + public static final Region RADIO_BUTTON_MENU_ITEM = new Region("RadioButtonMenuItem", false); /** * RootPane region. To bind a style to this Region use * the name RootPane. */ - public static final Region ROOT_PANE = new Region("RootPane", - "RootPaneUI"); + public static final Region ROOT_PANE = new Region("RootPane", false); /** * ScrollBar region. To bind a style to this Region use * the name ScrollBar. */ - public static final Region SCROLL_BAR = new Region("ScrollBar", - "ScrollBarUI"); + public static final Region SCROLL_BAR = new Region("ScrollBar", false); + /** * Track of the ScrollBar. To bind a style to this Region use * the name ScrollBarTrack. */ - public static final Region SCROLL_BAR_TRACK = new Region("ScrollBarTrack"); + public static final Region SCROLL_BAR_TRACK = new Region("ScrollBarTrack", true); + /** * Thumb of the ScrollBar. The thumb is the region of the ScrollBar * that gives a graphical depiction of what percentage of the View is * currently visible. To bind a style to this Region use * the name ScrollBarThumb. */ - public static final Region SCROLL_BAR_THUMB = new Region("ScrollBarThumb"); + public static final Region SCROLL_BAR_THUMB = new Region("ScrollBarThumb", true); /** * ScrollPane region. To bind a style to this Region use * the name ScrollPane. */ - public static final Region SCROLL_PANE = new Region("ScrollPane", - "ScrollPaneUI"); + public static final Region SCROLL_PANE = new Region("ScrollPane", false); /** * Separator region. To bind a style to this Region use * the name Separator. */ - public static final Region SEPARATOR = new Region("Separator", - "SeparatorUI"); + public static final Region SEPARATOR = new Region("Separator", false); /** * Slider region. To bind a style to this Region use * the name Slider. */ - public static final Region SLIDER = new Region("Slider", "SliderUI"); + public static final Region SLIDER = new Region("Slider", false); + /** * Track of the Slider. To bind a style to this Region use * the name SliderTrack. */ - public static final Region SLIDER_TRACK = new Region("SliderTrack"); + public static final Region SLIDER_TRACK = new Region("SliderTrack", true); + /** * Thumb of the Slider. The thumb of the Slider identifies the current * value. To bind a style to this Region use the name * SliderThumb. */ - public static final Region SLIDER_THUMB = new Region("SliderThumb"); + public static final Region SLIDER_THUMB = new Region("SliderThumb", true); /** * Spinner region. To bind a style to this Region use the name * Spinner. */ - public static final Region SPINNER = new Region("Spinner", "SpinnerUI"); + public static final Region SPINNER = new Region("Spinner", false); /** * SplitPane region. To bind a style to this Region use the name * SplitPane. */ - public static final Region SPLIT_PANE = new Region("SplitPane", - "SplitPaneUI"); + public static final Region SPLIT_PANE = new Region("SplitPane", false); /** * Divider of the SplitPane. To bind a style to this Region * use the name SplitPaneDivider. */ - public static final Region SPLIT_PANE_DIVIDER = new Region( - "SplitPaneDivider"); + public static final Region SPLIT_PANE_DIVIDER = new Region("SplitPaneDivider", true); /** * TabbedPane region. To bind a style to this Region use * the name TabbedPane. */ - public static final Region TABBED_PANE = new Region("TabbedPane", - "TabbedPaneUI"); + public static final Region TABBED_PANE = new Region("TabbedPane", false); + /** * Region of a TabbedPane for one tab. To bind a style to this * Region use the name TabbedPaneTab. */ - public static final Region TABBED_PANE_TAB = new Region("TabbedPaneTab"); + public static final Region TABBED_PANE_TAB = new Region("TabbedPaneTab", true); + /** * Region of a TabbedPane containing the tabs. To bind a style to this * Region use the name TabbedPaneTabArea. */ - public static final Region TABBED_PANE_TAB_AREA = - new Region("TabbedPaneTabArea"); + public static final Region TABBED_PANE_TAB_AREA = new Region("TabbedPaneTabArea", true); + /** * Region of a TabbedPane containing the content. To bind a style to this * Region use the name TabbedPaneContent. */ - public static final Region TABBED_PANE_CONTENT = - new Region("TabbedPaneContent"); + public static final Region TABBED_PANE_CONTENT = new Region("TabbedPaneContent", true); /** * Table region. To bind a style to this Region use * the name Table. */ - public static final Region TABLE = new Region("Table", "TableUI"); + public static final Region TABLE = new Region("Table", false); /** * TableHeader region. To bind a style to this Region use * the name TableHeader. */ - public static final Region TABLE_HEADER = new Region("TableHeader", - "TableHeaderUI"); + public static final Region TABLE_HEADER = new Region("TableHeader", false); + /** * TextArea region. To bind a style to this Region use * the name TextArea. */ - public static final Region TEXT_AREA = new Region("TextArea", - "TextAreaUI"); + public static final Region TEXT_AREA = new Region("TextArea", false); /** * TextField region. To bind a style to this Region use * the name TextField. */ - public static final Region TEXT_FIELD = new Region("TextField", - "TextFieldUI"); + public static final Region TEXT_FIELD = new Region("TextField", false); /** * TextPane region. To bind a style to this Region use * the name TextPane. */ - public static final Region TEXT_PANE = new Region("TextPane", - "TextPaneUI"); + public static final Region TEXT_PANE = new Region("TextPane", false); /** * ToggleButton region. To bind a style to this Region use * the name ToggleButton. */ - public static final Region TOGGLE_BUTTON = new Region("ToggleButton", - "ToggleButtonUI"); + public static final Region TOGGLE_BUTTON = new Region("ToggleButton", false); /** * ToolBar region. To bind a style to this Region use * the name ToolBar. */ - public static final Region TOOL_BAR = new Region("ToolBar", "ToolBarUI"); + public static final Region TOOL_BAR = new Region("ToolBar", false); + /** * Region of the ToolBar containing the content. To bind a style to this * Region use the name ToolBarContent. */ - public static final Region TOOL_BAR_CONTENT = new Region("ToolBarContent"); + public static final Region TOOL_BAR_CONTENT = new Region("ToolBarContent", true); + /** * Region for the Window containing the ToolBar. To bind a style to this * Region use the name ToolBarDragWindow. */ - public static final Region TOOL_BAR_DRAG_WINDOW = new Region( - "ToolBarDragWindow", null, false); + public static final Region TOOL_BAR_DRAG_WINDOW = new Region("ToolBarDragWindow", false); /** * ToolTip region. To bind a style to this Region use * the name ToolTip. */ - public static final Region TOOL_TIP = new Region("ToolTip", "ToolTipUI"); + public static final Region TOOL_TIP = new Region("ToolTip", false); /** * ToolBar separator region. To bind a style to this Region use * the name ToolBarSeparator. */ - public static final Region TOOL_BAR_SEPARATOR = new Region( - "ToolBarSeparator", "ToolBarSeparatorUI"); + public static final Region TOOL_BAR_SEPARATOR = new Region("ToolBarSeparator", false); /** * Tree region. To bind a style to this Region use the name * Tree. */ - public static final Region TREE = new Region("Tree", "TreeUI"); + public static final Region TREE = new Region("Tree", false); + /** * Region of the Tree for one cell. To bind a style to this * Region use the name TreeCell. */ - public static final Region TREE_CELL = new Region("TreeCell"); + public static final Region TREE_CELL = new Region("TreeCell", true); /** * Viewport region. To bind a style to this Region use * the name Viewport. */ - public static final Region VIEWPORT = new Region("Viewport", "ViewportUI"); + public static final Region VIEWPORT = new Region("Viewport", false); + private static Map getUItoRegionMap() { + AppContext context = AppContext.getAppContext(); + Map map = (Map) context.get(UI_TO_REGION_MAP_KEY); + if (map == null) { + map = new HashMap(); + map.put("ArrowButtonUI", ARROW_BUTTON); + map.put("ButtonUI", BUTTON); + map.put("CheckBoxUI", CHECK_BOX); + map.put("CheckBoxMenuItemUI", CHECK_BOX_MENU_ITEM); + map.put("ColorChooserUI", COLOR_CHOOSER); + map.put("ComboBoxUI", COMBO_BOX); + map.put("DesktopPaneUI", DESKTOP_PANE); + map.put("DesktopIconUI", DESKTOP_ICON); + map.put("EditorPaneUI", EDITOR_PANE); + map.put("FileChooserUI", FILE_CHOOSER); + map.put("FormattedTextFieldUI", FORMATTED_TEXT_FIELD); + map.put("InternalFrameUI", INTERNAL_FRAME); + map.put("InternalFrameTitlePaneUI", INTERNAL_FRAME_TITLE_PANE); + map.put("LabelUI", LABEL); + map.put("ListUI", LIST); + map.put("MenuUI", MENU); + map.put("MenuBarUI", MENU_BAR); + map.put("MenuItemUI", MENU_ITEM); + map.put("OptionPaneUI", OPTION_PANE); + map.put("PanelUI", PANEL); + map.put("PasswordFieldUI", PASSWORD_FIELD); + map.put("PopupMenuUI", POPUP_MENU); + map.put("PopupMenuSeparatorUI", POPUP_MENU_SEPARATOR); + map.put("ProgressBarUI", PROGRESS_BAR); + map.put("RadioButtonUI", RADIO_BUTTON); + map.put("RadioButtonMenuItemUI", RADIO_BUTTON_MENU_ITEM); + map.put("RootPaneUI", ROOT_PANE); + map.put("ScrollBarUI", SCROLL_BAR); + map.put("ScrollPaneUI", SCROLL_PANE); + map.put("SeparatorUI", SEPARATOR); + map.put("SliderUI", SLIDER); + map.put("SpinnerUI", SPINNER); + map.put("SplitPaneUI", SPLIT_PANE); + map.put("TabbedPaneUI", TABBED_PANE); + map.put("TableUI", TABLE); + map.put("TableHeaderUI", TABLE_HEADER); + map.put("TextAreaUI", TEXT_AREA); + map.put("TextFieldUI", TEXT_FIELD); + map.put("TextPaneUI", TEXT_PANE); + map.put("ToggleButtonUI", TOGGLE_BUTTON); + map.put("ToolBarUI", TOOL_BAR); + map.put("ToolTipUI", TOOL_TIP); + map.put("ToolBarSeparatorUI", TOOL_BAR_SEPARATOR); + map.put("TreeUI", TREE); + map.put("ViewportUI", VIEWPORT); + context.put(UI_TO_REGION_MAP_KEY, map); + } + return map; + } - private String name; - private boolean subregion; - + private static Map getLowerCaseNameMap() { + AppContext context = AppContext.getAppContext(); + Map map = (Map) context.get(LOWER_CASE_NAME_MAP_KEY); + if (map == null) { + map = new HashMap(); + context.put(LOWER_CASE_NAME_MAP_KEY, map); + } + return map; + } static Region getRegion(JComponent c) { - return uiToRegionMap.get(c.getUIClassID()); + return getUItoRegionMap().get(c.getUIClassID()); } static void registerUIs(UIDefaults table) { - for (String key : uiToRegionMap.keySet()) { + for (Object key : getUItoRegionMap().keySet()) { table.put(key, "javax.swing.plaf.synth.SynthLookAndFeel"); } } + private final String name; + private final boolean subregion; - Region(String name) { - this(name, null, true); - } - - Region(String name, String ui) { - this(name, ui, false); + private Region(String name, boolean subregion) { + if (name == null) { + throw new NullPointerException("You must specify a non-null name"); + } + this.name = name; + this.subregion = subregion; } /** @@ -481,14 +523,10 @@ public class Region { * @param subregion Whether or not this is a subregion. */ protected Region(String name, String ui, boolean subregion) { - if (name == null) { - throw new NullPointerException("You must specify a non-null name"); - } - this.name = name; + this(name, subregion); if (ui != null) { - uiToRegionMap.put(ui, this); + getUItoRegionMap().put(ui, this); } - this.subregion = subregion; } /** @@ -514,16 +552,17 @@ public class Region { /** * Returns the name, in lowercase. + * + * @return lower case representation of the name of the Region */ String getLowerCaseName() { - synchronized(lowerCaseNameMap) { - String lowerCaseName = lowerCaseNameMap.get(this); - if (lowerCaseName == null) { - lowerCaseName = getName().toLowerCase(); - lowerCaseNameMap.put(this, lowerCaseName); - } - return lowerCaseName; + Map lowerCaseNameMap = getLowerCaseNameMap(); + String lowerCaseName = lowerCaseNameMap.get(this); + if (lowerCaseName == null) { + lowerCaseName = name.toLowerCase(Locale.ENGLISH); + lowerCaseNameMap.put(this, lowerCaseName); } + return lowerCaseName; } /** @@ -531,6 +570,7 @@ public class Region { * * @return name of the Region. */ + @Override public String toString() { return name; } diff --git a/jdk/test/javax/swing/plaf/synth/Test6660049.java b/jdk/test/javax/swing/plaf/synth/Test6660049.java new file mode 100644 index 00000000000..466453a8a60 --- /dev/null +++ b/jdk/test/javax/swing/plaf/synth/Test6660049.java @@ -0,0 +1,123 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6660049 6849518 + * @summary Tests the Region initialization + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import javax.swing.plaf.synth.Region; +import javax.swing.plaf.synth.SynthLookAndFeel; + +public class Test6660049 implements Runnable { + public static void main(String[] args) { + SwingUtilities.invokeLater(new Test6660049( + javax.swing.JButton.class, + javax.swing.JCheckBox.class, + javax.swing.JCheckBoxMenuItem.class, + javax.swing.JColorChooser.class, + javax.swing.JComboBox.class, + javax.swing.JDesktopPane.class, + javax.swing.JEditorPane.class, + javax.swing.JFileChooser.class, + javax.swing.JFormattedTextField.class, + javax.swing.JInternalFrame.class, + javax.swing.JLabel.class, + javax.swing.JList.class, + javax.swing.JMenu.class, + javax.swing.JMenuBar.class, + javax.swing.JMenuItem.class, + javax.swing.JOptionPane.class, + javax.swing.JPanel.class, + javax.swing.JPasswordField.class, + javax.swing.JPopupMenu.class, + javax.swing.JProgressBar.class, + javax.swing.JRadioButton.class, + javax.swing.JRadioButtonMenuItem.class, + javax.swing.JRootPane.class, + javax.swing.JScrollBar.class, + javax.swing.JScrollPane.class, + javax.swing.JSeparator.class, + javax.swing.JSlider.class, + javax.swing.JSpinner.class, + javax.swing.JSplitPane.class, + javax.swing.JTabbedPane.class, + javax.swing.JTable.class, + javax.swing.JTextArea.class, + javax.swing.JTextField.class, + javax.swing.JTextPane.class, + javax.swing.JToggleButton.class, + javax.swing.JToolBar.class, + javax.swing.JToolTip.class, + javax.swing.JTree.class, + javax.swing.JViewport.class, + javax.swing.table.JTableHeader.class)); + } + + private final Class[] types; + private final Region region; + + private Test6660049(Class... types) { + this.types = types; + run(); + + this.region = new Region("Button", "ButtonUI", true) { + @Override + public String getName() { + throw new Error("6660049: exploit is available"); + } + }; + } + + public void run() { + if (this.region != null) { + SunToolkit.createNewAppContext(); + } + for (Class type : this.types) { + Region region = getRegion(type); + if (region == null) { + throw new Error("6849518: region is not initialized"); + } + } + getRegion(JButton.class).getName(); + } + + private static Region getRegion(Class type) { + try { + return SynthLookAndFeel.getRegion(type.newInstance()); + } + catch (IllegalAccessException exception) { + throw new Error("unexpected exception", exception); + } + catch (InstantiationException exception) { + throw new Error("unexpected exception", exception); + } + } +} From 6b90310fed55e58b749b5d4b1fbbdc67ef227eca Mon Sep 17 00:00:00 2001 From: Abhijit Saha Date: Mon, 22 Jun 2009 13:36:37 -0700 Subject: [PATCH 017/102] 6656610: AccessibleResourceBundle.getContents exposes mutable static (findbugs) Reviewed-by: hawtin --- .../accessibility/AccessibleResourceBundle.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java b/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java index b5f23e199fa..ec27c756bde 100644 --- a/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java +++ b/jdk/src/share/classes/javax/accessibility/AccessibleResourceBundle.java @@ -44,15 +44,11 @@ public class AccessibleResourceBundle extends ListResourceBundle { * localized display strings. */ public Object[][] getContents() { - return contents; - } + // The table holding the mapping between the programmatic keys + // and the display strings for the en_US locale. + return new Object[][] { - /** - * The table holding the mapping between the programmatic keys - * and the display strings for the en_US locale. - */ - static final Object[][] contents = { - // LOCALIZE THIS + // LOCALIZE THIS // Role names // { "application","application" }, // { "border","border" }, @@ -151,5 +147,6 @@ public class AccessibleResourceBundle extends ListResourceBundle { { "vertical","vertical" }, { "horizontal","horizontal" } // END OF MATERIAL TO LOCALIZE - }; + }; + } } From 68d0756ea67b3c8655a28193e6725e07d3b8554b Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Tue, 23 Jun 2009 13:54:36 -0400 Subject: [PATCH 018/102] 6824440: XML Signature HMAC issue Reviewed-by: asaha --- .../implementations/IntegrityHmac.java | 76 +++++++---- .../internal/dom/DOMHMACSignatureMethod.java | 53 ++++---- .../xml/internal/security/TruncateHMAC.java | 118 ++++++++++++++++++ ...enveloping-hmac-sha1-trunclen-0-attack.xml | 16 +++ ...enveloping-hmac-sha1-trunclen-8-attack.xml | 17 +++ .../xml/crypto/dsig/GenerationTests.java | 16 ++- .../xml/crypto/dsig/ValidationTests.java | 39 +++++- ...enveloping-hmac-sha1-trunclen-0-attack.xml | 16 +++ ...enveloping-hmac-sha1-trunclen-8-attack.xml | 17 +++ 9 files changed, 311 insertions(+), 57 deletions(-) create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml create mode 100644 jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml create mode 100644 jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index d3495bb567f..85cc9e38a68 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -60,8 +60,14 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { */ public abstract String engineGetURI(); + /** + * Returns the output length of the hash/digest. + */ + abstract int getDigestLength(); + /** Field _macAlgorithm */ private Mac _macAlgorithm = null; + private boolean _HMACOutputLengthSet = false; /** Field _HMACOutputLength */ int _HMACOutputLength = 0; @@ -115,14 +121,16 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { throws XMLSignatureException { try { - byte[] completeResult = this._macAlgorithm.doFinal(); - - if ((this._HMACOutputLength == 0) || (this._HMACOutputLength >= 160)) { + if (this._HMACOutputLengthSet && this._HMACOutputLength < getDigestLength()) { + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, + "HMACOutputLength must not be less than " + getDigestLength()); + } + throw new XMLSignatureException("errorMessages.XMLSignatureException"); + } else { + byte[] completeResult = this._macAlgorithm.doFinal(); return MessageDigestAlgorithm.isEqual(completeResult, signature); } - byte[] stripped = IntegrityHmac.reduceBitLength(completeResult, - this._HMACOutputLength); - return MessageDigestAlgorithm.isEqual(stripped, signature); } catch (IllegalStateException ex) { throw new XMLSignatureException("empty", ex); } @@ -176,14 +184,15 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { protected byte[] engineSign() throws XMLSignatureException { try { - byte[] completeResult = this._macAlgorithm.doFinal(); - - if ((this._HMACOutputLength == 0) || (this._HMACOutputLength >= 160)) { - return completeResult; + if (this._HMACOutputLengthSet && this._HMACOutputLength < getDigestLength()) { + if (log.isLoggable(java.util.logging.Level.FINE)) { + log.log(java.util.logging.Level.FINE, + "HMACOutputLength must not be less than " + getDigestLength()); + } + throw new XMLSignatureException("errorMessages.XMLSignatureException"); + } else { + return this._macAlgorithm.doFinal(); } - return IntegrityHmac.reduceBitLength(completeResult, - this._HMACOutputLength); - } catch (IllegalStateException ex) { throw new XMLSignatureException("empty", ex); } @@ -361,6 +370,7 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { */ protected void engineSetHMACOutputLength(int HMACOutputLength) { this._HMACOutputLength = HMACOutputLength; + this._HMACOutputLengthSet = true; } /** @@ -376,12 +386,13 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { throw new IllegalArgumentException("element null"); } - Text hmaclength =XMLUtils.selectDsNodeText(element.getFirstChild(), - Constants._TAG_HMACOUTPUTLENGTH,0); + Text hmaclength =XMLUtils.selectDsNodeText(element.getFirstChild(), + Constants._TAG_HMACOUTPUTLENGTH,0); - if (hmaclength != null) { - this._HMACOutputLength = Integer.parseInt(hmaclength.getData()); - } + if (hmaclength != null) { + this._HMACOutputLength = Integer.parseInt(hmaclength.getData()); + this._HMACOutputLengthSet = true; + } } @@ -390,14 +401,13 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { * * @param element */ - public void engineAddContextToElement(Element element) - { + public void engineAddContextToElement(Element element) { if (element == null) { throw new IllegalArgumentException("null element"); } - if (this._HMACOutputLength != 0) { + if (this._HMACOutputLengthSet) { Document doc = element.getOwnerDocument(); Element HMElem = XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_HMACOUTPUTLENGTH); @@ -436,6 +446,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA1; } + + int getDigestLength() { + return 160; + } } /** @@ -463,6 +477,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA256; } + + int getDigestLength() { + return 256; + } } /** @@ -490,6 +508,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA384; } + + int getDigestLength() { + return 384; + } } /** @@ -517,6 +539,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_SHA512; } + + int getDigestLength() { + return 512; + } } /** @@ -544,6 +570,10 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_RIPEMD160; } + + int getDigestLength() { + return 160; + } } /** @@ -571,5 +601,9 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { public String engineGetURI() { return XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5; } + + int getDigestLength() { + return 128; + } } } diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java index 5a9000c898c..482283b616e 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java @@ -19,7 +19,7 @@ * */ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. All rights reserved. */ /* * $Id: DOMHMACSignatureMethod.java,v 1.2 2008/07/24 15:20:32 mullan Exp $ @@ -58,6 +58,7 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { Logger.getLogger("org.jcp.xml.dsig.internal.dom"); private Mac hmac; private int outputLength; + private boolean outputLengthSet; /** * Creates a DOMHMACSignatureMethod with the specified params @@ -87,6 +88,7 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { ("params must be of type HMACParameterSpec"); } outputLength = ((HMACParameterSpec) params).getOutputLength(); + outputLengthSet = true; if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Setting outputLength from HMACParameterSpec to: " @@ -101,6 +103,7 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { throws MarshalException { outputLength = new Integer (paramsElem.getFirstChild().getNodeValue()).intValue(); + outputLengthSet = true; if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "unmarshalled outputLength: " + outputLength); } @@ -135,23 +138,13 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { throw new XMLSignatureException(nsae); } } - if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "outputLength = " + outputLength); + if (outputLengthSet && outputLength < getDigestLength()) { + throw new XMLSignatureException + ("HMACOutputLength must not be less than " + getDigestLength()); } hmac.init((SecretKey) key); si.canonicalize(context, new MacOutputStream(hmac)); byte[] result = hmac.doFinal(); - if (log.isLoggable(Level.FINE)) { - log.log(Level.FINE, "resultLength = " + result.length); - } - if (outputLength != -1) { - int byteLength = outputLength/8; - if (result.length > byteLength) { - byte[] truncated = new byte[byteLength]; - System.arraycopy(result, 0, truncated, 0, byteLength); - result = truncated; - } - } return MessageDigest.isEqual(sig, result); } @@ -171,18 +164,13 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { throw new XMLSignatureException(nsae); } } + if (outputLengthSet && outputLength < getDigestLength()) { + throw new XMLSignatureException + ("HMACOutputLength must not be less than " + getDigestLength()); + } hmac.init((SecretKey) key); si.canonicalize(context, new MacOutputStream(hmac)); - byte[] result = hmac.doFinal(); - if (outputLength != -1) { - int byteLength = outputLength/8; - if (result.length > byteLength) { - byte[] truncated = new byte[byteLength]; - System.arraycopy(result, 0, truncated, 0, byteLength); - result = truncated; - } - } - return result; + return hmac.doFinal(); } boolean paramsEqual(AlgorithmParameterSpec spec) { @@ -197,6 +185,11 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { return (outputLength == ospec.getOutputLength()); } + /** + * Returns the output length of the hash/digest. + */ + abstract int getDigestLength(); + static final class SHA1 extends DOMHMACSignatureMethod { SHA1(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { @@ -211,6 +204,9 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA1"; } + int getDigestLength() { + return 160; + } } static final class SHA256 extends DOMHMACSignatureMethod { @@ -227,6 +223,9 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA256"; } + int getDigestLength() { + return 256; + } } static final class SHA384 extends DOMHMACSignatureMethod { @@ -243,6 +242,9 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA384"; } + int getDigestLength() { + return 384; + } } static final class SHA512 extends DOMHMACSignatureMethod { @@ -259,5 +261,8 @@ public abstract class DOMHMACSignatureMethod extends DOMSignatureMethod { String getSignatureAlgorithm() { return "HmacSHA512"; } + int getDigestLength() { + return 512; + } } } diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java new file mode 100644 index 00000000000..ebb424de328 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java @@ -0,0 +1,118 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test %I% %E% + * @bug 6824440 + * @summary Check that Apache XMLSec APIs will not accept HMAC truncation + * lengths less than minimum bound + * @compile -XDignore.symbol.file TruncateHMAC.java + * @run main TruncateHMAC + */ + +import java.io.File; +import javax.crypto.SecretKey; +import javax.xml.parsers.DocumentBuilderFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import com.sun.org.apache.xml.internal.security.Init; +import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer; +import com.sun.org.apache.xml.internal.security.signature.XMLSignature; +import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException; +import com.sun.org.apache.xml.internal.security.utils.Constants; + + +public class TruncateHMAC { + + private final static String DIR = System.getProperty("test.src", "."); + private static DocumentBuilderFactory dbf = null; + private static boolean atLeastOneFailed = false; + + public static void main(String[] args) throws Exception { + + Init.init(); + dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(false); + validate("signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); + validate("signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); + generate_hmac_sha1_40(); + + if (atLeastOneFailed) { + throw new Exception + ("At least one signature did not validate as expected"); + } + } + + private static void validate(String data) throws Exception { + System.out.println("Validating " + data); + File file = new File(DIR, data); + + Document doc = dbf.newDocumentBuilder().parse(file); + NodeList nl = + doc.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature"); + if (nl.getLength() == 0) { + throw new Exception("Couldn't find signature Element"); + } + Element sigElement = (Element) nl.item(0); + XMLSignature signature = new XMLSignature + (sigElement, file.toURI().toString()); + SecretKey sk = signature.createSecretKey("secret".getBytes("ASCII")); + try { + System.out.println + ("Validation status: " + signature.checkSignatureValue(sk)); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + } + + private static void generate_hmac_sha1_40() throws Exception { + System.out.println("Generating "); + + Document doc = dbf.newDocumentBuilder().newDocument(); + XMLSignature sig = new XMLSignature + (doc, null, XMLSignature.ALGO_ID_MAC_HMAC_SHA1, 40, + Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); + try { + sig.sign(getSecretKey("secret".getBytes("ASCII"))); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + } + + private static SecretKey getSecretKey(final byte[] secret) { + return new SecretKey() { + public String getFormat() { return "RAW"; } + public byte[] getEncoded() { return secret; } + public String getAlgorithm(){ return "SECRET"; } + }; + } +} diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml new file mode 100644 index 00000000000..5008dae5193 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-0-attack.xml @@ -0,0 +1,16 @@ + + + + + + 0 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + + some other text + diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml new file mode 100644 index 00000000000..dfe0a0df9a5 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1-trunclen-8-attack.xml @@ -0,0 +1,17 @@ + + + + + + 8 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + Qw== + + some other text + diff --git a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java index ea4fd610e1e..13881966d32 100644 --- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java +++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,7 @@ /** * @test - * @bug 4635230 - * @bug 6283345 - * @bug 6303830 + * @bug 4635230 6283345 6303830 6824440 * @summary Basic unit tests for generating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java GenerationTests.java @@ -248,8 +246,14 @@ public class GenerationTests { System.out.println("* Generating signature-enveloping-hmac-sha1-40.xml"); SignatureMethod hmacSha1 = fac.newSignatureMethod (SignatureMethod.HMAC_SHA1, new HMACParameterSpec(40)); - test_create_signature_enveloping(sha1, hmacSha1, null, - getSecretKey("secret".getBytes("ASCII")), sks, false); + try { + test_create_signature_enveloping(sha1, hmacSha1, null, + getSecretKey("secret".getBytes("ASCII")), sks, false); + } catch (Exception e) { + if (!(e instanceof XMLSignatureException)) { + throw e; + } + } System.out.println(); } diff --git a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java index 0934de7e921..0604af9bbc5 100644 --- a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java +++ b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,7 @@ /** * @test - * @bug 4635230 - * @bug 6365103 - * @bug 6366054 + * @bug 4635230 6365103 6366054 6824440 * @summary Basic unit tests for validating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java ValidationTests.java @@ -42,6 +40,7 @@ import javax.xml.crypto.URIDereferencer; import javax.xml.crypto.URIReference; import javax.xml.crypto.URIReferenceException; import javax.xml.crypto.XMLCryptoContext; +import javax.xml.crypto.dsig.XMLSignatureException; import javax.xml.crypto.dsig.XMLSignatureFactory; /** @@ -68,7 +67,6 @@ public class ValidationTests { "signature-enveloping-dsa.xml", "signature-enveloping-rsa.xml", "signature-enveloping-hmac-sha1.xml", - "signature-enveloping-hmac-sha1-40.xml", "signature-external-dsa.xml", "signature-external-b64-dsa.xml", "signature-retrievalmethod-rawx509crt.xml", @@ -106,7 +104,6 @@ public class ValidationTests { KVKS, KVKS, SKKS, - SKKS, KVKS, KVKS, CKS, @@ -146,6 +143,36 @@ public class ValidationTests { atLeastOneFailed = true; } + System.out.println("Validating signature-enveloping-hmac-sha1-40.xml"); + try { + test_signature("signature-enveloping-hmac-sha1-40.xml", SKKS, false); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + + System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); + try { + test_signature("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS, false); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + + System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); + try { + test_signature("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS, false); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } + if (atLeastOneFailed) { throw new Exception ("At least one signature did not validate as expected"); diff --git a/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml new file mode 100644 index 00000000000..5008dae5193 --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-0-attack.xml @@ -0,0 +1,16 @@ + + + + + + 0 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + + some other text + diff --git a/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml new file mode 100644 index 00000000000..dfe0a0df9a5 --- /dev/null +++ b/jdk/test/javax/xml/crypto/dsig/data/signature-enveloping-hmac-sha1-trunclen-8-attack.xml @@ -0,0 +1,17 @@ + + + + + + 8 + + + + nz4GS0NbH2SrWlD/4fX313CoTzc= + + + + Qw== + + some other text + From d92c74443f73ee3c282a052d9e5027a5123621d1 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Mon, 22 Jun 2009 07:23:20 -0700 Subject: [PATCH 019/102] 6830335: Java JAR Pack200 Decompression Integer Overflow Vulnerability Fixes a potential vulnerability in the unpack200 logic, by adding extra checks, a back-port. Reviewed-by: asaha --- .../share/native/com/sun/java/util/jar/pack/unpack.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp index a6f4ca0c2c8..7ca65c5d61e 100644 --- a/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp +++ b/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp @@ -908,10 +908,12 @@ void cpool::init(unpacker* u_, int counts[NUM_COUNTS]) { // place a limit on future CP growth: int generous = 0; - generous += u->ic_count*3; // implicit name, outer, outer.utf8 - generous += 40; // WKUs, misc - generous += u->class_count; // implicit SourceFile strings - maxentries = nentries + generous; + generous = add_size(generous, u->ic_count); // implicit name + generous = add_size(generous, u->ic_count); // outer + generous = add_size(generous, u->ic_count); // outer.utf8 + generous = add_size(generous, 40); // WKUs, misc + generous = add_size(generous, u->class_count); // implicit SourceFile strings + maxentries = add_size(nentries, generous); // Note that this CP does not include "empty" entries // for longs and doubles. Those are introduced when From 95f53ce57bb36019087a774f46bfeadc843d4d68 Mon Sep 17 00:00:00 2001 From: Abhijit Saha Date: Mon, 22 Jun 2009 13:56:30 -0700 Subject: [PATCH 020/102] 6845701: Xerces2 Java XML library infinite loop with malformed XML input Reviewed-by: hawtin --- .../com/sun/org/apache/xerces/internal/impl/XMLScanner.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index e7071fde4f1..513dec48f04 100644 --- a/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -1027,6 +1027,9 @@ public abstract class XMLScanner int c = fEntityScanner.peekChar(); if (XMLChar.isMarkup(c) || c == ']') { fStringBuffer.append((char)fEntityScanner.scanChar()); + } else if (c != -1 && isInvalidLiteral(c)) { + reportFatalError("InvalidCharInSystemID", + new Object[] {Integer.toString(c, 16)}); } } while (fEntityScanner.scanLiteral(quote, ident) != quote); fStringBuffer.append(ident); From e4502f3b6fa5fc7bb678e0f02736bd2407883bca Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Wed, 8 Jul 2009 16:57:40 -0400 Subject: [PATCH 021/102] 6858484: If an invalid HMAC XML Signature is validated, all subsequent valid HMAC signatures are invalid Reviewed-by: asaha --- .../implementations/IntegrityHmac.java | 4 +++- .../xml/internal/security/TruncateHMAC.java | 24 +++++++++++++------ .../signature-enveloping-hmac-sha1.xml | 15 ++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java index 85cc9e38a68..7231b069a18 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java @@ -106,7 +106,9 @@ public abstract class IntegrityHmac extends SignatureAlgorithmSpi { } public void reset() { - _HMACOutputLength=0; + _HMACOutputLength=0; + _HMACOutputLengthSet = false; + _macAlgorithm.reset(); } /** diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java index ebb424de328..a77d02b84f9 100644 --- a/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java +++ b/jdk/test/com/sun/org/apache/xml/internal/security/TruncateHMAC.java @@ -23,7 +23,7 @@ /** * @test %I% %E% - * @bug 6824440 + * @bug 6824440 6858484 * @summary Check that Apache XMLSec APIs will not accept HMAC truncation * lengths less than minimum bound * @compile -XDignore.symbol.file TruncateHMAC.java @@ -56,8 +56,10 @@ public class TruncateHMAC { dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setValidating(false); - validate("signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); - validate("signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); + validate("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", false); + validate("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", false); + // this one should pass + validate("signature-enveloping-hmac-sha1.xml", true); generate_hmac_sha1_40(); if (atLeastOneFailed) { @@ -66,7 +68,7 @@ public class TruncateHMAC { } } - private static void validate(String data) throws Exception { + private static void validate(String data, boolean pass) throws Exception { System.out.println("Validating " + data); File file = new File(DIR, data); @@ -83,11 +85,19 @@ public class TruncateHMAC { try { System.out.println ("Validation status: " + signature.checkSignatureValue(sk)); - System.out.println("FAILED"); - atLeastOneFailed = true; + if (!pass) { + System.out.println("FAILED"); + atLeastOneFailed = true; + } else { + System.out.println("PASSED"); + } } catch (XMLSignatureException xse) { System.out.println(xse.getMessage()); - System.out.println("PASSED"); + if (!pass) { + System.out.println("PASSED"); + } else { + System.out.println("FAILED"); + } } } diff --git a/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml new file mode 100644 index 00000000000..c0c8343a895 --- /dev/null +++ b/jdk/test/com/sun/org/apache/xml/internal/security/signature-enveloping-hmac-sha1.xml @@ -0,0 +1,15 @@ + + + + + + + + 7/XTsHaBSOnJ/jXD5v0zL6VKYsk= + + + + JElPttIT4Am7Q+MNoMyv+WDfAZw= + + some text + From 97bb9bff6fec0de4d29248cdea3d535c57666157 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 17 Jul 2009 20:29:41 +0100 Subject: [PATCH 022/102] 6657619: DnsContext.debug is public static mutable (findbugs) Reviewed-by: alanb --- .../classes/com/sun/jndi/dns/DnsContext.java | 4 +- jdk/test/com/sun/jndi/dns/CheckAccess.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 jdk/test/com/sun/jndi/dns/CheckAccess.java diff --git a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java index a5c8f01f3c1..3b30bb96a6e 100644 --- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java +++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -922,7 +922,7 @@ public class DnsContext extends ComponentDirContext { //---------- Debugging - public static boolean debug = false; + private static final boolean debug = false; private static final void dprint(String msg) { if (debug) { diff --git a/jdk/test/com/sun/jndi/dns/CheckAccess.java b/jdk/test/com/sun/jndi/dns/CheckAccess.java new file mode 100644 index 00000000000..478575167a5 --- /dev/null +++ b/jdk/test/com/sun/jndi/dns/CheckAccess.java @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6657619 + * @summary DnsContext.debug is public static mutable (findbugs) + * @author Vincent Ryan + */ + +import java.lang.reflect.*; + +/* + * Check that the 'debug' class member is no longer publicly accessible. + */ +public class CheckAccess { + public static final void main(String[] args) throws Exception { + try { + Class clazz = Class.forName("com.sun.jndi.dns.DnsContext"); + Field field = clazz.getField("debug"); + if (Modifier.isPublic(field.getModifiers())) { + throw new Exception( + "class member 'debug' must not be publicly accessible"); + } + } catch (NoSuchFieldException e) { + // 'debug' is not publicly accessible, ignore exception + } + } +} From d12079f670e26bd0c26e80ace4f63b3308622396 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 17 Jul 2009 20:43:53 +0100 Subject: [PATCH 023/102] 6657695: AbstractSaslImpl.logger is a static mutable (findbugs) Reviewed-by: alanb --- .../security/sasl/util/AbstractSaslImpl.java | 21 +++------ .../sun/security/sasl/util/CheckAccess.java | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 jdk/test/com/sun/security/sasl/util/CheckAccess.java diff --git a/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java b/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java index 9c24b55ecf6..ac6fa258632 100644 --- a/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java +++ b/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * 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,10 +48,6 @@ import sun.misc.HexDumpEncoder; * @author Rosanna Lee */ public abstract class AbstractSaslImpl { - /** - * Logger for debug messages - */ - protected static Logger logger; // set in initLogger(); lazily loads logger protected boolean completed = false; protected boolean privacy = false; @@ -68,7 +64,6 @@ public abstract class AbstractSaslImpl { protected String myClassName; protected AbstractSaslImpl(Map props, String className) throws SaslException { - initLogger(); myClassName = className; // Parse properties to set desired context options @@ -325,19 +320,15 @@ public abstract class AbstractSaslImpl { } } - /** - * Sets logger field. - */ - private static synchronized void initLogger() { - if (logger == null) { - logger = Logger.getLogger(SASL_LOGGER_NAME); - } - } - // ---------------- Constants ----------------- private static final String SASL_LOGGER_NAME = "javax.security.sasl"; protected static final String MAX_SEND_BUF = "javax.security.sasl.sendmaxbuffer"; + /** + * Logger for debug messages + */ + protected static final Logger logger = Logger.getLogger(SASL_LOGGER_NAME); + // default 0 (no protection); 1 (integrity only) protected static final byte NO_PROTECTION = (byte)1; protected static final byte INTEGRITY_ONLY_PROTECTION = (byte)2; diff --git a/jdk/test/com/sun/security/sasl/util/CheckAccess.java b/jdk/test/com/sun/security/sasl/util/CheckAccess.java new file mode 100644 index 00000000000..9ac0674b15c --- /dev/null +++ b/jdk/test/com/sun/security/sasl/util/CheckAccess.java @@ -0,0 +1,46 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6657695 + * @summary AbstractSaslImpl.logger is a static mutable (findbugs) + * @author Vincent Ryan + */ + +import java.lang.reflect.*; + +/* + * Check that the 'logger' class member is immutable. + */ +public class CheckAccess { + public static final void main(String[] args) throws Exception { + Class clazz = + Class.forName("com.sun.security.sasl.util.AbstractSaslImpl"); + Field field = clazz.getDeclaredField("logger"); + if (! Modifier.isFinal(field.getModifiers())) { + throw new Exception( + "class member 'logger' must be immutable"); + } + } +} From e9b3362acef6ec1e420ccf6b523f15085112b4e3 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Fri, 24 Jul 2009 11:06:57 -0700 Subject: [PATCH 024/102] 5063507: (fmt) missing exception for "%#s" format specifier Throw appropriate exception when necessary Reviewed-by: alanb --- jdk/src/share/classes/java/util/Formatter.java | 11 +++++++---- jdk/test/java/util/Formatter/Basic-X.java | 4 ++++ jdk/test/java/util/Formatter/Basic.java | 2 +- jdk/test/java/util/Formatter/BasicBigDecimal.java | 4 ++++ jdk/test/java/util/Formatter/BasicBigInteger.java | 4 ++++ jdk/test/java/util/Formatter/BasicBoolean.java | 4 ++++ jdk/test/java/util/Formatter/BasicBooleanObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicByte.java | 4 ++++ jdk/test/java/util/Formatter/BasicByteObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicChar.java | 4 ++++ jdk/test/java/util/Formatter/BasicCharObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicDateTime.java | 4 ++++ jdk/test/java/util/Formatter/BasicDouble.java | 4 ++++ jdk/test/java/util/Formatter/BasicDoubleObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicFloat.java | 4 ++++ jdk/test/java/util/Formatter/BasicFloatObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicInt.java | 4 ++++ jdk/test/java/util/Formatter/BasicIntObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicLong.java | 4 ++++ jdk/test/java/util/Formatter/BasicLongObject.java | 4 ++++ jdk/test/java/util/Formatter/BasicShort.java | 4 ++++ jdk/test/java/util/Formatter/BasicShortObject.java | 4 ++++ 22 files changed, 88 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/util/Formatter.java b/jdk/src/share/classes/java/util/Formatter.java index eb49ec9c5da..027e36dcc81 100644 --- a/jdk/src/share/classes/java/util/Formatter.java +++ b/jdk/src/share/classes/java/util/Formatter.java @@ -2818,15 +2818,18 @@ public final class Formatter implements Closeable, Flushable { } private void printString(Object arg, Locale l) throws IOException { - if (arg == null) { - print("null"); - } else if (arg instanceof Formattable) { + if (arg instanceof Formattable) { Formatter fmt = formatter; if (formatter.locale() != l) fmt = new Formatter(formatter.out(), l); ((Formattable)arg).formatTo(fmt, f.valueOf(), width, precision); } else { - print(arg.toString()); + if (f.contains(Flags.ALTERNATE)) + failMismatch(Flags.ALTERNATE, 's'); + if (arg == null) + print("null"); + else + print(arg.toString()); } } diff --git a/jdk/test/java/util/Formatter/Basic-X.java b/jdk/test/java/util/Formatter/Basic-X.java index 4677062cc14..2469417d256 100644 --- a/jdk/test/java/util/Formatter/Basic-X.java +++ b/jdk/test/java/util/Formatter/Basic-X.java @@ -486,6 +486,10 @@ public class Basic$Type$ extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/Basic.java b/jdk/test/java/util/Formatter/Basic.java index 3a957b2f4fa..e973b186842 100644 --- a/jdk/test/java/util/Formatter/Basic.java +++ b/jdk/test/java/util/Formatter/Basic.java @@ -25,7 +25,7 @@ * @summary Unit test for formatter * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 - * 6344623 6369500 6534606 6282094 6286592 6476425 + * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 * * @run shell/timeout=240 Basic.sh */ diff --git a/jdk/test/java/util/Formatter/BasicBigDecimal.java b/jdk/test/java/util/Formatter/BasicBigDecimal.java index da96391384c..7f49988ee9d 100644 --- a/jdk/test/java/util/Formatter/BasicBigDecimal.java +++ b/jdk/test/java/util/Formatter/BasicBigDecimal.java @@ -486,6 +486,10 @@ public class BasicBigDecimal extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicBigInteger.java b/jdk/test/java/util/Formatter/BasicBigInteger.java index 4bba5a0fbe4..c7b3bc56002 100644 --- a/jdk/test/java/util/Formatter/BasicBigInteger.java +++ b/jdk/test/java/util/Formatter/BasicBigInteger.java @@ -486,6 +486,10 @@ public class BasicBigInteger extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicBoolean.java b/jdk/test/java/util/Formatter/BasicBoolean.java index ea60e388652..d626fdaba1d 100644 --- a/jdk/test/java/util/Formatter/BasicBoolean.java +++ b/jdk/test/java/util/Formatter/BasicBoolean.java @@ -486,6 +486,10 @@ public class BasicBoolean extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicBooleanObject.java b/jdk/test/java/util/Formatter/BasicBooleanObject.java index b4fbabb76b8..b0a3ab3694d 100644 --- a/jdk/test/java/util/Formatter/BasicBooleanObject.java +++ b/jdk/test/java/util/Formatter/BasicBooleanObject.java @@ -486,6 +486,10 @@ public class BasicBooleanObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicByte.java b/jdk/test/java/util/Formatter/BasicByte.java index deaf37957e5..8c630445459 100644 --- a/jdk/test/java/util/Formatter/BasicByte.java +++ b/jdk/test/java/util/Formatter/BasicByte.java @@ -486,6 +486,10 @@ public class BasicByte extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicByteObject.java b/jdk/test/java/util/Formatter/BasicByteObject.java index 06eb68ebd27..b2563784ee8 100644 --- a/jdk/test/java/util/Formatter/BasicByteObject.java +++ b/jdk/test/java/util/Formatter/BasicByteObject.java @@ -486,6 +486,10 @@ public class BasicByteObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicChar.java b/jdk/test/java/util/Formatter/BasicChar.java index 5ada7b166e7..cec8b76f58d 100644 --- a/jdk/test/java/util/Formatter/BasicChar.java +++ b/jdk/test/java/util/Formatter/BasicChar.java @@ -486,6 +486,10 @@ public class BasicChar extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicCharObject.java b/jdk/test/java/util/Formatter/BasicCharObject.java index 1e7d05d543f..4d1845977e3 100644 --- a/jdk/test/java/util/Formatter/BasicCharObject.java +++ b/jdk/test/java/util/Formatter/BasicCharObject.java @@ -486,6 +486,10 @@ public class BasicCharObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicDateTime.java b/jdk/test/java/util/Formatter/BasicDateTime.java index fd42da06f70..b30709d5465 100644 --- a/jdk/test/java/util/Formatter/BasicDateTime.java +++ b/jdk/test/java/util/Formatter/BasicDateTime.java @@ -486,6 +486,10 @@ public class BasicDateTime extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicDouble.java b/jdk/test/java/util/Formatter/BasicDouble.java index d985b46b1a5..5d5021717ec 100644 --- a/jdk/test/java/util/Formatter/BasicDouble.java +++ b/jdk/test/java/util/Formatter/BasicDouble.java @@ -486,6 +486,10 @@ public class BasicDouble extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicDoubleObject.java b/jdk/test/java/util/Formatter/BasicDoubleObject.java index 70dfd2929e5..1bbd67f18e9 100644 --- a/jdk/test/java/util/Formatter/BasicDoubleObject.java +++ b/jdk/test/java/util/Formatter/BasicDoubleObject.java @@ -486,6 +486,10 @@ public class BasicDoubleObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicFloat.java b/jdk/test/java/util/Formatter/BasicFloat.java index 122b44f1e75..c7592107261 100644 --- a/jdk/test/java/util/Formatter/BasicFloat.java +++ b/jdk/test/java/util/Formatter/BasicFloat.java @@ -486,6 +486,10 @@ public class BasicFloat extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicFloatObject.java b/jdk/test/java/util/Formatter/BasicFloatObject.java index 64c874cf2d5..c64bbb0f9d6 100644 --- a/jdk/test/java/util/Formatter/BasicFloatObject.java +++ b/jdk/test/java/util/Formatter/BasicFloatObject.java @@ -486,6 +486,10 @@ public class BasicFloatObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicInt.java b/jdk/test/java/util/Formatter/BasicInt.java index 4010d2250e0..5e42b45f76d 100644 --- a/jdk/test/java/util/Formatter/BasicInt.java +++ b/jdk/test/java/util/Formatter/BasicInt.java @@ -486,6 +486,10 @@ public class BasicInt extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicIntObject.java b/jdk/test/java/util/Formatter/BasicIntObject.java index fe41ea2964b..a9728b5bbf0 100644 --- a/jdk/test/java/util/Formatter/BasicIntObject.java +++ b/jdk/test/java/util/Formatter/BasicIntObject.java @@ -486,6 +486,10 @@ public class BasicIntObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicLong.java b/jdk/test/java/util/Formatter/BasicLong.java index fe232f1978e..41a74163050 100644 --- a/jdk/test/java/util/Formatter/BasicLong.java +++ b/jdk/test/java/util/Formatter/BasicLong.java @@ -486,6 +486,10 @@ public class BasicLong extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicLongObject.java b/jdk/test/java/util/Formatter/BasicLongObject.java index c99e0ba3c2a..c41c711ec7c 100644 --- a/jdk/test/java/util/Formatter/BasicLongObject.java +++ b/jdk/test/java/util/Formatter/BasicLongObject.java @@ -486,6 +486,10 @@ public class BasicLongObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicShort.java b/jdk/test/java/util/Formatter/BasicShort.java index 39079e4ad1e..e2e4e4c44f8 100644 --- a/jdk/test/java/util/Formatter/BasicShort.java +++ b/jdk/test/java/util/Formatter/BasicShort.java @@ -486,6 +486,10 @@ public class BasicShort extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h diff --git a/jdk/test/java/util/Formatter/BasicShortObject.java b/jdk/test/java/util/Formatter/BasicShortObject.java index e2dcc230174..48b33d18d85 100644 --- a/jdk/test/java/util/Formatter/BasicShortObject.java +++ b/jdk/test/java/util/Formatter/BasicShortObject.java @@ -486,6 +486,10 @@ public class BasicShortObject extends Basic { //--------------------------------------------------------------------- tryCatch("%-s", MissingFormatWidthException.class); tryCatch("%--s", DuplicateFormatFlagsException.class); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, 0.5f); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, "hello"); + tryCatch("%#s", FormatFlagsConversionMismatchException.class, null); //--------------------------------------------------------------------- // %h From 2655dbfaac691060df7b4a05f2e1ffbc52cd70ab Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 28 Jul 2009 10:36:25 -0700 Subject: [PATCH 025/102] 6855990: javap InstructionDetailWriter should support new 308 annotations attribute Reviewed-by: mcimadamore --- .../tools/classfile/ExtendedAnnotation.java | 6 - .../com/sun/tools/javap/AnnotationWriter.java | 220 ++++++++++++++++-- .../com/sun/tools/javap/CodeWriter.java | 7 + .../tools/javap/InstructionDetailWriter.java | 3 +- .../sun/tools/javap/TypeAnnotationWriter.java | 126 ++++++++++ .../tools/javap/typeAnnotations/T6855990.java | 51 ++++ 6 files changed, 384 insertions(+), 29 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java create mode 100644 langtools/test/tools/javap/typeAnnotations/T6855990.java diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java b/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java index 85e49d6c926..bb7b017dfc2 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java @@ -260,9 +260,6 @@ public class ExtendedAnnotation { // For generic/array types. public List location = new ArrayList(); - // Tree position. - public int pos = -1; - // For typecasts, type tests, new (and locals, as start_pc). public int offset = -1; @@ -391,9 +388,6 @@ public class ExtendedAnnotation { sb.append(")"); } - sb.append(", pos = "); - sb.append(pos); - sb.append(']'); return sb.toString(); } diff --git a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java index 1424255df5a..029026c47f5 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java @@ -32,6 +32,10 @@ import com.sun.tools.classfile.Annotation.Array_element_value; import com.sun.tools.classfile.Annotation.Class_element_value; import com.sun.tools.classfile.Annotation.Enum_element_value; import com.sun.tools.classfile.Annotation.Primitive_element_value; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Descriptor; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; /** * A writer for writing annotations as text. @@ -51,71 +55,243 @@ public class AnnotationWriter extends BasicWriter { protected AnnotationWriter(Context context) { super(context); + classWriter = ClassWriter.instance(context); + constantWriter = ConstantWriter.instance(context); } public void write(Annotation annot) { - print("#" + annot.type_index + "("); + write(annot, false); + } + + public void write(Annotation annot, boolean resolveIndices) { + writeDescriptor(annot.type_index, resolveIndices); + boolean showParens = annot.num_element_value_pairs > 0 || !resolveIndices; + if (showParens) + print("("); for (int i = 0; i < annot.num_element_value_pairs; i++) { if (i > 0) print(","); - write(annot.element_value_pairs[i]); + write(annot.element_value_pairs[i], resolveIndices); } - print(")"); + if (showParens) + print(")"); } public void write(ExtendedAnnotation annot) { - write(annot.annotation); - print('@'); - print(annot.position.toString()); + write(annot, true, false); + } + + public void write(ExtendedAnnotation annot, boolean showOffsets, boolean resolveIndices) { + write(annot.annotation, resolveIndices); + print(": "); + write(annot.position, showOffsets); + } + + public void write(ExtendedAnnotation.Position pos, boolean showOffsets) { + print(pos.type); + + switch (pos.type) { + // type case + case TYPECAST: + case TYPECAST_GENERIC_OR_ARRAY: + // object creation + case INSTANCEOF: + case INSTANCEOF_GENERIC_OR_ARRAY: + // new expression + case NEW: + case NEW_GENERIC_OR_ARRAY: + case NEW_TYPE_ARGUMENT: + case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + break; + // local variable + case LOCAL_VARIABLE: + case LOCAL_VARIABLE_GENERIC_OR_ARRAY: + print(", {"); + for (int i = 0; i < pos.lvarOffset.length; ++i) { + if (i != 0) print("; "); + if (showOffsets) { + print(", start_pc="); + print(pos.lvarOffset[i]); + } + print(", length="); + print(pos.lvarLength[i]); + print(", index="); + print(pos.lvarIndex[i]); + } + print("}"); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameters + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + // type parameters bound + case CLASS_TYPE_PARAMETER_BOUND: + case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY: + case METHOD_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY: + print(", param_index="); + print(pos.parameter_index); + print(", bound_index="); + print(pos.bound_index); + break; + // wildcard + case WILDCARD_BOUND: + case WILDCARD_BOUND_GENERIC_OR_ARRAY: + print(", wild_card="); + print(pos.wildcard_position); + break; + // Class extends and implements clauses + case CLASS_EXTENDS: + case CLASS_EXTENDS_GENERIC_OR_ARRAY: + print(", type_index="); + print(pos.type_index); + break; + // throws + case THROWS: + print(", type_index="); + print(pos.type_index); + break; + case CLASS_LITERAL: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + break; + // method parameter: not specified + case METHOD_PARAMETER_GENERIC_OR_ARRAY: + print(", param_index="); + print(pos.parameter_index); + break; + // method type argument: wasn't specified + case METHOD_TYPE_ARGUMENT: + case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + print(", type_index="); + print(pos.type_index); + break; + // We don't need to worry abut these + case METHOD_RETURN_GENERIC_OR_ARRAY: + case FIELD_GENERIC_OR_ARRAY: + break; + case UNKNOWN: + break; + default: + throw new AssertionError("unknown type: " + pos.type); + } + + // Append location data for generics/arrays. + if (pos.type.hasLocation()) { + print(", location="); + print(pos.location); + } } public void write(Annotation.element_value_pair pair) { - print("#" + pair.element_name_index + ":"); - write(pair.value); + write(pair, false); + } + + public void write(Annotation.element_value_pair pair, boolean resolveIndices) { + writeIndex(pair.element_name_index, resolveIndices); + print("="); + write(pair.value, resolveIndices); } public void write(Annotation.element_value value) { - ev_writer.write(value); + write(value, false); + } + + public void write(Annotation.element_value value, boolean resolveIndices) { + ev_writer.write(value, resolveIndices); + } + + private void writeDescriptor(int index, boolean resolveIndices) { + if (resolveIndices) { + try { + ConstantPool constant_pool = classWriter.getClassFile().constant_pool; + Descriptor d = new Descriptor(index); + print(d.getFieldType(constant_pool)); + return; + } catch (ConstantPoolException ignore) { + } catch (InvalidDescriptor ignore) { + } + } + + print("#" + index); + } + + private void writeIndex(int index, boolean resolveIndices) { + if (resolveIndices) { + print(constantWriter.stringValue(index)); + } else + print("#" + index); } element_value_Writer ev_writer = new element_value_Writer(); - class element_value_Writer implements Annotation.element_value.Visitor { - public void write(Annotation.element_value value) { - value.accept(this, null); + class element_value_Writer implements Annotation.element_value.Visitor { + public void write(Annotation.element_value value, boolean resolveIndices) { + value.accept(this, resolveIndices); } - public Void visitPrimitive(Primitive_element_value ev, Void p) { - print(((char) ev.tag) + "#" + ev.const_value_index); + public Void visitPrimitive(Primitive_element_value ev, Boolean resolveIndices) { + if (resolveIndices) + writeIndex(ev.const_value_index, resolveIndices); + else + print(((char) ev.tag) + "#" + ev.const_value_index); return null; } - public Void visitEnum(Enum_element_value ev, Void p) { - print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index); + public Void visitEnum(Enum_element_value ev, Boolean resolveIndices) { + if (resolveIndices) { + writeIndex(ev.type_name_index, resolveIndices); + print("."); + writeIndex(ev.const_name_index, resolveIndices); + } else + print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index); return null; } - public Void visitClass(Class_element_value ev, Void p) { - print(((char) ev.tag) + "#" + ev.class_info_index); + public Void visitClass(Class_element_value ev, Boolean resolveIndices) { + if (resolveIndices) { + writeIndex(ev.class_info_index, resolveIndices); + print(".class"); + } else + print(((char) ev.tag) + "#" + ev.class_info_index); return null; } - public Void visitAnnotation(Annotation_element_value ev, Void p) { + public Void visitAnnotation(Annotation_element_value ev, Boolean resolveIndices) { print((char) ev.tag); - AnnotationWriter.this.write(ev.annotation_value); + AnnotationWriter.this.write(ev.annotation_value, resolveIndices); return null; } - public Void visitArray(Array_element_value ev, Void p) { + public Void visitArray(Array_element_value ev, Boolean resolveIndices) { print("["); for (int i = 0; i < ev.num_values; i++) { if (i > 0) print(","); - write(ev.values[i]); + write(ev.values[i], resolveIndices); } print("]"); return null; } } + + private ClassWriter classWriter; + private ConstantWriter constantWriter; } diff --git a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java index 631e1685acc..975e3621536 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java @@ -64,6 +64,7 @@ class CodeWriter extends BasicWriter { stackMapWriter = StackMapWriter.instance(context); localVariableTableWriter = LocalVariableTableWriter.instance(context); localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context); + typeAnnotationWriter = TypeAnnotationWriter.instance(context); options = Options.instance(context); } @@ -253,6 +254,11 @@ class CodeWriter extends BasicWriter { detailWriters.add(tryBlockWriter); } + if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) { + typeAnnotationWriter.reset(attr); + detailWriters.add(typeAnnotationWriter); + } + return detailWriters; } @@ -261,6 +267,7 @@ class CodeWriter extends BasicWriter { private ConstantWriter constantWriter; private LocalVariableTableWriter localVariableTableWriter; private LocalVariableTypeTableWriter localVariableTypeTableWriter; + private TypeAnnotationWriter typeAnnotationWriter; private SourceWriter sourceWriter; private StackMapWriter stackMapWriter; private TryBlockWriter tryBlockWriter; diff --git a/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java b/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java index 81b31755865..02492b1ee6e 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java @@ -42,7 +42,8 @@ public abstract class InstructionDetailWriter extends BasicWriter { LOCAL_VAR_TYPES("localVariableTypes"), SOURCE("source"), STACKMAPS("stackMaps"), - TRY_BLOCKS("tryBlocks"); + TRY_BLOCKS("tryBlocks"), + TYPE_ANNOS("typeAnnotations"); Kind(String option) { this.option = option; } diff --git a/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java new file mode 100644 index 00000000000..3e7aef8bf35 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java @@ -0,0 +1,126 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.sun.tools.javap; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ExtendedAnnotation; +import com.sun.tools.classfile.ExtendedAnnotation.Position; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; +import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Annotate instructions with details about type annotations. + * + *

This is NOT part of any API supported by Sun Microsystems. 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 TypeAnnotationWriter extends InstructionDetailWriter { + public enum NoteKind { VISIBLE, INVISIBLE }; + public static class Note { + Note(NoteKind kind, ExtendedAnnotation anno) { + this.kind = kind; + this.anno = anno; + } + public final NoteKind kind; + public final ExtendedAnnotation anno; + } + + static TypeAnnotationWriter instance(Context context) { + TypeAnnotationWriter instance = context.get(TypeAnnotationWriter.class); + if (instance == null) + instance = new TypeAnnotationWriter(context); + return instance; + } + + protected TypeAnnotationWriter(Context context) { + super(context); + context.put(TypeAnnotationWriter.class, this); + annotationWriter = AnnotationWriter.instance(context); + classWriter = ClassWriter.instance(context); + } + + public void reset(Code_attribute attr) { + Method m = classWriter.getMethod(); + pcMap = new HashMap>(); + check(NoteKind.VISIBLE, (RuntimeVisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleTypeAnnotations)); + check(NoteKind.INVISIBLE, (RuntimeInvisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeInvisibleTypeAnnotations)); + } + + private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) { + if (attr == null) + return; + + for (ExtendedAnnotation anno: attr.annotations) { + Position p = anno.position; + Note note = null; + if (p.offset != -1) + addNote(p.offset, note = new Note(kind, anno)); + if (p.lvarOffset != null) { + for (int i = 0; i < p.lvarOffset.length; i++) { + if (note == null) + note = new Note(kind, anno); + addNote(p.lvarOffset[i], note); + } + } + } + } + + private void addNote(int pc, Note note) { + List list = pcMap.get(pc); + if (list == null) + pcMap.put(pc, list = new ArrayList()); + list.add(note); + } + + @Override + void writeDetails(Instruction instr) { + String indent = space(2); // get from Options? + int pc = instr.getPC(); + List notes = pcMap.get(pc); + if (notes != null) { + for (Note n: notes) { + print(indent); + print("@"); + annotationWriter.write(n.anno, false, true); + print(", "); + println(n.kind.toString().toLowerCase()); + } + } + } + + private AnnotationWriter annotationWriter; + private ClassWriter classWriter; + private Map> pcMap; +} diff --git a/langtools/test/tools/javap/typeAnnotations/T6855990.java b/langtools/test/tools/javap/typeAnnotations/T6855990.java new file mode 100644 index 00000000000..f5baa3dc6f0 --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/T6855990.java @@ -0,0 +1,51 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; + +/* + * @test + * @bug 6855990 + * @summary InstructionDetailWriter should support new 308 annotations attribute + */ + +public class T6855990 { + public static void main(String[] args) throws Exception { + new T6855990().run(); + } + + public void run() throws Exception { + @Simple String[] args = { "-c", "-XDdetails:typeAnnotations", "T6855990" }; + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javap.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + System.out.println(out); + if (out.indexOf("@Simple: LOCAL_VARIABLE") == -1) + throw new Exception("expected output not found"); + } +} + +@interface Simple { } + From 66637352acdec40561df47c94bef2883136a1380 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 28 Jul 2009 11:00:05 -0700 Subject: [PATCH 026/102] 6734068: Some variable length attributes set their size incorrectly Reviewed-by: mcimadamore --- .../com/sun/tools/classfile/CharacterRangeTable_attribute.java | 2 +- .../com/sun/tools/classfile/LineNumberTable_attribute.java | 2 +- .../com/sun/tools/classfile/LocalVariableTable_attribute.java | 2 +- .../sun/tools/classfile/LocalVariableTypeTable_attribute.java | 2 +- .../com/sun/tools/classfile/ModuleExportTable_attribute.java | 2 +- .../com/sun/tools/classfile/ModuleMemberTable_attribute.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java index 8a668660cc5..1ecfd82e575 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java @@ -58,7 +58,7 @@ public class CharacterRangeTable_attribute extends Attribute { } public CharacterRangeTable_attribute(int name_index, Entry[] character_range_table) { - super(name_index, character_range_table.length * Entry.length()); + super(name_index, 2 + character_range_table.length * Entry.length()); this.character_range_table = character_range_table; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java index 999e89ac507..a26d9c7f86d 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java @@ -50,7 +50,7 @@ public class LineNumberTable_attribute extends Attribute { } public LineNumberTable_attribute(int name_index, Entry[] line_number_table) { - super(name_index, line_number_table.length * Entry.length()); + super(name_index, 2 + line_number_table.length * Entry.length()); this.line_number_table_length = line_number_table.length; this.line_number_table = line_number_table; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java index 0975132c373..c33edfbfd5f 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java @@ -50,7 +50,7 @@ public class LocalVariableTable_attribute extends Attribute { } public LocalVariableTable_attribute(int name_index, Entry[] local_variable_table) { - super(name_index, local_variable_table.length * Entry.length()); + super(name_index, 2 + local_variable_table.length * Entry.length()); this.local_variable_table_length = local_variable_table.length; this.local_variable_table = local_variable_table; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java index 0cf4588411a..d98d5b5c02f 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java @@ -50,7 +50,7 @@ public class LocalVariableTypeTable_attribute extends Attribute { } public LocalVariableTypeTable_attribute(int name_index, Entry[] local_variable_table) { - super(name_index, local_variable_table.length * Entry.length()); + super(name_index, 2 + local_variable_table.length * Entry.length()); this.local_variable_table_length = local_variable_table.length; this.local_variable_table = local_variable_table; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java index 5bb0679f117..74cc3b395c6 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java @@ -50,7 +50,7 @@ public class ModuleExportTable_attribute extends Attribute { } public ModuleExportTable_attribute(int name_index, int[] export_type_table) { - super(name_index, 2 * export_type_table.length); + super(name_index, 2 + 2 * export_type_table.length); this.export_type_table = export_type_table; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java index eb679cc9ed4..c5eaf78eff5 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java @@ -49,7 +49,7 @@ public class ModuleMemberTable_attribute extends Attribute { } public ModuleMemberTable_attribute(int name_index, int[] package_member_table) { - super(name_index, 2 * package_member_table.length); + super(name_index, 2 + 2 * package_member_table.length); this.package_member_table = package_member_table; } From df5da31f55e9a647549d7e3a91a01b00f4b42833 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Tue, 28 Jul 2009 13:24:52 -0700 Subject: [PATCH 027/102] 6785442: ConcurrentLinkedQueue.remove() and poll() can both remove the same element 6493942: ConcurrentLinkedQueue.remove sometimes very slow New algorithm for handling concurrent linked lists Reviewed-by: martin --- .../concurrent/ConcurrentLinkedQueue.java | 448 ++++++++++++------ .../ConcurrentQueueLoops.java | 98 +++- .../ConcurrentQueues/GCRetention.java | 165 +++++++ .../LoopHelpers.java | 0 .../ConcurrentQueues/RemovePollRace.java | 230 +++++++++ .../LinkedBlockingQueue/OfferRemoveLoops.java | 74 +-- 6 files changed, 806 insertions(+), 209 deletions(-) rename jdk/test/java/util/concurrent/{ConcurrentLinkedQueue => ConcurrentQueues}/ConcurrentQueueLoops.java (57%) create mode 100644 jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java rename jdk/test/java/util/concurrent/{ConcurrentLinkedQueue => ConcurrentQueues}/LoopHelpers.java (100%) create mode 100644 jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index fafbcc01704..fe2bb9d8bca 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -34,9 +34,13 @@ */ package java.util.concurrent; -import java.util.*; -import java.util.concurrent.atomic.*; +import java.util.AbstractQueue; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Queue; /** * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes. @@ -47,9 +51,9 @@ import java.util.concurrent.atomic.*; * queue the shortest time. New elements * are inserted at the tail of the queue, and the queue retrieval * operations obtain elements at the head of the queue. - * A ConcurrentLinkedQueue is an appropriate choice when + * A {@code ConcurrentLinkedQueue} is an appropriate choice when * many threads will share access to a common collection. - * This queue does not permit null elements. + * This queue does not permit {@code null} elements. * *

This implementation employs an efficient "wait-free" * algorithm based on one described in by Maged M. Michael and Michael L. Scott. * - *

Beware that, unlike in most collections, the size method + *

Beware that, unlike in most collections, the {@code size} method * is NOT a constant-time operation. Because of the * asynchronous nature of these queues, determining the current number * of elements requires a traversal of the elements. @@ -87,51 +91,102 @@ public class ConcurrentLinkedQueue extends AbstractQueue private static final long serialVersionUID = 196745693267521676L; /* - * This is a straight adaptation of Michael & Scott algorithm. - * For explanation, read the paper. The only (minor) algorithmic - * difference is that this version supports lazy deletion of - * internal nodes (method remove(Object)) -- remove CAS'es item - * fields to null. The normal queue operations unlink but then - * pass over nodes with null item fields. Similarly, iteration - * methods ignore those with nulls. + * This is a modification of the Michael & Scott algorithm, + * adapted for a garbage-collected environment, with support for + * interior node deletion (to support remove(Object)). For + * explanation, read the paper. * - * Also note that like most non-blocking algorithms in this - * package, this implementation relies on the fact that in garbage + * Note that like most non-blocking algorithms in this package, + * this implementation relies on the fact that in garbage * collected systems, there is no possibility of ABA problems due * to recycled nodes, so there is no need to use "counted * pointers" or related techniques seen in versions used in * non-GC'ed settings. + * + * The fundamental invariants are: + * - There is exactly one (last) Node with a null next reference, + * which is CASed when enqueueing. This last Node can be + * reached in O(1) time from tail, but tail is merely an + * optimization - it can always be reached in O(N) time from + * head as well. + * - The elements contained in the queue are the non-null items in + * Nodes that are reachable from head. CASing the item + * reference of a Node to null atomically removes it from the + * queue. Reachability of all elements from head must remain + * true even in the case of concurrent modifications that cause + * head to advance. A dequeued Node may remain in use + * indefinitely due to creation of an Iterator or simply a + * poll() that has lost its time slice. + * + * The above might appear to imply that all Nodes are GC-reachable + * from a predecessor dequeued Node. That would cause two problems: + * - allow a rogue Iterator to cause unbounded memory retention + * - cause cross-generational linking of old Nodes to new Nodes if + * a Node was tenured while live, which generational GCs have a + * hard time dealing with, causing repeated major collections. + * However, only non-deleted Nodes need to be reachable from + * dequeued Nodes, and reachability does not necessarily have to + * be of the kind understood by the GC. We use the trick of + * linking a Node that has just been dequeued to itself. Such a + * self-link implicitly means to advance to head. + * + * Both head and tail are permitted to lag. In fact, failing to + * update them every time one could is a significant optimization + * (fewer CASes). This is controlled by local "hops" variables + * that only trigger helping-CASes after experiencing multiple + * lags. + * + * Since head and tail are updated concurrently and independently, + * it is possible for tail to lag behind head (why not)? + * + * CASing a Node's item reference to null atomically removes the + * element from the queue. Iterators skip over Nodes with null + * items. Prior implementations of this class had a race between + * poll() and remove(Object) where the same element would appear + * to be successfully removed by two concurrent operations. The + * method remove(Object) also lazily unlinks deleted Nodes, but + * this is merely an optimization. + * + * When constructing a Node (before enqueuing it) we avoid paying + * for a volatile write to item by using lazySet instead of a + * normal write. This allows the cost of enqueue to be + * "one-and-a-half" CASes. + * + * Both head and tail may or may not point to a Node with a + * non-null item. If the queue is empty, all items must of course + * be null. Upon creation, both head and tail refer to a dummy + * Node with null item. Both head and tail are only updated using + * CAS, so they never regress, although again this is merely an + * optimization. */ private static class Node { private volatile E item; private volatile Node next; - private static final - AtomicReferenceFieldUpdater - nextUpdater = - AtomicReferenceFieldUpdater.newUpdater - (Node.class, Node.class, "next"); - private static final - AtomicReferenceFieldUpdater - itemUpdater = - AtomicReferenceFieldUpdater.newUpdater - (Node.class, Object.class, "item"); - - Node(E x) { item = x; } - - Node(E x, Node n) { item = x; next = n; } + Node(E item) { + // Piggyback on imminent casNext() + lazySetItem(item); + } E getItem() { return item; } boolean casItem(E cmp, E val) { - return itemUpdater.compareAndSet(this, cmp, val); + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val); } void setItem(E val) { - itemUpdater.set(this, val); + item = val; + } + + void lazySetItem(E val) { + UNSAFE.putOrderedObject(this, itemOffset, val); + } + + void lazySetNext(Node val) { + UNSAFE.putOrderedObject(this, nextOffset, val); } Node getNext() { @@ -139,52 +194,55 @@ public class ConcurrentLinkedQueue extends AbstractQueue } boolean casNext(Node cmp, Node val) { - return nextUpdater.compareAndSet(this, cmp, val); + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); } - void setNext(Node val) { - nextUpdater.set(this, val); - } + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE = + sun.misc.Unsafe.getUnsafe(); + private static final long nextOffset = + objectFieldOffset(UNSAFE, "next", Node.class); + private static final long itemOffset = + objectFieldOffset(UNSAFE, "item", Node.class); } - private static final - AtomicReferenceFieldUpdater - tailUpdater = - AtomicReferenceFieldUpdater.newUpdater - (ConcurrentLinkedQueue.class, Node.class, "tail"); - private static final - AtomicReferenceFieldUpdater - headUpdater = - AtomicReferenceFieldUpdater.newUpdater - (ConcurrentLinkedQueue.class, Node.class, "head"); - - private boolean casTail(Node cmp, Node val) { - return tailUpdater.compareAndSet(this, cmp, val); - } - - private boolean casHead(Node cmp, Node val) { - return headUpdater.compareAndSet(this, cmp, val); - } - - /** - * Pointer to header node, initialized to a dummy node. The first - * actual node is at head.getNext(). + * A node from which the first live (non-deleted) node (if any) + * can be reached in O(1) time. + * Invariants: + * - all live nodes are reachable from head via succ() + * - head != null + * - (tmp = head).next != tmp || tmp != head + * Non-invariants: + * - head.item may or may not be null. + * - it is permitted for tail to lag behind head, that is, for tail + * to not be reachable from head! */ - private transient volatile Node head = new Node(null, null); + private transient volatile Node head = new Node(null); - /** Pointer to last node on list **/ + /** + * A node from which the last node on list (that is, the unique + * node with node.next == null) can be reached in O(1) time. + * Invariants: + * - the last node is always reachable from tail via succ() + * - tail != null + * Non-invariants: + * - tail.item may or may not be null. + * - it is permitted for tail to lag behind head, that is, for tail + * to not be reachable from head! + * - tail.next may or may not be self-pointing to tail. + */ private transient volatile Node tail = head; /** - * Creates a ConcurrentLinkedQueue that is initially empty. + * Creates a {@code ConcurrentLinkedQueue} that is initially empty. */ public ConcurrentLinkedQueue() {} /** - * Creates a ConcurrentLinkedQueue + * Creates a {@code ConcurrentLinkedQueue} * initially containing the elements of the given collection, * added in traversal order of the collection's iterator. * @param c the collection of elements to initially contain @@ -201,115 +259,143 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Inserts the specified element at the tail of this queue. * - * @return true (as specified by {@link Collection#add}) + * @return {@code true} (as specified by {@link Collection#add}) * @throws NullPointerException if the specified element is null */ public boolean add(E e) { return offer(e); } + /** + * We don't bother to update head or tail pointers if fewer than + * HOPS links from "true" location. We assume that volatile + * writes are significantly more expensive than volatile reads. + */ + private static final int HOPS = 1; + + /** + * Try to CAS head to p. If successful, repoint old head to itself + * as sentinel for succ(), below. + */ + final void updateHead(Node h, Node p) { + if (h != p && casHead(h, p)) + h.lazySetNext(h); + } + + /** + * Returns the successor of p, or the head node if p.next has been + * linked to self, which will only be true if traversing with a + * stale pointer that is now off the list. + */ + final Node succ(Node p) { + Node next = p.getNext(); + return (p == next) ? head : next; + } + /** * Inserts the specified element at the tail of this queue. * - * @return true (as specified by {@link Queue#offer}) + * @return {@code true} (as specified by {@link Queue#offer}) * @throws NullPointerException if the specified element is null */ public boolean offer(E e) { if (e == null) throw new NullPointerException(); - Node n = new Node(e, null); + Node n = new Node(e); + retry: for (;;) { Node t = tail; - Node s = t.getNext(); - if (t == tail) { - if (s == null) { - if (t.casNext(s, n)) { - casTail(t, n); - return true; - } + Node p = t; + for (int hops = 0; ; hops++) { + Node next = succ(p); + if (next != null) { + if (hops > HOPS && t != tail) + continue retry; + p = next; + } else if (p.casNext(null, n)) { + if (hops >= HOPS) + casTail(t, n); // Failure is OK. + return true; } else { - casTail(t, s); + p = succ(p); } } } } public E poll() { - for (;;) { - Node h = head; - Node t = tail; - Node first = h.getNext(); - if (h == head) { - if (h == t) { - if (first == null) - return null; - else - casTail(t, first); - } else if (casHead(h, first)) { - E item = first.getItem(); - if (item != null) { - first.setItem(null); - return item; - } - // else skip over deleted item, continue loop, + Node h = head; + Node p = h; + for (int hops = 0; ; hops++) { + E item = p.getItem(); + + if (item != null && p.casItem(item, null)) { + if (hops >= HOPS) { + Node q = p.getNext(); + updateHead(h, (q != null) ? q : p); } + return item; } + Node next = succ(p); + if (next == null) { + updateHead(h, p); + break; + } + p = next; } + return null; } - public E peek() { // same as poll except don't remove item + public E peek() { + Node h = head; + Node p = h; + E item; for (;;) { - Node h = head; - Node t = tail; - Node first = h.getNext(); - if (h == head) { - if (h == t) { - if (first == null) - return null; - else - casTail(t, first); - } else { - E item = first.getItem(); - if (item != null) - return item; - else // remove deleted node and continue - casHead(h, first); - } + item = p.getItem(); + if (item != null) + break; + Node next = succ(p); + if (next == null) { + break; } + p = next; } + updateHead(h, p); + return item; } /** - * Returns the first actual (non-header) node on list. This is yet - * another variant of poll/peek; here returning out the first - * node, not element (so we cannot collapse with peek() without - * introducing race.) + * Returns the first live (non-deleted) node on list, or null if none. + * This is yet another variant of poll/peek; here returning the + * first node, not element. We could make peek() a wrapper around + * first(), but that would cost an extra volatile read of item, + * and the need to add a retry loop to deal with the possibility + * of losing a race to a concurrent poll(). */ Node first() { + Node h = head; + Node p = h; + Node result; for (;;) { - Node h = head; - Node t = tail; - Node first = h.getNext(); - if (h == head) { - if (h == t) { - if (first == null) - return null; - else - casTail(t, first); - } else { - if (first.getItem() != null) - return first; - else // remove deleted node and continue - casHead(h, first); - } + E item = p.getItem(); + if (item != null) { + result = p; + break; } + Node next = succ(p); + if (next == null) { + result = null; + break; + } + p = next; } + updateHead(h, p); + return result; } - /** - * Returns true if this queue contains no elements. + * Returns {@code true} if this queue contains no elements. * - * @return true if this queue contains no elements + * @return {@code true} if this queue contains no elements */ public boolean isEmpty() { return first() == null; @@ -317,8 +403,8 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Returns the number of elements in this queue. If this queue - * contains more than Integer.MAX_VALUE elements, returns - * Integer.MAX_VALUE. + * contains more than {@code Integer.MAX_VALUE} elements, returns + * {@code Integer.MAX_VALUE}. * *

Beware that, unlike in most collections, this method is * NOT a constant-time operation. Because of the @@ -329,7 +415,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue */ public int size() { int count = 0; - for (Node p = first(); p != null; p = p.getNext()) { + for (Node p = first(); p != null; p = succ(p)) { if (p.getItem() != null) { // Collections.size() spec says to max out if (++count == Integer.MAX_VALUE) @@ -340,16 +426,16 @@ public class ConcurrentLinkedQueue extends AbstractQueue } /** - * Returns true if this queue contains the specified element. - * More formally, returns true if and only if this queue contains - * at least one element e such that o.equals(e). + * Returns {@code true} if this queue contains the specified element. + * More formally, returns {@code true} if and only if this queue contains + * at least one element {@code e} such that {@code o.equals(e)}. * * @param o object to be checked for containment in this queue - * @return true if this queue contains the specified element + * @return {@code true} if this queue contains the specified element */ public boolean contains(Object o) { if (o == null) return false; - for (Node p = first(); p != null; p = p.getNext()) { + for (Node p = first(); p != null; p = succ(p)) { E item = p.getItem(); if (item != null && o.equals(item)) @@ -360,23 +446,29 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element e such - * that o.equals(e), if this queue contains one or more such + * if it is present. More formally, removes an element {@code e} such + * that {@code o.equals(e)}, if this queue contains one or more such * elements. - * Returns true if this queue contained the specified element + * Returns {@code true} if this queue contained the specified element * (or equivalently, if this queue changed as a result of the call). * * @param o element to be removed from this queue, if present - * @return true if this queue changed as a result of the call + * @return {@code true} if this queue changed as a result of the call */ public boolean remove(Object o) { if (o == null) return false; - for (Node p = first(); p != null; p = p.getNext()) { + Node pred = null; + for (Node p = first(); p != null; p = succ(p)) { E item = p.getItem(); if (item != null && o.equals(item) && - p.casItem(item, null)) + p.casItem(item, null)) { + Node next = succ(p); + if (pred != null && next != null) + pred.casNext(p, next); return true; + } + pred = p; } return false; } @@ -397,7 +489,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue public Object[] toArray() { // Use ArrayList to deal with resizing. ArrayList al = new ArrayList(); - for (Node p = first(); p != null; p = p.getNext()) { + for (Node p = first(); p != null; p = succ(p)) { E item = p.getItem(); if (item != null) al.add(item); @@ -415,22 +507,22 @@ public class ConcurrentLinkedQueue extends AbstractQueue *

If this queue fits in the specified array with room to spare * (i.e., the array has more elements than this queue), the element in * the array immediately following the end of the queue is set to - * null. + * {@code null}. * *

Like the {@link #toArray()} method, this method acts as bridge between * array-based and collection-based APIs. Further, this method allows * precise control over the runtime type of the output array, and may, * under certain circumstances, be used to save allocation costs. * - *

Suppose x is a queue known to contain only strings. + *

Suppose {@code x} is a queue known to contain only strings. * The following code can be used to dump the queue into a newly - * allocated array of String: + * allocated array of {@code String}: * *

      *     String[] y = x.toArray(new String[0]);
* - * Note that toArray(new Object[0]) is identical in function to - * toArray(). + * Note that {@code toArray(new Object[0])} is identical in function to + * {@code toArray()}. * * @param a the array into which the elements of the queue are to * be stored, if it is big enough; otherwise, a new array of the @@ -441,11 +533,12 @@ public class ConcurrentLinkedQueue extends AbstractQueue * this queue * @throws NullPointerException if the specified array is null */ + @SuppressWarnings("unchecked") public T[] toArray(T[] a) { // try to use sent-in array int k = 0; Node p; - for (p = first(); p != null && k < a.length; p = p.getNext()) { + for (p = first(); p != null && k < a.length; p = succ(p)) { E item = p.getItem(); if (item != null) a[k++] = (T)item; @@ -458,7 +551,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue // If won't fit, use ArrayList version ArrayList al = new ArrayList(); - for (Node q = first(); q != null; q = q.getNext()) { + for (Node q = first(); q != null; q = succ(q)) { E item = q.getItem(); if (item != null) al.add(item); @@ -511,7 +604,15 @@ public class ConcurrentLinkedQueue extends AbstractQueue lastRet = nextNode; E x = nextItem; - Node p = (nextNode == null)? first() : nextNode.getNext(); + Node pred, p; + if (nextNode == null) { + p = first(); + pred = null; + } else { + pred = nextNode; + p = succ(nextNode); + } + for (;;) { if (p == null) { nextNode = null; @@ -523,8 +624,13 @@ public class ConcurrentLinkedQueue extends AbstractQueue nextNode = p; nextItem = item; return x; - } else // skip over nulls - p = p.getNext(); + } else { + // skip over nulls + Node next = succ(p); + if (pred != null && next != null) + pred.casNext(p, next); + p = next; + } } } @@ -549,7 +655,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Save the state to a stream (that is, serialize it). * - * @serialData All of the elements (each an E) in + * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null * @param s the stream */ @@ -560,7 +666,7 @@ public class ConcurrentLinkedQueue extends AbstractQueue s.defaultWriteObject(); // Write out all elements in the proper order. - for (Node p = first(); p != null; p = p.getNext()) { + for (Node p = first(); p != null; p = succ(p)) { Object item = p.getItem(); if (item != null) s.writeObject(item); @@ -579,10 +685,11 @@ public class ConcurrentLinkedQueue extends AbstractQueue throws java.io.IOException, ClassNotFoundException { // Read in capacity, and any hidden stuff s.defaultReadObject(); - head = new Node(null, null); + head = new Node(null); tail = head; // Read in all elements and place in queue for (;;) { + @SuppressWarnings("unchecked") E item = (E)s.readObject(); if (item == null) break; @@ -591,4 +698,35 @@ public class ConcurrentLinkedQueue extends AbstractQueue } } + // Unsafe mechanics + + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); + private static final long headOffset = + objectFieldOffset(UNSAFE, "head", ConcurrentLinkedQueue.class); + private static final long tailOffset = + objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedQueue.class); + + private boolean casTail(Node cmp, Node val) { + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); + } + + private boolean casHead(Node cmp, Node val) { + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); + } + + private void lazySetHead(Node val) { + UNSAFE.putOrderedObject(this, headOffset, val); + } + + static long objectFieldOffset(sun.misc.Unsafe UNSAFE, + String field, Class klazz) { + try { + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); + } catch (NoSuchFieldException e) { + // Convert Exception to corresponding Error + NoSuchFieldError error = new NoSuchFieldError(field); + error.initCause(e); + throw error; + } + } } diff --git a/jdk/test/java/util/concurrent/ConcurrentLinkedQueue/ConcurrentQueueLoops.java b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java similarity index 57% rename from jdk/test/java/util/concurrent/ConcurrentLinkedQueue/ConcurrentQueueLoops.java rename to jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java index b0c4b68e10e..73dfc65c768 100644 --- a/jdk/test/java/util/concurrent/ConcurrentLinkedQueue/ConcurrentQueueLoops.java +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java @@ -33,9 +33,8 @@ /* * @test - * @bug 4486658 - * @compile -source 1.5 ConcurrentQueueLoops.java - * @run main/timeout=230 ConcurrentQueueLoops + * @bug 4486658 6785442 + * @run main ConcurrentQueueLoops 8 123456 * @summary Checks that a set of threads can repeatedly get and modify items */ @@ -44,34 +43,75 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.*; public class ConcurrentQueueLoops { - static final ExecutorService pool = Executors.newCachedThreadPool(); - static AtomicInteger totalItems; - static boolean print = false; + ExecutorService pool; + AtomicInteger totalItems; + boolean print; - public static void main(String[] args) throws Exception { - int maxStages = 8; - int items = 100000; + // Suitable for benchmarking. Overriden by args[0] for testing. + int maxStages = 20; + // Suitable for benchmarking. Overriden by args[1] for testing. + int items = 1024 * 1024; + + Collection> concurrentQueues() { + List> queues = new ArrayList>(); + queues.add(new ConcurrentLinkedQueue()); + queues.add(new ArrayBlockingQueue(items, false)); + //queues.add(new ArrayBlockingQueue(count, true)); + queues.add(new LinkedBlockingQueue()); + queues.add(new LinkedBlockingDeque()); + + try { + queues.add((Queue) + Class.forName("java.util.concurrent.LinkedTransferQueue") + .newInstance()); + } catch (IllegalAccessException e) { + } catch (InstantiationException e) { + } catch (ClassNotFoundException e) { + // OK; not yet added to JDK + } + + // Following additional implementations are available from: + // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html + // queues.add(new LinkedTransferQueue()); + // queues.add(new SynchronizedLinkedListQueue()); + + // Avoid "first fast, second slow" benchmark effect. + Collections.shuffle(queues); + return queues; + } + + void test(String[] args) throws Throwable { if (args.length > 0) maxStages = Integer.parseInt(args[0]); + if (args.length > 1) + items = Integer.parseInt(args[1]); + + for (Queue queue : concurrentQueues()) + test(queue); + } + + void test(final Queue q) throws Throwable { + System.out.println(q.getClass().getSimpleName()); + pool = Executors.newCachedThreadPool(); + print = false; print = false; System.out.println("Warmup..."); - oneRun(1, items); - Thread.sleep(100); - oneRun(1, items); + oneRun(1, items, q); + //Thread.sleep(100); + oneRun(3, items, q); Thread.sleep(100); print = true; for (int i = 1; i <= maxStages; i += (i+1) >>> 1) { - oneRun(i, items); + oneRun(i, items, q); } pool.shutdown(); - if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) - throw new Error(); + check(pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)); } - static class Stage implements Callable { + class Stage implements Callable { final Queue queue; final CyclicBarrier barrier; int items; @@ -110,15 +150,11 @@ public class ConcurrentQueueLoops { } return new Integer(l); } - catch (Exception ie) { - ie.printStackTrace(); - throw new Error("Call loop failed"); - } + catch (Throwable t) { unexpected(t); return null; } } } - static void oneRun(int n, int items) throws Exception { - Queue q = new ConcurrentLinkedQueue(); + void oneRun(int n, int items, final Queue q) throws Exception { LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); CyclicBarrier barrier = new CyclicBarrier(n + 1, timer); totalItems = new AtomicInteger(n * items); @@ -141,6 +177,22 @@ public class ConcurrentQueueLoops { System.out.println(LoopHelpers.rightJustify(time / (items * n)) + " ns per item"); if (total == 0) // avoid overoptimization System.out.println("useless result: " + total); - } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new ConcurrentQueueLoops().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} } diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java b/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java new file mode 100644 index 00000000000..68e62734359 --- /dev/null +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java @@ -0,0 +1,165 @@ +/* + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ +/* + * @test + * @bug 6785442 + * @summary Benchmark that tries to GC-tenure head, followed by + * many add/remove operations. + * @run main GCRetention 12345 + */ + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.PriorityBlockingQueue; +import java.util.LinkedList; +import java.util.PriorityQueue; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Queue; +import java.util.Map; + +public class GCRetention { + // Suitable for benchmarking. Overriden by args[0] for testing. + int count = 1024 * 1024; + + final Map results = new ConcurrentHashMap(); + + Collection> queues() { + List> queues = new ArrayList>(); + queues.add(new ConcurrentLinkedQueue()); + queues.add(new ArrayBlockingQueue(count, false)); + queues.add(new ArrayBlockingQueue(count, true)); + queues.add(new LinkedBlockingQueue()); + queues.add(new LinkedBlockingDeque()); + queues.add(new PriorityBlockingQueue()); + queues.add(new PriorityQueue()); + queues.add(new LinkedList()); + + try { + queues.add((Queue) + Class.forName("java.util.concurrent.LinkedTransferQueue") + .newInstance()); + } catch (IllegalAccessException e) { + } catch (InstantiationException e) { + } catch (ClassNotFoundException e) { + // OK; not yet added to JDK + } + + // Following additional implementations are available from: + // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html + // queues.add(new LinkedTransferQueue()); + // queues.add(new SynchronizedLinkedListQueue()); + + // Avoid "first fast, second slow" benchmark effect. + Collections.shuffle(queues); + return queues; + } + + void prettyPrintResults() { + List classNames = new ArrayList(results.keySet()); + Collections.sort(classNames); + int maxClassNameLength = 0; + int maxNanosLength = 0; + for (String name : classNames) { + if (maxClassNameLength < name.length()) + maxClassNameLength = name.length(); + if (maxNanosLength < results.get(name).length()) + maxNanosLength = results.get(name).length(); + } + String format = String.format("%%%ds %%%ds nanos/item%%n", + maxClassNameLength, maxNanosLength); + for (String name : classNames) + System.out.printf(format, name, results.get(name)); + } + + void test(String[] args) { + if (args.length > 0) + count = Integer.valueOf(args[0]); + // Warmup + for (Queue queue : queues()) + test(queue); + results.clear(); + for (Queue queue : queues()) + test(queue); + + prettyPrintResults(); + } + + void test(Queue q) { + long t0 = System.nanoTime(); + for (int i = 0; i < count; i++) + check(q.add(Boolean.TRUE)); + System.gc(); + System.gc(); + Boolean x; + while ((x = q.poll()) != null) + equal(x, Boolean.TRUE); + check(q.isEmpty()); + + for (int i = 0; i < 10 * count; i++) { + for (int k = 0; k < 3; k++) + check(q.add(Boolean.TRUE)); + for (int k = 0; k < 3; k++) + if (q.poll() != Boolean.TRUE) + fail(); + } + check(q.isEmpty()); + + String className = q.getClass().getSimpleName(); + long elapsed = System.nanoTime() - t0; + int nanos = (int) ((double) elapsed / (10 * 3 * count)); + results.put(className, String.valueOf(nanos)); + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new GCRetention().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/jdk/test/java/util/concurrent/ConcurrentLinkedQueue/LoopHelpers.java b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java similarity index 100% rename from jdk/test/java/util/concurrent/ConcurrentLinkedQueue/LoopHelpers.java rename to jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java b/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java new file mode 100644 index 00000000000..f3e4ee9feb8 --- /dev/null +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java @@ -0,0 +1,230 @@ +/* + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +/* + * @test + * @bug 6785442 + * @summary Checks race between poll and remove(Object), while + * occasionally moonlighting as a microbenchmark. + * @run main RemovePollRace 12345 + */ + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.atomic.AtomicLong; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Queue; +import java.util.Map; + +public class RemovePollRace { + // Suitable for benchmarking. Overriden by args[0] for testing. + int count = 1024 * 1024; + + final Map results = new ConcurrentHashMap(); + + Collection> concurrentQueues() { + List> queues = new ArrayList>(); + queues.add(new ConcurrentLinkedQueue()); + queues.add(new ArrayBlockingQueue(count, false)); + queues.add(new ArrayBlockingQueue(count, true)); + queues.add(new LinkedBlockingQueue()); + queues.add(new LinkedBlockingDeque()); + + try { + queues.add((Queue) + Class.forName("java.util.concurrent.LinkedTransferQueue") + .newInstance()); + } catch (IllegalAccessException e) { + } catch (InstantiationException e) { + } catch (ClassNotFoundException e) { + // OK; not yet added to JDK + } + + // Following additional implementations are available from: + // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html + // queues.add(new LinkedTransferQueue()); + // queues.add(new SynchronizedLinkedListQueue()); + + // Avoid "first fast, second slow" benchmark effect. + Collections.shuffle(queues); + return queues; + } + + void prettyPrintResults() { + List classNames = new ArrayList(results.keySet()); + Collections.sort(classNames); + int maxClassNameLength = 0; + int maxNanosLength = 0; + for (String name : classNames) { + if (maxClassNameLength < name.length()) + maxClassNameLength = name.length(); + if (maxNanosLength < results.get(name).length()) + maxNanosLength = results.get(name).length(); + } + String format = String.format("%%%ds %%%ds nanos/item%%n", + maxClassNameLength, maxNanosLength); + for (String name : classNames) + System.out.printf(format, name, results.get(name)); + } + + void test(String[] args) throws Throwable { + if (args.length > 0) + count = Integer.valueOf(args[0]); + // Warmup + for (Queue queue : concurrentQueues()) + test(queue); + results.clear(); + for (Queue queue : concurrentQueues()) + test(queue); + + prettyPrintResults(); + } + + void await(CountDownLatch latch) { + try { latch.await(); } + catch (InterruptedException e) { unexpected(e); } + } + + void test(final Queue q) throws Throwable { + long t0 = System.nanoTime(); + final int SPINS = 5; + final AtomicLong removes = new AtomicLong(0); + final AtomicLong polls = new AtomicLong(0); + final int adderCount = + Math.max(1, Runtime.getRuntime().availableProcessors() / 4); + final int removerCount = + Math.max(1, Runtime.getRuntime().availableProcessors() / 4); + final int pollerCount = removerCount; + final int threadCount = adderCount + removerCount + pollerCount; + final CountDownLatch startingGate = new CountDownLatch(1); + final CountDownLatch addersDone = new CountDownLatch(adderCount); + final Runnable remover = new Runnable() { + public void run() { + await(startingGate); + int spins = 0; + for (;;) { + boolean quittingTime = (addersDone.getCount() == 0); + if (q.remove(Boolean.TRUE)) + removes.getAndIncrement(); + else if (quittingTime) + break; + else if (++spins > SPINS) { + Thread.yield(); + spins = 0; + }}}}; + final Runnable poller = new Runnable() { + public void run() { + await(startingGate); + int spins = 0; + for (;;) { + boolean quittingTime = (addersDone.getCount() == 0); + if (q.poll() == Boolean.TRUE) + polls.getAndIncrement(); + else if (quittingTime) + break; + else if (++spins > SPINS) { + Thread.yield(); + spins = 0; + }}}}; + final Runnable adder = new Runnable() { + public void run() { + await(startingGate); + for (int i = 0; i < count; i++) { + for (;;) { + try { q.add(Boolean.TRUE); break; } + catch (IllegalStateException e) { Thread.yield(); } + } + } + addersDone.countDown(); + }}; + + final List adders = new ArrayList(); + final List removers = new ArrayList(); + final List pollers = new ArrayList(); + for (int i = 0; i < adderCount; i++) + adders.add(checkedThread(adder)); + for (int i = 0; i < removerCount; i++) + removers.add(checkedThread(remover)); + for (int i = 0; i < pollerCount; i++) + pollers.add(checkedThread(poller)); + + final List allThreads = new ArrayList(); + allThreads.addAll(removers); + allThreads.addAll(pollers); + allThreads.addAll(adders); + + for (Thread t : allThreads) + t.start(); + startingGate.countDown(); + for (Thread t : allThreads) + t.join(); + + String className = q.getClass().getSimpleName(); + long elapsed = System.nanoTime() - t0; + int nanos = (int) ((double) elapsed / (adderCount * count)); + results.put(className, String.valueOf(nanos)); + if (removes.get() + polls.get() != adderCount * count) { + String msg = String.format + ("class=%s removes=%s polls=%d count=%d", + className, removes.get(), polls.get(), count); + fail(msg); + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new RemovePollRace().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} + Thread checkedThread(final Runnable r) { + return new Thread() {public void run() { + try {r.run();} catch (Throwable t) {unexpected(t);}}};} +} diff --git a/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java b/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java index e66dfb7042d..fbd0070a7a7 100644 --- a/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java +++ b/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java @@ -28,62 +28,74 @@ * @author Martin Buchholz */ +import java.util.*; import java.util.concurrent.*; public class OfferRemoveLoops { - private static void realMain(String[] args) throws Throwable { + void test(String[] args) throws Throwable { testQueue(new LinkedBlockingQueue(10)); testQueue(new LinkedBlockingQueue()); testQueue(new LinkedBlockingDeque(10)); testQueue(new LinkedBlockingDeque()); testQueue(new ArrayBlockingQueue(10)); testQueue(new PriorityBlockingQueue(10)); + testQueue(new ConcurrentLinkedQueue()); } - private abstract static class ControlledThread extends Thread { + abstract class CheckedThread extends Thread { abstract protected void realRun(); public void run() { try { realRun(); } catch (Throwable t) { unexpected(t); } } } - private static void testQueue(final BlockingQueue q) throws Throwable { - System.out.println(q.getClass()); - final int count = 10000; - final long quittingTime = System.nanoTime() + 1L * 1000L * 1000L * 1000L; - Thread t1 = new ControlledThread() { - protected void realRun() { - for (int i = 0, j = 0; i < count; i++) - while (! q.remove(String.valueOf(i)) - && System.nanoTime() - quittingTime < 0) - Thread.yield();}}; - Thread t2 = new ControlledThread() { - protected void realRun() { - for (int i = 0, j = 0; i < count; i++) - while (! q.offer(String.valueOf(i)) - && System.nanoTime() - quittingTime < 0) - Thread.yield();}}; + void testQueue(final Queue q) throws Throwable { + System.out.println(q.getClass().getSimpleName()); + final int count = 1000 * 1000; + final long testDurationSeconds = 1L; + final long testDurationMillis = testDurationSeconds * 1000L; + final long quittingTimeNanos + = System.nanoTime() + testDurationSeconds * 1000L * 1000L * 1000L; + Thread t1 = new CheckedThread() { + protected void realRun() { + for (int i = 0; i < count; i++) { + if ((i % 1024) == 0 && + System.nanoTime() - quittingTimeNanos > 0) + return; + while (! q.remove(String.valueOf(i))) + Thread.yield(); + }}}; + Thread t2 = new CheckedThread() { + protected void realRun() { + for (int i = 0; i < count; i++) { + if ((i % 1024) == 0 && + System.nanoTime() - quittingTimeNanos > 0) + return; + while (! q.offer(String.valueOf(i))) + Thread.yield(); + }}}; t1.setDaemon(true); t2.setDaemon(true); t1.start(); t2.start(); - t1.join(10000); t2.join(10000); + t1.join(10 * testDurationMillis); + t2.join(10 * testDurationMillis); check(! t1.isAlive()); check(! t2.isAlive()); } //--------------------- Infrastructure --------------------------- - static volatile int passed = 0, failed = 0; - static void pass() { passed++; } - static void fail() { failed++; Thread.dumpStack(); } - static void unexpected(Throwable t) { failed++; t.printStackTrace(); } - static void check(boolean cond) { if (cond) pass(); else fail(); } - static void equal(Object x, Object y) { + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { if (x == null ? y == null : x.equals(y)) pass(); - else {System.out.println(x + " not equal to " + y); fail(); }} - + else fail(x + " not equal to " + y);} public static void main(String[] args) throws Throwable { - try { realMain(args); } catch (Throwable t) { unexpected(t); } - + new OfferRemoveLoops().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); - if (failed > 0) throw new Exception("Some tests failed"); - } + if (failed > 0) throw new AssertionError("Some tests failed");} } From d43e798981fa1c1d3119555e087776f09fb3015b Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Tue, 28 Jul 2009 17:17:55 -0700 Subject: [PATCH 028/102] 6805775: LinkedBlockingQueue Nodes should unlink themselves before becoming garbage 6815766: LinkedBlockingQueue's iterator can return null if drainTo(c) executes concurrently Faster, more correct. Use self-linking trick to avoid gc retention Reviewed-by: martin, dholmes --- .../util/concurrent/LinkedBlockingDeque.java | 394 +++++++++++------ .../util/concurrent/LinkedBlockingQueue.java | 403 ++++++++++-------- jdk/test/java/util/Collection/MOAT.java | 35 ++ .../BlockingQueue/OfferDrainToLoops.java | 130 ++++++ .../IteratorWeakConsistency.java | 93 ++++ 5 files changed, 730 insertions(+), 325 deletions(-) create mode 100644 jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java create mode 100644 jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 48fc8717a42..7db94a6efba 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -34,8 +34,13 @@ */ package java.util.concurrent; -import java.util.*; -import java.util.concurrent.locks.*; + +import java.util.AbstractQueue; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; /** * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on @@ -73,6 +78,20 @@ public class LinkedBlockingDeque /* * Implemented as a simple doubly-linked list protected by a * single lock and using conditions to manage blocking. + * + * To implement weakly consistent iterators, it appears we need to + * keep all Nodes GC-reachable from a predecessor dequeued Node. + * That would cause two problems: + * - allow a rogue Iterator to cause unbounded memory retention + * - cause cross-generational linking of old Nodes to new Nodes if + * a Node was tenured while live, which generational GCs have a + * hard time dealing with, causing repeated major collections. + * However, only non-deleted Nodes need to be reachable from + * dequeued Nodes, and reachability does not necessarily have to + * be of the kind understood by the GC. We use the trick of + * linking a Node that has just been dequeued to itself. Such a + * self-link implicitly means to jump to "first" (for next links) + * or "last" (for prev links). */ /* @@ -86,9 +105,27 @@ public class LinkedBlockingDeque /** Doubly-linked list node class */ static final class Node { + /** + * The item, or null if this node has been removed. + */ E item; + + /** + * One of: + * - the real predecessor Node + * - this Node, meaning the predecessor is tail + * - null, meaning there is no predecessor + */ Node prev; + + /** + * One of: + * - the real successor Node + * - this Node, meaning the successor is head + * - null, meaning there is no successor + */ Node next; + Node(E x, Node p, Node n) { item = x; prev = p; @@ -96,23 +133,37 @@ public class LinkedBlockingDeque } } - /** Pointer to first node */ - private transient Node first; - /** Pointer to last node */ - private transient Node last; + /** + * Pointer to first node. + * Invariant: (first == null && last == null) || + * (first.prev == null && first.item != null) + */ + transient Node first; + + /** + * Pointer to last node. + * Invariant: (first == null && last == null) || + * (last.next == null && last.item != null) + */ + transient Node last; + /** Number of items in the deque */ private transient int count; + /** Maximum number of items in the deque */ private final int capacity; + /** Main lock guarding all access */ - private final ReentrantLock lock = new ReentrantLock(); + final ReentrantLock lock = new ReentrantLock(); + /** Condition for waiting takes */ private final Condition notEmpty = lock.newCondition(); + /** Condition for waiting puts */ private final Condition notFull = lock.newCondition(); /** - * Creates a LinkedBlockingDeque with a capacity of + * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}. */ public LinkedBlockingDeque() { @@ -120,10 +171,10 @@ public class LinkedBlockingDeque } /** - * Creates a LinkedBlockingDeque with the given (fixed) capacity. + * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity. * * @param capacity the capacity of this deque - * @throws IllegalArgumentException if capacity is less than 1 + * @throws IllegalArgumentException if {@code capacity} is less than 1 */ public LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); @@ -131,7 +182,7 @@ public class LinkedBlockingDeque } /** - * Creates a LinkedBlockingDeque with a capacity of + * Creates a {@code LinkedBlockingDeque} with a capacity of * {@link Integer#MAX_VALUE}, initially containing the elements of * the given collection, added in traversal order of the * collection's iterator. @@ -142,8 +193,18 @@ public class LinkedBlockingDeque */ public LinkedBlockingDeque(Collection c) { this(Integer.MAX_VALUE); - for (E e : c) - add(e); + final ReentrantLock lock = this.lock; + lock.lock(); // Never contended, but necessary for visibility + try { + for (E e : c) { + if (e == null) + throw new NullPointerException(); + if (!linkLast(e)) + throw new IllegalStateException("Deque full"); + } + } finally { + lock.unlock(); + } } @@ -153,9 +214,9 @@ public class LinkedBlockingDeque * Links e as first element, or returns false if full. */ private boolean linkFirst(E e) { + // assert lock.isHeldByCurrentThread(); if (count >= capacity) return false; - ++count; Node f = first; Node x = new Node(e, null, f); first = x; @@ -163,6 +224,7 @@ public class LinkedBlockingDeque last = x; else f.prev = x; + ++count; notEmpty.signal(); return true; } @@ -171,9 +233,9 @@ public class LinkedBlockingDeque * Links e as last element, or returns false if full. */ private boolean linkLast(E e) { + // assert lock.isHeldByCurrentThread(); if (count >= capacity) return false; - ++count; Node l = last; Node x = new Node(e, l, null); last = x; @@ -181,6 +243,7 @@ public class LinkedBlockingDeque first = x; else l.next = x; + ++count; notEmpty.signal(); return true; } @@ -189,10 +252,14 @@ public class LinkedBlockingDeque * Removes and returns first element, or null if empty. */ private E unlinkFirst() { + // assert lock.isHeldByCurrentThread(); Node f = first; if (f == null) return null; Node n = f.next; + E item = f.item; + f.item = null; + f.next = f; // help GC first = n; if (n == null) last = null; @@ -200,17 +267,21 @@ public class LinkedBlockingDeque n.prev = null; --count; notFull.signal(); - return f.item; + return item; } /** * Removes and returns last element, or null if empty. */ private E unlinkLast() { + // assert lock.isHeldByCurrentThread(); Node l = last; if (l == null) return null; Node p = l.prev; + E item = l.item; + l.item = null; + l.prev = l; // help GC last = p; if (p == null) first = null; @@ -218,31 +289,29 @@ public class LinkedBlockingDeque p.next = null; --count; notFull.signal(); - return l.item; + return item; } /** - * Unlink e + * Unlinks x. */ - private void unlink(Node x) { + void unlink(Node x) { + // assert lock.isHeldByCurrentThread(); Node p = x.prev; Node n = x.next; if (p == null) { - if (n == null) - first = last = null; - else { - n.prev = null; - first = n; - } + unlinkFirst(); } else if (n == null) { - p.next = null; - last = p; + unlinkLast(); } else { p.next = n; n.prev = p; + x.item = null; + // Don't mess with x's links. They may still be in use by + // an iterator. + --count; + notFull.signal(); } - --count; - notFull.signalAll(); } // BlockingDeque methods @@ -270,6 +339,7 @@ public class LinkedBlockingDeque */ public boolean offerFirst(E e) { if (e == null) throw new NullPointerException(); + final ReentrantLock lock = this.lock; lock.lock(); try { return linkFirst(e); @@ -283,6 +353,7 @@ public class LinkedBlockingDeque */ public boolean offerLast(E e) { if (e == null) throw new NullPointerException(); + final ReentrantLock lock = this.lock; lock.lock(); try { return linkLast(e); @@ -297,6 +368,7 @@ public class LinkedBlockingDeque */ public void putFirst(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); + final ReentrantLock lock = this.lock; lock.lock(); try { while (!linkFirst(e)) @@ -312,6 +384,7 @@ public class LinkedBlockingDeque */ public void putLast(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); + final ReentrantLock lock = this.lock; lock.lock(); try { while (!linkLast(e)) @@ -329,15 +402,15 @@ public class LinkedBlockingDeque throws InterruptedException { if (e == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { - for (;;) { - if (linkFirst(e)) - return true; + while (!linkFirst(e)) { if (nanos <= 0) return false; nanos = notFull.awaitNanos(nanos); } + return true; } finally { lock.unlock(); } @@ -351,15 +424,15 @@ public class LinkedBlockingDeque throws InterruptedException { if (e == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { - for (;;) { - if (linkLast(e)) - return true; + while (!linkLast(e)) { if (nanos <= 0) return false; nanos = notFull.awaitNanos(nanos); } + return true; } finally { lock.unlock(); } @@ -384,6 +457,7 @@ public class LinkedBlockingDeque } public E pollFirst() { + final ReentrantLock lock = this.lock; lock.lock(); try { return unlinkFirst(); @@ -393,6 +467,7 @@ public class LinkedBlockingDeque } public E pollLast() { + final ReentrantLock lock = this.lock; lock.lock(); try { return unlinkLast(); @@ -402,6 +477,7 @@ public class LinkedBlockingDeque } public E takeFirst() throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lock(); try { E x; @@ -414,6 +490,7 @@ public class LinkedBlockingDeque } public E takeLast() throws InterruptedException { + final ReentrantLock lock = this.lock; lock.lock(); try { E x; @@ -428,16 +505,16 @@ public class LinkedBlockingDeque public E pollFirst(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { - for (;;) { - E x = unlinkFirst(); - if (x != null) - return x; + E x; + while ( (x = unlinkFirst()) == null) { if (nanos <= 0) return null; nanos = notEmpty.awaitNanos(nanos); } + return x; } finally { lock.unlock(); } @@ -446,16 +523,16 @@ public class LinkedBlockingDeque public E pollLast(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { - for (;;) { - E x = unlinkLast(); - if (x != null) - return x; + E x; + while ( (x = unlinkLast()) == null) { if (nanos <= 0) return null; nanos = notEmpty.awaitNanos(nanos); } + return x; } finally { lock.unlock(); } @@ -480,6 +557,7 @@ public class LinkedBlockingDeque } public E peekFirst() { + final ReentrantLock lock = this.lock; lock.lock(); try { return (first == null) ? null : first.item; @@ -489,6 +567,7 @@ public class LinkedBlockingDeque } public E peekLast() { + final ReentrantLock lock = this.lock; lock.lock(); try { return (last == null) ? null : last.item; @@ -499,6 +578,7 @@ public class LinkedBlockingDeque public boolean removeFirstOccurrence(Object o) { if (o == null) return false; + final ReentrantLock lock = this.lock; lock.lock(); try { for (Node p = first; p != null; p = p.next) { @@ -515,6 +595,7 @@ public class LinkedBlockingDeque public boolean removeLastOccurrence(Object o) { if (o == null) return false; + final ReentrantLock lock = this.lock; lock.lock(); try { for (Node p = last; p != null; p = p.prev) { @@ -619,14 +700,15 @@ public class LinkedBlockingDeque * Returns the number of additional elements that this deque can ideally * (in the absence of memory or resource constraints) accept without * blocking. This is always equal to the initial capacity of this deque - * less the current size of this deque. + * less the current {@code size} of this deque. * *

Note that you cannot always tell if an attempt to insert - * an element will succeed by inspecting remainingCapacity + * an element will succeed by inspecting {@code remainingCapacity} * because it may be the case that another thread is about to * insert or remove an element. */ public int remainingCapacity() { + final ReentrantLock lock = this.lock; lock.lock(); try { return capacity - count; @@ -642,22 +724,7 @@ public class LinkedBlockingDeque * @throws IllegalArgumentException {@inheritDoc} */ public int drainTo(Collection c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - lock.lock(); - try { - for (Node p = first; p != null; p = p.next) - c.add(p.item); - int n = count; - count = 0; - first = last = null; - notFull.signalAll(); - return n; - } finally { - lock.unlock(); - } + return drainTo(c, Integer.MAX_VALUE); } /** @@ -671,19 +738,14 @@ public class LinkedBlockingDeque throw new NullPointerException(); if (c == this) throw new IllegalArgumentException(); + final ReentrantLock lock = this.lock; lock.lock(); try { - int n = 0; - while (n < maxElements && first != null) { - c.add(first.item); - first.prev = null; - first = first.next; - --count; - ++n; + int n = Math.min(maxElements, count); + for (int i = 0; i < n; i++) { + c.add(first.item); // In this order, in case add() throws. + unlinkFirst(); } - if (first == null) - last = null; - notFull.signalAll(); return n; } finally { lock.unlock(); @@ -712,16 +774,16 @@ public class LinkedBlockingDeque /** * Removes the first occurrence of the specified element from this deque. * If the deque does not contain the element, it is unchanged. - * More formally, removes the first element e such that - * o.equals(e) (if such an element exists). - * Returns true if this deque contained the specified element + * More formally, removes the first element {@code e} such that + * {@code o.equals(e)} (if such an element exists). + * Returns {@code true} if this deque contained the specified element * (or equivalently, if this deque changed as a result of the call). * *

This method is equivalent to * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}. * * @param o element to be removed from this deque, if present - * @return true if this deque changed as a result of the call + * @return {@code true} if this deque changed as a result of the call */ public boolean remove(Object o) { return removeFirstOccurrence(o); @@ -733,6 +795,7 @@ public class LinkedBlockingDeque * @return the number of elements in this deque */ public int size() { + final ReentrantLock lock = this.lock; lock.lock(); try { return count; @@ -742,15 +805,16 @@ public class LinkedBlockingDeque } /** - * Returns true if this deque contains the specified element. - * More formally, returns true if and only if this deque contains - * at least one element e such that o.equals(e). + * Returns {@code true} if this deque contains the specified element. + * More formally, returns {@code true} if and only if this deque contains + * at least one element {@code e} such that {@code o.equals(e)}. * * @param o object to be checked for containment in this deque - * @return true if this deque contains the specified element + * @return {@code true} if this deque contains the specified element */ public boolean contains(Object o) { if (o == null) return false; + final ReentrantLock lock = this.lock; lock.lock(); try { for (Node p = first; p != null; p = p.next) @@ -762,24 +826,46 @@ public class LinkedBlockingDeque } } - /** - * Variant of removeFirstOccurrence needed by iterator.remove. - * Searches for the node, not its contents. + /* + * TODO: Add support for more efficient bulk operations. + * + * We don't want to acquire the lock for every iteration, but we + * also want other threads a chance to interact with the + * collection, especially when count is close to capacity. */ - boolean removeNode(Node e) { - lock.lock(); - try { - for (Node p = first; p != null; p = p.next) { - if (p == e) { - unlink(p); - return true; - } - } - return false; - } finally { - lock.unlock(); - } - } + +// /** +// * Adds all of the elements in the specified collection to this +// * queue. Attempts to addAll of a queue to itself result in +// * {@code IllegalArgumentException}. Further, the behavior of +// * this operation is undefined if the specified collection is +// * modified while the operation is in progress. +// * +// * @param c collection containing elements to be added to this queue +// * @return {@code true} if this queue changed as a result of the call +// * @throws ClassCastException {@inheritDoc} +// * @throws NullPointerException {@inheritDoc} +// * @throws IllegalArgumentException {@inheritDoc} +// * @throws IllegalStateException {@inheritDoc} +// * @see #add(Object) +// */ +// public boolean addAll(Collection c) { +// if (c == null) +// throw new NullPointerException(); +// if (c == this) +// throw new IllegalArgumentException(); +// final ReentrantLock lock = this.lock; +// lock.lock(); +// try { +// boolean modified = false; +// for (E e : c) +// if (linkLast(e)) +// modified = true; +// return modified; +// } finally { +// lock.unlock(); +// } +// } /** * Returns an array containing all of the elements in this deque, in @@ -794,7 +880,9 @@ public class LinkedBlockingDeque * * @return an array containing all of the elements in this deque */ + @SuppressWarnings("unchecked") public Object[] toArray() { + final ReentrantLock lock = this.lock; lock.lock(); try { Object[] a = new Object[count]; @@ -817,22 +905,22 @@ public class LinkedBlockingDeque *

If this deque fits in the specified array with room to spare * (i.e., the array has more elements than this deque), the element in * the array immediately following the end of the deque is set to - * null. + * {@code null}. * *

Like the {@link #toArray()} method, this method acts as bridge between * array-based and collection-based APIs. Further, this method allows * precise control over the runtime type of the output array, and may, * under certain circumstances, be used to save allocation costs. * - *

Suppose x is a deque known to contain only strings. + *

Suppose {@code x} is a deque known to contain only strings. * The following code can be used to dump the deque into a newly - * allocated array of String: + * allocated array of {@code String}: * *

      *     String[] y = x.toArray(new String[0]);
* - * Note that toArray(new Object[0]) is identical in function to - * toArray(). + * Note that {@code toArray(new Object[0])} is identical in function to + * {@code toArray()}. * * @param a the array into which the elements of the deque are to * be stored, if it is big enough; otherwise, a new array of the @@ -843,14 +931,14 @@ public class LinkedBlockingDeque * this deque * @throws NullPointerException if the specified array is null */ + @SuppressWarnings("unchecked") public T[] toArray(T[] a) { + final ReentrantLock lock = this.lock; lock.lock(); try { if (a.length < count) - a = (T[])java.lang.reflect.Array.newInstance( - a.getClass().getComponentType(), - count - ); + a = (T[])java.lang.reflect.Array.newInstance + (a.getClass().getComponentType(), count); int k = 0; for (Node p = first; p != null; p = p.next) @@ -864,6 +952,7 @@ public class LinkedBlockingDeque } public String toString() { + final ReentrantLock lock = this.lock; lock.lock(); try { return super.toString(); @@ -877,8 +966,16 @@ public class LinkedBlockingDeque * The deque will be empty after this call returns. */ public void clear() { + final ReentrantLock lock = this.lock; lock.lock(); try { + for (Node f = first; f != null; ) { + f.item = null; + Node n = f.next; + f.prev = null; + f.next = null; + f = n; + } first = last = null; count = 0; notFull.signalAll(); @@ -890,7 +987,7 @@ public class LinkedBlockingDeque /** * Returns an iterator over the elements in this deque in proper sequence. * The elements will be returned in order from first (head) to last (tail). - * The returned Iterator is a "weakly consistent" iterator that + * The returned {@code Iterator} is a "weakly consistent" iterator that * will never throw {@link ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) @@ -906,7 +1003,7 @@ public class LinkedBlockingDeque * Returns an iterator over the elements in this deque in reverse * sequential order. The elements will be returned in order from * last (tail) to first (head). - * The returned Iterator is a "weakly consistent" iterator that + * The returned {@code Iterator} is a "weakly consistent" iterator that * will never throw {@link ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) @@ -921,7 +1018,7 @@ public class LinkedBlockingDeque */ private abstract class AbstractItr implements Iterator { /** - * The next node to return in next + * The next node to return in next() */ Node next; @@ -939,15 +1036,44 @@ public class LinkedBlockingDeque */ private Node lastRet; + abstract Node firstNode(); + abstract Node nextNode(Node n); + AbstractItr() { - advance(); // set to initial position + // set to initial position + final ReentrantLock lock = LinkedBlockingDeque.this.lock; + lock.lock(); + try { + next = firstNode(); + nextItem = (next == null) ? null : next.item; + } finally { + lock.unlock(); + } } /** - * Advances next, or if not yet initialized, sets to first node. - * Implemented to move forward vs backward in the two subclasses. + * Advances next. */ - abstract void advance(); + void advance() { + final ReentrantLock lock = LinkedBlockingDeque.this.lock; + lock.lock(); + try { + // assert next != null; + Node s = nextNode(next); + if (s == next) { + next = firstNode(); + } else { + // Skip over removed nodes. + // May be necessary if multiple interior Nodes are removed. + while (s != null && s.item == null) + s = nextNode(s); + next = s; + } + nextItem = (next == null) ? null : next.item; + } finally { + lock.unlock(); + } + } public boolean hasNext() { return next != null; @@ -967,52 +1093,39 @@ public class LinkedBlockingDeque if (n == null) throw new IllegalStateException(); lastRet = null; - // Note: removeNode rescans looking for this node to make - // sure it was not already removed. Otherwise, trying to - // re-remove could corrupt list. - removeNode(n); + final ReentrantLock lock = LinkedBlockingDeque.this.lock; + lock.lock(); + try { + if (n.item != null) + unlink(n); + } finally { + lock.unlock(); + } } } /** Forward iterator */ private class Itr extends AbstractItr { - void advance() { - final ReentrantLock lock = LinkedBlockingDeque.this.lock; - lock.lock(); - try { - next = (next == null)? first : next.next; - nextItem = (next == null)? null : next.item; - } finally { - lock.unlock(); - } - } + Node firstNode() { return first; } + Node nextNode(Node n) { return n.next; } } - /** - * Descending iterator for LinkedBlockingDeque - */ + /** Descending iterator */ private class DescendingItr extends AbstractItr { - void advance() { - final ReentrantLock lock = LinkedBlockingDeque.this.lock; - lock.lock(); - try { - next = (next == null)? last : next.prev; - nextItem = (next == null)? null : next.item; - } finally { - lock.unlock(); - } - } + Node firstNode() { return last; } + Node nextNode(Node n) { return n.prev; } } /** * Save the state of this deque to a stream (that is, serialize it). * * @serialData The capacity (int), followed by elements (each an - * Object) in the proper order, followed by a null + * {@code Object}) in the proper order, followed by a null * @param s the stream */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { + final ReentrantLock lock = this.lock; lock.lock(); try { // Write out capacity and any hidden stuff @@ -1040,6 +1153,7 @@ public class LinkedBlockingDeque last = null; // Read in all elements and place in queue for (;;) { + @SuppressWarnings("unchecked") E item = (E)s.readObject(); if (item == null) break; diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java index dc56a034665..9c1c6cc7b1f 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -34,9 +34,14 @@ */ package java.util.concurrent; -import java.util.concurrent.atomic.*; -import java.util.concurrent.locks.*; -import java.util.*; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; +import java.util.AbstractQueue; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; /** * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on @@ -86,15 +91,43 @@ public class LinkedBlockingQueue extends AbstractQueue * items have been entered since the signal. And symmetrically for * takes signalling puts. Operations such as remove(Object) and * iterators acquire both locks. + * + * Visibility between writers and readers is provided as follows: + * + * Whenever an element is enqueued, the putLock is acquired and + * count updated. A subsequent reader guarantees visibility to the + * enqueued Node by either acquiring the putLock (via fullyLock) + * or by acquiring the takeLock, and then reading n = count.get(); + * this gives visibility to the first n items. + * + * To implement weakly consistent iterators, it appears we need to + * keep all Nodes GC-reachable from a predecessor dequeued Node. + * That would cause two problems: + * - allow a rogue Iterator to cause unbounded memory retention + * - cause cross-generational linking of old Nodes to new Nodes if + * a Node was tenured while live, which generational GCs have a + * hard time dealing with, causing repeated major collections. + * However, only non-deleted Nodes need to be reachable from + * dequeued Nodes, and reachability does not necessarily have to + * be of the kind understood by the GC. We use the trick of + * linking a Node that has just been dequeued to itself. Such a + * self-link implicitly means to advance to head.next. */ /** * Linked list node class */ static class Node { - /** The item, volatile to ensure barrier separating write and read */ - volatile E item; + E item; + + /** + * One of: + * - the real successor Node + * - this Node, meaning the successor is head.next + * - null, meaning there is no successor (this is the last node) + */ Node next; + Node(E x) { item = x; } } @@ -104,10 +137,16 @@ public class LinkedBlockingQueue extends AbstractQueue /** Current number of elements */ private final AtomicInteger count = new AtomicInteger(0); - /** Head of linked list */ + /** + * Head of linked list. + * Invariant: head.item == null + */ private transient Node head; - /** Tail of linked list */ + /** + * Tail of linked list. + * Invariant: last.next == null + */ private transient Node last; /** Lock held by take, poll, etc */ @@ -151,18 +190,26 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Creates a node and links it at end of queue. + * * @param x the item */ - private void insert(E x) { + private void enqueue(E x) { + // assert putLock.isHeldByCurrentThread(); + // assert last.next == null; last = last.next = new Node(x); } /** - * Removes a node from head of queue, + * Removes a node from head of queue. + * * @return the node */ - private E extract() { - Node first = head.next; + private E dequeue() { + // assert takeLock.isHeldByCurrentThread(); + // assert head.item == null; + Node h = head; + Node first = h.next; + h.next = h; // help GC head = first; E x = first.item; first.item = null; @@ -172,7 +219,7 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Lock to prevent both puts and takes. */ - private void fullyLock() { + void fullyLock() { putLock.lock(); takeLock.lock(); } @@ -180,14 +227,21 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Unlock to allow both puts and takes. */ - private void fullyUnlock() { + void fullyUnlock() { takeLock.unlock(); putLock.unlock(); } +// /** +// * Tells whether both locks are held by current thread. +// */ +// boolean isFullyLocked() { +// return (putLock.isHeldByCurrentThread() && +// takeLock.isHeldByCurrentThread()); +// } /** - * Creates a LinkedBlockingQueue with a capacity of + * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}. */ public LinkedBlockingQueue() { @@ -195,10 +249,10 @@ public class LinkedBlockingQueue extends AbstractQueue } /** - * Creates a LinkedBlockingQueue with the given (fixed) capacity. + * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity. * * @param capacity the capacity of this queue - * @throws IllegalArgumentException if capacity is not greater + * @throws IllegalArgumentException if {@code capacity} is not greater * than zero */ public LinkedBlockingQueue(int capacity) { @@ -208,7 +262,7 @@ public class LinkedBlockingQueue extends AbstractQueue } /** - * Creates a LinkedBlockingQueue with a capacity of + * Creates a {@code LinkedBlockingQueue} with a capacity of * {@link Integer#MAX_VALUE}, initially containing the elements of the * given collection, * added in traversal order of the collection's iterator. @@ -219,8 +273,22 @@ public class LinkedBlockingQueue extends AbstractQueue */ public LinkedBlockingQueue(Collection c) { this(Integer.MAX_VALUE); - for (E e : c) - add(e); + final ReentrantLock putLock = this.putLock; + putLock.lock(); // Never contended, but necessary for visibility + try { + int n = 0; + for (E e : c) { + if (e == null) + throw new NullPointerException(); + if (n == capacity) + throw new IllegalStateException("Queue full"); + enqueue(e); + ++n; + } + count.set(n); + } finally { + putLock.unlock(); + } } @@ -241,10 +309,10 @@ public class LinkedBlockingQueue extends AbstractQueue * Returns the number of additional elements that this queue can ideally * (in the absence of memory or resource constraints) accept without * blocking. This is always equal to the initial capacity of this queue - * less the current size of this queue. + * less the current {@code size} of this queue. * *

Note that you cannot always tell if an attempt to insert - * an element will succeed by inspecting remainingCapacity + * an element will succeed by inspecting {@code remainingCapacity} * because it may be the case that another thread is about to * insert or remove an element. */ @@ -261,8 +329,8 @@ public class LinkedBlockingQueue extends AbstractQueue */ public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); - // Note: convention in all put/take/etc is to preset - // local var holding count negative to indicate failure unless set. + // Note: convention in all put/take/etc is to preset local var + // holding count negative to indicate failure unless set. int c = -1; final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; @@ -273,18 +341,13 @@ public class LinkedBlockingQueue extends AbstractQueue * not protected by lock. This works because count can * only decrease at this point (all other puts are shut * out by lock), and we (or some other waiting put) are - * signalled if it ever changes from - * capacity. Similarly for all other uses of count in - * other wait guards. + * signalled if it ever changes from capacity. Similarly + * for all other uses of count in other wait guards. */ - try { - while (count.get() == capacity) - notFull.await(); - } catch (InterruptedException ie) { - notFull.signal(); // propagate to a non-interrupted thread - throw ie; + while (count.get() == capacity) { + notFull.await(); } - insert(e); + enqueue(e); c = count.getAndIncrement(); if (c + 1 < capacity) notFull.signal(); @@ -299,7 +362,7 @@ public class LinkedBlockingQueue extends AbstractQueue * Inserts the specified element at the tail of this queue, waiting if * necessary up to the specified wait time for space to become available. * - * @return true if successful, or false if + * @return {@code true} if successful, or {@code false} if * the specified waiting time elapses before space is available. * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} @@ -314,23 +377,15 @@ public class LinkedBlockingQueue extends AbstractQueue final AtomicInteger count = this.count; putLock.lockInterruptibly(); try { - for (;;) { - if (count.get() < capacity) { - insert(e); - c = count.getAndIncrement(); - if (c + 1 < capacity) - notFull.signal(); - break; - } + while (count.get() == capacity) { if (nanos <= 0) return false; - try { - nanos = notFull.awaitNanos(nanos); - } catch (InterruptedException ie) { - notFull.signal(); // propagate to a non-interrupted thread - throw ie; - } + nanos = notFull.awaitNanos(nanos); } + enqueue(e); + c = count.getAndIncrement(); + if (c + 1 < capacity) + notFull.signal(); } finally { putLock.unlock(); } @@ -342,7 +397,7 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Inserts the specified element at the tail of this queue if it is * possible to do so immediately without exceeding the queue's capacity, - * returning true upon success and false if this queue + * returning {@code true} upon success and {@code false} if this queue * is full. * When using a capacity-restricted queue, this method is generally * preferable to method {@link BlockingQueue#add add}, which can fail to @@ -360,7 +415,7 @@ public class LinkedBlockingQueue extends AbstractQueue putLock.lock(); try { if (count.get() < capacity) { - insert(e); + enqueue(e); c = count.getAndIncrement(); if (c + 1 < capacity) notFull.signal(); @@ -381,15 +436,10 @@ public class LinkedBlockingQueue extends AbstractQueue final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); try { - try { - while (count.get() == 0) - notEmpty.await(); - } catch (InterruptedException ie) { - notEmpty.signal(); // propagate to a non-interrupted thread - throw ie; + while (count.get() == 0) { + notEmpty.await(); } - - x = extract(); + x = dequeue(); c = count.getAndDecrement(); if (c > 1) notEmpty.signal(); @@ -409,23 +459,15 @@ public class LinkedBlockingQueue extends AbstractQueue final ReentrantLock takeLock = this.takeLock; takeLock.lockInterruptibly(); try { - for (;;) { - if (count.get() > 0) { - x = extract(); - c = count.getAndDecrement(); - if (c > 1) - notEmpty.signal(); - break; - } + while (count.get() == 0) { if (nanos <= 0) return null; - try { - nanos = notEmpty.awaitNanos(nanos); - } catch (InterruptedException ie) { - notEmpty.signal(); // propagate to a non-interrupted thread - throw ie; - } + nanos = notEmpty.awaitNanos(nanos); } + x = dequeue(); + c = count.getAndDecrement(); + if (c > 1) + notEmpty.signal(); } finally { takeLock.unlock(); } @@ -444,7 +486,7 @@ public class LinkedBlockingQueue extends AbstractQueue takeLock.lock(); try { if (count.get() > 0) { - x = extract(); + x = dequeue(); c = count.getAndDecrement(); if (c > 1) notEmpty.signal(); @@ -457,7 +499,6 @@ public class LinkedBlockingQueue extends AbstractQueue return x; } - public E peek() { if (count.get() == 0) return null; @@ -474,44 +515,48 @@ public class LinkedBlockingQueue extends AbstractQueue } } + /** + * Unlinks interior Node p with predecessor trail. + */ + void unlink(Node p, Node trail) { + // assert isFullyLocked(); + // p.next is not changed, to allow iterators that are + // traversing p to maintain their weak-consistency guarantee. + p.item = null; + trail.next = p.next; + if (last == p) + last = trail; + if (count.getAndDecrement() == capacity) + notFull.signal(); + } + /** * Removes a single instance of the specified element from this queue, - * if it is present. More formally, removes an element e such - * that o.equals(e), if this queue contains one or more such + * if it is present. More formally, removes an element {@code e} such + * that {@code o.equals(e)}, if this queue contains one or more such * elements. - * Returns true if this queue contained the specified element + * Returns {@code true} if this queue contained the specified element * (or equivalently, if this queue changed as a result of the call). * * @param o element to be removed from this queue, if present - * @return true if this queue changed as a result of the call + * @return {@code true} if this queue changed as a result of the call */ public boolean remove(Object o) { if (o == null) return false; - boolean removed = false; fullyLock(); try { - Node trail = head; - Node p = head.next; - while (p != null) { + for (Node trail = head, p = trail.next; + p != null; + trail = p, p = p.next) { if (o.equals(p.item)) { - removed = true; - break; + unlink(p, trail); + return true; } - trail = p; - p = p.next; - } - if (removed) { - p.item = null; - trail.next = p.next; - if (last == p) - last = trail; - if (count.getAndDecrement() == capacity) - notFull.signalAll(); } + return false; } finally { fullyUnlock(); } - return removed; } /** @@ -551,22 +596,22 @@ public class LinkedBlockingQueue extends AbstractQueue *

If this queue fits in the specified array with room to spare * (i.e., the array has more elements than this queue), the element in * the array immediately following the end of the queue is set to - * null. + * {@code null}. * *

Like the {@link #toArray()} method, this method acts as bridge between * array-based and collection-based APIs. Further, this method allows * precise control over the runtime type of the output array, and may, * under certain circumstances, be used to save allocation costs. * - *

Suppose x is a queue known to contain only strings. + *

Suppose {@code x} is a queue known to contain only strings. * The following code can be used to dump the queue into a newly - * allocated array of String: + * allocated array of {@code String}: * *

      *     String[] y = x.toArray(new String[0]);
* - * Note that toArray(new Object[0]) is identical in function to - * toArray(). + * Note that {@code toArray(new Object[0])} is identical in function to + * {@code toArray()}. * * @param a the array into which the elements of the queue are to * be stored, if it is big enough; otherwise, a new array of the @@ -577,6 +622,7 @@ public class LinkedBlockingQueue extends AbstractQueue * this queue * @throws NullPointerException if the specified array is null */ + @SuppressWarnings("unchecked") public T[] toArray(T[] a) { fullyLock(); try { @@ -586,7 +632,7 @@ public class LinkedBlockingQueue extends AbstractQueue (a.getClass().getComponentType(), size); int k = 0; - for (Node p = head.next; p != null; p = p.next) + for (Node p = head.next; p != null; p = p.next) a[k++] = (T)p.item; if (a.length > k) a[k] = null; @@ -612,11 +658,14 @@ public class LinkedBlockingQueue extends AbstractQueue public void clear() { fullyLock(); try { - head.next = null; - assert head.item == null; - last = head; + for (Node p, h = head; (p = h.next) != null; h = p) { + h.next = h; + p.item = null; + } + head = last; + // assert head.item == null && head.next == null; if (count.getAndSet(0) == capacity) - notFull.signalAll(); + notFull.signal(); } finally { fullyUnlock(); } @@ -629,30 +678,7 @@ public class LinkedBlockingQueue extends AbstractQueue * @throws IllegalArgumentException {@inheritDoc} */ public int drainTo(Collection c) { - if (c == null) - throw new NullPointerException(); - if (c == this) - throw new IllegalArgumentException(); - Node first; - fullyLock(); - try { - first = head.next; - head.next = null; - assert head.item == null; - last = head; - if (count.getAndSet(0) == capacity) - notFull.signalAll(); - } finally { - fullyUnlock(); - } - // Transfer the elements outside of locks - int n = 0; - for (Node p = first; p != null; p = p.next) { - c.add(p.item); - p.item = null; - ++n; - } - return n; + return drainTo(c, Integer.MAX_VALUE); } /** @@ -666,33 +692,42 @@ public class LinkedBlockingQueue extends AbstractQueue throw new NullPointerException(); if (c == this) throw new IllegalArgumentException(); - fullyLock(); + boolean signalNotFull = false; + final ReentrantLock takeLock = this.takeLock; + takeLock.lock(); try { - int n = 0; - Node p = head.next; - while (p != null && n < maxElements) { - c.add(p.item); - p.item = null; - p = p.next; - ++n; + int n = Math.min(maxElements, count.get()); + // count.get provides visibility to first n Nodes + Node h = head; + int i = 0; + try { + while (i < n) { + Node p = h.next; + c.add(p.item); + p.item = null; + h.next = h; + h = p; + ++i; + } + return n; + } finally { + // Restore invariants even if c.add() threw + if (i > 0) { + // assert h.item == null; + head = h; + signalNotFull = (count.getAndAdd(-i) == capacity); + } } - if (n != 0) { - head.next = p; - assert head.item == null; - if (p == null) - last = head; - if (count.getAndAdd(-n) == capacity) - notFull.signalAll(); - } - return n; } finally { - fullyUnlock(); + takeLock.unlock(); + if (signalNotFull) + signalNotFull(); } } /** * Returns an iterator over the elements in this queue in proper sequence. - * The returned Iterator is a "weakly consistent" iterator that + * The returned {@code Iterator} is a "weakly consistent" iterator that * will never throw {@link ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) @@ -706,7 +741,7 @@ public class LinkedBlockingQueue extends AbstractQueue private class Itr implements Iterator { /* - * Basic weak-consistent iterator. At all times hold the next + * Basic weakly-consistent iterator. At all times hold the next * item to hand out so that if hasNext() reports true, we will * still have it to return even if lost race with a take etc. */ @@ -715,17 +750,13 @@ public class LinkedBlockingQueue extends AbstractQueue private E currentElement; Itr() { - final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; - final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; - putLock.lock(); - takeLock.lock(); + fullyLock(); try { current = head.next; if (current != null) currentElement = current.item; } finally { - takeLock.unlock(); - putLock.unlock(); + fullyUnlock(); } } @@ -733,54 +764,54 @@ public class LinkedBlockingQueue extends AbstractQueue return current != null; } + /** + * Unlike other traversal methods, iterators need to handle: + * - dequeued nodes (p.next == p) + * - interior removed nodes (p.item == null) + */ + private Node nextNode(Node p) { + Node s = p.next; + if (p == s) + return head.next; + // Skip over removed nodes. + // May be necessary if multiple interior Nodes are removed. + while (s != null && s.item == null) + s = s.next; + return s; + } + public E next() { - final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; - final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; - putLock.lock(); - takeLock.lock(); + fullyLock(); try { if (current == null) throw new NoSuchElementException(); E x = currentElement; lastRet = current; - current = current.next; - if (current != null) - currentElement = current.item; + current = nextNode(current); + currentElement = (current == null) ? null : current.item; return x; } finally { - takeLock.unlock(); - putLock.unlock(); + fullyUnlock(); } } public void remove() { if (lastRet == null) throw new IllegalStateException(); - final ReentrantLock putLock = LinkedBlockingQueue.this.putLock; - final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock; - putLock.lock(); - takeLock.lock(); + fullyLock(); try { Node node = lastRet; lastRet = null; - Node trail = head; - Node p = head.next; - while (p != null && p != node) { - trail = p; - p = p.next; - } - if (p == node) { - p.item = null; - trail.next = p.next; - if (last == p) - last = trail; - int c = count.getAndDecrement(); - if (c == capacity) - notFull.signalAll(); + for (Node trail = head, p = trail.next; + p != null; + trail = p, p = p.next) { + if (p == node) { + unlink(p, trail); + break; + } } } finally { - takeLock.unlock(); - putLock.unlock(); + fullyUnlock(); } } } @@ -789,7 +820,7 @@ public class LinkedBlockingQueue extends AbstractQueue * Save the state to a stream (that is, serialize it). * * @serialData The capacity is emitted (int), followed by all of - * its elements (each an Object) in the proper order, + * its elements (each an {@code Object}) in the proper order, * followed by a null * @param s the stream */ @@ -815,6 +846,7 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Reconstitute this queue instance from a stream (that is, * deserialize it). + * * @param s the stream */ private void readObject(java.io.ObjectInputStream s) @@ -827,6 +859,7 @@ public class LinkedBlockingQueue extends AbstractQueue // Read in all elements and place in queue for (;;) { + @SuppressWarnings("unchecked") E item = (E)s.readObject(); if (item == null) break; diff --git a/jdk/test/java/util/Collection/MOAT.java b/jdk/test/java/util/Collection/MOAT.java index f9d30f56217..d2b6b686903 100644 --- a/jdk/test/java/util/Collection/MOAT.java +++ b/jdk/test/java/util/Collection/MOAT.java @@ -426,6 +426,36 @@ public class MOAT { q.poll(); equal(q.size(), 4); checkFunctionalInvariants(q); + if ((q instanceof LinkedBlockingQueue) || + (q instanceof LinkedBlockingDeque) || + (q instanceof ConcurrentLinkedQueue)) { + testQueueIteratorRemove(q); + } + } + + private static void testQueueIteratorRemove(Queue q) { + System.err.printf("testQueueIteratorRemove %s%n", + q.getClass().getSimpleName()); + q.clear(); + for (int i = 0; i < 5; i++) + q.add(i); + Iterator it = q.iterator(); + check(it.hasNext()); + for (int i = 3; i >= 0; i--) + q.remove(i); + equal(it.next(), 0); + equal(it.next(), 4); + + q.clear(); + for (int i = 0; i < 5; i++) + q.add(i); + it = q.iterator(); + equal(it.next(), 0); + check(it.hasNext()); + for (int i = 1; i < 4; i++) + q.remove(i); + equal(it.next(), 1); + equal(it.next(), 4); } private static void testList(final List l) { @@ -451,6 +481,11 @@ public class MOAT { } private static void testCollection(Collection c) { + try { testCollection1(c); } + catch (Throwable t) { unexpected(t); } + } + + private static void testCollection1(Collection c) { System.out.println("\n==> " + c.getClass().getName()); diff --git a/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java new file mode 100644 index 00000000000..eb85f7bb3ab --- /dev/null +++ b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java @@ -0,0 +1,130 @@ +/* + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +/* + * @test + * @bug 6805775 6815766 + * @summary Test concurrent offer vs. drainTo + */ + +import java.util.*; +import java.util.concurrent.*; + +@SuppressWarnings({"unchecked", "rawtypes"}) +public class OfferDrainToLoops { + void checkNotContainsNull(Iterable it) { + for (Object x : it) + check(x != null); + } + + abstract class CheckedThread extends Thread { + abstract protected void realRun(); + public void run() { + try { realRun(); } catch (Throwable t) { unexpected(t); } + } + { + setDaemon(true); + start(); + } + } + + void test(String[] args) throws Throwable { + test(new LinkedBlockingQueue()); + test(new LinkedBlockingQueue(2000)); + test(new LinkedBlockingDeque()); + test(new LinkedBlockingDeque(2000)); + test(new ArrayBlockingQueue(2000)); + } + + void test(final BlockingQueue q) throws Throwable { + System.out.println(q.getClass().getSimpleName()); + final long testDurationSeconds = 1L; + final long testDurationMillis = testDurationSeconds * 1000L; + final long quittingTimeNanos + = System.nanoTime() + testDurationSeconds * 1000L * 1000L * 1000L; + + Thread offerer = new CheckedThread() { + protected void realRun() { + for (long i = 0; ; i++) { + if ((i % 1024) == 0 && + System.nanoTime() - quittingTimeNanos > 0) + break; + while (! q.offer(i)) + Thread.yield(); + }}}; + + Thread drainer = new CheckedThread() { + protected void realRun() { + for (long i = 0; ; i++) { + if (System.nanoTime() - quittingTimeNanos > 0) + break; + List list = new ArrayList(); + int n = q.drainTo(list); + equal(list.size(), n); + for (int j = 0; j < n - 1; j++) + equal((Long) list.get(j) + 1L, list.get(j + 1)); + Thread.yield(); + }}}; + + Thread scanner = new CheckedThread() { + protected void realRun() { + for (long i = 0; ; i++) { + if (System.nanoTime() - quittingTimeNanos > 0) + break; + checkNotContainsNull(q); + Thread.yield(); + }}}; + + offerer.join(10 * testDurationMillis); + drainer.join(10 * testDurationMillis); + check(! offerer.isAlive()); + check(! drainer.isAlive()); + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new OfferDrainToLoops().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff --git a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java new file mode 100644 index 00000000000..727f6495651 --- /dev/null +++ b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java @@ -0,0 +1,93 @@ +/* + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +import java.util.*; +import java.util.concurrent.*; + +/* + * @test + * @bug 6805775 6815766 + * @summary Check weak consistency of concurrent queue iterators + */ + +@SuppressWarnings({"unchecked", "rawtypes"}) +public class IteratorWeakConsistency { + + void test(String[] args) throws Throwable { + test(new LinkedBlockingQueue()); + test(new LinkedBlockingQueue(20)); + test(new LinkedBlockingDeque()); + test(new LinkedBlockingDeque(20)); + test(new ConcurrentLinkedQueue()); + // Other concurrent queues (e.g. ArrayBlockingQueue) do not + // currently have weakly consistent iterators. + // test(new ArrayBlockingQueue(20)); + } + + void test(Queue q) throws Throwable { + // TODO: make this more general + for (int i = 0; i < 10; i++) + q.add(i); + Iterator it = q.iterator(); + q.poll(); + q.poll(); + q.poll(); + q.remove(7); + List list = new ArrayList(); + while (it.hasNext()) + list.add(it.next()); + equal(list, Arrays.asList(0, 3, 4, 5, 6, 8, 9)); + check(! list.contains(null)); + System.out.printf("%s: %s%n", + q.getClass().getSimpleName(), + list); + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + static Class thisClass = new Object(){}.getClass().getEnclosingClass(); + public static void main(String[] args) throws Throwable { + new IteratorWeakConsistency().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} From 54b80cfe2a0d5ae8c6e6d1a010faf7ebbf99f764 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 29 Jul 2009 13:26:26 -0700 Subject: [PATCH 029/102] 4777949: Javap Rewrite : Warn javap usage on package classes with simple name Reviewed-by: mcimadamore --- .../com/sun/tools/javap/JavapFileManager.java | 4 +- .../com/sun/tools/javap/JavapTask.java | 75 ++++++++---- .../tools/javap/resources/javap.properties | 9 ++ langtools/test/tools/javap/T4777949.java | 111 ++++++++++++++++++ 4 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 langtools/test/tools/javap/T4777949.java diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java b/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java index 85c40921e85..80625b9570b 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java @@ -41,13 +41,13 @@ import com.sun.tools.javac.util.Context; * This code and its internal interfaces are subject to change or * deletion without notice. */ -class JavapFileManager extends JavacFileManager { +public class JavapFileManager extends JavacFileManager { private JavapFileManager(Context context, Charset charset) { super(context, true, charset); setIgnoreSymbolFile(true); } - static JavapFileManager create(final DiagnosticListener dl, PrintWriter log, Options options) { + public static JavapFileManager create(final DiagnosticListener dl, PrintWriter log) { Context javac_context = new Context(); if (dl != null) diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index 285f1b48347..faf526419b7 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -316,17 +316,17 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { Iterable classes) { this(out, fileManager, diagnosticListener); - try { - handleOptions(options, false); - } catch (BadArgs e) { - throw new IllegalArgumentException(e.getMessage()); - } - this.classes = new ArrayList(); for (String classname: classes) { classname.getClass(); // null-check this.classes.add(classname); } + + try { + handleOptions(options, false); + } catch (BadArgs e) { + throw new IllegalArgumentException(e.getMessage()); + } } public void setLocale(Locale locale) { @@ -372,10 +372,18 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { final PrintWriter pw = getPrintWriterForWriter(w); return new DiagnosticListener () { public void report(Diagnostic diagnostic) { - if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + switch (diagnostic.getKind()) { + case ERROR: pw.print(getMessage("err.prefix")); - pw.print(" "); + break; + case WARNING: + pw.print(getMessage("warn.prefix")); + break; + case NOTE: + pw.print(getMessage("note.prefix")); + break; } + pw.print(" "); pw.println(diagnostic.getMessage(null)); } }; @@ -405,7 +413,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { boolean ok = run(); return ok ? EXIT_OK : EXIT_ERROR; } catch (BadArgs e) { - diagnosticListener.report(createDiagnostic(e.key, e.args)); + reportError(e.key, e.args); if (e.showUsage) { log.println(getMessage("main.usage.summary", progname)); } @@ -419,7 +427,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { e_args[0] = e.getCause(); System.arraycopy(e.args, 0, e_args, 1, e.args.length); } - diagnosticListener.report(createDiagnostic("err.internal.error", e_args)); + reportError("err.internal.error", e_args); return EXIT_ABNORMAL; } finally { log.flush(); @@ -531,7 +539,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; fo = sfm.getJavaFileObjects(className).iterator().next(); } else { - diagnosticListener.report(createDiagnostic("err.not.standard.file.manager", className)); + reportError("err.not.standard.file.manager", className); ok = false; continue; } @@ -547,38 +555,42 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { } } if (fo == null) { - diagnosticListener.report(createDiagnostic("err.class.not.found", className)); + reportError("err.class.not.found", className); ok = false; continue; } } attributeFactory.setCompat(options.compat); attributeFactory.setJSR277(options.jsr277); - - write(read(fo)); - + ClassFileInfo cfInfo = read(fo); + if (!className.endsWith(".class")) { + String cfName = cfInfo.cf.getName(); + if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) + reportWarning("warn.unexpected.class", className, cfName.replace('/', '.')); + } + write(cfInfo); } catch (ConstantPoolException e) { - diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage())); + reportError("err.bad.constant.pool", className, e.getLocalizedMessage()); ok = false; } catch (EOFException e) { - diagnosticListener.report(createDiagnostic("err.end.of.file", className)); + reportError("err.end.of.file", className); ok = false; } catch (FileNotFoundException e) { - diagnosticListener.report(createDiagnostic("err.file.not.found", e.getLocalizedMessage())); + reportError("err.file.not.found", e.getLocalizedMessage()); ok = false; } catch (IOException e) { //e.printStackTrace(); Object msg = e.getLocalizedMessage(); if (msg == null) msg = e; - diagnosticListener.report(createDiagnostic("err.ioerror", className, msg)); + reportError("err.ioerror", className, msg); ok = false; } catch (Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); pw.close(); - diagnosticListener.report(createDiagnostic("err.crash", t.toString(), sw.toString())); + reportError("err.crash", t.toString(), sw.toString()); ok = false; } } @@ -684,7 +696,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { } private JavaFileManager getDefaultFileManager(final DiagnosticListener dl, PrintWriter log) { - return JavapFileManager.create(dl, log, options); + return JavapFileManager.create(dl, log); } private JavaFileObject getClassFileObject(String className) throws IOException { @@ -738,10 +750,23 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { } } - private Diagnostic createDiagnostic(final String key, final Object... args) { + private void reportError(String key, Object... args) { + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args)); + } + + private void reportNote(String key, Object... args) { + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.NOTE, key, args)); + } + + private void reportWarning(String key, Object... args) { + diagnosticListener.report(createDiagnostic(Diagnostic.Kind.WARNING, key, args)); + } + + private Diagnostic createDiagnostic( + final Diagnostic.Kind kind, final String key, final Object... args) { return new Diagnostic() { public Kind getKind() { - return Diagnostic.Kind.ERROR; + return kind; } public JavaFileObject getSource() { @@ -776,6 +801,10 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { return JavapTask.this.getMessage(locale, key, args); } + public String toString() { + return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]"; + } + }; } diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties index 06d00b7f3dc..87b9a332886 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties @@ -24,6 +24,15 @@ main.usage.summary=\ Usage: {0} \n\ use -help for a list of possible options +warn.prefix=Warning: +warn.unexpected.class=Binary file {0} contains {1} + +note.prefix=Note: + +main.usage.summary=\ +Usage: {0} \n\ +use -help for a list of possible options + main.usage=\ Usage: {0} \n\ where possible options include: diff --git a/langtools/test/tools/javap/T4777949.java b/langtools/test/tools/javap/T4777949.java new file mode 100644 index 00000000000..612b1d23806 --- /dev/null +++ b/langtools/test/tools/javap/T4777949.java @@ -0,0 +1,111 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import com.sun.tools.javap.*; + +/* + * @test + * @bug 4777949 + * @summary Warn javap usage on package with simple name + */ +public class T4777949 { + public static void main(String... args) throws Exception { + new T4777949().run(); + } + + void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + test(".", "p.q.r.Test", false); + test("p", "q.r.Test", true); + test("p/q", "r.Test", true); + test("p/q/r", "Test", true); + test(".", "p.q.r.Test.Inner", false); + test(".", "p.q.r.Test$Inner", false); + test("p", "q.r.Test.Inner", true); + test("p", "q.r.Test$Inner", true); + + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + void test(String classPath, String className, boolean expectWarnings) { + List> diags = + javap(Arrays.asList("-classpath", classPath), Arrays.asList(className)); + boolean foundWarnings = false; + for (Diagnostic d: diags) { + if (d.getKind() == Diagnostic.Kind.WARNING) + foundWarnings = true; + } + } + + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("package p.q.r;"); + out.println("class Test { class Inner { } }"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-d", ".", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + List> javap(List args, List classes) { + DiagnosticCollector dc = new DiagnosticCollector(); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + JavaFileManager fm = JavapFileManager.create(dc, pw); + JavapTask t = new JavapTask(pw, fm, dc, args, classes); + boolean ok = t.run(); + + List> diags = dc.getDiagnostics(); + + if (!ok) + error("javap failed unexpectedly"); + + System.err.println("args=" + args + " classes=" + classes + "\n" + + diags + "\n" + + sw); + + return diags; + } + + void error(String msg) { + System.err.println("error: " + msg); + errors++; + } + + int errors; +} + From 36736be8baa432ebfe0d7bfa0042496402d06459 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Wed, 29 Jul 2009 13:56:15 -0700 Subject: [PATCH 030/102] 6866554: Misc. javadoc warnings Reviewed-by: alanb --- .../share/classes/java/nio/channels/DatagramChannel.java | 2 +- jdk/src/share/classes/java/nio/channels/package-info.java | 4 ++-- jdk/src/share/classes/java/nio/file/DirectoryStream.java | 2 +- jdk/src/share/classes/java/nio/file/Path.java | 2 +- .../share/classes/java/nio/file/attribute/package-info.java | 4 ++-- .../classes/java/util/concurrent/ConcurrentLinkedQueue.java | 3 ++- .../classes/java/util/concurrent/LinkedBlockingDeque.java | 6 ++++-- .../classes/java/util/concurrent/LinkedBlockingQueue.java | 3 ++- 8 files changed, 15 insertions(+), 11 deletions(-) diff --git a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java index cbf402f5933..1dde1d7a399 100644 --- a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java +++ b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java @@ -421,7 +421,7 @@ public abstract class DatagramChannel * invocation of this method will block until the first operation is * complete. If this channel's socket is not bound then this method will * first cause the socket to be bound to an address that is assigned - * automatically, as if by invoking the {@link #bind bind) method with a + * automatically, as if by invoking the {@link #bind bind} method with a * parameter of {@code null}.

* * @param src diff --git a/jdk/src/share/classes/java/nio/channels/package-info.java b/jdk/src/share/classes/java/nio/channels/package-info.java index 47a1cb5f979..36a40840260 100644 --- a/jdk/src/share/classes/java/nio/channels/package-info.java +++ b/jdk/src/share/classes/java/nio/channels/package-info.java @@ -115,8 +115,8 @@ * Reads, writes, maps, and manipulates files * {@link java.nio.channels.FileLock} * A lock on a (region of a) file - * {@link java.nio.MappedByteBuffer}/{@link java.nio.MappedBigByteBuffer}   - * A direct byte buffer or big byte buffer mapped to a region of a file + * {@link java.nio.MappedByteBuffer}   + * A direct byte buffer mapped to a region of a file * * *

The {@link java.nio.channels.FileChannel} class supports the usual diff --git a/jdk/src/share/classes/java/nio/file/DirectoryStream.java b/jdk/src/share/classes/java/nio/file/DirectoryStream.java index 001f22b0723..f0be02172d6 100644 --- a/jdk/src/share/classes/java/nio/file/DirectoryStream.java +++ b/jdk/src/share/classes/java/nio/file/DirectoryStream.java @@ -53,7 +53,7 @@ import java.io.IOException; * invoking the {@link #close close} method. Closing the directory stream * releases any resources associated with the stream. Once a directory stream * is closed, all further method invocations on the iterator throw {@link - * java.util.concurrent.ConcurrentModificationException} with cause {@link + * java.util.ConcurrentModificationException} with cause {@link * ClosedDirectoryStreamException}. * *

A directory stream is not required to be asynchronously closeable. diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java index 113a7c58067..d9ba6de7835 100644 --- a/jdk/src/share/classes/java/nio/file/Path.java +++ b/jdk/src/share/classes/java/nio/file/Path.java @@ -987,7 +987,7 @@ public abstract class Path * exception then it is propogated to the iterator's {@link Iterator#hasNext() * hasNext} or {@link Iterator#next() next} method. Where an {@code * IOException} is thrown, it is propogated as a {@link - * java.util.concurrent.ConcurrentModificationException} with the {@code + * java.util.ConcurrentModificationException} with the {@code * IOException} as the cause. * *

When an implementation supports operations on entries in the diff --git a/jdk/src/share/classes/java/nio/file/attribute/package-info.java b/jdk/src/share/classes/java/nio/file/attribute/package-info.java index c5301b1f840..b2192b89237 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/package-info.java +++ b/jdk/src/share/classes/java/nio/file/attribute/package-info.java @@ -102,9 +102,9 @@ *

  • The {@link java.nio.file.attribute.UserPrincipalLookupService} * interface defines methods to lookup user or group principals.
  • * - *

  • The {@link java.nio.file.attribute.Attribute} interface + *

  • The {@link java.nio.file.attribute.FileAttribute} interface * represents the value of an attribute for cases where the attribute value is - * require to be set atomically when creating an object in the file system.
  • + * required to be set atomically when creating an object in the file system. * * * diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index fe2bb9d8bca..5e31adea247 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -562,7 +562,8 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Returns an iterator over the elements in this queue in proper sequence. * The returned iterator is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) * reflect any modifications subsequent to construction. diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 7db94a6efba..dd34d0dc6b7 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -988,7 +988,8 @@ public class LinkedBlockingDeque * Returns an iterator over the elements in this deque in proper sequence. * The elements will be returned in order from first (head) to last (tail). * The returned {@code Iterator} is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) * reflect any modifications subsequent to construction. @@ -1004,7 +1005,8 @@ public class LinkedBlockingDeque * sequential order. The elements will be returned in order from * last (tail) to first (head). * The returned {@code Iterator} is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) * reflect any modifications subsequent to construction. diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java index 9c1c6cc7b1f..10f2b6540cd 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -728,7 +728,8 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Returns an iterator over the elements in this queue in proper sequence. * The returned {@code Iterator} is a "weakly consistent" iterator that - * will never throw {@link ConcurrentModificationException}, + * will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException}, * and guarantees to traverse elements as they existed upon * construction of the iterator, and may (but is not guaranteed to) * reflect any modifications subsequent to construction. From 827200b265d5837bda0abb4c450e8267414588a8 Mon Sep 17 00:00:00 2001 From: Josh Bloch Date: Wed, 29 Jul 2009 14:24:19 -0700 Subject: [PATCH 031/102] 6804124: Replace "modified mergesort" in java.util.Arrays.sort with timsort Easy port of timsort from android Reviewed-by: martin --- jdk/make/java/java/FILES_java.gmk | 2 + jdk/src/share/classes/java/util/Arrays.java | 277 ++++-- .../share/classes/java/util/Collections.java | 97 +- .../classes/java/util/ComparableTimSort.java | 895 +++++++++++++++++ jdk/src/share/classes/java/util/TimSort.java | 928 ++++++++++++++++++ jdk/test/java/util/TimSort/ArrayBuilder.java | 142 +++ jdk/test/java/util/TimSort/README | 4 + jdk/test/java/util/TimSort/SortPerf.java | 66 ++ jdk/test/java/util/TimSort/Sorter.java | 55 ++ 9 files changed, 2381 insertions(+), 85 deletions(-) create mode 100644 jdk/src/share/classes/java/util/ComparableTimSort.java create mode 100644 jdk/src/share/classes/java/util/TimSort.java create mode 100644 jdk/test/java/util/TimSort/ArrayBuilder.java create mode 100644 jdk/test/java/util/TimSort/README create mode 100644 jdk/test/java/util/TimSort/SortPerf.java create mode 100644 jdk/test/java/util/TimSort/Sorter.java diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index 58c7b13608c..f9dd26383ce 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -250,6 +250,8 @@ JAVA_JAVA_java = \ java/util/IdentityHashMap.java \ java/util/EnumMap.java \ java/util/Arrays.java \ + java/util/TimSort.java \ + java/util/ComparableTimSort.java \ java/util/ConcurrentModificationException.java \ java/util/ServiceLoader.java \ java/util/ServiceConfigurationError.java \ diff --git a/jdk/src/share/classes/java/util/Arrays.java b/jdk/src/share/classes/java/util/Arrays.java index 313c686eb36..eac5521cd86 100644 --- a/jdk/src/share/classes/java/util/Arrays.java +++ b/jdk/src/share/classes/java/util/Arrays.java @@ -1065,29 +1065,103 @@ public class Arrays { (x[b] > x[c] ? b : x[a] > x[c] ? c : a)); } + /** + * Old merge sort implementation can be selected (for + * compatibility with broken comparators) using a system property. + * Cannot be a static boolean in the enclosing class due to + * circular dependencies. To be removed in a future release. + */ + static final class LegacyMergeSort { + private static final boolean userRequested = + java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "java.util.Arrays.useLegacyMergeSort")).booleanValue(); + } + + /* + * If this platform has an optimizing VM, check whether ComparableTimSort + * offers any performance benefit over TimSort in conjunction with a + * comparator that returns: + * {@code ((Comparable)first).compareTo(Second)}. + * If not, you are better off deleting ComparableTimSort to + * eliminate the code duplication. In other words, the commented + * out code below is the preferable implementation for sorting + * arrays of Comparables if it offers sufficient performance. + */ + +// /** +// * A comparator that implements the natural ordering of a group of +// * mutually comparable elements. Using this comparator saves us +// * from duplicating most of the code in this file (one version for +// * Comparables, one for explicit Comparators). +// */ +// private static final Comparator NATURAL_ORDER = +// new Comparator() { +// @SuppressWarnings("unchecked") +// public int compare(Object first, Object second) { +// return ((Comparable)first).compareTo(second); +// } +// }; +// +// public static void sort(Object[] a) { +// sort(a, 0, a.length, NATURAL_ORDER); +// } +// +// public static void sort(Object[] a, int fromIndex, int toIndex) { +// sort(a, fromIndex, toIndex, NATURAL_ORDER); +// } /** - * Sorts the specified array of objects into ascending order, according to - * the {@linkplain Comparable natural ordering} - * of its elements. All elements in the array - * must implement the {@link Comparable} interface. Furthermore, all - * elements in the array must be mutually comparable (that is, - * e1.compareTo(e2) must not throw a ClassCastException - * for any elements e1 and e2 in the array).

    + * Sorts the specified array of objects into ascending order, according + * to the {@linkplain Comparable natural ordering} of its elements. + * All elements in the array must implement the {@link Comparable} + * interface. Furthermore, all elements in the array must be + * mutually comparable (that is, {@code e1.compareTo(e2)} must + * not throw a {@code ClassCastException} for any elements {@code e1} + * and {@code e2} in the array). * - * This sort is guaranteed to be stable: equal elements will - * not be reordered as a result of the sort.

    + *

    This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. * - * The sorting algorithm is a modified mergesort (in which the merge is - * omitted if the highest element in the low sublist is less than the - * lowest element in the high sublist). This algorithm offers guaranteed - * n*log(n) performance. + *

    Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

    The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

    The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techiques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. * * @param a the array to be sorted - * @throws ClassCastException if the array contains elements that are not - * mutually comparable (for example, strings and integers). + * @throws ClassCastException if the array contains elements that are not + * mutually comparable (for example, strings and integers) + * @throws IllegalArgumentException (optional) if the natural + * ordering of the array elements is found to violate the + * {@link Comparable} contract */ public static void sort(Object[] a) { + if (LegacyMergeSort.userRequested) + legacyMergeSort(a); + else + ComparableTimSort.sort(a); + } + + /** To be removed in a future release. */ + private static void legacyMergeSort(Object[] a) { Object[] aux = a.clone(); mergeSort(aux, a, 0, a.length, 0); } @@ -1097,34 +1171,63 @@ public class Arrays { * ascending order, according to the * {@linkplain Comparable natural ordering} of its * elements. The range to be sorted extends from index - * fromIndex, inclusive, to index toIndex, exclusive. - * (If fromIndex==toIndex, the range to be sorted is empty.) All + * {@code fromIndex}, inclusive, to index {@code toIndex}, exclusive. + * (If {@code fromIndex==toIndex}, the range to be sorted is empty.) All * elements in this range must implement the {@link Comparable} * interface. Furthermore, all elements in this range must be mutually - * comparable (that is, e1.compareTo(e2) must not throw a - * ClassCastException for any elements e1 and - * e2 in the array).

    + * comparable (that is, {@code e1.compareTo(e2)} must not throw a + * {@code ClassCastException} for any elements {@code e1} and + * {@code e2} in the array). * - * This sort is guaranteed to be stable: equal elements will - * not be reordered as a result of the sort.

    + *

    This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. * - * The sorting algorithm is a modified mergesort (in which the merge is - * omitted if the highest element in the low sublist is less than the - * lowest element in the high sublist). This algorithm offers guaranteed - * n*log(n) performance. + *

    Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

    The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

    The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techiques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be * sorted * @param toIndex the index of the last element (exclusive) to be sorted - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or - * toIndex > a.length - * @throws ClassCastException if the array contains elements that are - * not mutually comparable (for example, strings and - * integers). + * @throws IllegalArgumentException if {@code fromIndex > toIndex} or + * (optional) if the natural ordering of the array elements is + * found to violate the {@link Comparable} contract + * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or + * {@code toIndex > a.length} + * @throws ClassCastException if the array contains elements that are + * not mutually comparable (for example, strings and + * integers). */ public static void sort(Object[] a, int fromIndex, int toIndex) { + if (LegacyMergeSort.userRequested) + legacyMergeSort(a, fromIndex, toIndex); + else + ComparableTimSort.sort(a, fromIndex, toIndex); + } + + /** To be removed in a future release. */ + private static void legacyMergeSort(Object[] a, + int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); Object[] aux = copyOfRange(a, fromIndex, toIndex); mergeSort(aux, a, fromIndex, toIndex, -fromIndex); @@ -1133,6 +1236,7 @@ public class Arrays { /** * Tuning parameter: list size at or below which insertion sort will be * used in preference to mergesort or quicksort. + * To be removed in a future release. */ private static final int INSERTIONSORT_THRESHOLD = 7; @@ -1142,6 +1246,7 @@ public class Arrays { * low is the index in dest to start sorting * high is the end index in dest to end sorting * off is the offset to generate corresponding low, high in src + * To be removed in a future release. */ private static void mergeSort(Object[] src, Object[] dest, @@ -1197,25 +1302,53 @@ public class Arrays { * Sorts the specified array of objects according to the order induced by * the specified comparator. All elements in the array must be * mutually comparable by the specified comparator (that is, - * c.compare(e1, e2) must not throw a ClassCastException - * for any elements e1 and e2 in the array).

    + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the array). * - * This sort is guaranteed to be stable: equal elements will - * not be reordered as a result of the sort.

    + *

    This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. * - * The sorting algorithm is a modified mergesort (in which the merge is - * omitted if the highest element in the low sublist is less than the - * lowest element in the high sublist). This algorithm offers guaranteed - * n*log(n) performance. + *

    Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

    The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

    The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techiques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. * * @param a the array to be sorted * @param c the comparator to determine the order of the array. A - * null value indicates that the elements' + * {@code null} value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. - * @throws ClassCastException if the array contains elements that are - * not mutually comparable using the specified comparator. + * @throws ClassCastException if the array contains elements that are + * not mutually comparable using the specified comparator + * @throws IllegalArgumentException (optional) if the comparator is + * found to violate the {@link Comparator} contract */ public static void sort(T[] a, Comparator c) { + if (LegacyMergeSort.userRequested) + legacyMergeSort(a, c); + else + TimSort.sort(a, c); + } + + /** To be removed in a future release. */ + private static void legacyMergeSort(T[] a, Comparator c) { T[] aux = a.clone(); if (c==null) mergeSort(aux, a, 0, a.length, 0); @@ -1226,36 +1359,65 @@ public class Arrays { /** * Sorts the specified range of the specified array of objects according * to the order induced by the specified comparator. The range to be - * sorted extends from index fromIndex, inclusive, to index - * toIndex, exclusive. (If fromIndex==toIndex, the + * sorted extends from index {@code fromIndex}, inclusive, to index + * {@code toIndex}, exclusive. (If {@code fromIndex==toIndex}, the * range to be sorted is empty.) All elements in the range must be * mutually comparable by the specified comparator (that is, - * c.compare(e1, e2) must not throw a ClassCastException - * for any elements e1 and e2 in the range).

    + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the range). * - * This sort is guaranteed to be stable: equal elements will - * not be reordered as a result of the sort.

    + *

    This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. * - * The sorting algorithm is a modified mergesort (in which the merge is - * omitted if the highest element in the low sublist is less than the - * lowest element in the high sublist). This algorithm offers guaranteed - * n*log(n) performance. + *

    Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

    The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

    The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techiques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. * * @param a the array to be sorted * @param fromIndex the index of the first element (inclusive) to be * sorted * @param toIndex the index of the last element (exclusive) to be sorted * @param c the comparator to determine the order of the array. A - * null value indicates that the elements' + * {@code null} value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. * @throws ClassCastException if the array contains elements that are not * mutually comparable using the specified comparator. - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 or - * toIndex > a.length + * @throws IllegalArgumentException if {@code fromIndex > toIndex} or + * (optional) if the comparator is found to violate the + * {@link Comparator} contract + * @throws ArrayIndexOutOfBoundsException if {@code fromIndex < 0} or + * {@code toIndex > a.length} */ public static void sort(T[] a, int fromIndex, int toIndex, Comparator c) { + if (LegacyMergeSort.userRequested) + legacyMergeSort(a, fromIndex, toIndex, c); + else + TimSort.sort(a, fromIndex, toIndex, c); + } + + /** To be removed in a future release. */ + private static void legacyMergeSort(T[] a, int fromIndex, int toIndex, + Comparator c) { rangeCheck(a.length, fromIndex, toIndex); T[] aux = copyOfRange(a, fromIndex, toIndex); if (c==null) @@ -1270,6 +1432,7 @@ public class Arrays { * low is the index in dest to start sorting * high is the end index in dest to end sorting * off is the offset into src corresponding to low in dest + * To be removed in a future release. */ private static void mergeSort(Object[] src, Object[] dest, diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java index caec3ffd11c..8597888dfa5 100644 --- a/jdk/src/share/classes/java/util/Collections.java +++ b/jdk/src/share/classes/java/util/Collections.java @@ -100,23 +100,42 @@ public class Collections { /** * Sorts the specified list into ascending order, according to the - * natural ordering of its elements. All elements in the list must - * implement the Comparable interface. Furthermore, all elements - * in the list must be mutually comparable (that is, - * e1.compareTo(e2) must not throw a ClassCastException - * for any elements e1 and e2 in the list).

    + * {@linkplain Comparable natural ordering} of its elements. + * All elements in the list must implement the {@link Comparable} + * interface. Furthermore, all elements in the list must be + * mutually comparable (that is, {@code e1.compareTo(e2)} + * must not throw a {@code ClassCastException} for any elements + * {@code e1} and {@code e2} in the list). * - * This sort is guaranteed to be stable: equal elements will - * not be reordered as a result of the sort.

    + *

    This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. * - * The specified list must be modifiable, but need not be resizable.

    + *

    The specified list must be modifiable, but need not be resizable. * - * The sorting algorithm is a modified mergesort (in which the merge is - * omitted if the highest element in the low sublist is less than the - * lowest element in the high sublist). This algorithm offers guaranteed - * n log(n) performance. + *

    Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. * - * This implementation dumps the specified list into an array, sorts + *

    The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

    The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techiques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. + * + *

    This implementation dumps the specified list into an array, sorts * the array, and iterates over the list resetting each element * from the corresponding position in the array. This avoids the * n2 log(n) performance that would result from attempting @@ -126,8 +145,10 @@ public class Collections { * @throws ClassCastException if the list contains elements that are not * mutually comparable (for example, strings and integers). * @throws UnsupportedOperationException if the specified list's - * list-iterator does not support the set operation. - * @see Comparable + * list-iterator does not support the {@code set} operation. + * @throws IllegalArgumentException (optional) if the implementation + * detects that the natural ordering of the list elements is + * found to violate the {@link Comparable} contract */ public static > void sort(List list) { Object[] a = list.toArray(); @@ -143,19 +164,38 @@ public class Collections { * Sorts the specified list according to the order induced by the * specified comparator. All elements in the list must be mutually * comparable using the specified comparator (that is, - * c.compare(e1, e2) must not throw a ClassCastException - * for any elements e1 and e2 in the list).

    + * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} + * for any elements {@code e1} and {@code e2} in the list). * - * This sort is guaranteed to be stable: equal elements will - * not be reordered as a result of the sort.

    + *

    This sort is guaranteed to be stable: equal elements will + * not be reordered as a result of the sort. * - * The sorting algorithm is a modified mergesort (in which the merge is - * omitted if the highest element in the low sublist is less than the - * lowest element in the high sublist). This algorithm offers guaranteed - * n log(n) performance. + *

    The specified list must be modifiable, but need not be resizable. * - * The specified list must be modifiable, but need not be resizable. - * This implementation dumps the specified list into an array, sorts + *

    Implementation note: This implementation is a stable, adaptive, + * iterative mergesort that requires far fewer than n lg(n) comparisons + * when the input array is partially sorted, while offering the + * performance of a traditional mergesort when the input array is + * randomly ordered. If the input array is nearly sorted, the + * implementation requires approximately n comparisons. Temporary + * storage requirements vary from a small constant for nearly sorted + * input arrays to n/2 object references for randomly ordered input + * arrays. + * + *

    The implementation takes equal advantage of ascending and + * descending order in its input array, and can take advantage of + * ascending and descending order in different parts of the the same + * input array. It is well-suited to merging two or more sorted arrays: + * simply concatenate the arrays and sort the resulting array. + * + *

    The implementation was adapted from Tim Peters's list sort for Python + * ( + * TimSort). It uses techiques from Peter McIlroy's "Optimistic + * Sorting and Information Theoretic Complexity", in Proceedings of the + * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, + * January 1993. + * + *

    This implementation dumps the specified list into an array, sorts * the array, and iterates over the list resetting each element * from the corresponding position in the array. This avoids the * n2 log(n) performance that would result from attempting @@ -163,13 +203,14 @@ public class Collections { * * @param list the list to be sorted. * @param c the comparator to determine the order of the list. A - * null value indicates that the elements' natural + * {@code null} value indicates that the elements' natural * ordering should be used. * @throws ClassCastException if the list contains elements that are not * mutually comparable using the specified comparator. * @throws UnsupportedOperationException if the specified list's - * list-iterator does not support the set operation. - * @see Comparator + * list-iterator does not support the {@code set} operation. + * @throws IllegalArgumentException (optional) if the comparator is + * found to violate the {@link Comparator} contract */ public static void sort(List list, Comparator c) { Object[] a = list.toArray(); diff --git a/jdk/src/share/classes/java/util/ComparableTimSort.java b/jdk/src/share/classes/java/util/ComparableTimSort.java new file mode 100644 index 00000000000..750a89bebaa --- /dev/null +++ b/jdk/src/share/classes/java/util/ComparableTimSort.java @@ -0,0 +1,895 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.util; + +/** + * This is a near duplicate of {@link TimSort}, modified for use with + * arrays of objects that implement {@link Comparable}, instead of using + * explicit comparators. + * + *

    If you are using an optimizing VM, you may find that ComparableTimSort + * offers no performance benefit over TimSort in conjunction with a + * comparator that simply returns {@code ((Comparable)first).compareTo(Second)}. + * If this is the case, you are better off deleting ComparableTimSort to + * eliminate the code duplication. (See Arrays.java for details.) + * + * @author Josh Bloch + */ +class ComparableTimSort { + /** + * This is the minimum sized sequence that will be merged. Shorter + * sequences will be lengthened by calling binarySort. If the entire + * array is less than this length, no merges will be performed. + * + * This constant should be a power of two. It was 64 in Tim Peter's C + * implementation, but 32 was empirically determined to work better in + * this implementation. In the unlikely event that you set this constant + * to be a number that's not a power of two, you'll need to change the + * {@link #minRunLength} computation. + * + * If you decrease this constant, you must change the stackLen + * computation in the TimSort constructor, or you risk an + * ArrayOutOfBounds exception. See listsort.txt for a discussion + * of the minimum stack length required as a function of the length + * of the array being sorted and the minimum merge sequence length. + */ + private static final int MIN_MERGE = 32; + + /** + * The array being sorted. + */ + private final Object[] a; + + /** + * When we get into galloping mode, we stay there until both runs win less + * often than MIN_GALLOP consecutive times. + */ + private static final int MIN_GALLOP = 7; + + /** + * This controls when we get *into* galloping mode. It is initialized + * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for + * random data, and lower for highly structured data. + */ + private int minGallop = MIN_GALLOP; + + /** + * Maximum initial size of tmp array, which is used for merging. The array + * can grow to accommodate demand. + * + * Unlike Tim's original C version, we do not allocate this much storage + * when sorting smaller arrays. This change was required for performance. + */ + private static final int INITIAL_TMP_STORAGE_LENGTH = 256; + + /** + * Temp storage for merges. + */ + private Object[] tmp; + + /** + * A stack of pending runs yet to be merged. Run i starts at + * address base[i] and extends for len[i] elements. It's always + * true (so long as the indices are in bounds) that: + * + * runBase[i] + runLen[i] == runBase[i + 1] + * + * so we could cut the storage for this, but it's a minor amount, + * and keeping all the info explicit simplifies the code. + */ + private int stackSize = 0; // Number of pending runs on stack + private final int[] runBase; + private final int[] runLen; + + /** + * Creates a TimSort instance to maintain the state of an ongoing sort. + * + * @param a the array to be sorted + */ + private ComparableTimSort(Object[] a) { + this.a = a; + + // Allocate temp storage (which may be increased later if necessary) + int len = a.length; + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) + Object[] newArray = new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ? + len >>> 1 : INITIAL_TMP_STORAGE_LENGTH]; + tmp = newArray; + + /* + * Allocate runs-to-be-merged stack (which cannot be expanded). The + * stack length requirements are described in listsort.txt. The C + * version always uses the same stack length (85), but this was + * measured to be too expensive when sorting "mid-sized" arrays (e.g., + * 100 elements) in Java. Therefore, we use smaller (but sufficiently + * large) stack lengths for smaller arrays. The "magic numbers" in the + * computation below must be changed if MIN_MERGE is decreased. See + * the MIN_MERGE declaration above for more information. + */ + int stackLen = (len < 120 ? 5 : + len < 1542 ? 10 : + len < 119151 ? 19 : 40); + runBase = new int[stackLen]; + runLen = new int[stackLen]; + } + + /* + * The next two methods (which are package private and static) constitute + * the entire API of this class. Each of these methods obeys the contract + * of the public method with the same signature in java.util.Arrays. + */ + + static void sort(Object[] a) { + sort(a, 0, a.length); + } + + static void sort(Object[] a, int lo, int hi) { + rangeCheck(a.length, lo, hi); + int nRemaining = hi - lo; + if (nRemaining < 2) + return; // Arrays of size 0 and 1 are always sorted + + // If array is small, do a "mini-TimSort" with no merges + if (nRemaining < MIN_MERGE) { + int initRunLen = countRunAndMakeAscending(a, lo, hi); + binarySort(a, lo, hi, lo + initRunLen); + return; + } + + /** + * March over the array once, left to right, finding natural runs, + * extending short natural runs to minRun elements, and merging runs + * to maintain stack invariant. + */ + ComparableTimSort ts = new ComparableTimSort(a); + int minRun = minRunLength(nRemaining); + do { + // Identify next run + int runLen = countRunAndMakeAscending(a, lo, hi); + + // If run is short, extend to min(minRun, nRemaining) + if (runLen < minRun) { + int force = nRemaining <= minRun ? nRemaining : minRun; + binarySort(a, lo, lo + force, lo + runLen); + runLen = force; + } + + // Push run onto pending-run stack, and maybe merge + ts.pushRun(lo, runLen); + ts.mergeCollapse(); + + // Advance to find next run + lo += runLen; + nRemaining -= runLen; + } while (nRemaining != 0); + + // Merge all remaining runs to complete sort + assert lo == hi; + ts.mergeForceCollapse(); + assert ts.stackSize == 1; + } + + /** + * Sorts the specified portion of the specified array using a binary + * insertion sort. This is the best method for sorting small numbers + * of elements. It requires O(n log n) compares, but O(n^2) data + * movement (worst case). + * + * If the initial part of the specified range is already sorted, + * this method can take advantage of it: the method assumes that the + * elements from index {@code lo}, inclusive, to {@code start}, + * exclusive are already sorted. + * + * @param a the array in which a range is to be sorted + * @param lo the index of the first element in the range to be sorted + * @param hi the index after the last element in the range to be sorted + * @param start the index of the first element in the range that is + * not already known to be sorted (@code lo <= start <= hi} + */ + @SuppressWarnings("fallthrough") + private static void binarySort(Object[] a, int lo, int hi, int start) { + assert lo <= start && start <= hi; + if (start == lo) + start++; + for ( ; start < hi; start++) { + @SuppressWarnings("unchecked") + Comparable pivot = (Comparable) a[start]; + + // Set left (and right) to the index where a[start] (pivot) belongs + int left = lo; + int right = start; + assert left <= right; + /* + * Invariants: + * pivot >= all in [lo, left). + * pivot < all in [right, start). + */ + while (left < right) { + int mid = (left + right) >>> 1; + if (pivot.compareTo(a[mid]) < 0) + right = mid; + else + left = mid + 1; + } + assert left == right; + + /* + * The invariants still hold: pivot >= all in [lo, left) and + * pivot < all in [left, start), so pivot belongs at left. Note + * that if there are elements equal to pivot, left points to the + * first slot after them -- that's why this sort is stable. + * Slide elements over to make room to make room for pivot. + */ + int n = start - left; // The number of elements to move + // Switch is just an optimization for arraycopy in default case + switch(n) { + case 2: a[left + 2] = a[left + 1]; + case 1: a[left + 1] = a[left]; + break; + default: System.arraycopy(a, left, a, left + 1, n); + } + a[left] = pivot; + } + } + + /** + * Returns the length of the run beginning at the specified position in + * the specified array and reverses the run if it is descending (ensuring + * that the run will always be ascending when the method returns). + * + * A run is the longest ascending sequence with: + * + * a[lo] <= a[lo + 1] <= a[lo + 2] <= ... + * + * or the longest descending sequence with: + * + * a[lo] > a[lo + 1] > a[lo + 2] > ... + * + * For its intended use in a stable mergesort, the strictness of the + * definition of "descending" is needed so that the call can safely + * reverse a descending sequence without violating stability. + * + * @param a the array in which a run is to be counted and possibly reversed + * @param lo index of the first element in the run + * @param hi index after the last element that may be contained in the run. + It is required that @code{lo < hi}. + * @return the length of the run beginning at the specified position in + * the specified array + */ + @SuppressWarnings("unchecked") + private static int countRunAndMakeAscending(Object[] a, int lo, int hi) { + assert lo < hi; + int runHi = lo + 1; + if (runHi == hi) + return 1; + + // Find end of run, and reverse range if descending + if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending + while(runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0) + runHi++; + reverseRange(a, lo, runHi); + } else { // Ascending + while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0) + runHi++; + } + + return runHi - lo; + } + + /** + * Reverse the specified range of the specified array. + * + * @param a the array in which a range is to be reversed + * @param lo the index of the first element in the range to be reversed + * @param hi the index after the last element in the range to be reversed + */ + private static void reverseRange(Object[] a, int lo, int hi) { + hi--; + while (lo < hi) { + Object t = a[lo]; + a[lo++] = a[hi]; + a[hi--] = t; + } + } + + /** + * Returns the minimum acceptable run length for an array of the specified + * length. Natural runs shorter than this will be extended with + * {@link #binarySort}. + * + * Roughly speaking, the computation is: + * + * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff). + * Else if n is an exact power of 2, return MIN_MERGE/2. + * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k + * is close to, but strictly less than, an exact power of 2. + * + * For the rationale, see listsort.txt. + * + * @param n the length of the array to be sorted + * @return the length of the minimum run to be merged + */ + private static int minRunLength(int n) { + assert n >= 0; + int r = 0; // Becomes 1 if any 1 bits are shifted off + while (n >= MIN_MERGE) { + r |= (n & 1); + n >>= 1; + } + return n + r; + } + + /** + * Pushes the specified run onto the pending-run stack. + * + * @param runBase index of the first element in the run + * @param runLen the number of elements in the run + */ + private void pushRun(int runBase, int runLen) { + this.runBase[stackSize] = runBase; + this.runLen[stackSize] = runLen; + stackSize++; + } + + /** + * Examines the stack of runs waiting to be merged and merges adjacent runs + * until the stack invariants are reestablished: + * + * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1] + * 2. runLen[i - 2] > runLen[i - 1] + * + * This method is called each time a new run is pushed onto the stack, + * so the invariants are guaranteed to hold for i < stackSize upon + * entry to the method. + */ + private void mergeCollapse() { + while (stackSize > 1) { + int n = stackSize - 2; + if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) { + if (runLen[n - 1] < runLen[n + 1]) + n--; + mergeAt(n); + } else if (runLen[n] <= runLen[n + 1]) { + mergeAt(n); + } else { + break; // Invariant is established + } + } + } + + /** + * Merges all runs on the stack until only one remains. This method is + * called once, to complete the sort. + */ + private void mergeForceCollapse() { + while (stackSize > 1) { + int n = stackSize - 2; + if (n > 0 && runLen[n - 1] < runLen[n + 1]) + n--; + mergeAt(n); + } + } + + /** + * Merges the two runs at stack indices i and i+1. Run i must be + * the penultimate or antepenultimate run on the stack. In other words, + * i must be equal to stackSize-2 or stackSize-3. + * + * @param i stack index of the first of the two runs to merge + */ + @SuppressWarnings("unchecked") + private void mergeAt(int i) { + assert stackSize >= 2; + assert i >= 0; + assert i == stackSize - 2 || i == stackSize - 3; + + int base1 = runBase[i]; + int len1 = runLen[i]; + int base2 = runBase[i + 1]; + int len2 = runLen[i + 1]; + assert len1 > 0 && len2 > 0; + assert base1 + len1 == base2; + + /* + * Record the length of the combined runs; if i is the 3rd-last + * run now, also slide over the last run (which isn't involved + * in this merge). The current run (i+1) goes away in any case. + */ + runLen[i] = len1 + len2; + if (i == stackSize - 3) { + runBase[i + 1] = runBase[i + 2]; + runLen[i + 1] = runLen[i + 2]; + } + stackSize--; + + /* + * Find where the first element of run2 goes in run1. Prior elements + * in run1 can be ignored (because they're already in place). + */ + int k = gallopRight((Comparable) a[base2], a, base1, len1, 0); + assert k >= 0; + base1 += k; + len1 -= k; + if (len1 == 0) + return; + + /* + * Find where the last element of run1 goes in run2. Subsequent elements + * in run2 can be ignored (because they're already in place). + */ + len2 = gallopLeft((Comparable) a[base1 + len1 - 1], a, + base2, len2, len2 - 1); + assert len2 >= 0; + if (len2 == 0) + return; + + // Merge remaining runs, using tmp array with min(len1, len2) elements + if (len1 <= len2) + mergeLo(base1, len1, base2, len2); + else + mergeHi(base1, len1, base2, len2); + } + + /** + * Locates the position at which to insert the specified key into the + * specified sorted range; if the range contains an element equal to key, + * returns the index of the leftmost equal element. + * + * @param key the key whose insertion point to search for + * @param a the array in which to search + * @param base the index of the first element in the range + * @param len the length of the range; must be > 0 + * @param hint the index at which to begin the search, 0 <= hint < n. + * The closer hint is to the result, the faster this method will run. + * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k], + * pretending that a[b - 1] is minus infinity and a[b + n] is infinity. + * In other words, key belongs at index b + k; or in other words, + * the first k elements of a should precede key, and the last n - k + * should follow it. + */ + private static int gallopLeft(Comparable key, Object[] a, + int base, int len, int hint) { + assert len > 0 && hint >= 0 && hint < len; + + int lastOfs = 0; + int ofs = 1; + if (key.compareTo(a[base + hint]) > 0) { + // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs] + int maxOfs = len - hint; + while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) > 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to base + lastOfs += hint; + ofs += hint; + } else { // key <= a[base + hint] + // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs] + final int maxOfs = hint + 1; + while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) <= 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to base + int tmp = lastOfs; + lastOfs = hint - ofs; + ofs = hint - tmp; + } + assert -1 <= lastOfs && lastOfs < ofs && ofs <= len; + + /* + * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere + * to the right of lastOfs but no farther right than ofs. Do a binary + * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs]. + */ + lastOfs++; + while (lastOfs < ofs) { + int m = lastOfs + ((ofs - lastOfs) >>> 1); + + if (key.compareTo(a[base + m]) > 0) + lastOfs = m + 1; // a[base + m] < key + else + ofs = m; // key <= a[base + m] + } + assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs] + return ofs; + } + + /** + * Like gallopLeft, except that if the range contains an element equal to + * key, gallopRight returns the index after the rightmost equal element. + * + * @param key the key whose insertion point to search for + * @param a the array in which to search + * @param base the index of the first element in the range + * @param len the length of the range; must be > 0 + * @param hint the index at which to begin the search, 0 <= hint < n. + * The closer hint is to the result, the faster this method will run. + * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k] + */ + private static int gallopRight(Comparable key, Object[] a, + int base, int len, int hint) { + assert len > 0 && hint >= 0 && hint < len; + + int ofs = 1; + int lastOfs = 0; + if (key.compareTo(a[base + hint]) < 0) { + // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs] + int maxOfs = hint + 1; + while (ofs < maxOfs && key.compareTo(a[base + hint - ofs]) < 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to b + int tmp = lastOfs; + lastOfs = hint - ofs; + ofs = hint - tmp; + } else { // a[b + hint] <= key + // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs] + int maxOfs = len - hint; + while (ofs < maxOfs && key.compareTo(a[base + hint + ofs]) >= 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to b + lastOfs += hint; + ofs += hint; + } + assert -1 <= lastOfs && lastOfs < ofs && ofs <= len; + + /* + * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to + * the right of lastOfs but no farther right than ofs. Do a binary + * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs]. + */ + lastOfs++; + while (lastOfs < ofs) { + int m = lastOfs + ((ofs - lastOfs) >>> 1); + + if (key.compareTo(a[base + m]) < 0) + ofs = m; // key < a[b + m] + else + lastOfs = m + 1; // a[b + m] <= key + } + assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs] + return ofs; + } + + /** + * Merges two adjacent runs in place, in a stable fashion. The first + * element of the first run must be greater than the first element of the + * second run (a[base1] > a[base2]), and the last element of the first run + * (a[base1 + len1-1]) must be greater than all elements of the second run. + * + * For performance, this method should be called only when len1 <= len2; + * its twin, mergeHi should be called if len1 >= len2. (Either method + * may be called if len1 == len2.) + * + * @param base1 index of first element in first run to be merged + * @param len1 length of first run to be merged (must be > 0) + * @param base2 index of first element in second run to be merged + * (must be aBase + aLen) + * @param len2 length of second run to be merged (must be > 0) + */ + @SuppressWarnings("unchecked") + private void mergeLo(int base1, int len1, int base2, int len2) { + assert len1 > 0 && len2 > 0 && base1 + len1 == base2; + + // Copy first run into temp array + Object[] a = this.a; // For performance + Object[] tmp = ensureCapacity(len1); + System.arraycopy(a, base1, tmp, 0, len1); + + int cursor1 = 0; // Indexes into tmp array + int cursor2 = base2; // Indexes int a + int dest = base1; // Indexes int a + + // Move first element of second run and deal with degenerate cases + a[dest++] = a[cursor2++]; + if (--len2 == 0) { + System.arraycopy(tmp, cursor1, a, dest, len1); + return; + } + if (len1 == 1) { + System.arraycopy(a, cursor2, a, dest, len2); + a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge + return; + } + + int minGallop = this.minGallop; // Use local variable for performance + outer: + while (true) { + int count1 = 0; // Number of times in a row that first run won + int count2 = 0; // Number of times in a row that second run won + + /* + * Do the straightforward thing until (if ever) one run starts + * winning consistently. + */ + do { + assert len1 > 1 && len2 > 0; + if (((Comparable) a[cursor2]).compareTo(tmp[cursor1]) < 0) { + a[dest++] = a[cursor2++]; + count2++; + count1 = 0; + if (--len2 == 0) + break outer; + } else { + a[dest++] = tmp[cursor1++]; + count1++; + count2 = 0; + if (--len1 == 1) + break outer; + } + } while ((count1 | count2) < minGallop); + + /* + * One run is winning so consistently that galloping may be a + * huge win. So try that, and continue galloping until (if ever) + * neither run appears to be winning consistently anymore. + */ + do { + assert len1 > 1 && len2 > 0; + count1 = gallopRight((Comparable) a[cursor2], tmp, cursor1, len1, 0); + if (count1 != 0) { + System.arraycopy(tmp, cursor1, a, dest, count1); + dest += count1; + cursor1 += count1; + len1 -= count1; + if (len1 <= 1) // len1 == 1 || len1 == 0 + break outer; + } + a[dest++] = a[cursor2++]; + if (--len2 == 0) + break outer; + + count2 = gallopLeft((Comparable) tmp[cursor1], a, cursor2, len2, 0); + if (count2 != 0) { + System.arraycopy(a, cursor2, a, dest, count2); + dest += count2; + cursor2 += count2; + len2 -= count2; + if (len2 == 0) + break outer; + } + a[dest++] = tmp[cursor1++]; + if (--len1 == 1) + break outer; + minGallop--; + } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP); + if (minGallop < 0) + minGallop = 0; + minGallop += 2; // Penalize for leaving gallop mode + } // End of "outer" loop + this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field + + if (len1 == 1) { + assert len2 > 0; + System.arraycopy(a, cursor2, a, dest, len2); + a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge + } else if (len1 == 0) { + throw new IllegalArgumentException( + "Comparison method violates its general contract!"); + } else { + assert len2 == 0; + assert len1 > 1; + System.arraycopy(tmp, cursor1, a, dest, len1); + } + } + + /** + * Like mergeLo, except that this method should be called only if + * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method + * may be called if len1 == len2.) + * + * @param base1 index of first element in first run to be merged + * @param len1 length of first run to be merged (must be > 0) + * @param base2 index of first element in second run to be merged + * (must be aBase + aLen) + * @param len2 length of second run to be merged (must be > 0) + */ + @SuppressWarnings("unchecked") + private void mergeHi(int base1, int len1, int base2, int len2) { + assert len1 > 0 && len2 > 0 && base1 + len1 == base2; + + // Copy second run into temp array + Object[] a = this.a; // For performance + Object[] tmp = ensureCapacity(len2); + System.arraycopy(a, base2, tmp, 0, len2); + + int cursor1 = base1 + len1 - 1; // Indexes into a + int cursor2 = len2 - 1; // Indexes into tmp array + int dest = base2 + len2 - 1; // Indexes into a + + // Move last element of first run and deal with degenerate cases + a[dest--] = a[cursor1--]; + if (--len1 == 0) { + System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); + return; + } + if (len2 == 1) { + dest -= len1; + cursor1 -= len1; + System.arraycopy(a, cursor1 + 1, a, dest + 1, len1); + a[dest] = tmp[cursor2]; + return; + } + + int minGallop = this.minGallop; // Use local variable for performance + outer: + while (true) { + int count1 = 0; // Number of times in a row that first run won + int count2 = 0; // Number of times in a row that second run won + + /* + * Do the straightforward thing until (if ever) one run + * appears to win consistently. + */ + do { + assert len1 > 0 && len2 > 1; + if (((Comparable) tmp[cursor2]).compareTo(a[cursor1]) < 0) { + a[dest--] = a[cursor1--]; + count1++; + count2 = 0; + if (--len1 == 0) + break outer; + } else { + a[dest--] = tmp[cursor2--]; + count2++; + count1 = 0; + if (--len2 == 1) + break outer; + } + } while ((count1 | count2) < minGallop); + + /* + * One run is winning so consistently that galloping may be a + * huge win. So try that, and continue galloping until (if ever) + * neither run appears to be winning consistently anymore. + */ + do { + assert len1 > 0 && len2 > 1; + count1 = len1 - gallopRight((Comparable) tmp[cursor2], a, base1, len1, len1 - 1); + if (count1 != 0) { + dest -= count1; + cursor1 -= count1; + len1 -= count1; + System.arraycopy(a, cursor1 + 1, a, dest + 1, count1); + if (len1 == 0) + break outer; + } + a[dest--] = tmp[cursor2--]; + if (--len2 == 1) + break outer; + + count2 = len2 - gallopLeft((Comparable) a[cursor1], tmp, 0, len2, len2 - 1); + if (count2 != 0) { + dest -= count2; + cursor2 -= count2; + len2 -= count2; + System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2); + if (len2 <= 1) + break outer; // len2 == 1 || len2 == 0 + } + a[dest--] = a[cursor1--]; + if (--len1 == 0) + break outer; + minGallop--; + } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP); + if (minGallop < 0) + minGallop = 0; + minGallop += 2; // Penalize for leaving gallop mode + } // End of "outer" loop + this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field + + if (len2 == 1) { + assert len1 > 0; + dest -= len1; + cursor1 -= len1; + System.arraycopy(a, cursor1 + 1, a, dest + 1, len1); + a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge + } else if (len2 == 0) { + throw new IllegalArgumentException( + "Comparison method violates its general contract!"); + } else { + assert len1 == 0; + assert len2 > 0; + System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); + } + } + + /** + * Ensures that the external array tmp has at least the specified + * number of elements, increasing its size if necessary. The size + * increases exponentially to ensure amortized linear time complexity. + * + * @param minCapacity the minimum required capacity of the tmp array + * @return tmp, whether or not it grew + */ + private Object[] ensureCapacity(int minCapacity) { + if (tmp.length < minCapacity) { + // Compute smallest power of 2 > minCapacity + int newSize = minCapacity; + newSize |= newSize >> 1; + newSize |= newSize >> 2; + newSize |= newSize >> 4; + newSize |= newSize >> 8; + newSize |= newSize >> 16; + newSize++; + + if (newSize < 0) // Not bloody likely! + newSize = minCapacity; + else + newSize = Math.min(newSize, a.length >>> 1); + + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) + Object[] newArray = new Object[newSize]; + tmp = newArray; + } + return tmp; + } + + /** + * Checks that fromIndex and toIndex are in range, and throws an + * appropriate exception if they aren't. + * + * @param arrayLen the length of the array + * @param fromIndex the index of the first element of the range + * @param toIndex the index after the last element of the range + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 + * or toIndex > arrayLen + */ + private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) { + if (fromIndex > toIndex) + throw new IllegalArgumentException("fromIndex(" + fromIndex + + ") > toIndex(" + toIndex+")"); + if (fromIndex < 0) + throw new ArrayIndexOutOfBoundsException(fromIndex); + if (toIndex > arrayLen) + throw new ArrayIndexOutOfBoundsException(toIndex); + } +} diff --git a/jdk/src/share/classes/java/util/TimSort.java b/jdk/src/share/classes/java/util/TimSort.java new file mode 100644 index 00000000000..1d4e710a499 --- /dev/null +++ b/jdk/src/share/classes/java/util/TimSort.java @@ -0,0 +1,928 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.util; + +/** + * A stable, adaptive, iterative mergesort that requires far fewer than + * n lg(n) comparisons when running on partially sorted arrays, while + * offering performance comparable to a traditional mergesort when run + * on random arrays. Like all proper mergesorts, this sort is stable and + * runs O(n log n) time (worst case). In the worst case, this sort requires + * temporary storage space for n/2 object references; in the best case, + * it requires only a small constant amount of space. + * + * This implementation was adapted from Tim Peters's list sort for + * Python, which is described in detail here: + * + * http://svn.python.org/projects/python/trunk/Objects/listsort.txt + * + * Tim's C code may be found here: + * + * http://svn.python.org/projects/python/trunk/Objects/listobject.c + * + * The underlying techniques are described in this paper (and may have + * even earlier origins): + * + * "Optimistic Sorting and Information Theoretic Complexity" + * Peter McIlroy + * SODA (Fourth Annual ACM-SIAM Symposium on Discrete Algorithms), + * pp 467-474, Austin, Texas, 25-27 January 1993. + * + * While the API to this class consists solely of static methods, it is + * (privately) instantiable; a TimSort instance holds the state of an ongoing + * sort, assuming the input array is large enough to warrant the full-blown + * TimSort. Small arrays are sorted in place, using a binary insertion sort. + * + * @author Josh Bloch + */ +class TimSort { + /** + * This is the minimum sized sequence that will be merged. Shorter + * sequences will be lengthened by calling binarySort. If the entire + * array is less than this length, no merges will be performed. + * + * This constant should be a power of two. It was 64 in Tim Peter's C + * implementation, but 32 was empirically determined to work better in + * this implementation. In the unlikely event that you set this constant + * to be a number that's not a power of two, you'll need to change the + * {@link #minRunLength} computation. + * + * If you decrease this constant, you must change the stackLen + * computation in the TimSort constructor, or you risk an + * ArrayOutOfBounds exception. See listsort.txt for a discussion + * of the minimum stack length required as a function of the length + * of the array being sorted and the minimum merge sequence length. + */ + private static final int MIN_MERGE = 32; + + /** + * The array being sorted. + */ + private final T[] a; + + /** + * The comparator for this sort. + */ + private final Comparator c; + + /** + * When we get into galloping mode, we stay there until both runs win less + * often than MIN_GALLOP consecutive times. + */ + private static final int MIN_GALLOP = 7; + + /** + * This controls when we get *into* galloping mode. It is initialized + * to MIN_GALLOP. The mergeLo and mergeHi methods nudge it higher for + * random data, and lower for highly structured data. + */ + private int minGallop = MIN_GALLOP; + + /** + * Maximum initial size of tmp array, which is used for merging. The array + * can grow to accommodate demand. + * + * Unlike Tim's original C version, we do not allocate this much storage + * when sorting smaller arrays. This change was required for performance. + */ + private static final int INITIAL_TMP_STORAGE_LENGTH = 256; + + /** + * Temp storage for merges. + */ + private T[] tmp; // Actual runtime type will be Object[], regardless of T + + /** + * A stack of pending runs yet to be merged. Run i starts at + * address base[i] and extends for len[i] elements. It's always + * true (so long as the indices are in bounds) that: + * + * runBase[i] + runLen[i] == runBase[i + 1] + * + * so we could cut the storage for this, but it's a minor amount, + * and keeping all the info explicit simplifies the code. + */ + private int stackSize = 0; // Number of pending runs on stack + private final int[] runBase; + private final int[] runLen; + + /** + * Creates a TimSort instance to maintain the state of an ongoing sort. + * + * @param a the array to be sorted + * @param c the comparator to determine the order of the sort + */ + private TimSort(T[] a, Comparator c) { + this.a = a; + this.c = c; + + // Allocate temp storage (which may be increased later if necessary) + int len = a.length; + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) + T[] newArray = (T[]) new Object[len < 2 * INITIAL_TMP_STORAGE_LENGTH ? + len >>> 1 : INITIAL_TMP_STORAGE_LENGTH]; + tmp = newArray; + + /* + * Allocate runs-to-be-merged stack (which cannot be expanded). The + * stack length requirements are described in listsort.txt. The C + * version always uses the same stack length (85), but this was + * measured to be too expensive when sorting "mid-sized" arrays (e.g., + * 100 elements) in Java. Therefore, we use smaller (but sufficiently + * large) stack lengths for smaller arrays. The "magic numbers" in the + * computation below must be changed if MIN_MERGE is decreased. See + * the MIN_MERGE declaration above for more information. + */ + int stackLen = (len < 120 ? 5 : + len < 1542 ? 10 : + len < 119151 ? 19 : 40); + runBase = new int[stackLen]; + runLen = new int[stackLen]; + } + + /* + * The next two methods (which are package private and static) constitute + * the entire API of this class. Each of these methods obeys the contract + * of the public method with the same signature in java.util.Arrays. + */ + + static void sort(T[] a, Comparator c) { + sort(a, 0, a.length, c); + } + + static void sort(T[] a, int lo, int hi, Comparator c) { + if (c == null) { + Arrays.sort(a, lo, hi); + return; + } + + rangeCheck(a.length, lo, hi); + int nRemaining = hi - lo; + if (nRemaining < 2) + return; // Arrays of size 0 and 1 are always sorted + + // If array is small, do a "mini-TimSort" with no merges + if (nRemaining < MIN_MERGE) { + int initRunLen = countRunAndMakeAscending(a, lo, hi, c); + binarySort(a, lo, hi, lo + initRunLen, c); + return; + } + + /** + * March over the array once, left to right, finding natural runs, + * extending short natural runs to minRun elements, and merging runs + * to maintain stack invariant. + */ + TimSort ts = new TimSort(a, c); + int minRun = minRunLength(nRemaining); + do { + // Identify next run + int runLen = countRunAndMakeAscending(a, lo, hi, c); + + // If run is short, extend to min(minRun, nRemaining) + if (runLen < minRun) { + int force = nRemaining <= minRun ? nRemaining : minRun; + binarySort(a, lo, lo + force, lo + runLen, c); + runLen = force; + } + + // Push run onto pending-run stack, and maybe merge + ts.pushRun(lo, runLen); + ts.mergeCollapse(); + + // Advance to find next run + lo += runLen; + nRemaining -= runLen; + } while (nRemaining != 0); + + // Merge all remaining runs to complete sort + assert lo == hi; + ts.mergeForceCollapse(); + assert ts.stackSize == 1; + } + + /** + * Sorts the specified portion of the specified array using a binary + * insertion sort. This is the best method for sorting small numbers + * of elements. It requires O(n log n) compares, but O(n^2) data + * movement (worst case). + * + * If the initial part of the specified range is already sorted, + * this method can take advantage of it: the method assumes that the + * elements from index {@code lo}, inclusive, to {@code start}, + * exclusive are already sorted. + * + * @param a the array in which a range is to be sorted + * @param lo the index of the first element in the range to be sorted + * @param hi the index after the last element in the range to be sorted + * @param start the index of the first element in the range that is + * not already known to be sorted (@code lo <= start <= hi} + * @param c comparator to used for the sort + */ + @SuppressWarnings("fallthrough") + private static void binarySort(T[] a, int lo, int hi, int start, + Comparator c) { + assert lo <= start && start <= hi; + if (start == lo) + start++; + for ( ; start < hi; start++) { + T pivot = a[start]; + + // Set left (and right) to the index where a[start] (pivot) belongs + int left = lo; + int right = start; + assert left <= right; + /* + * Invariants: + * pivot >= all in [lo, left). + * pivot < all in [right, start). + */ + while (left < right) { + int mid = (left + right) >>> 1; + if (c.compare(pivot, a[mid]) < 0) + right = mid; + else + left = mid + 1; + } + assert left == right; + + /* + * The invariants still hold: pivot >= all in [lo, left) and + * pivot < all in [left, start), so pivot belongs at left. Note + * that if there are elements equal to pivot, left points to the + * first slot after them -- that's why this sort is stable. + * Slide elements over to make room to make room for pivot. + */ + int n = start - left; // The number of elements to move + // Switch is just an optimization for arraycopy in default case + switch(n) { + case 2: a[left + 2] = a[left + 1]; + case 1: a[left + 1] = a[left]; + break; + default: System.arraycopy(a, left, a, left + 1, n); + } + a[left] = pivot; + } + } + + /** + * Returns the length of the run beginning at the specified position in + * the specified array and reverses the run if it is descending (ensuring + * that the run will always be ascending when the method returns). + * + * A run is the longest ascending sequence with: + * + * a[lo] <= a[lo + 1] <= a[lo + 2] <= ... + * + * or the longest descending sequence with: + * + * a[lo] > a[lo + 1] > a[lo + 2] > ... + * + * For its intended use in a stable mergesort, the strictness of the + * definition of "descending" is needed so that the call can safely + * reverse a descending sequence without violating stability. + * + * @param a the array in which a run is to be counted and possibly reversed + * @param lo index of the first element in the run + * @param hi index after the last element that may be contained in the run. + It is required that @code{lo < hi}. + * @param c the comparator to used for the sort + * @return the length of the run beginning at the specified position in + * the specified array + */ + private static int countRunAndMakeAscending(T[] a, int lo, int hi, + Comparator c) { + assert lo < hi; + int runHi = lo + 1; + if (runHi == hi) + return 1; + + // Find end of run, and reverse range if descending + if (c.compare(a[runHi++], a[lo]) < 0) { // Descending + while(runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0) + runHi++; + reverseRange(a, lo, runHi); + } else { // Ascending + while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0) + runHi++; + } + + return runHi - lo; + } + + /** + * Reverse the specified range of the specified array. + * + * @param a the array in which a range is to be reversed + * @param lo the index of the first element in the range to be reversed + * @param hi the index after the last element in the range to be reversed + */ + private static void reverseRange(Object[] a, int lo, int hi) { + hi--; + while (lo < hi) { + Object t = a[lo]; + a[lo++] = a[hi]; + a[hi--] = t; + } + } + + /** + * Returns the minimum acceptable run length for an array of the specified + * length. Natural runs shorter than this will be extended with + * {@link #binarySort}. + * + * Roughly speaking, the computation is: + * + * If n < MIN_MERGE, return n (it's too small to bother with fancy stuff). + * Else if n is an exact power of 2, return MIN_MERGE/2. + * Else return an int k, MIN_MERGE/2 <= k <= MIN_MERGE, such that n/k + * is close to, but strictly less than, an exact power of 2. + * + * For the rationale, see listsort.txt. + * + * @param n the length of the array to be sorted + * @return the length of the minimum run to be merged + */ + private static int minRunLength(int n) { + assert n >= 0; + int r = 0; // Becomes 1 if any 1 bits are shifted off + while (n >= MIN_MERGE) { + r |= (n & 1); + n >>= 1; + } + return n + r; + } + + /** + * Pushes the specified run onto the pending-run stack. + * + * @param runBase index of the first element in the run + * @param runLen the number of elements in the run + */ + private void pushRun(int runBase, int runLen) { + this.runBase[stackSize] = runBase; + this.runLen[stackSize] = runLen; + stackSize++; + } + + /** + * Examines the stack of runs waiting to be merged and merges adjacent runs + * until the stack invariants are reestablished: + * + * 1. runLen[i - 3] > runLen[i - 2] + runLen[i - 1] + * 2. runLen[i - 2] > runLen[i - 1] + * + * This method is called each time a new run is pushed onto the stack, + * so the invariants are guaranteed to hold for i < stackSize upon + * entry to the method. + */ + private void mergeCollapse() { + while (stackSize > 1) { + int n = stackSize - 2; + if (n > 0 && runLen[n-1] <= runLen[n] + runLen[n+1]) { + if (runLen[n - 1] < runLen[n + 1]) + n--; + mergeAt(n); + } else if (runLen[n] <= runLen[n + 1]) { + mergeAt(n); + } else { + break; // Invariant is established + } + } + } + + /** + * Merges all runs on the stack until only one remains. This method is + * called once, to complete the sort. + */ + private void mergeForceCollapse() { + while (stackSize > 1) { + int n = stackSize - 2; + if (n > 0 && runLen[n - 1] < runLen[n + 1]) + n--; + mergeAt(n); + } + } + + /** + * Merges the two runs at stack indices i and i+1. Run i must be + * the penultimate or antepenultimate run on the stack. In other words, + * i must be equal to stackSize-2 or stackSize-3. + * + * @param i stack index of the first of the two runs to merge + */ + private void mergeAt(int i) { + assert stackSize >= 2; + assert i >= 0; + assert i == stackSize - 2 || i == stackSize - 3; + + int base1 = runBase[i]; + int len1 = runLen[i]; + int base2 = runBase[i + 1]; + int len2 = runLen[i + 1]; + assert len1 > 0 && len2 > 0; + assert base1 + len1 == base2; + + /* + * Record the length of the combined runs; if i is the 3rd-last + * run now, also slide over the last run (which isn't involved + * in this merge). The current run (i+1) goes away in any case. + */ + runLen[i] = len1 + len2; + if (i == stackSize - 3) { + runBase[i + 1] = runBase[i + 2]; + runLen[i + 1] = runLen[i + 2]; + } + stackSize--; + + /* + * Find where the first element of run2 goes in run1. Prior elements + * in run1 can be ignored (because they're already in place). + */ + int k = gallopRight(a[base2], a, base1, len1, 0, c); + assert k >= 0; + base1 += k; + len1 -= k; + if (len1 == 0) + return; + + /* + * Find where the last element of run1 goes in run2. Subsequent elements + * in run2 can be ignored (because they're already in place). + */ + len2 = gallopLeft(a[base1 + len1 - 1], a, base2, len2, len2 - 1, c); + assert len2 >= 0; + if (len2 == 0) + return; + + // Merge remaining runs, using tmp array with min(len1, len2) elements + if (len1 <= len2) + mergeLo(base1, len1, base2, len2); + else + mergeHi(base1, len1, base2, len2); + } + + /** + * Locates the position at which to insert the specified key into the + * specified sorted range; if the range contains an element equal to key, + * returns the index of the leftmost equal element. + * + * @param key the key whose insertion point to search for + * @param a the array in which to search + * @param base the index of the first element in the range + * @param len the length of the range; must be > 0 + * @param hint the index at which to begin the search, 0 <= hint < n. + * The closer hint is to the result, the faster this method will run. + * @param c the comparator used to order the range, and to search + * @return the int k, 0 <= k <= n such that a[b + k - 1] < key <= a[b + k], + * pretending that a[b - 1] is minus infinity and a[b + n] is infinity. + * In other words, key belongs at index b + k; or in other words, + * the first k elements of a should precede key, and the last n - k + * should follow it. + */ + private static int gallopLeft(T key, T[] a, int base, int len, int hint, + Comparator c) { + assert len > 0 && hint >= 0 && hint < len; + int lastOfs = 0; + int ofs = 1; + if (c.compare(key, a[base + hint]) > 0) { + // Gallop right until a[base+hint+lastOfs] < key <= a[base+hint+ofs] + int maxOfs = len - hint; + while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) > 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to base + lastOfs += hint; + ofs += hint; + } else { // key <= a[base + hint] + // Gallop left until a[base+hint-ofs] < key <= a[base+hint-lastOfs] + final int maxOfs = hint + 1; + while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) <= 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to base + int tmp = lastOfs; + lastOfs = hint - ofs; + ofs = hint - tmp; + } + assert -1 <= lastOfs && lastOfs < ofs && ofs <= len; + + /* + * Now a[base+lastOfs] < key <= a[base+ofs], so key belongs somewhere + * to the right of lastOfs but no farther right than ofs. Do a binary + * search, with invariant a[base + lastOfs - 1] < key <= a[base + ofs]. + */ + lastOfs++; + while (lastOfs < ofs) { + int m = lastOfs + ((ofs - lastOfs) >>> 1); + + if (c.compare(key, a[base + m]) > 0) + lastOfs = m + 1; // a[base + m] < key + else + ofs = m; // key <= a[base + m] + } + assert lastOfs == ofs; // so a[base + ofs - 1] < key <= a[base + ofs] + return ofs; + } + + /** + * Like gallopLeft, except that if the range contains an element equal to + * key, gallopRight returns the index after the rightmost equal element. + * + * @param key the key whose insertion point to search for + * @param a the array in which to search + * @param base the index of the first element in the range + * @param len the length of the range; must be > 0 + * @param hint the index at which to begin the search, 0 <= hint < n. + * The closer hint is to the result, the faster this method will run. + * @param c the comparator used to order the range, and to search + * @return the int k, 0 <= k <= n such that a[b + k - 1] <= key < a[b + k] + */ + private static int gallopRight(T key, T[] a, int base, int len, + int hint, Comparator c) { + assert len > 0 && hint >= 0 && hint < len; + + int ofs = 1; + int lastOfs = 0; + if (c.compare(key, a[base + hint]) < 0) { + // Gallop left until a[b+hint - ofs] <= key < a[b+hint - lastOfs] + int maxOfs = hint + 1; + while (ofs < maxOfs && c.compare(key, a[base + hint - ofs]) < 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to b + int tmp = lastOfs; + lastOfs = hint - ofs; + ofs = hint - tmp; + } else { // a[b + hint] <= key + // Gallop right until a[b+hint + lastOfs] <= key < a[b+hint + ofs] + int maxOfs = len - hint; + while (ofs < maxOfs && c.compare(key, a[base + hint + ofs]) >= 0) { + lastOfs = ofs; + ofs = (ofs << 1) + 1; + if (ofs <= 0) // int overflow + ofs = maxOfs; + } + if (ofs > maxOfs) + ofs = maxOfs; + + // Make offsets relative to b + lastOfs += hint; + ofs += hint; + } + assert -1 <= lastOfs && lastOfs < ofs && ofs <= len; + + /* + * Now a[b + lastOfs] <= key < a[b + ofs], so key belongs somewhere to + * the right of lastOfs but no farther right than ofs. Do a binary + * search, with invariant a[b + lastOfs - 1] <= key < a[b + ofs]. + */ + lastOfs++; + while (lastOfs < ofs) { + int m = lastOfs + ((ofs - lastOfs) >>> 1); + + if (c.compare(key, a[base + m]) < 0) + ofs = m; // key < a[b + m] + else + lastOfs = m + 1; // a[b + m] <= key + } + assert lastOfs == ofs; // so a[b + ofs - 1] <= key < a[b + ofs] + return ofs; + } + + /** + * Merges two adjacent runs in place, in a stable fashion. The first + * element of the first run must be greater than the first element of the + * second run (a[base1] > a[base2]), and the last element of the first run + * (a[base1 + len1-1]) must be greater than all elements of the second run. + * + * For performance, this method should be called only when len1 <= len2; + * its twin, mergeHi should be called if len1 >= len2. (Either method + * may be called if len1 == len2.) + * + * @param base1 index of first element in first run to be merged + * @param len1 length of first run to be merged (must be > 0) + * @param base2 index of first element in second run to be merged + * (must be aBase + aLen) + * @param len2 length of second run to be merged (must be > 0) + */ + private void mergeLo(int base1, int len1, int base2, int len2) { + assert len1 > 0 && len2 > 0 && base1 + len1 == base2; + + // Copy first run into temp array + T[] a = this.a; // For performance + T[] tmp = ensureCapacity(len1); + System.arraycopy(a, base1, tmp, 0, len1); + + int cursor1 = 0; // Indexes into tmp array + int cursor2 = base2; // Indexes int a + int dest = base1; // Indexes int a + + // Move first element of second run and deal with degenerate cases + a[dest++] = a[cursor2++]; + if (--len2 == 0) { + System.arraycopy(tmp, cursor1, a, dest, len1); + return; + } + if (len1 == 1) { + System.arraycopy(a, cursor2, a, dest, len2); + a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge + return; + } + + Comparator c = this.c; // Use local variable for performance + int minGallop = this.minGallop; // " " " " " + outer: + while (true) { + int count1 = 0; // Number of times in a row that first run won + int count2 = 0; // Number of times in a row that second run won + + /* + * Do the straightforward thing until (if ever) one run starts + * winning consistently. + */ + do { + assert len1 > 1 && len2 > 0; + if (c.compare(a[cursor2], tmp[cursor1]) < 0) { + a[dest++] = a[cursor2++]; + count2++; + count1 = 0; + if (--len2 == 0) + break outer; + } else { + a[dest++] = tmp[cursor1++]; + count1++; + count2 = 0; + if (--len1 == 1) + break outer; + } + } while ((count1 | count2) < minGallop); + + /* + * One run is winning so consistently that galloping may be a + * huge win. So try that, and continue galloping until (if ever) + * neither run appears to be winning consistently anymore. + */ + do { + assert len1 > 1 && len2 > 0; + count1 = gallopRight(a[cursor2], tmp, cursor1, len1, 0, c); + if (count1 != 0) { + System.arraycopy(tmp, cursor1, a, dest, count1); + dest += count1; + cursor1 += count1; + len1 -= count1; + if (len1 <= 1) // len1 == 1 || len1 == 0 + break outer; + } + a[dest++] = a[cursor2++]; + if (--len2 == 0) + break outer; + + count2 = gallopLeft(tmp[cursor1], a, cursor2, len2, 0, c); + if (count2 != 0) { + System.arraycopy(a, cursor2, a, dest, count2); + dest += count2; + cursor2 += count2; + len2 -= count2; + if (len2 == 0) + break outer; + } + a[dest++] = tmp[cursor1++]; + if (--len1 == 1) + break outer; + minGallop--; + } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP); + if (minGallop < 0) + minGallop = 0; + minGallop += 2; // Penalize for leaving gallop mode + } // End of "outer" loop + this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field + + if (len1 == 1) { + assert len2 > 0; + System.arraycopy(a, cursor2, a, dest, len2); + a[dest + len2] = tmp[cursor1]; // Last elt of run 1 to end of merge + } else if (len1 == 0) { + throw new IllegalArgumentException( + "Comparison method violates its general contract!"); + } else { + assert len2 == 0; + assert len1 > 1; + System.arraycopy(tmp, cursor1, a, dest, len1); + } + } + + /** + * Like mergeLo, except that this method should be called only if + * len1 >= len2; mergeLo should be called if len1 <= len2. (Either method + * may be called if len1 == len2.) + * + * @param base1 index of first element in first run to be merged + * @param len1 length of first run to be merged (must be > 0) + * @param base2 index of first element in second run to be merged + * (must be aBase + aLen) + * @param len2 length of second run to be merged (must be > 0) + */ + private void mergeHi(int base1, int len1, int base2, int len2) { + assert len1 > 0 && len2 > 0 && base1 + len1 == base2; + + // Copy second run into temp array + T[] a = this.a; // For performance + T[] tmp = ensureCapacity(len2); + System.arraycopy(a, base2, tmp, 0, len2); + + int cursor1 = base1 + len1 - 1; // Indexes into a + int cursor2 = len2 - 1; // Indexes into tmp array + int dest = base2 + len2 - 1; // Indexes into a + + // Move last element of first run and deal with degenerate cases + a[dest--] = a[cursor1--]; + if (--len1 == 0) { + System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); + return; + } + if (len2 == 1) { + dest -= len1; + cursor1 -= len1; + System.arraycopy(a, cursor1 + 1, a, dest + 1, len1); + a[dest] = tmp[cursor2]; + return; + } + + Comparator c = this.c; // Use local variable for performance + int minGallop = this.minGallop; // " " " " " + outer: + while (true) { + int count1 = 0; // Number of times in a row that first run won + int count2 = 0; // Number of times in a row that second run won + + /* + * Do the straightforward thing until (if ever) one run + * appears to win consistently. + */ + do { + assert len1 > 0 && len2 > 1; + if (c.compare(tmp[cursor2], a[cursor1]) < 0) { + a[dest--] = a[cursor1--]; + count1++; + count2 = 0; + if (--len1 == 0) + break outer; + } else { + a[dest--] = tmp[cursor2--]; + count2++; + count1 = 0; + if (--len2 == 1) + break outer; + } + } while ((count1 | count2) < minGallop); + + /* + * One run is winning so consistently that galloping may be a + * huge win. So try that, and continue galloping until (if ever) + * neither run appears to be winning consistently anymore. + */ + do { + assert len1 > 0 && len2 > 1; + count1 = len1 - gallopRight(tmp[cursor2], a, base1, len1, len1 - 1, c); + if (count1 != 0) { + dest -= count1; + cursor1 -= count1; + len1 -= count1; + System.arraycopy(a, cursor1 + 1, a, dest + 1, count1); + if (len1 == 0) + break outer; + } + a[dest--] = tmp[cursor2--]; + if (--len2 == 1) + break outer; + + count2 = len2 - gallopLeft(a[cursor1], tmp, 0, len2, len2 - 1, c); + if (count2 != 0) { + dest -= count2; + cursor2 -= count2; + len2 -= count2; + System.arraycopy(tmp, cursor2 + 1, a, dest + 1, count2); + if (len2 <= 1) // len2 == 1 || len2 == 0 + break outer; + } + a[dest--] = a[cursor1--]; + if (--len1 == 0) + break outer; + minGallop--; + } while (count1 >= MIN_GALLOP | count2 >= MIN_GALLOP); + if (minGallop < 0) + minGallop = 0; + minGallop += 2; // Penalize for leaving gallop mode + } // End of "outer" loop + this.minGallop = minGallop < 1 ? 1 : minGallop; // Write back to field + + if (len2 == 1) { + assert len1 > 0; + dest -= len1; + cursor1 -= len1; + System.arraycopy(a, cursor1 + 1, a, dest + 1, len1); + a[dest] = tmp[cursor2]; // Move first elt of run2 to front of merge + } else if (len2 == 0) { + throw new IllegalArgumentException( + "Comparison method violates its general contract!"); + } else { + assert len1 == 0; + assert len2 > 0; + System.arraycopy(tmp, 0, a, dest - (len2 - 1), len2); + } + } + + /** + * Ensures that the external array tmp has at least the specified + * number of elements, increasing its size if necessary. The size + * increases exponentially to ensure amortized linear time complexity. + * + * @param minCapacity the minimum required capacity of the tmp array + * @return tmp, whether or not it grew + */ + private T[] ensureCapacity(int minCapacity) { + if (tmp.length < minCapacity) { + // Compute smallest power of 2 > minCapacity + int newSize = minCapacity; + newSize |= newSize >> 1; + newSize |= newSize >> 2; + newSize |= newSize >> 4; + newSize |= newSize >> 8; + newSize |= newSize >> 16; + newSize++; + + if (newSize < 0) // Not bloody likely! + newSize = minCapacity; + else + newSize = Math.min(newSize, a.length >>> 1); + + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) + T[] newArray = (T[]) new Object[newSize]; + tmp = newArray; + } + return tmp; + } + + /** + * Checks that fromIndex and toIndex are in range, and throws an + * appropriate exception if they aren't. + * + * @param arrayLen the length of the array + * @param fromIndex the index of the first element of the range + * @param toIndex the index after the last element of the range + * @throws IllegalArgumentException if fromIndex > toIndex + * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 + * or toIndex > arrayLen + */ + private static void rangeCheck(int arrayLen, int fromIndex, int toIndex) { + if (fromIndex > toIndex) + throw new IllegalArgumentException("fromIndex(" + fromIndex + + ") > toIndex(" + toIndex+")"); + if (fromIndex < 0) + throw new ArrayIndexOutOfBoundsException(fromIndex); + if (toIndex > arrayLen) + throw new ArrayIndexOutOfBoundsException(toIndex); + } +} diff --git a/jdk/test/java/util/TimSort/ArrayBuilder.java b/jdk/test/java/util/TimSort/ArrayBuilder.java new file mode 100644 index 00000000000..25194f6ca57 --- /dev/null +++ b/jdk/test/java/util/TimSort/ArrayBuilder.java @@ -0,0 +1,142 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.util.Random; +import java.math.BigInteger; + +public enum ArrayBuilder { + + // These seven are from Tim's paper (listsort.txt) + + RANDOM_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = rnd.nextInt(); + return result; + } + }, + + DESCENDING_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = len - i; + return result; + } + }, + + ASCENDING_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = i; + return result; + } + }, + + ASCENDING_3_RND_EXCH_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = i; + for (int i = 0; i < 3; i++) + swap(result, rnd.nextInt(result.length), + rnd.nextInt(result.length)); + return result; + } + }, + + ASCENDING_10_RND_AT_END_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + int endStart = len - 10; + for (int i = 0; i < endStart; i++) + result[i] = i; + for (int i = endStart; i < len; i++) + result[i] = rnd.nextInt(endStart + 10); + return result; + } + }, + + ALL_EQUAL_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = 666; + return result; + } + }, + + DUPS_GALORE_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = rnd.nextInt(4); + return result; + } + }, + + RANDOM_WITH_DUPS_INT { + public Object[] build(int len) { + Integer[] result = new Integer[len]; + for (int i = 0; i < len; i++) + result[i] = rnd.nextInt(len); + return result; + } + }, + + PSEUDO_ASCENDING_STRING { + public String[] build(int len) { + String[] result = new String[len]; + for (int i = 0; i < len; i++) + result[i] = Integer.toString(i); + return result; + } + }, + + RANDOM_BIGINT { + public BigInteger[] build(int len) { + BigInteger[] result = new BigInteger[len]; + for (int i = 0; i < len; i++) + result[i] = HUGE.add(BigInteger.valueOf(rnd.nextInt(len))); + return result; + } + }; + + public abstract Object[] build(int len); + + public void resetRandom() { + rnd = new Random(666); + } + + private static Random rnd = new Random(666); + + private static void swap(Object[] a, int i, int j) { + Object t = a[i]; + a[i] = a[j]; + a[j] = t; + } + + private static BigInteger HUGE = BigInteger.ONE.shiftLeft(100); +} diff --git a/jdk/test/java/util/TimSort/README b/jdk/test/java/util/TimSort/README new file mode 100644 index 00000000000..7add0be0a50 --- /dev/null +++ b/jdk/test/java/util/TimSort/README @@ -0,0 +1,4 @@ +This directory contains benchmark programs used to compare the +performance of the TimSort algorithm against the historic 1997 +implementation of Arrays.sort. Any future benchmarking will require +minor modifications. diff --git a/jdk/test/java/util/TimSort/SortPerf.java b/jdk/test/java/util/TimSort/SortPerf.java new file mode 100644 index 00000000000..89b41bb7527 --- /dev/null +++ b/jdk/test/java/util/TimSort/SortPerf.java @@ -0,0 +1,66 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.util.Arrays; + +public class SortPerf { + private static final int NUM_SETS = 5; + private static final int[] lengths = { 10, 100, 1000, 10000, 1000000 }; + + // Returns the number of repetitions as a function of the list length + private static int reps(int n) { + return (int) (12000000 / (n * Math.log10(n))); + } + + public static void main(String[] args) { + Sorter.warmup(); + + System.out.print("Strategy,Length"); + for (Sorter sorter : Sorter.values()) + System.out.print("," + sorter); + System.out.println(); + + for (ArrayBuilder ab : ArrayBuilder.values()) { + for (int n : lengths) { + System.out.printf("%s,%d", ab, n); + int reps = reps(n); + Object[] proto = ab.build(n); + for (Sorter sorter : Sorter.values()) { + double minTime = Double.POSITIVE_INFINITY; + for (int set = 0; set < NUM_SETS; set++) { + long startTime = System.nanoTime(); + for (int k = 0; k < reps; k++) { + Object[] a = proto.clone(); + sorter.sort(a); + } + long endTime = System.nanoTime(); + double time = (endTime - startTime) / (1000000. * reps); + minTime = Math.min(minTime, time); + } + System.out.printf(",%5f", minTime); + } + System.out.println(); + } + } + } +} diff --git a/jdk/test/java/util/TimSort/Sorter.java b/jdk/test/java/util/TimSort/Sorter.java new file mode 100644 index 00000000000..4867996490f --- /dev/null +++ b/jdk/test/java/util/TimSort/Sorter.java @@ -0,0 +1,55 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +import java.util.*; + +public enum Sorter { + TIMSORT { + public void sort(Object[] array) { + ComparableTimSort.sort(array); + } + }, + MERGESORT { + public void sort(Object[] array) { + Arrays.sort(array); + } + }; + + public abstract void sort(Object[] array); + + public static void warmup() { + System.out.println("start warm up"); + Integer[] gold = new Integer[10000]; + Random random = new java.util.Random(); + for (int i=0; i < gold.length; i++) + gold[i] = random.nextInt(); + + for (int i=0; i < 10000; i++) { + for (Sorter s : values()) { + Integer[] test= gold.clone(); + s.sort(test); + } + } + System.out.println(" end warm up"); + } +} From 2d83195be50ebb1b92c534d119ed1ead93d128aa Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Wed, 29 Jul 2009 21:45:52 -0700 Subject: [PATCH 032/102] 6866719: Rename execvpe to avoid symbol clash with glibc 2.10 Reviewed-by: darcy --- jdk/src/solaris/native/java/lang/UNIXProcess_md.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c index 041413574d4..d0226d07735 100644 --- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c @@ -447,14 +447,16 @@ execve_with_shell_fallback(const char *file, } /** - * execvpe should have been included in the Unix standards. - * execvpe is identical to execvp, except that the child environment is + * 'execvpe' should have been included in the Unix standards, + * and is a GNU extension in glibc 2.10. + * + * JDK_execvpe is identical to execvp, except that the child environment is * specified via the 3rd argument instead of being inherited from environ. */ static void -execvpe(const char *file, - const char *argv[], - const char *const envp[]) +JDK_execvpe(const char *file, + const char *argv[], + const char *const envp[]) { /* This is one of the rare times it's more portable to declare an * external symbol explicitly, rather than via a system header. @@ -644,7 +646,7 @@ childProcess(void *arg) if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) goto WhyCantJohnnyExec; - execvpe(p->argv[0], p->argv, p->envv); + JDK_execvpe(p->argv[0], p->argv, p->envv); WhyCantJohnnyExec: /* We used to go to an awful lot of trouble to predict whether the From 59b2cbc44834ebd1fd07e6833e464c262ae554cb Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Thu, 30 Jul 2009 10:29:53 +0100 Subject: [PATCH 033/102] 6827648: Extremely slow compilation time for visitor pattern code + generics Javac unnecessarily recomputates type-substitutions multiple times Reviewed-by: jjg --- .../com/sun/tools/javac/code/Symbol.java | 18 ++------ .../com/sun/tools/javac/code/Types.java | 46 +++++++++++++++++-- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index da1567aa5bb..ab1f995a089 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1197,21 +1197,9 @@ public abstract class Symbol implements Element { * as possible implementations. */ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { - for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) { - while (t.tag == TYPEVAR) - t = t.getUpperBound(); - TypeSymbol c = t.tsym; - for (Scope.Entry e = c.members().lookup(name); - e.scope != null; - e = e.next()) { - if (e.sym.kind == MTH) { - MethodSymbol m = (MethodSymbol) e.sym; - if (m.overrides(this, origin, types, checkResult) && - (m.flags() & SYNTHETIC) == 0) - return m; - } - } - } + MethodSymbol res = types.implementation(this, origin, types, checkResult); + if (res != null) + return res; // if origin is derived from a raw type, we might have missed // an implementation because we do not know enough about instantiations. // in this case continue with the supertype as origin. diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 9a6e5725c74..ca89b426ce7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -25,10 +25,9 @@ package com.sun.tools.javac.code; +import java.lang.ref.SoftReference; import java.util.*; -import com.sun.tools.javac.api.Messages; - import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.List; @@ -1442,7 +1441,7 @@ public class Types { return (sym.flags() & STATIC) != 0 ? sym.type : memberType.visit(t, sym); - } + } // where private SimpleVisitor memberType = new SimpleVisitor() { @@ -1552,7 +1551,7 @@ public class Types { return t; /* fast special case */ else return erasure.visit(t, recurse); - } + } // where private SimpleVisitor erasure = new SimpleVisitor() { public Type visitType(Type t, Boolean recurse) { @@ -1946,6 +1945,45 @@ public class Types { hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); } + private WeakHashMap>> implCache_check = + new WeakHashMap>>(); + + private WeakHashMap>> implCache_nocheck = + new WeakHashMap>>(); + + public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult) { + Map>> implCache = checkResult ? + implCache_check : implCache_nocheck; + SoftReference> ref_cache = implCache.get(ms); + Map cache = ref_cache != null ? ref_cache.get() : null; + if (cache == null) { + cache = new HashMap(); + implCache.put(ms, new SoftReference>(cache)); + } + MethodSymbol impl = cache.get(origin); + if (impl == null) { + for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) { + while (t.tag == TYPEVAR) + t = t.getUpperBound(); + TypeSymbol c = t.tsym; + for (Scope.Entry e = c.members().lookup(ms.name); + e.scope != null; + e = e.next()) { + if (e.sym.kind == Kinds.MTH) { + MethodSymbol m = (MethodSymbol) e.sym; + if (m.overrides(ms, origin, types, checkResult) && + (m.flags() & SYNTHETIC) == 0) { + impl = m; + cache.put(origin, m); + return impl; + } + } + } + } + } + return impl; + } + /** * Does t have the same arguments as s? It is assumed that both * types are (possibly polymorphic) method types. Monomorphic From 25497fcea7156654d2c59a49b313d5aec0790076 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Thu, 30 Jul 2009 10:30:10 +0100 Subject: [PATCH 034/102] 6862608: rich diagnostic sometimes contain wrong type variable numbering The rich formatter generates worng numbers for type-variables in where clauses Reviewed-by: jjg --- .../tools/javac/resources/compiler.properties | 2 +- .../javac/util/RichDiagnosticFormatter.java | 59 +++++++++---------- .../javac/Diagnostics/6862608/T6862608a.java | 44 ++++++++++++++ .../javac/Diagnostics/6862608/T6862608a.out | 3 + .../javac/Diagnostics/6862608/T6862608b.java | 38 ++++++++++++ .../javac/Diagnostics/6862608/T6862608b.out | 3 + 6 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 langtools/test/tools/javac/Diagnostics/6862608/T6862608a.java create mode 100644 langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out create mode 100644 langtools/test/tools/javac/Diagnostics/6862608/T6862608b.java create mode 100644 langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 3365ae06635..b972332b014 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1003,7 +1003,7 @@ compiler.misc.inferred.do.not.conform.to.bounds=\ inferred: {0}\n\ bound(s): {1} compiler.misc.inferred.do.not.conform.to.params=\ - actual arguments do not conforms to inferred formal arguments\n\ + actual arguments do not conform to inferred formal arguments\n\ required: {0}\n\ found: {1} diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index 0996c42f715..58812a781d7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -208,6 +208,32 @@ public class RichDiagnosticFormatter extends } return clauses.reverse(); } + + private int indexOf(Type type, WhereClauseKind kind) { + int index = 1; + for (Type t : whereClauses.get(kind).keySet()) { + if (t.tsym == type.tsym) { + return index; + } + if (kind != WhereClauseKind.TYPEVAR || + t.toString().equals(type.toString())) { + index++; + } + } + return -1; + } + + private boolean unique(TypeVar typevar) { + int found = 0; + for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) { + if (t.toString().equals(typevar.toString())) { + found++; + } + } + if (found < 1) + throw new AssertionError("Missing type variable in where clause " + typevar); + return found == 1; + } //where /** * This enum defines all posssible kinds of where clauses that can be @@ -366,33 +392,6 @@ public class RichDiagnosticFormatter extends } } - private int indexOf(Type type, WhereClauseKind kind) { - int index = 0; - boolean found = false; - for (Type t : whereClauses.get(kind).keySet()) { - if (t == type) { - found = true; - break; - } - index++; - } - if (!found) - throw new AssertionError("Missing symbol in where clause " + type); - return index + 1; - } - - private boolean unique(TypeVar typevar) { - int found = 0; - for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) { - if (t.toString().equals(typevar.toString())) { - found++; - } - } - if (found < 1) - throw new AssertionError("Missing type variable in where clause " + typevar); - return found == 1; - } - @Override protected String printMethodArgs(List args, boolean varArgs, Locale locale) { return super.printMethodArgs(args, varArgs, locale); @@ -492,7 +491,7 @@ public class RichDiagnosticFormatter extends @Override public Void visitCapturedType(CapturedType t, Void ignored) { - if (!whereClauses.get(WhereClauseKind.CAPTURED).containsKey(t)) { + if (indexOf(t, WhereClauseKind.CAPTURED) == -1) { String suffix = t.lower == syms.botType ? ".1" : ""; JCDiagnostic d = diags.fragment("where.captured"+ suffix, t, t.bound, t.lower, t.wildcard); whereClauses.get(WhereClauseKind.CAPTURED).put(t, d); @@ -506,7 +505,7 @@ public class RichDiagnosticFormatter extends @Override public Void visitClassType(ClassType t, Void ignored) { if (t.isCompound()) { - if (!whereClauses.get(WhereClauseKind.INTERSECTION).containsKey(t)) { + if (indexOf(t, WhereClauseKind.INTERSECTION) == -1) { Type supertype = types.supertype(t); List interfaces = types.interfaces(t); JCDiagnostic d = diags.fragment("where.intersection", t, interfaces.prepend(supertype)); @@ -524,7 +523,7 @@ public class RichDiagnosticFormatter extends @Override public Void visitTypeVar(TypeVar t, Void ignored) { - if (!whereClauses.get(WhereClauseKind.TYPEVAR).containsKey(t)) { + if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) { Type bound = t.bound; while ((bound instanceof ErrorType)) bound = ((ErrorType)bound).getOriginalType(); diff --git a/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.java b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.java new file mode 100644 index 00000000000..df3c9b0c910 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.java @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6862608 + * @summary rich diagnostic sometimes contain wrong type variable numbering + * @author mcimadamore + * @compile/fail/ref=T6862608a.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6862608a.java + */ + + +import java.util.*; + +class T6862608a { + + Comparator compound(Iterable> it) { + return null; + } + + public void test(List> x) { + Comparator c3 = compound(x); + } +} diff --git a/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out new file mode 100644 index 00000000000..181b78b7698 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out @@ -0,0 +1,3 @@ +T6862608a.java:42:41: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Iterable>, java.util.List>) +- compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, compound(java.lang.Iterable>))} +1 error diff --git a/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.java b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.java new file mode 100644 index 00000000000..db5a5ac3354 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.java @@ -0,0 +1,38 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6862608 + * @summary rich diagnostic sometimes contain wrong type variable numbering + * @author mcimadamore + * @compile/fail/ref=T6862608b.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6862608b.java + */ + +class T66862608b { + void foo(T t) { + test(t); + } + + void test(T t) {} +} diff --git a/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out new file mode 100644 index 00000000000..34ac1a61cb4 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out @@ -0,0 +1,3 @@ +T6862608b.java:34: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 +- 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 From fe1aaa815421a0d0aea129dc136a3a14fda3ba03 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Thu, 30 Jul 2009 10:30:24 +0100 Subject: [PATCH 035/102] 6864382: NPE in the rich formatter when processing an unattributed type-variable Unattributed type variable should not be accessed by the rich formatter when emitting where clauses Reviewed-by: jjg --- .../javac/util/RichDiagnosticFormatter.java | 8 ++++- .../javac/Diagnostics/6864382/T6864382.java | 32 +++++++++++++++++++ .../javac/Diagnostics/6864382/T6864382.out | 2 ++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/Diagnostics/6864382/T6864382.java create mode 100644 langtools/test/tools/javac/Diagnostics/6864382/T6864382.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index 58812a781d7..2275ba935b4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -524,10 +524,16 @@ public class RichDiagnosticFormatter extends @Override public Void visitTypeVar(TypeVar t, Void ignored) { if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) { + //access the bound type and skip error types Type bound = t.bound; while ((bound instanceof ErrorType)) bound = ((ErrorType)bound).getOriginalType(); - List bounds = types.getBounds(t); + //retrieve the bound list - if the type variable + //has not been attributed the bound is not set + List bounds = bound != null ? + types.getBounds(t) : + List.nil(); + nameSimplifier.addUsage(t.tsym); boolean boundErroneous = bounds.head == null || diff --git a/langtools/test/tools/javac/Diagnostics/6864382/T6864382.java b/langtools/test/tools/javac/Diagnostics/6864382/T6864382.java new file mode 100644 index 00000000000..f6ab5d891a1 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6864382/T6864382.java @@ -0,0 +1,32 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6864382 + * @summary NullPointerException when compiling a negative java source + * @author mcimadamore + * @compile/fail/ref=T6864382.out -XDrawDiagnostics T6864382.java + */ + +class T6864382 extends T {} diff --git a/langtools/test/tools/javac/Diagnostics/6864382/T6864382.out b/langtools/test/tools/javac/Diagnostics/6864382/T6864382.out new file mode 100644 index 00000000000..40013de7081 --- /dev/null +++ b/langtools/test/tools/javac/Diagnostics/6864382/T6864382.out @@ -0,0 +1,2 @@ +T6864382.java:32:27: compiler.err.type.found.req: (compiler.misc.type.parameter: T), (compiler.misc.type.req.class) +1 error From 638db1aabb648e996d40e600337611deede22257 Mon Sep 17 00:00:00 2001 From: Mahmood Ali Date: Thu, 30 Jul 2009 10:30:34 +0100 Subject: [PATCH 036/102] 6861837: JCK compilation failures Type-annotations processing is accessing type info before they are available in MemberEnter Reviewed-by: jjg --- .../com/sun/tools/javac/comp/MemberEnter.java | 9 -------- .../com/sun/tools/javac/comp/TransTypes.java | 17 +++++++++++++++ .../javac/typeAnnotations/InnerClass.java | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 5c0245a0a98..39dd35902a5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -1040,15 +1040,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer { JavaFileObject prev = log.useSource(env.toplevel.sourcefile); try { enterTypeAnnotations(annotations); - - // enrich type parameter symbols... easier for annotation processors - if (tree instanceof JCTypeParameter) { - JCTypeParameter typeparam = (JCTypeParameter)tree; - ListBuffer buf = ListBuffer.lb(); - for (JCTypeAnnotation anno : annotations) - buf.add(anno.attribute_field); - typeparam.type.tsym.attributes_field = buf.toList(); - } } finally { log.useSource(prev); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index 18dcceb56df..26269e81558 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -817,6 +817,23 @@ public class TransTypes extends TreeTranslator { pop(); } + private boolean inClass = false; + + @Override + public void visitClassDef(JCClassDecl tree) { + if (!inClass) { + // Do not recurse into nested and inner classes since + // TransTypes.visitClassDef makes an invocation for each class + // separately. + inClass = true; + try { + super.visitClassDef(tree); + } finally { + inClass = false; + } + } + } + private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame, List path, TypeAnnotationPosition p) { switch (frame.getKind()) { diff --git a/langtools/test/tools/javac/typeAnnotations/InnerClass.java b/langtools/test/tools/javac/typeAnnotations/InnerClass.java index fd14cea782a..dba8202be90 100644 --- a/langtools/test/tools/javac/typeAnnotations/InnerClass.java +++ b/langtools/test/tools/javac/typeAnnotations/InnerClass.java @@ -30,9 +30,30 @@ */ class InnerClass { + + InnerClass() {} + InnerClass(Object o) {} + private void a() { new Object() { public void method() { } }; } + + Object f1 = new InnerClass() { + void method() { } + }; + + Object f2 = new InnerClass() { + <@A R> void method() { } + }; + + Object f3 = new InnerClass(null) { + void method() { } + }; + + Object f4 = new InnerClass(null) { + <@A R> void method() { } + }; + @interface A { } } From 219445d03ac4dbda971d80fa68871b7be91fd623 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 30 Jul 2009 07:48:24 -0700 Subject: [PATCH 037/102] 6866657: add byteLength method to primary classfile types Reviewed-by: mchung --- .../com/sun/tools/classfile/AccessFlags.java | 4 + .../com/sun/tools/classfile/Attribute.java | 4 + .../com/sun/tools/classfile/Attributes.java | 7 ++ .../com/sun/tools/classfile/ClassFile.java | 32 ++++++++ .../com/sun/tools/classfile/ConstantPool.java | 60 ++++++++++++++ .../com/sun/tools/classfile/Field.java | 4 + .../com/sun/tools/classfile/Method.java | 4 + langtools/test/tools/javap/T6866657.java | 82 +++++++++++++++++++ 8 files changed, 197 insertions(+) create mode 100644 langtools/test/tools/javap/T6866657.java diff --git a/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java b/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java index 2cfc363d995..a8b51bf9546 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/AccessFlags.java @@ -76,6 +76,10 @@ public class AccessFlags { return (flags & mask) != 0; } + public int byteLength() { + return 2; + } + private static final int[] classModifiers = { ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE }; diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java index ccb50b58675..326de77a7c9 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java @@ -166,6 +166,10 @@ public abstract class Attribute { public abstract R accept(Attribute.Visitor visitor, D data); + public int byteLength() { + return 6 + attribute_length; + } + public final int attribute_name_index; public final int attribute_length; diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Attributes.java b/langtools/src/share/classes/com/sun/tools/classfile/Attributes.java index d3ea27f7337..6f61a1d6e75 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Attributes.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Attributes.java @@ -95,6 +95,13 @@ public class Attributes implements Iterable { return attrs.length; } + public int byteLength() { + int length = 2; + for (Attribute a: attrs) + length += a.byteLength(); + return length; + } + public final Attribute[] attrs; public final Map map; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java index 4be151d31f6..8efe7ebe912 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java @@ -139,6 +139,38 @@ public class ClassFile { return access_flags.is(ACC_INTERFACE); } + public int byteLength() { + return 4 + // magic + 2 + // minor + 2 + // major + constant_pool.byteLength() + + 2 + // access flags + 2 + // this_class + 2 + // super_class + byteLength(interfaces) + + byteLength(fields) + + byteLength(methods) + + attributes.byteLength(); + } + + private int byteLength(int[] indices) { + return 2 + 2 * indices.length; + } + + private int byteLength(Field[] fields) { + int length = 2; + for (Field f: fields) + length += f.byteLength(); + return length; + } + + private int byteLength(Method[] methods) { + int length = 2; + for (Method m: methods) + length += m.byteLength(); + return length; + } + public final int magic; public final int minor_version; public final int major_version; diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java b/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java index 2f1dc357e64..ba53f2d2a24 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java @@ -25,7 +25,9 @@ package com.sun.tools.classfile; +import java.io.DataOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.Iterator; /** @@ -179,6 +181,16 @@ public class ConstantPool { return pool.length; } + public int byteLength() { + int length = 2; + for (int i = 1; i < size(); ) { + CPInfo cpInfo = pool[i]; + length += cpInfo.byteLength(); + i += cpInfo.size(); + } + return length; + } + public CPInfo get(int index) throws InvalidIndex { if (index <= 0 || index >= pool.length) throw new InvalidIndex(index); @@ -291,6 +303,8 @@ public class ConstantPool { return 1; } + public abstract int byteLength(); + public abstract R accept(Visitor visitor, D data); protected final ConstantPool cp; @@ -315,6 +329,10 @@ public class ConstantPool { return tag; } + public int byteLength() { + return 5; + } + public CONSTANT_Class_info getClassInfo() throws ConstantPoolException { return cp.getClassInfo(class_index); } @@ -347,6 +365,10 @@ public class ConstantPool { return CONSTANT_Class; } + public int byteLength() { + return 3; + } + public String getName() throws ConstantPoolException { return cp.getUTF8Value(name_index); } @@ -390,6 +412,10 @@ public class ConstantPool { return CONSTANT_Double; } + public int byteLength() { + return 9; + } + @Override public int size() { return 2; @@ -439,6 +465,10 @@ public class ConstantPool { return CONSTANT_Float; } + public int byteLength() { + return 5; + } + @Override public String toString() { return "CONSTANT_Float_info[value: " + value + "]"; @@ -464,6 +494,10 @@ public class ConstantPool { return CONSTANT_Integer; } + public int byteLength() { + return 5; + } + @Override public String toString() { return "CONSTANT_Integer_info[value: " + value + "]"; @@ -513,6 +547,10 @@ public class ConstantPool { return 2; } + public int byteLength() { + return 9; + } + @Override public String toString() { return "CONSTANT_Long_info[value: " + value + "]"; @@ -561,6 +599,10 @@ public class ConstantPool { return CONSTANT_NameAndType; } + public int byteLength() { + return 5; + } + public String getName() throws ConstantPoolException { return cp.getUTF8Value(name_index); } @@ -597,6 +639,10 @@ public class ConstantPool { return CONSTANT_String; } + public int byteLength() { + return 3; + } + public String getString() throws ConstantPoolException { return cp.getUTF8Value(string_index); } @@ -626,6 +672,20 @@ public class ConstantPool { return CONSTANT_Utf8; } + public int byteLength() { + class SizeOutputStream extends OutputStream { + @Override + public void write(int b) throws IOException { + size++; + } + int size; + } + SizeOutputStream sizeOut = new SizeOutputStream(); + DataOutputStream out = new DataOutputStream(sizeOut); + try { out.writeUTF(value); } catch (IOException ignore) { } + return 1 + sizeOut.size; + } + @Override public String toString() { if (value.length() < 32 && isPrintableAscii(value)) diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Field.java b/langtools/src/share/classes/com/sun/tools/classfile/Field.java index a98f73fda3a..87ecea98cdb 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Field.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Field.java @@ -50,6 +50,10 @@ public class Field { this.attributes = attributes; } + public int byteLength() { + return 6 + attributes.byteLength(); + } + public String getName(ConstantPool constant_pool) throws ConstantPoolException { return constant_pool.getUTF8Value(name_index); } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Method.java b/langtools/src/share/classes/com/sun/tools/classfile/Method.java index 4018bdc2588..4ad92d586a7 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Method.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Method.java @@ -50,6 +50,10 @@ public class Method { this.attributes = attributes; } + public int byteLength() { + return 6 + attributes.byteLength(); + } + public String getName(ConstantPool constant_pool) throws ConstantPoolException { return constant_pool.getUTF8Value(name_index); } diff --git a/langtools/test/tools/javap/T6866657.java b/langtools/test/tools/javap/T6866657.java new file mode 100644 index 00000000000..5a4f7f5e391 --- /dev/null +++ b/langtools/test/tools/javap/T6866657.java @@ -0,0 +1,82 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* + * @test + * @bug 6866657 + * @summary add byteLength() method to primary classfile types + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import com.sun.tools.javap.*; + +public class T6866657 +{ + public static void main(String... args) { + new T6866657().run(); + } + + void run() { + verify("java.lang.Object"); + verify("java.lang.String"); + verify("java.util.List"); + verify("java.util.ArrayList"); + if (errors > 0) + throw new Error(errors + " found."); + } + + void verify(String className) { + try { + PrintWriter log = new PrintWriter(System.out); + JavaFileManager fileManager = JavapFileManager.create(null, log); + JavaFileObject fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS); + if (fo == null) { + error("Can't find " + className); + } else { + JavapTask t = new JavapTask(log, fileManager, null); + t.handleOptions(new String[] { "-sysinfo", className }); + JavapTask.ClassFileInfo cfInfo = t.read(fo); + expectEqual(cfInfo.cf.byteLength(), cfInfo.size); + } + } catch (Exception e) { + e.printStackTrace(); + error("Exception: " + e); + } + } + + void expectEqual(int found, int expected) { + if (found != expected) + error("bad value found: " + found + " expected: " + expected); + } + + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; +} + From 24bbb68d3861cbe9fcc66998634607b8cbffcbd2 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 30 Jul 2009 09:18:55 -0700 Subject: [PATCH 038/102] 4880672: javap does not output inner interfaces of an interface Reviewed-by: mcimadamore --- .../com/sun/tools/javap/JavapTask.java | 116 ++++++++++++------ .../classes/com/sun/tools/javap/Options.java | 1 + .../tools/javap/resources/javap.properties | 1 + langtools/test/tools/javap/T4880672.java | 86 +++++++++++++ 4 files changed, 169 insertions(+), 35 deletions(-) create mode 100644 langtools/test/tools/javap/T4880672.java diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index faf526419b7..f86534f923c 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -289,6 +289,12 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { void process(JavapTask task, String opt, String arg) { task.options.showConstants = true; } + }, + + new Option(false, "-XDinner") { + void process(JavapTask task, String opt, String arg) { + task.options.showInnerClasses = true; + } } }; @@ -529,46 +535,15 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { SourceWriter sourceWriter = SourceWriter.instance(context); sourceWriter.setFileManager(fileManager); + attributeFactory.setCompat(options.compat); + attributeFactory.setJSR277(options.jsr277); + boolean ok = true; for (String className: classes) { JavaFileObject fo; try { - if (className.endsWith(".class")) { - if (fileManager instanceof StandardJavaFileManager) { - StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; - fo = sfm.getJavaFileObjects(className).iterator().next(); - } else { - reportError("err.not.standard.file.manager", className); - ok = false; - continue; - } - } else { - fo = getClassFileObject(className); - if (fo == null) { - // see if it is an inner class, by replacing dots to $, starting from the right - String cn = className; - int lastDot; - while (fo == null && (lastDot = cn.lastIndexOf(".")) != -1) { - cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1); - fo = getClassFileObject(cn); - } - } - if (fo == null) { - reportError("err.class.not.found", className); - ok = false; - continue; - } - } - attributeFactory.setCompat(options.compat); - attributeFactory.setJSR277(options.jsr277); - ClassFileInfo cfInfo = read(fo); - if (!className.endsWith(".class")) { - String cfName = cfInfo.cf.getName(); - if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) - reportWarning("warn.unexpected.class", className, cfName.replace('/', '.')); - } - write(cfInfo); + writeClass(classWriter, className); } catch (ConstantPoolException e) { reportError("err.bad.constant.pool", className, e.getLocalizedMessage()); ok = false; @@ -598,6 +573,76 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { return ok; } + protected boolean writeClass(ClassWriter classWriter, String className) + throws IOException, ConstantPoolException { + JavaFileObject fo; + if (className.endsWith(".class")) { + if (fileManager instanceof StandardJavaFileManager) { + StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; + fo = sfm.getJavaFileObjects(className).iterator().next(); + } else { + reportError("err.not.standard.file.manager", className); + return false; + } + } else { + fo = getClassFileObject(className); + if (fo == null) { + // see if it is an inner class, by replacing dots to $, starting from the right + String cn = className; + int lastDot; + while (fo == null && (lastDot = cn.lastIndexOf(".")) != -1) { + cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1); + fo = getClassFileObject(cn); + } + } + if (fo == null) { + reportError("err.class.not.found", className); + return false; + } + } + + ClassFileInfo cfInfo = read(fo); + if (!className.endsWith(".class")) { + String cfName = cfInfo.cf.getName(); + if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) + reportWarning("warn.unexpected.class", className, cfName.replace('/', '.')); + } + write(cfInfo); + + if (options.showInnerClasses) { + ClassFile cf = cfInfo.cf; + Attribute a = cf.getAttribute(Attribute.InnerClasses); + if (a instanceof InnerClasses_attribute) { + InnerClasses_attribute inners = (InnerClasses_attribute) a; + try { + boolean ok = true; + for (int i = 0; i < inners.classes.length; i++) { + int outerIndex = inners.classes[i].outer_class_info_index; + ConstantPool.CONSTANT_Class_info outerClassInfo = cf.constant_pool.getClassInfo(outerIndex); + String outerClassName = outerClassInfo.getName(); + if (outerClassName.equals(cf.getName())) { + int innerIndex = inners.classes[i].inner_class_info_index; + ConstantPool.CONSTANT_Class_info innerClassInfo = cf.constant_pool.getClassInfo(innerIndex); + String innerClassName = innerClassInfo.getName(); + classWriter.println("// inner class " + innerClassName.replaceAll("[/$]", ".")); + classWriter.println(); + ok = ok & writeClass(classWriter, innerClassName); + } + } + return ok; + } catch (ConstantPoolException e) { + reportError("err.bad.innerclasses.attribute", className); + return false; + } + } else if (a != null) { + reportError("err.bad.innerclasses.attribute", className); + return false; + } + } + + return true; + } + public static class ClassFileInfo { ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) { this.fo = fo; @@ -801,6 +846,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { return JavapTask.this.getMessage(locale, key, args); } + @Override public String toString() { return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]"; } diff --git a/langtools/src/share/classes/com/sun/tools/javap/Options.java b/langtools/src/share/classes/com/sun/tools/javap/Options.java index 70f76060ebc..e6b37345582 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javap/Options.java @@ -85,6 +85,7 @@ public class Options { public boolean showAllAttrs; public boolean showConstants; public boolean sysInfo; + public boolean showInnerClasses; public boolean compat; // bug-for-bug compatibility mode with old javap public boolean jsr277; diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties index 87b9a332886..4a13d601970 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties @@ -18,6 +18,7 @@ err.unknown.option=unknown option: {0} err.verify.not.supported=-verify not supported err.no.SourceFile.attribute=no SourceFile attribute err.source.file.not.found=source file not found +err.bad.innerclasses.attribute=bad InnerClasses attribute for {0} warn.Xold.not.supported=-Xold is no longer available main.usage.summary=\ diff --git a/langtools/test/tools/javap/T4880672.java b/langtools/test/tools/javap/T4880672.java new file mode 100644 index 00000000000..b58182eb63c --- /dev/null +++ b/langtools/test/tools/javap/T4880672.java @@ -0,0 +1,86 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* + * @test + * @bug 4880672 + * @summary javap does not output inner interfaces of an interface + */ + +import java.io.*; +import java.util.*; + +public class T4880672 +{ + public static void main(String... args) { + new T4880672().run(); + } + + void run() { + verify("java.util.Map", "public interface java.util.Map$Entry"); + verify("T4880672", "class T4880672$A$B extends java.lang.Object"); + verify("C", ""); // must not give error if no InnerClasses attribute + if (errors > 0) + throw new Error(errors + " found."); + } + + void verify(String className, String... expects) { + String output = javap(className); + for (String expect: expects) { + if (output.indexOf(expect)< 0) + error(expect + " not found"); + } + } + + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; + + String javap(String className) { + String testClasses = System.getProperty("test.classes", "."); + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + String[] args = { "-XDinner", "-classpath", testClasses, className }; + int rc = com.sun.tools.javap.Main.run(args, out); + out.close(); + String output = sw.toString(); + System.out.println("class " + className); + System.out.println(output); + if (rc != 0) + throw new Error("javap failed. rc=" + rc); + if (output.indexOf("Error:") != -1) + throw new Error("javap reported error."); + return output; + } + + class A { + class B { } + } +} + +class C { } + From 08f07d0f8ae988eef70c57404f2f6202ad20a7e6 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Fri, 31 Jul 2009 08:44:28 +0100 Subject: [PATCH 039/102] 6867101: Path.checkAccess fails with sharing violation on special files such as pagefile.sys Reviewed-by: sherman --- .../classes/sun/nio/fs/WindowsConstants.java | 1 + .../sun/nio/fs/WindowsFileAttributes.java | 33 +++++++++++++++++++ jdk/test/java/nio/file/Path/Misc.java | 24 +++++++++++++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java index 077a4893b2f..a99f3fd448f 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java @@ -92,6 +92,7 @@ class WindowsConstants { public static final int ERROR_INVALID_DATA = 13; public static final int ERROR_NOT_SAME_DEVICE = 17; public static final int ERROR_NOT_READY = 21; + public static final int ERROR_SHARING_VIOLATION = 32; public static final int ERROR_FILE_EXISTS = 80; public static final int ERROR_INVALID_PARAMATER = 87; public static final int ERROR_DISK_FULL = 112; diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java index f930eab98d3..9a1e0bd1a15 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributes.java @@ -299,6 +299,9 @@ class WindowsFileAttributes throws WindowsException { if (!ensureAccurateMetadata) { + WindowsException firstException = null; + + // GetFileAttributesEx is the fastest way to read the attributes NativeBuffer buffer = NativeBuffers.getNativeBuffer(SIZEOF_FILE_ATTRIBUTE_DATA); try { @@ -310,9 +313,39 @@ class WindowsFileAttributes .getInt(address + OFFSETOF_FILE_ATTRIBUTE_DATA_ATTRIBUTES); if ((fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) == 0) return fromFileAttributeData(address, 0); + } catch (WindowsException x) { + if (x.lastError() != ERROR_SHARING_VIOLATION) + throw x; + firstException = x; } finally { buffer.release(); } + + // For sharing violations, fallback to FindFirstFile if the file + // is not a root directory. + if (firstException != null) { + String search = path.getPathForWin32Calls(); + char last = search.charAt(search.length() -1); + if (last == ':' || last == '\\') + throw firstException; + buffer = getBufferForFindData(); + try { + long handle = FindFirstFile(search, buffer.address()); + FindClose(handle); + WindowsFileAttributes attrs = fromFindData(buffer.address()); + // FindFirstFile does not follow sym links. Even if + // followLinks is false, there isn't sufficient information + // in the WIN32_FIND_DATA structure to know if the reparse + // point is a sym link. + if (attrs.isReparsePoint()) + throw firstException; + return attrs; + } catch (WindowsException ignore) { + throw firstException; + } finally { + buffer.release(); + } + } } // file is reparse point so need to open file to get attributes diff --git a/jdk/test/java/nio/file/Path/Misc.java b/jdk/test/java/nio/file/Path/Misc.java index 066cf6bedf9..07418844fd8 100644 --- a/jdk/test/java/nio/file/Path/Misc.java +++ b/jdk/test/java/nio/file/Path/Misc.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 + * @bug 4313887 6838333 6866804 * @summary Unit test for java.nio.file.Path for miscellenous methods not * covered by other tests * @library .. @@ -106,6 +106,28 @@ public class Misc { dir.checkAccess(AccessMode.WRITE); dir.checkAccess(AccessMode.READ, AccessMode.WRITE); + /** + * Test: Check access to all files in all root directories. + * (A useful test on Windows for special files such as pagefile.sys) + */ + for (Path root: FileSystems.getDefault().getRootDirectories()) { + DirectoryStream stream; + try { + stream = root.newDirectoryStream(); + } catch (IOException x) { + continue; // skip root directories that aren't accessible + } + try { + for (Path entry: stream) { + try { + entry.checkAccess(); + } catch (AccessDeniedException ignore) { } + } + } finally { + stream.close(); + } + } + /** * Test: File does not exist */ From 6538a1bcf911c4dff0eb75958208b748dba8d474 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Fri, 31 Jul 2009 08:45:30 +0100 Subject: [PATCH 040/102] 6867244: Tests missing @run tag Reviewed-by: sherman --- .../java/nio/channels/DatagramChannel/BasicMulticastTests.java | 1 + .../nio/channels/DatagramChannel/MulticastSendReceiveTests.java | 1 + jdk/test/java/nio/file/Files/ContentType.java | 1 + 3 files changed, 3 insertions(+) diff --git a/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java b/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java index 6928bcded3e..86b9752ba0c 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java +++ b/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java @@ -25,6 +25,7 @@ * @bug 4527345 * @summary Unit test for DatagramChannel's multicast support * @build BasicMulticastTests NetworkConfiguration + * @run main BasicMulticastTests */ import java.nio.ByteBuffer; diff --git a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java index 11e3b0be068..bb1b7037571 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java +++ b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java @@ -25,6 +25,7 @@ * @bug 4527345 * @summary Unit test for DatagramChannel's multicast support * @build MulticastSendReceiveTests NetworkConfiguration + * @run main MulticastSendReceiveTests */ import java.nio.ByteBuffer; diff --git a/jdk/test/java/nio/file/Files/ContentType.java b/jdk/test/java/nio/file/Files/ContentType.java index 8a2267ebd4e..fdbb9014ef6 100644 --- a/jdk/test/java/nio/file/Files/ContentType.java +++ b/jdk/test/java/nio/file/Files/ContentType.java @@ -26,6 +26,7 @@ * @summary Unit test for probeContentType method * @library .. * @build ContentType SimpleFileTypeDetector + * @run main ContentType */ import java.nio.file.*; From bdafe7ca74c373ff15b650ecfa4e114f55bdf8af Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 31 Jul 2009 16:21:30 +0800 Subject: [PATCH 041/102] 6867231: Regression: jdk/test/sun/security/krb5/ConfPlusProp.java error against jdk7/pit/b68 Reviewed-by: xuelei --- jdk/test/sun/security/krb5/ConfPlusProp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/sun/security/krb5/ConfPlusProp.java b/jdk/test/sun/security/krb5/ConfPlusProp.java index e2c49a237a9..ac9ec81c277 100644 --- a/jdk/test/sun/security/krb5/ConfPlusProp.java +++ b/jdk/test/sun/security/krb5/ConfPlusProp.java @@ -23,7 +23,7 @@ /* * @test * @bug 6857795 - * @buf 6858589 + * @bug 6858589 * @summary krb5.conf ignored if system properties on realm and kdc are provided */ From 426d2a0ee7502bbb428a2b85926f45642fe71a10 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Fri, 31 Jul 2009 17:24:27 +0400 Subject: [PATCH 042/102] 6851688: Hung up in applet application Reviewed-by: art, dcherepanov --- jdk/src/windows/native/sun/windows/awt_Toolkit.cpp | 6 +++--- jdk/src/windows/native/sun/windows/awt_Toolkit.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index 5158ef6c43e..b612bd1bf16 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -1596,18 +1596,18 @@ void AwtToolkit::RegisterEmbedderProcessId(HWND embedder) } JNIEnv* AwtToolkit::m_env; -HANDLE AwtToolkit::m_thread; +DWORD AwtToolkit::m_threadId; void AwtToolkit::SetEnv(JNIEnv *env) { if (m_env != NULL) { // If already cashed (by means of embeddedInit() call). return; } - m_thread = GetCurrentThread(); + m_threadId = GetCurrentThreadId(); m_env = env; } JNIEnv* AwtToolkit::GetEnv() { - return (m_env == NULL || m_thread != GetCurrentThread()) ? + return (m_env == NULL || m_threadId != GetCurrentThreadId()) ? (JNIEnv*)JNU_GetEnv(jvm, JNI_VERSION_1_2) : m_env; } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.h b/jdk/src/windows/native/sun/windows/awt_Toolkit.h index 0673201d026..efaf9ff8432 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h @@ -442,7 +442,7 @@ public: private: static JNIEnv *m_env; - static HANDLE m_thread; + static DWORD m_threadId; public: static void SetEnv(JNIEnv *env); static JNIEnv* GetEnv(); From 3fef36803a7a223a8b701fb19c865d644d77da35 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sun, 2 Aug 2009 13:40:03 +0800 Subject: [PATCH 043/102] 6867687: keytool's standard.sh test timeout sometimes Reviewed-by: xuelei --- jdk/test/sun/security/tools/keytool/standard.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/test/sun/security/tools/keytool/standard.sh b/jdk/test/sun/security/tools/keytool/standard.sh index fe4a0a81312..f3e052ed510 100644 --- a/jdk/test/sun/security/tools/keytool/standard.sh +++ b/jdk/test/sun/security/tools/keytool/standard.sh @@ -24,6 +24,7 @@ # @test # @summary (almost) all keytool behaviors # @author Weijun Wang +# @run shell/timeout=600 standard.sh # # This test is always excecuted. # From 6dfe09a9a619e753084d64831c66cbc8a81527f4 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Tue, 4 Aug 2009 12:44:03 -0700 Subject: [PATCH 044/102] 4116222: Errors in Arabic code-conversion tables, part II Updated the IBM420 datatable Reviewed-by: alanb --- jdk/make/tools/CharsetMapping/IBM420.c2b | 188 ++++++- jdk/make/tools/CharsetMapping/IBM420.map | 510 +++++++++--------- jdk/make/tools/CharsetMapping/IBM420.nr | 2 +- .../tools/charsetmapping/GenerateSBCS.java | 194 +++---- 4 files changed, 543 insertions(+), 351 deletions(-) diff --git a/jdk/make/tools/CharsetMapping/IBM420.c2b b/jdk/make/tools/CharsetMapping/IBM420.c2b index 6cb38028124..7e0c201b41b 100644 --- a/jdk/make/tools/CharsetMapping/IBM420.c2b +++ b/jdk/make/tools/CharsetMapping/IBM420.c2b @@ -1 +1,187 @@ -0x15 U+0085 +# +# The diff of 01A434B0.TXMAP110 and 34B001A4.RXMAP110 +# +# Added: 0x15 U+0085 +# +0x15 U+0085 +0x42 U+FE7C +0x46 U+FE80 +0x47 U+FE81 +0x49 U+FE83 +0x4B U+066C +0x4B U+FF0E +0x4C U+FF1C +0x4D U+FF08 +0x4E U+FF0B +0x4F U+FF5C +0x50 U+FF06 +0x52 U+FE85 +0x52 U+FE86 +0x55 U+FE89 +0x55 U+FE8A +0x55 U+FE8B +0x55 U+FE8C +0x56 U+0625 +0x56 U+FE87 +0x56 U+FE8D +0x57 U+FE88 +0x58 U+FE8F +0x58 U+FE90 +0x59 U+FE92 +0x5A U+FF01 +0x5B U+FF04 +0x5C U+066D +0x5C U+FF0A +0x5D U+FF09 +0x5E U+FF1B +0x60 U+FF0D +0x61 U+FF0F +0x62 U+FE93 +0x62 U+FE94 +0x63 U+FE95 +0x63 U+FE96 +0x64 U+FE98 +0x65 U+FE99 +0x65 U+FE9A +0x66 U+FE9C +0x67 U+FE9D +0x67 U+FE9E +0x68 U+FEA0 +0x69 U+FEA1 +0x69 U+FEA2 +0x6B U+066B +0x6B U+FF0C +0x6C U+066A +0x6C U+FF05 +0x6D U+FF3F +0x6E U+FF1E +0x6F U+FF1F +0x70 U+FEA4 +0x71 U+FEA5 +0x71 U+FEA6 +0x72 U+FEA8 +0x73 U+FEA9 +0x73 U+FEAA +0x74 U+FEAB +0x74 U+FEAC +0x75 U+FEAD +0x75 U+FEAE +0x76 U+FEAF +0x76 U+FEB0 +0x77 U+FEB1 +0x77 U+FEB2 +0x78 U+FEB4 +0x7A U+FF1A +0x7B U+FF03 +0x7C U+FF20 +0x7D U+FF07 +0x7E U+FF1D +0x7F U+FF02 +0x80 U+FEB5 +0x80 U+FEB6 +0x81 U+FF41 +0x82 U+FF42 +0x83 U+FF43 +0x84 U+FF44 +0x85 U+FF45 +0x86 U+FF46 +0x87 U+FF47 +0x88 U+FF48 +0x89 U+FF49 +0x8A U+FEB8 +0x8B U+FEB9 +0x8B U+FEBA +0x8C U+FEBC +0x8D U+FEBD +0x8D U+FEBE +0x8E U+FEC0 +0x8F U+FEC1 +0x8F U+FEC2 +0x8F U+FEC3 +0x8F U+FEC4 +0x90 U+FEC5 +0x90 U+FEC6 +0x90 U+FEC7 +0x90 U+FEC8 +0x91 U+FF4A +0x92 U+FF4B +0x93 U+FF4C +0x94 U+FF4D +0x95 U+FF4E +0x96 U+FF4F +0x97 U+FF50 +0x98 U+FF51 +0x99 U+FF52 +0x9A U+FEC9 +0x9E U+FECD +0xA2 U+FF53 +0xA3 U+FF54 +0xA4 U+FF55 +0xA5 U+FF56 +0xA6 U+FF57 +0xA7 U+FF58 +0xA8 U+FF59 +0xA9 U+FF5A +0xAB U+FED1 +0xAB U+FED2 +0xAC U+FED4 +0xAD U+FED5 +0xAD U+FED6 +0xAE U+FED8 +0xAF U+FED9 +0xAF U+FEDA +0xB0 U+FEDC +0xB1 U+FEDD +0xB1 U+FEDE +0xB8 U+FEF9 +0xB9 U+FEFA +0xBA U+FEE0 +0xBB U+FEE1 +0xBB U+FEE2 +0xBC U+FEE4 +0xBD U+FEE5 +0xBD U+FEE6 +0xBE U+FEE8 +0xBF U+FEE9 +0xBF U+FEEA +0xC1 U+FF21 +0xC2 U+FF22 +0xC3 U+FF23 +0xC4 U+FF24 +0xC5 U+FF25 +0xC6 U+FF26 +0xC7 U+FF27 +0xC8 U+FF28 +0xC9 U+FF29 +0xCF U+FEED +0xCF U+FEEE +0xD1 U+FF2A +0xD2 U+FF2B +0xD3 U+FF2C +0xD4 U+FF2D +0xD5 U+FF2E +0xD6 U+FF2F +0xD7 U+FF30 +0xD8 U+FF31 +0xD9 U+FF32 +0xDA U+FEEF +0xDC U+FEF1 +0xDE U+FEF4 +0xE2 U+FF33 +0xE3 U+FF34 +0xE4 U+FF35 +0xE5 U+FF36 +0xE6 U+FF37 +0xE7 U+FF38 +0xE8 U+FF39 +0xE9 U+FF3A +0xF0 U+FF10 +0xF1 U+FF11 +0xF2 U+FF12 +0xF3 U+FF13 +0xF4 U+FF14 +0xF5 U+FF15 +0xF6 U+FF16 +0xF7 U+FF17 +0xF8 U+FF18 +0xF9 U+FF19 diff --git a/jdk/make/tools/CharsetMapping/IBM420.map b/jdk/make/tools/CharsetMapping/IBM420.map index d4ce19249b3..f4f78533d27 100644 --- a/jdk/make/tools/CharsetMapping/IBM420.map +++ b/jdk/make/tools/CharsetMapping/IBM420.map @@ -1,257 +1,253 @@ -#Generated from IBM420.java -0x00 U+0000 -0x01 U+0001 -0x02 U+0002 -0x03 U+0003 -0x04 U+009c -0x05 U+0009 -0x06 U+0086 -0x07 U+007f -0x08 U+0097 -0x09 U+008d -0x0a U+008e -0x0b U+000b -0x0c U+000c -0x0d U+000d -0x0e U+000e -0x0f U+000f -0x10 U+0010 -0x11 U+0011 -0x12 U+0012 -0x13 U+0013 -0x14 U+009d -0x15 U+000a -0x16 U+0008 -0x17 U+0087 -0x18 U+0018 -0x19 U+0019 -0x1a U+0092 -0x1b U+008f -0x1c U+001c -0x1d U+001d -0x1e U+001e -0x1f U+001f -0x20 U+0080 -0x21 U+0081 -0x22 U+0082 -0x23 U+0083 -0x24 U+0084 -0x25 U+000a -0x26 U+0017 -0x27 U+001b -0x28 U+0088 -0x29 U+0089 -0x2a U+008a -0x2b U+008b -0x2c U+008c -0x2d U+0005 -0x2e U+0006 -0x2f U+0007 -0x30 U+0090 -0x31 U+0091 -0x32 U+0016 -0x33 U+0093 -0x34 U+0094 -0x35 U+0095 -0x36 U+0096 -0x37 U+0004 -0x38 U+0098 -0x39 U+0099 -0x3a U+009a -0x3b U+009b -0x3c U+0014 -0x3d U+0015 -0x3e U+009e -0x3f U+001a -0x40 U+0020 -0x41 U+00a0 -0x42 U+fe7c -0x43 U+fe7d -0x44 U+0640 -0x45 U+f8fc -0x46 U+fe80 -0x47 U+fe81 -0x48 U+fe82 -0x49 U+fe83 -0x4a U+00a2 -0x4b U+002e -0x4c U+003c -0x4d U+0028 -0x4e U+002b -0x4f U+007c -0x50 U+0026 -0x51 U+fe84 -0x52 U+fe85 -0x53 U+fffd -0x54 U+fffd -0x55 U+fe8b -0x56 U+fe8d -0x57 U+fe8e -0x58 U+fe8f -0x59 U+fe91 -0x5a U+0021 -0x5b U+0024 -0x5c U+002a -0x5d U+0029 -0x5e U+003b -0x5f U+00ac -0x60 U+002d -0x61 U+002f -0x62 U+fe93 -0x63 U+fe95 -0x64 U+fe97 -0x65 U+fe99 -0x66 U+fe9b -0x67 U+fe9d -0x68 U+fe9f -0x69 U+fea1 -0x6a U+00a6 -0x6b U+002c -0x6c U+0025 -0x6d U+005f -0x6e U+003e -0x6f U+003f -0x70 U+fea3 -0x71 U+fea5 -0x72 U+fea7 -0x73 U+fea9 -0x74 U+feab -0x75 U+fead -0x76 U+feaf -0x77 U+f8f6 -0x78 U+feb3 -0x79 U+060c -0x7a U+003a -0x7b U+0023 -0x7c U+0040 -0x7d U+0027 -0x7e U+003d -0x7f U+0022 -0x80 U+f8f5 -0x81 U+0061 -0x82 U+0062 -0x83 U+0063 -0x84 U+0064 -0x85 U+0065 -0x86 U+0066 -0x87 U+0067 -0x88 U+0068 -0x89 U+0069 -0x8a U+feb7 -0x8b U+f8f4 -0x8c U+febb -0x8d U+f8f7 -0x8e U+febf -0x8f U+fec3 -0x90 U+fec7 -0x91 U+006a -0x92 U+006b -0x93 U+006c -0x94 U+006d -0x95 U+006e -0x96 U+006f -0x97 U+0070 -0x98 U+0071 -0x99 U+0072 -0x9a U+fec9 -0x9b U+feca -0x9c U+fecb -0x9d U+fecc -0x9e U+fecd -0x9f U+fece -0xa0 U+fecf -0xa1 U+00f7 -0xa2 U+0073 -0xa3 U+0074 -0xa4 U+0075 -0xa5 U+0076 -0xa6 U+0077 -0xa7 U+0078 -0xa8 U+0079 -0xa9 U+007a -0xaa U+fed0 -0xab U+fed1 -0xac U+fed3 -0xad U+fed5 -0xae U+fed7 -0xaf U+fed9 -0xb0 U+fedb -0xb1 U+fedd -0xb2 U+fef5 -0xb3 U+fef6 -0xb4 U+fef7 -0xb5 U+fef8 -0xb6 U+fffd -0xb7 U+fffd -0xb8 U+fefb -0xb9 U+fefc -0xba U+fedf -0xbb U+fee1 -0xbc U+fee3 -0xbd U+fee5 -0xbe U+fee7 -0xbf U+fee9 -0xc0 U+061b -0xc1 U+0041 -0xc2 U+0042 -0xc3 U+0043 -0xc4 U+0044 -0xc5 U+0045 -0xc6 U+0046 -0xc7 U+0047 -0xc8 U+0048 -0xc9 U+0049 -0xca U+00ad -0xcb U+feeb -0xcc U+fffd -0xcd U+feec -0xce U+fffd -0xcf U+feed -0xd0 U+061f -0xd1 U+004a -0xd2 U+004b -0xd3 U+004c -0xd4 U+004d -0xd5 U+004e -0xd6 U+004f -0xd7 U+0050 -0xd8 U+0051 -0xd9 U+0052 -0xda U+feef -0xdb U+fef0 -0xdc U+fef1 -0xdd U+fef2 -0xde U+fef3 -0xdf U+0660 -0xe0 U+00d7 -0xe1 U+2007 -0xe2 U+0053 -0xe3 U+0054 -0xe4 U+0055 -0xe5 U+0056 -0xe6 U+0057 -0xe7 U+0058 -0xe8 U+0059 -0xe9 U+005a -0xea U+0661 -0xeb U+0662 -0xec U+fffd -0xed U+0663 -0xee U+0664 -0xef U+0665 -0xf0 U+0030 -0xf1 U+0031 -0xf2 U+0032 -0xf3 U+0033 -0xf4 U+0034 -0xf5 U+0035 -0xf6 U+0036 -0xf7 U+0037 -0xf8 U+0038 -0xf9 U+0039 -0xfa U+fffd -0xfb U+0666 -0xfc U+0667 -0xfd U+0668 -0xfe U+0669 -0xff U+009f +# +# Frm IBMCDC datatable 01A434B0.TXMAP110 +# +# Changed +# 0x15 U+0085 -> 0x15 U+000a +# +0x00 U+0000 +0x01 U+0001 +0x02 U+0002 +0x03 U+0003 +0x04 U+009C +0x05 U+0009 +0x06 U+0086 +0x07 U+007F +0x08 U+0097 +0x09 U+008D +0x0A U+008E +0x0B U+000B +0x0C U+000C +0x0D U+000D +0x0E U+000E +0x0F U+000F +0x10 U+0010 +0x11 U+0011 +0x12 U+0012 +0x13 U+0013 +0x14 U+009D +0x15 U+000A +0x16 U+0008 +0x17 U+0087 +0x18 U+0018 +0x19 U+0019 +0x1A U+0092 +0x1B U+008F +0x1C U+001C +0x1D U+001D +0x1E U+001E +0x1F U+001F +0x20 U+0080 +0x21 U+0081 +0x22 U+0082 +0x23 U+0083 +0x24 U+0084 +0x25 U+000A +0x26 U+0017 +0x27 U+001B +0x28 U+0088 +0x29 U+0089 +0x2A U+008A +0x2B U+008B +0x2C U+008C +0x2D U+0005 +0x2E U+0006 +0x2F U+0007 +0x30 U+0090 +0x31 U+0091 +0x32 U+0016 +0x33 U+0093 +0x34 U+0094 +0x35 U+0095 +0x36 U+0096 +0x37 U+0004 +0x38 U+0098 +0x39 U+0099 +0x3A U+009A +0x3B U+009B +0x3C U+0014 +0x3D U+0015 +0x3E U+009E +0x3F U+001A +0x40 U+0020 +0x41 U+00A0 +0x42 U+0651 +0x43 U+FE7D +0x44 U+0640 +0x45 U+200B +0x46 U+0621 +0x47 U+0622 +0x48 U+FE82 +0x49 U+0623 +0x4A U+00A2 +0x4B U+002E +0x4C U+003C +0x4D U+0028 +0x4E U+002B +0x4F U+007C +0x50 U+0026 +0x51 U+FE84 +0x52 U+0624 +0x55 U+0626 +0x56 U+0627 +0x57 U+FE8E +0x58 U+0628 +0x59 U+FE91 +0x5A U+0021 +0x5B U+0024 +0x5C U+002A +0x5D U+0029 +0x5E U+003B +0x5F U+00AC +0x60 U+002D +0x61 U+002F +0x62 U+0629 +0x63 U+062A +0x64 U+FE97 +0x65 U+062B +0x66 U+FE9B +0x67 U+062C +0x68 U+FE9F +0x69 U+062D +0x6A U+00A6 +0x6B U+002C +0x6C U+0025 +0x6D U+005F +0x6E U+003E +0x6F U+003F +0x70 U+FEA3 +0x71 U+062E +0x72 U+FEA7 +0x73 U+062F +0x74 U+0630 +0x75 U+0631 +0x76 U+0632 +0x77 U+0633 +0x78 U+FEB3 +0x79 U+060C +0x7A U+003A +0x7B U+0023 +0x7C U+0040 +0x7D U+0027 +0x7E U+003D +0x7F U+0022 +0x80 U+0634 +0x81 U+0061 +0x82 U+0062 +0x83 U+0063 +0x84 U+0064 +0x85 U+0065 +0x86 U+0066 +0x87 U+0067 +0x88 U+0068 +0x89 U+0069 +0x8A U+FEB7 +0x8B U+0635 +0x8C U+FEBB +0x8D U+0636 +0x8E U+FEBF +0x8F U+0637 +0x90 U+0638 +0x91 U+006A +0x92 U+006B +0x93 U+006C +0x94 U+006D +0x95 U+006E +0x96 U+006F +0x97 U+0070 +0x98 U+0071 +0x99 U+0072 +0x9A U+0639 +0x9B U+FECA +0x9C U+FECB +0x9D U+FECC +0x9E U+063A +0x9F U+FECE +0xA0 U+FECF +0xA1 U+00F7 +0xA2 U+0073 +0xA3 U+0074 +0xA4 U+0075 +0xA5 U+0076 +0xA6 U+0077 +0xA7 U+0078 +0xA8 U+0079 +0xA9 U+007A +0xAA U+FED0 +0xAB U+0641 +0xAC U+FED3 +0xAD U+0642 +0xAE U+FED7 +0xAF U+0643 +0xB0 U+FEDB +0xB1 U+0644 +0xB2 U+FEF5 +0xB3 U+FEF6 +0xB4 U+FEF7 +0xB5 U+FEF8 +0xB8 U+FEFB +0xB9 U+FEFC +0xBA U+FEDF +0xBB U+0645 +0xBC U+FEE3 +0xBD U+0646 +0xBE U+FEE7 +0xBF U+0647 +0xC0 U+061B +0xC1 U+0041 +0xC2 U+0042 +0xC3 U+0043 +0xC4 U+0044 +0xC5 U+0045 +0xC6 U+0046 +0xC7 U+0047 +0xC8 U+0048 +0xC9 U+0049 +0xCA U+00AD +0xCB U+FEEB +0xCD U+FEEC +0xCF U+0648 +0xD0 U+061F +0xD1 U+004A +0xD2 U+004B +0xD3 U+004C +0xD4 U+004D +0xD5 U+004E +0xD6 U+004F +0xD7 U+0050 +0xD8 U+0051 +0xD9 U+0052 +0xDA U+0649 +0xDB U+FEF0 +0xDC U+064A +0xDD U+FEF2 +0xDE U+FEF3 +0xDF U+0660 +0xE0 U+00D7 +0xE2 U+0053 +0xE3 U+0054 +0xE4 U+0055 +0xE5 U+0056 +0xE6 U+0057 +0xE7 U+0058 +0xE8 U+0059 +0xE9 U+005A +0xEA U+0661 +0xEB U+0662 +0xED U+0663 +0xEE U+0664 +0xEF U+0665 +0xF0 U+0030 +0xF1 U+0031 +0xF2 U+0032 +0xF3 U+0033 +0xF4 U+0034 +0xF5 U+0035 +0xF6 U+0036 +0xF7 U+0037 +0xF8 U+0038 +0xF9 U+0039 +0xFB U+0666 +0xFC U+0667 +0xFD U+0668 +0xFE U+0669 +0xFF U+009F diff --git a/jdk/make/tools/CharsetMapping/IBM420.nr b/jdk/make/tools/CharsetMapping/IBM420.nr index 675451906d4..c3d93ee4774 100644 --- a/jdk/make/tools/CharsetMapping/IBM420.nr +++ b/jdk/make/tools/CharsetMapping/IBM420.nr @@ -1 +1 @@ -0x25 U+000a +0x25 U+000a diff --git a/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java b/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java index 5d791d51591..8a57a6521bc 100644 --- a/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java +++ b/jdk/make/tools/src/build/tools/charsetmapping/GenerateSBCS.java @@ -26,6 +26,7 @@ package build.tools.charsetmapping; import java.io.*; +import java.util.Arrays; import java.util.ArrayList; import java.util.Scanner; import java.util.Formatter; @@ -54,33 +55,19 @@ public class GenerateSBCS { String pkgName = fields[4]; System.out.printf("%s,%s,%s,%b,%s%n", clzName, csName, hisName, isASCII, pkgName); - StringBuilder b2c = new StringBuilder(); - int c2bLen = genB2C( - new FileInputStream(new File(args[0], clzName+".map")), b2c); - - String b2cNR = null; - File nrF = new File(args[0], clzName+".nr"); - if (nrF.exists()) { - b2cNR = genNR(new FileInputStream(nrF)); - } - - String c2bNR = null; - File c2bF = new File(args[0], clzName+".c2b"); - if (c2bF.exists()) { - c2bNR = genC2BNR(new FileInputStream(c2bF)); - } - - genSBCSClass(args[0], args[1], "SingleByte-X.java", - clzName, csName, hisName, pkgName, isASCII, - b2c.toString(), b2cNR, c2bNR, c2bLen); + genClass(args[0], args[1], "SingleByte-X.java", + clzName, csName, hisName, pkgName, isASCII); } } private static void toString(char[] sb, int off, int end, - Formatter out, String closure) { + Formatter out, String closure, + boolean comment) { while (off < end) { out.format(" \""); for (int j = 0; j < 8; j++) { + if (off == end) + break; char c = sb[off++]; switch (c) { case '\b': @@ -103,101 +90,124 @@ public class GenerateSBCS { out.format("\\u%04X", c & 0xffff); } } - if (off == end) - out.format("\" %s // 0x%02x - 0x%02x%n", closure, off-8, off-1); - else - out.format("\" + // 0x%02x - 0x%02x%n", off-8, off-1); + if (comment) { + if (off == end) + out.format("\" %s // 0x%02x - 0x%02x%n", + closure, off-8, off-1); + else + out.format("\" + // 0x%02x - 0x%02x%n", + off-8, off-1); + } else { + if (off == end) + out.format("\"%s%n", closure); + else + out.format("\" +%n"); + } } } static Pattern sbmap = Pattern.compile("0x(\\p{XDigit}++)\\s++U\\+(\\p{XDigit}++)(\\s++#.*)?"); - private static int genB2C(InputStream in, StringBuilder out) + + private static void genClass(String srcDir, String dstDir, + String template, + String clzName, + String csName, + String hisName, + String pkgName, + boolean isASCII) throws Exception { + StringBuilder b2cSB = new StringBuilder(); + StringBuilder b2cNRSB = new StringBuilder(); + StringBuilder c2bNRSB = new StringBuilder(); + char[] sb = new char[0x100]; - int[] indexC2B = new int[0x100]; + char[] c2bIndex = new char[0x100]; + int c2bOff = 0; + Arrays.fill(sb, UNMAPPABLE_DECODING); + Arrays.fill(c2bIndex, UNMAPPABLE_DECODING); - for (int i = 0; i < sb.length; i++) - sb[i] = UNMAPPABLE_DECODING; - - // parse the b2c mapping table + // (1)read in .map to parse all b->c entries + FileInputStream in = new FileInputStream( + new File(srcDir, clzName + ".map")); Parser p = new Parser(in, sbmap); Entry e = null; - int off = 0; + while ((e = p.next()) != null) { sb[e.bs] = (char)e.cp; - if (indexC2B[e.cp>>8] == 0) { - off += 0x100; - indexC2B[e.cp>>8] = 1; + if (c2bIndex[e.cp>>8] == UNMAPPABLE_DECODING) { + c2bOff += 0x100; + c2bIndex[e.cp>>8] = 1; } } - Formatter fm = new Formatter(out); + Formatter fm = new Formatter(b2cSB); fm.format("%n"); // vm -server shows cc[byte + 128] access is much faster than // cc[byte&0xff] so we output the upper segment first - toString(sb, 0x80, 0x100, fm, "+"); - toString(sb, 0x00, 0x80, fm, ";"); - + toString(sb, 0x80, 0x100, fm, "+", true); + toString(sb, 0x00, 0x80, fm, ";", true); fm.close(); - return off; - } - // generate non-roundtrip entries from xxx.nr file - private static String genNR(InputStream in) throws Exception - { - StringBuilder sb = new StringBuilder(); - Formatter fm = new Formatter(sb); - Parser p = new Parser(in, sbmap); - Entry e = null; - fm.format("// remove non-roundtrip entries%n"); - fm.format(" b2cMap = b2cTable.toCharArray();%n"); - while ((e = p.next()) != null) { - fm.format(" b2cMap[%d] = UNMAPPABLE_DECODING;%n", - (e.bs>=0x80)?(e.bs-0x80):(e.bs+0x80)); - } - fm.close(); - return sb.toString(); - } + // (2)now the .nr file which includes "b->c" non-roundtrip entries + File f = new File(srcDir, clzName + ".nr"); + if (f.exists()) { + in = new FileInputStream(f); + fm = new Formatter(b2cNRSB); + p = new Parser(in, sbmap); + e = null; - // generate c2b only entries from xxx.c2b file - private static String genC2BNR(InputStream in) throws Exception - { - StringBuilder sb = new StringBuilder(); - Formatter fm = new Formatter(sb); - Parser p = new Parser(in, sbmap); - ArrayList es = new ArrayList(); - Entry e = null; - while ((e = p.next()) != null) { - es.add(e); + fm.format("// remove non-roundtrip entries%n"); + fm.format(" b2cMap = b2cTable.toCharArray();%n"); + while ((e = p.next()) != null) { + fm.format(" b2cMap[%d] = UNMAPPABLE_DECODING;%n", + (e.bs>=0x80)?(e.bs-0x80):(e.bs+0x80)); + } + fm.close(); } - fm.format("// non-roundtrip c2b only entries%n"); - fm.format(" c2bNR = new char[%d];%n", es.size() * 2); - int i = 0; - for (Entry entry: es) { - fm.format(" c2bNR[%d] = 0x%x; c2bNR[%d] = 0x%x;%n", - i++, entry.bs, i++, entry.cp); + // (3)finally the .c2b file which includes c->b non-roundtrip entries + f = new File(srcDir, clzName + ".c2b"); + if (f.exists()) { + in = new FileInputStream(f); + fm = new Formatter(c2bNRSB); + p = new Parser(in, sbmap); + e = null; + ArrayList es = new ArrayList(); + while ((e = p.next()) != null) { + if (c2bIndex[e.cp>>8] == UNMAPPABLE_DECODING) { + c2bOff += 0x100; + c2bIndex[e.cp>>8] = 1; + } + es.add(e); + } + fm.format("// non-roundtrip c2b only entries%n"); + if (es.size() < 100) { + fm.format(" c2bNR = new char[%d];%n", es.size() * 2); + int i = 0; + for (Entry entry: es) { + fm.format(" c2bNR[%d] = 0x%x; c2bNR[%d] = 0x%x;%n", + i++, entry.bs, i++, entry.cp); + } + } else { + char[] cc = new char[es.size() * 2]; + int i = 0; + for (Entry entry: es) { + cc[i++] = (char)entry.bs; + cc[i++] = (char)entry.cp; + } + fm.format(" c2bNR = (%n"); + toString(cc, 0, i, fm, ").toCharArray();", false); + } + fm.close(); } - fm.close(); - return sb.toString(); - } - private static void genSBCSClass(String srcDir, - String dstDir, - String template, - String clzName, - String csName, - String hisName, - String pkgName, - boolean isASCII, - String b2c, - String b2cNR, - String c2bNR, - int c2blen) - throws Exception - { + // (4)it's time to generate the source file + String b2c = b2cSB.toString(); + String b2cNR = b2cNRSB.toString(); + String c2bNR = c2bNRSB.toString(); + Scanner s = new Scanner(new File(srcDir, template)); PrintStream out = new PrintStream(new FileOutputStream( new File(dstDir, clzName + ".java"))); @@ -239,16 +249,16 @@ public class GenerateSBCS { line = line.replace("$B2CTABLE$", b2c); } if (line.indexOf("$C2BLENGTH$") != -1) { - line = line.replace("$C2BLENGTH$", "0x" + Integer.toString(c2blen, 16)); + line = line.replace("$C2BLENGTH$", "0x" + Integer.toString(c2bOff, 16)); } if (line.indexOf("$NONROUNDTRIP_B2C$") != -1) { - if (b2cNR == null) + if (b2cNR.length() == 0) continue; line = line.replace("$NONROUNDTRIP_B2C$", b2cNR); } if (line.indexOf("$NONROUNDTRIP_C2B$") != -1) { - if (c2bNR == null) + if (c2bNR.length() == 0) continue; line = line.replace("$NONROUNDTRIP_C2B$", c2bNR); } From 22c0a5cddfb8e7c26b687f6d276d431f2da5c4f4 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 4 Aug 2009 17:26:41 -0700 Subject: [PATCH 045/102] 6867671: javap whitespace formatting issues Reviewed-by: mcimadamore --- .../com/sun/tools/javap/AttributeWriter.java | 182 +++++++++++------- .../com/sun/tools/javap/BasicWriter.java | 54 +++++- .../com/sun/tools/javap/ClassWriter.java | 96 +++++---- .../com/sun/tools/javap/CodeWriter.java | 62 +++--- .../com/sun/tools/javap/ConstantWriter.java | 35 +++- .../com/sun/tools/javap/JavapTask.java | 32 +++ .../classes/com/sun/tools/javap/Options.java | 2 + 7 files changed, 297 insertions(+), 166 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java index ba190beea24..47c8e460188 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -41,7 +41,6 @@ import com.sun.tools.classfile.DefaultAttribute; import com.sun.tools.classfile.Deprecated_attribute; import com.sun.tools.classfile.EnclosingMethod_attribute; import com.sun.tools.classfile.Exceptions_attribute; -import com.sun.tools.classfile.Field; import com.sun.tools.classfile.InnerClasses_attribute; import com.sun.tools.classfile.LineNumberTable_attribute; import com.sun.tools.classfile.LocalVariableTable_attribute; @@ -149,22 +148,26 @@ public class AttributeWriter extends BasicWriter } public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) { - println(" AnnotationDefault: "); - print(" default_value: "); + println("AnnotationDefault:"); + indent(+1); + print("default_value: "); annotationWriter.write(attr.default_value); + indent(-1); return null; } public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) { - print(" CharacterRangeTable: "); + println("CharacterRangeTable:"); + indent(+1); for (int i = 0; i < attr.character_range_table.length; i++) { CharacterRangeTable_attribute.Entry e = attr.character_range_table[i]; print(" " + e.start_pc + ", " + e.end_pc + ", " + Integer.toHexString(e.character_range_start) + ", " + Integer.toHexString(e.character_range_end) + ", " + - Integer.toHexString(e.flags) + - "\t// "); + Integer.toHexString(e.flags)); + tab(); + print("// "); print(e.start_pc + ", " + e.end_pc + ", " + (e.character_range_start >> 10) + ":" + (e.character_range_start & 0x3ff) + ", " + @@ -187,16 +190,13 @@ public class AttributeWriter extends BasicWriter print(", branch-true"); if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0) print(", branch-false"); - - - } + indent(-1); return null; } public Void visitCode(Code_attribute attr, Void ignore) { codeWriter.write(attr, constant_pool); - println(); return null; } @@ -207,25 +207,23 @@ public class AttributeWriter extends BasicWriter public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) { if (options.compat) // BUG 6622216 javap names some attributes incorrectly - print(" Constant value: "); + print("Constant value: "); else - print(" ConstantValue: "); + print("ConstantValue: "); constantWriter.write(attr.constantvalue_index); - if (!options.compat) // BUG 6622232 javap gets whitespace confused - println(); + println(); return null; } public Void visitDeprecated(Deprecated_attribute attr, Void ignore) { - if (!(options.compat && owner instanceof Field)) // BUG 6622232 javap gets whitespace confused - print(" "); println("Deprecated: true"); return null; } public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) { - print(" EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index - + "\t// " + getJavaClassName(attr)); + print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index); + tab(); + print("// " + getJavaClassName(attr)); if (attr.method_index != 0) print("." + getMethodName(attr)); println(); @@ -249,15 +247,16 @@ public class AttributeWriter extends BasicWriter } public Void visitExceptions(Exceptions_attribute attr, Void ignore) { - println(" Exceptions: "); - print(" throws "); + println("Exceptions:"); + indent(+1); + print("throws "); for (int i = 0; i < attr.number_of_exceptions; i++) { if (i > 0) print(", "); print(getJavaException(attr, i)); } - if (!options.compat) // BUG 6622232 javap gets whitespace confused - println(); + println(); + indent(-1); return null; } @@ -290,8 +289,7 @@ public class AttributeWriter extends BasicWriter writeInnerClassHeader(); first = false; } - if (!options.compat) // BUG 6622232: javap gets whitespace confused - print(" "); + print(" "); for (String name: access_flags.getInnerClassModifiers()) print(name + " "); if (info.inner_name_index!=0) { @@ -313,6 +311,8 @@ public class AttributeWriter extends BasicWriter println(); } } + if (!first) + indent(-1); return null; } @@ -325,26 +325,28 @@ public class AttributeWriter extends BasicWriter } private void writeInnerClassHeader() { - print(" "); if (options.compat) // BUG 6622216: javap names some attributes incorrectly print("InnerClass"); else print("InnerClasses"); println(": "); + indent(+1); } public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) { - println(" LineNumberTable: "); + println("LineNumberTable:"); + indent(+1); for (LineNumberTable_attribute.Entry entry: attr.line_number_table) { - println(" line " + entry.line_number + ": " + entry.start_pc); + println("line " + entry.line_number + ": " + entry.start_pc); } + indent(-1); return null; } public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) { - println(" LocalVariableTable: "); - println(" Start Length Slot Name Signature"); - + println("LocalVariableTable:"); + indent(+1); + println("Start Length Slot Name Signature"); for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) { Formatter formatter = new Formatter(); println(formatter.format("%8d %7d %5d %5s %s", @@ -352,25 +354,28 @@ public class AttributeWriter extends BasicWriter constantWriter.stringValue(entry.name_index), constantWriter.stringValue(entry.descriptor_index))); } + indent(-1); return null; } public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) { - println(" LocalVariableTypeTable: "); - println(" Start Length Slot Name Signature"); - + println("LocalVariableTypeTable:"); + indent(+1); + println("Start Length Slot Name Signature"); for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) { - Formatter formatter = new Formatter(); - println(formatter.format("%8d %7d %5d %5s %s", + println(String.format("%5d %7d %5d %5s %s", entry.start_pc, entry.length, entry.index, constantWriter.stringValue(entry.name_index), constantWriter.stringValue(entry.signature_index))); } + indent(-1); return null; } public Void visitModule(Module_attribute attr, Void ignore) { - println(" Module: #" + attr.module_name + "\t// " + getModuleName(attr)); + print("Module: #" + attr.module_name); + tab(); + println("// " + getModuleName(attr)); return null; } @@ -383,11 +388,15 @@ public class AttributeWriter extends BasicWriter } public Void visitModuleExportTable(ModuleExportTable_attribute attr, Void ignore) { - println(" ModuleExportTable:"); - println(" Types: (" + attr.export_type_table.length + ")"); + println("ModuleExportTable:"); + indent(+1); + println("Types: (" + attr.export_type_table.length + ")"); for (int i = 0; i < attr.export_type_table.length; i++) { - println(" #" + attr.export_type_table[i] + "\t// " + getExportTypeName(attr, i)); + print("#" + attr.export_type_table[i]); + tab(); + println("// " + getExportTypeName(attr, i)); } + indent(-1); return null; } @@ -400,11 +409,15 @@ public class AttributeWriter extends BasicWriter } public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, Void ignore) { - println(" ModuleMemberTable:"); - println(" Packages: (" + attr.package_member_table.length + ")"); + println("ModuleMemberTable:"); + indent(+1); + println("Packages: (" + attr.package_member_table.length + ")"); for (int i = 0; i < attr.package_member_table.length; i++) { - println(" #" + attr.package_member_table[i] + "\t// " + getPackageMemberName(attr, i)); + print("#" + attr.package_member_table[i]); + tab(); + println("// " + getPackageMemberName(attr, i)); } + indent(-1); return null; } @@ -417,73 +430,91 @@ public class AttributeWriter extends BasicWriter } public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) { - println(" RuntimeVisibleAnnotations: "); + println("RuntimeVisibleAnnotations:"); + indent(+1); for (int i = 0; i < attr.annotations.length; i++) { - print(" " + i + ": "); + print(i + ": "); annotationWriter.write(attr.annotations[i]); println(); } + indent(-1); return null; } public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) { - println(" RuntimeInvisibleAnnotations: "); + println("RuntimeInvisibleAnnotations:"); + indent(+1); for (int i = 0; i < attr.annotations.length; i++) { - print(" " + i + ": "); + print(i + ": "); annotationWriter.write(attr.annotations[i]); println(); } + indent(-1); return null; } public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) { - println(" RuntimeVisibleTypeAnnotations: "); + println("RuntimeVisibleTypeAnnotations:"); + indent(+1); for (int i = 0; i < attr.annotations.length; i++) { - print(" " + i + ": "); + print(i + ": "); annotationWriter.write(attr.annotations[i]); println(); } + indent(-1); return null; } public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) { - println(" RuntimeInvisibleTypeAnnotations: "); + println("RuntimeInvisibleTypeAnnotations:"); + indent(+1); for (int i = 0; i < attr.annotations.length; i++) { - print(" " + i + ": "); + print(i + ": "); annotationWriter.write(attr.annotations[i]); println(); } + indent(-1); return null; } public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) { - println(" RuntimeVisibleParameterAnnotations: "); + println("RuntimeVisibleParameterAnnotations:"); + indent(+1); for (int param = 0; param < attr.parameter_annotations.length; param++) { - println(" parameter " + param + ": "); + println("parameter " + param + ": "); + indent(+1); for (int i = 0; i < attr.parameter_annotations[param].length; i++) { - print(" " + i + ": "); + print(i + ": "); annotationWriter.write(attr.parameter_annotations[param][i]); println(); } + indent(-1); } + indent(-1); return null; } public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) { - println(" RuntimeInvisibleParameterAnnotations: "); + println("RuntimeInvisibleParameterAnnotations:"); + indent(+1); for (int param = 0; param < attr.parameter_annotations.length; param++) { - println(" " + param + ": "); + println(param + ": "); + indent(+1); for (int i = 0; i < attr.parameter_annotations[param].length; i++) { - print(" " + i + ": "); + print(i + ": "); annotationWriter.write(attr.parameter_annotations[param][i]); println(); } + indent(-1); } + indent(-1); return null; } public Void visitSignature(Signature_attribute attr, Void ignore) { - println(" Signature: #" + attr.signature_index + "\t// " + getSignature(attr)); + print("Signature: #" + attr.signature_index); + tab(); + println("// " + getSignature(attr)); return null; } @@ -496,12 +527,12 @@ public class AttributeWriter extends BasicWriter } public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) { - println(" SourceDebugExtension: " + attr.getValue()); + println("SourceDebugExtension: " + attr.getValue()); return null; } public Void visitSourceFile(SourceFile_attribute attr, Void ignore) { - println(" SourceFile: \"" + getSourceFile(attr) + "\""); + println("SourceFile: \"" + getSourceFile(attr) + "\""); return null; } @@ -519,24 +550,26 @@ public class AttributeWriter extends BasicWriter } public Void visitStackMap(StackMap_attribute attr, Void ignore) { - println(" StackMap: number_of_entries = " + attr.number_of_entries); - + println("StackMap: number_of_entries = " + attr.number_of_entries); + indent(+1); StackMapTableWriter w = new StackMapTableWriter(); for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { w.write(entry); } println(); + indent(-1); return null; } public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) { - println(" StackMapTable: number_of_entries = " + attr.number_of_entries); - + println("StackMapTable: number_of_entries = " + attr.number_of_entries); + indent(+1); StackMapTableWriter w = new StackMapTableWriter(); for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { w.write(entry); } println(); + indent(-1); return null; } @@ -555,29 +588,37 @@ public class AttributeWriter extends BasicWriter public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) { printHeader(frame); println(" /* same_locals_1_stack_item */"); + indent(+1); printMap("stack", frame.stack); + indent(-1); return null; } public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) { printHeader(frame); println(" /* same_locals_1_stack_item_frame_extended */"); - println(" offset_delta = " + frame.offset_delta); + indent(+1); + println("offset_delta = " + frame.offset_delta); printMap("stack", frame.stack); + indent(-1); return null; } public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) { printHeader(frame); println(" /* chop */"); - println(" offset_delta = " + frame.offset_delta); + indent(+1); + println("offset_delta = " + frame.offset_delta); + indent(-1); return null; } public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) { printHeader(frame); println(" /* same_frame_extended */"); - println(" offset_delta = " + frame.offset_delta); + indent(+1); + println("offset_delta = " + frame.offset_delta); + indent(-1); return null; } @@ -592,13 +633,16 @@ public class AttributeWriter extends BasicWriter public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) { printHeader(frame); if (frame instanceof StackMap_attribute.stack_map_frame) { - println(" offset = " + frame.offset_delta); + indent(+1); + println(" offset = " + frame.offset_delta); } else { println(" /* full_frame */"); - println(" offset_delta = " + frame.offset_delta); + indent(+1); + println("offset_delta = " + frame.offset_delta); } printMap("locals", frame.locals); printMap("stack", frame.stack); + indent(-1); return null; } @@ -607,7 +651,7 @@ public class AttributeWriter extends BasicWriter } void printMap(String name, StackMapTable_attribute.verification_type_info[] map) { - print(" " + name + " = ["); + print(name + " = ["); for (int i = 0; i < map.length; i++) { StackMapTable_attribute.verification_type_info info = map[i]; int tag = info.tag; diff --git a/langtools/src/share/classes/com/sun/tools/javap/BasicWriter.java b/langtools/src/share/classes/com/sun/tools/javap/BasicWriter.java index 0f80004bacd..dc971dc68da 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/BasicWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/BasicWriter.java @@ -71,6 +71,18 @@ public class BasicWriter { lineWriter.println(); } + protected void indent(int delta) { + lineWriter.indent(delta); + } + + protected void tab() { + lineWriter.tab(); + } + + protected void setPendingNewline(boolean b) { + lineWriter.pendingNewline = b; + } + protected String report(AttributeException e) { out.println("Error: " + e.getMessage()); // i18n? return "???"; @@ -122,19 +134,30 @@ public class BasicWriter { protected LineWriter(Context context) { context.put(LineWriter.class, this); + Options options = Options.instance(context); + indentWidth = options.indentWidth; + tabColumn = options.tabColumn; out = context.get(PrintWriter.class); buffer = new StringBuilder(); } protected void print(String s) { + if (pendingNewline) { + println(); + pendingNewline = false; + } if (s == null) s = "null"; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); - if (c == '\n') { - println(); - } else { - buffer.append(c); + switch (c) { + case '\n': + println(); + break; + default: + if (buffer.length() == 0) + indent(); + buffer.append(c); } } @@ -145,8 +168,31 @@ public class BasicWriter { buffer.setLength(0); } + protected void indent(int delta) { + indentCount += delta; + } + + protected void tab() { + if (buffer.length() == 0) + indent(); + space(indentCount * indentWidth + tabColumn - buffer.length()); + } + + private void indent() { + space(indentCount * indentWidth); + } + + private void space(int n) { + for (int i = 0; i < n; i++) + buffer.append(' '); + } + private PrintWriter out; private StringBuilder buffer; + private int indentCount; + private int indentWidth; + private int tabColumn; + private boolean pendingNewline; } } diff --git a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java index 4500c365c37..9d657ee4d55 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java @@ -120,6 +120,7 @@ public class ClassWriter extends BasicWriter { else println("Classfile " + uri); } + indent(+1); if (lastModified != -1) { Date lm = new Date(lastModified); DateFormat df = DateFormat.getDateInstance(); @@ -144,6 +145,10 @@ public class ClassWriter extends BasicWriter { println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\""); } + if ((options.sysInfo || options.verbose) && !options.compat) { + indent(-1); + } + String name = getJavaName(classFile); AccessFlags flags = cf.access_flags; @@ -186,23 +191,24 @@ public class ClassWriter extends BasicWriter { if (options.verbose) { println(); + indent(+1); attrWriter.write(cf, cf.attributes, constant_pool); - println(" minor version: " + cf.minor_version); - println(" major version: " + cf.major_version); + println("minor version: " + cf.minor_version); + println("major version: " + cf.major_version); if (!options.compat) - writeList(" flags: ", flags.getClassFlags(), NEWLINE); + writeList("flags: ", flags.getClassFlags(), NEWLINE); + indent(-1); constantWriter.writeConstantPool(); - println(); } else { - if (!options.compat) - print(" "); + print(" "); } println("{"); + indent(+1); writeFields(); writeMethods(); + indent(-1); println("}"); - println(); } protected void writeFields() { @@ -215,14 +221,6 @@ public class ClassWriter extends BasicWriter { if (!options.checkAccess(f.access_flags)) return; - if (!(options.showLineAndLocalVariableTables - || options.showDisassembled - || options.verbose - || options.showInternalSignatures - || options.showAllAttrs)) { - print(" "); - } - AccessFlags flags = f.access_flags; writeModifiers(flags.getFieldModifiers()); Signature_attribute sigAttr = getSignature(f.attributes); @@ -251,11 +249,13 @@ public class ClassWriter extends BasicWriter { print(";"); println(); + indent(+1); + if (options.showInternalSignatures) - println(" Signature: " + getValue(f.descriptor)); + println("Signature: " + getValue(f.descriptor)); if (options.verbose && !options.compat) - writeList(" flags: ", flags.getFieldFlags(), NEWLINE); + writeList("flags: ", flags.getFieldFlags(), NEWLINE); if (options.showAllAttrs) { for (Attribute attr: f.attributes) @@ -263,6 +263,8 @@ public class ClassWriter extends BasicWriter { println(); } + indent(-1); + if (options.showDisassembled || options.showLineAndLocalVariableTables) println(); } @@ -270,6 +272,7 @@ public class ClassWriter extends BasicWriter { protected void writeMethods() { for (Method m: classFile.methods) writeMethod(m); + setPendingNewline(false); } protected void writeMethod(Method m) { @@ -278,14 +281,6 @@ public class ClassWriter extends BasicWriter { method = m; - if (!(options.showLineAndLocalVariableTables - || options.showDisassembled - || options.verbose - || options.showInternalSignatures - || options.showAllAttrs)) { - print(" "); - } - AccessFlags flags = m.access_flags; Descriptor d; @@ -333,16 +328,6 @@ public class ClassWriter extends BasicWriter { if (e_attr != null) { // if there are generic exceptions, there must be erased exceptions if (e_attr instanceof Exceptions_attribute) { Exceptions_attribute exceptions = (Exceptions_attribute) e_attr; - if (options.compat) { // Bug XXXXXXX whitespace - if (!(options.showLineAndLocalVariableTables - || options.showDisassembled - || options.verbose - || options.showInternalSignatures - || options.showAllAttrs)) { - print(" "); - } - print(" "); - } print(" throws "); if (methodExceptions != null) { // use generic list if available writeList("", methodExceptions, ""); @@ -358,14 +343,17 @@ public class ClassWriter extends BasicWriter { } } - print(";"); - println(); + println(";"); - if (options.showInternalSignatures) - println(" Signature: " + getValue(m.descriptor)); + indent(+1); - if (options.verbose && !options.compat) - writeList(" flags: ", flags.getMethodFlags(), NEWLINE); + if (options.showInternalSignatures) { + println("Signature: " + getValue(m.descriptor)); + } + + if (options.verbose && !options.compat) { + writeList("flags: ", flags.getMethodFlags(), NEWLINE); + } Code_attribute code = null; Attribute c_attr = m.attributes.get(Attribute.Code); @@ -378,33 +366,35 @@ public class ClassWriter extends BasicWriter { if (options.showDisassembled && !options.showAllAttrs) { if (code != null) { - println(" Code:"); + println("Code:"); codeWriter.writeInstrs(code); codeWriter.writeExceptionTable(code); } - println(); } if (options.showLineAndLocalVariableTables) { - if (code != null) + if (code != null) { attrWriter.write(code, code.attributes.get(Attribute.LineNumberTable), constant_pool); - println(); - if (code != null) attrWriter.write(code, code.attributes.get(Attribute.LocalVariableTable), constant_pool); - println(); - println(); + } } if (options.showAllAttrs) { Attribute[] attrs = m.attributes.attrs; for (Attribute attr: attrs) attrWriter.write(m, attr, constant_pool); - -// // the following condition is to mimic old javap -// if (!(attrs.length > 0 && -// attrs[attrs.length - 1] instanceof Exceptions_attribute)) - println(); } + + indent(-1); + + // set pendingNewline to write a newline before the next method (if any) + // if a separator is desired + setPendingNewline( + options.showDisassembled || + options.showAllAttrs || + options.showInternalSignatures || + options.showLineAndLocalVariableTables || + options.verbose); } void writeModifiers(Collection items) { diff --git a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java index 975e3621536..04508494395 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java @@ -69,11 +69,13 @@ class CodeWriter extends BasicWriter { } void write(Code_attribute attr, ConstantPool constant_pool) { - println(" Code:"); + println("Code:"); + indent(+1); writeVerboseHeader(attr, constant_pool); writeInstrs(attr); writeExceptionTable(attr); attrWriter.write(attr, attr.attributes, constant_pool); + indent(-1); } public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) { @@ -90,9 +92,9 @@ class CodeWriter extends BasicWriter { argCount = report(e); } - println(" Stack=" + attr.max_stack + - ", Locals=" + attr.max_locals + - ", Args_size=" + argCount); + println("stack=" + attr.max_stack + + ", locals=" + attr.max_locals + + ", args_size=" + argCount); } @@ -115,8 +117,7 @@ class CodeWriter extends BasicWriter { } public void writeInstr(Instruction instr) { - print(" " + instr.getPC() + ":\t"); - print(instr.getMnemonic()); + print(String.format("%4d: %-12s ", instr.getPC(), instr.getMnemonic())); instr.accept(instructionPrinter, null); println(); } @@ -134,54 +135,62 @@ class CodeWriter extends BasicWriter { } public Void visitBranch(Instruction instr, int offset, Void p) { - print("\t" + (instr.getPC() + offset)); + print((instr.getPC() + offset)); return null; } public Void visitConstantPoolRef(Instruction instr, int index, Void p) { - print("\t#" + index + "; //"); + print("#" + index + ";"); + tab(); + print("// "); printConstant(index); return null; } public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) { - print("\t#" + index + ", " + value + "; //"); + print("#" + index + ", " + value + ";"); + tab(); + print("// "); printConstant(index); return null; } public Void visitLocal(Instruction instr, int index, Void p) { - print("\t" + index); + print(index); return null; } public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) { - print("\t" + index + ", " + value); + print(index + ", " + value); return null; } public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets) { int pc = instr.getPC(); - print("{ //" + npairs); + print("{ // " + npairs); + indent(+1); for (int i = 0; i < npairs; i++) { - print("\n\t\t" + matches[i] + ": " + (pc + offsets[i]) + ";"); + print("\n" + matches[i] + ": " + (pc + offsets[i]) + ";"); } - print("\n\t\tdefault: " + (pc + default_) + " }"); + print("\ndefault: " + (pc + default_) + " }"); + indent(-1); return null; } public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets) { int pc = instr.getPC(); print("{ //" + low + " to " + high); + indent(+1); for (int i = 0; i < offsets.length; i++) { - print("\n\t\t" + (low + i) + ": " + (pc + offsets[i]) + ";"); + print("\n" + (low + i) + ": " + (pc + offsets[i]) + ";"); } - print("\n\t\tdefault: " + (pc + default_) + " }"); + print("\ndefault: " + (pc + default_) + " }"); + indent(-1); return null; } public Void visitValue(Instruction instr, int value, Void p) { - print("\t" + value); + print(value); return null; } @@ -193,13 +202,13 @@ class CodeWriter extends BasicWriter { public void writeExceptionTable(Code_attribute attr) { if (attr.exception_table_langth > 0) { - println(" Exception table:"); - println(" from to target type"); + println("Exception table:"); + indent(+1); + println(" from to target type"); for (int i = 0; i < attr.exception_table.length; i++) { Code_attribute.Exception_data handler = attr.exception_table[i]; - printFixedWidthInt(handler.start_pc, 6); - printFixedWidthInt(handler.end_pc, 6); - printFixedWidthInt(handler.handler_pc, 6); + print(String.format(" %5d %5d %5d", + handler.start_pc, handler.end_pc, handler.handler_pc)); print(" "); int catch_type = handler.catch_type; if (catch_type == 0) { @@ -207,9 +216,9 @@ class CodeWriter extends BasicWriter { } else { print("Class "); println(constantWriter.stringValue(catch_type)); - println(""); } } + indent(-1); } } @@ -218,13 +227,6 @@ class CodeWriter extends BasicWriter { constantWriter.write(index); } - private void printFixedWidthInt(int n, int width) { - String s = String.valueOf(n); - for (int i = s.length(); i < width; i++) - print(" "); - print(s); - } - private List getDetailWriters(Code_attribute attr) { List detailWriters = new ArrayList(); diff --git a/langtools/src/share/classes/com/sun/tools/javap/ConstantWriter.java b/langtools/src/share/classes/com/sun/tools/javap/ConstantWriter.java index c84cc57a0d4..5a53beb33ed 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/ConstantWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/ConstantWriter.java @@ -62,7 +62,9 @@ public class ConstantWriter extends BasicWriter { protected void writeConstantPool(ConstantPool constant_pool) { ConstantPool.Visitor v = new ConstantPool.Visitor() { public Integer visitClass(CONSTANT_Class_info info, Void p) { - println("#" + info.name_index + ";\t// " + stringValue(info)); + print("#" + info.name_index + ";"); + tab(); + println("// " + stringValue(info)); return 1; } @@ -72,7 +74,9 @@ public class ConstantWriter extends BasicWriter { } public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) { - println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info)); + print("#" + info.class_index + ".#" + info.name_and_type_index + ";"); + tab(); + println("// " + stringValue(info)); return 1; } @@ -87,7 +91,9 @@ public class ConstantWriter extends BasicWriter { } public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) { - println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info)); + print("#" + info.class_index + ".#" + info.name_and_type_index + ";"); + tab(); + println("// " + stringValue(info)); return 1; } @@ -97,18 +103,23 @@ public class ConstantWriter extends BasicWriter { } public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) { - String tab = (options.compat ? "" : "\t"); // BUG 6622232 javap gets whitespace confused - println("#" + info.name_index + ":#" + info.type_index + ";" + tab + "// " + stringValue(info)); + print("#" + info.name_index + ":#" + info.type_index + ";"); + tab(); + println("// " + stringValue(info)); return 1; } public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) { - println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info)); + print("#" + info.class_index + ".#" + info.name_and_type_index + ";"); + tab(); + println("// " + stringValue(info)); return 1; } public Integer visitString(CONSTANT_String_info info, Void p) { - println("#" + info.string_index + ";\t// " + stringValue(info)); + print("#" + info.string_index + ";"); + tab(); + println("// " + stringValue(info)); return 1; } @@ -118,17 +129,21 @@ public class ConstantWriter extends BasicWriter { } }; - println(" Constant pool:"); + println("Constant pool:"); + indent(+1); + int width = String.valueOf(constant_pool.size()).length() + 1; int cpx = 1; while (cpx < constant_pool.size()) { + print(String.format("const %" + width + "s", ("#" + cpx))); try { CPInfo cpInfo = constant_pool.get(cpx); - print("const #" + cpx + " = " + tagName(cpInfo.getTag()) + "\t"); + print(String.format(" = %-15s ", tagName(cpInfo.getTag()))); cpx += cpInfo.accept(v, null); } catch (ConstantPool.InvalidIndex ex) { - print("const #" + cpx); // should not happen + // should not happen } } + indent(-1); } protected void write(int cpx) { diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index f86534f923c..39e927559bf 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -295,6 +295,38 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { void process(JavapTask task, String opt, String arg) { task.options.showInnerClasses = true; } + }, + + new Option(false, "-XDindent:") { + @Override + boolean matches(String opt) { + int sep = opt.indexOf(":"); + return sep != -1 && super.matches(opt.substring(0, sep + 1)); + } + + void process(JavapTask task, String opt, String arg) throws BadArgs { + int sep = opt.indexOf(":"); + try { + task.options.indentWidth = Integer.valueOf(opt.substring(sep + 1)); + } catch (NumberFormatException e) { + } + } + }, + + new Option(false, "-XDtab:") { + @Override + boolean matches(String opt) { + int sep = opt.indexOf(":"); + return sep != -1 && super.matches(opt.substring(0, sep + 1)); + } + + void process(JavapTask task, String opt, String arg) throws BadArgs { + int sep = opt.indexOf(":"); + try { + task.options.tabColumn = Integer.valueOf(opt.substring(sep + 1)); + } catch (NumberFormatException e) { + } + } } }; diff --git a/langtools/src/share/classes/com/sun/tools/javap/Options.java b/langtools/src/share/classes/com/sun/tools/javap/Options.java index e6b37345582..0ff78a7edd2 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/Options.java +++ b/langtools/src/share/classes/com/sun/tools/javap/Options.java @@ -86,6 +86,8 @@ public class Options { public boolean showConstants; public boolean sysInfo; public boolean showInnerClasses; + public int indentWidth = 2; // #spaces per indentWidth level + public int tabColumn = 40; // column number for comments public boolean compat; // bug-for-bug compatibility mode with old javap public boolean jsr277; From c857f977c3b496e30ccf5c0d1ae33c07076ce550 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 4 Aug 2009 19:18:15 -0700 Subject: [PATCH 046/102] 6868160: (process) Use vfork, not fork, on Linux to avoid swap exhaustion Boldly go where no jdk has dared go before Reviewed-by: michaelm --- .../solaris/native/java/lang/UNIXProcess_md.c | 200 ++++++++++++------ 1 file changed, 138 insertions(+), 62 deletions(-) diff --git a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c index d0226d07735..8b0147bdfb7 100644 --- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c @@ -50,27 +50,72 @@ #include /* - * (Hopefully temporarily) disable the clone-exec feature pending - * further investigation and bug-fixing. - * 32-bit (but not 64-bit) Linux fails on the program - * Runtime.getRuntime().exec("/bin/true").waitFor(); - * with: - * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536 - * # Error: pthread_getattr_np failed with errno = 3 (ESRCH) - * Linux kernel/pthread gurus are invited to figure this out. + * There are 3 possible strategies we might use to "fork": + * + * - fork(2). Very portable and reliable but subject to + * failure due to overcommit (see the documentation on + * /proc/sys/vm/overcommit_memory in Linux proc(5)). + * This is the ancient problem of spurious failure whenever a large + * process starts a small subprocess. + * + * - vfork(). Using this is scary because all relevant man pages + * contain dire warnings, e.g. Linux vfork(2). But at least it's + * documented in the glibc docs and is standardized by XPG4. + * http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html + * On Linux, one might think that vfork() would be implemented using + * the clone system call with flag CLONE_VFORK, but in fact vfork is + * a separate system call (which is a good sign, suggesting that + * vfork will continue to be supported at least on Linux). + * Another good sign is that glibc implements posix_spawn using + * vfork whenever possible. Note that we cannot use posix_spawn + * ourselves because there's no reliable way to close all inherited + * file descriptors. + * + * - clone() with flags CLONE_VM but not CLONE_THREAD. clone() is + * Linux-specific, but this ought to work - at least the glibc + * sources contain code to handle different combinations of CLONE_VM + * and CLONE_THREAD. However, when this was implemented, it + * appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with + * the simple program + * Runtime.getRuntime().exec("/bin/true").waitFor(); + * with: + * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536 + * # Error: pthread_getattr_np failed with errno = 3 (ESRCH) + * We believe this is a glibc bug, reported here: + * http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311 + * but the glibc maintainers closed it as WONTFIX. + * + * Based on the above analysis, we are currently using vfork() on + * Linux and fork() on other Unix systems, but the code to use clone() + * remains. */ -#define USE_CLONE 0 -#ifndef USE_CLONE -#ifdef __linux__ -#define USE_CLONE 1 -#else -#define USE_CLONE 0 -#endif +#define START_CHILD_USE_CLONE 0 /* clone() currently disabled; see above. */ + +#ifndef START_CHILD_USE_CLONE + #ifdef __linux__ + #define START_CHILD_USE_CLONE 1 + #else + #define START_CHILD_USE_CLONE 0 + #endif #endif -#if USE_CLONE +/* By default, use vfork() on Linux. */ +#ifndef START_CHILD_USE_VFORK + #ifdef __linux__ + #define START_CHILD_USE_VFORK 1 + #else + #define START_CHILD_USE_VFORK 0 + #endif +#endif + +#if START_CHILD_USE_CLONE #include +#define START_CHILD_SYSTEM_CALL "clone" +#elif START_CHILD_USE_VFORK +#define START_CHILD_SYSTEM_CALL "vfork" +#else +#define START_CHILD_SYSTEM_CALL "fork" #endif #ifndef STDIN_FILENO @@ -95,6 +140,20 @@ #define FAIL_FILENO (STDERR_FILENO + 1) +/* This is one of the rare times it's more portable to declare an + * external symbol explicitly, rather than via a system header. + * The declaration is standardized as part of UNIX98, but there is + * no standard (not even de-facto) header file where the + * declaration is to be found. See: + * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html + * + * "All identifiers in this volume of IEEE Std 1003.1-2001, except + * environ, are defined in at least one of the headers" (!) + */ +extern char **environ; + + static void setSIGCHLDHandler(JNIEnv *env) { @@ -434,13 +493,13 @@ execve_with_shell_fallback(const char *file, const char *argv[], const char *const envp[]) { -#if USE_CLONE +#if START_CHILD_USE_CLONE || START_CHILD_USE_VFORK + /* shared address space; be very careful. */ execve(file, (char **) argv, (char **) envp); if (errno == ENOEXEC) execve_as_traditional_shell_script(file, argv, envp); #else - /* Our address space is unshared, so can mutate environ. */ - extern char **environ; + /* unshared address space; we can mutate environ. */ environ = (char **) envp; execvp(file, (char **) argv); #endif @@ -458,19 +517,6 @@ JDK_execvpe(const char *file, const char *argv[], const char *const envp[]) { - /* This is one of the rare times it's more portable to declare an - * external symbol explicitly, rather than via a system header. - * The declaration is standardized as part of UNIX98, but there is - * no standard (not even de-facto) header file where the - * declaration is to be found. See: - * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html - * - * "All identifiers in this volume of IEEE Std 1003.1-2001, except - * environ, are defined in at least one of the headers" (!) - */ - extern char **environ; - if (envp == NULL || (char **) envp == environ) { execvp(file, (char **) argv); return; @@ -589,6 +635,9 @@ typedef struct _ChildStuff const char **envv; const char *pdir; jboolean redirectErrorStream; +#if START_CHILD_USE_CLONE + void *clone_stack; +#endif } ChildStuff; static void @@ -668,6 +717,55 @@ childProcess(void *arg) return 0; /* Suppress warning "no return value from function" */ } +/** + * Start a child process running function childProcess. + * This function only returns in the parent. + * We are unusually paranoid; use of clone/vfork is + * especially likely to tickle gcc/glibc bugs. + */ +#ifdef __attribute_noinline__ /* See: sys/cdefs.h */ +__attribute_noinline__ +#endif +static pid_t +startChild(ChildStuff *c) { +#if START_CHILD_USE_CLONE +#define START_CHILD_CLONE_STACK_SIZE (64 * 1024) + /* + * See clone(2). + * Instead of worrying about which direction the stack grows, just + * allocate twice as much and start the stack in the middle. + */ + if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL) + /* errno will be set to ENOMEM */ + return -1; + return clone(childProcess, + c->clone_stack + START_CHILD_CLONE_STACK_SIZE, + CLONE_VFORK | CLONE_VM | SIGCHLD, c); +#else + #if START_CHILD_USE_VFORK + /* + * We separate the call to vfork into a separate function to make + * very sure to keep stack of child from corrupting stack of parent, + * as suggested by the scary gcc warning: + * warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork' + */ + volatile pid_t resultPid = vfork(); + #else + /* + * From Solaris fork(2): In Solaris 10, a call to fork() is + * identical to a call to fork1(); only the calling thread is + * replicated in the child process. This is the POSIX-specified + * behavior for fork(). + */ + pid_t resultPid = fork(); + #endif + if (resultPid == 0) + childProcess(c); + assert(resultPid != 0); /* childProcess never returns */ + return resultPid; +#endif /* ! START_CHILD_USE_CLONE */ +} + JNIEXPORT jint JNICALL Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, jobject process, @@ -680,9 +778,6 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, { int errnum; int resultPid = -1; -#if USE_CLONE - void *clone_stack = NULL; -#endif int in[2], out[2], err[2], fail[2]; jint *fds = NULL; const char *pprog = NULL; @@ -696,6 +791,9 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, c->argv = NULL; c->envv = NULL; c->pdir = NULL; +#if START_CHILD_USE_CLONE + c->clone_stack = NULL; +#endif /* Convert prog + argBlock into a char ** argv. * Add one word room for expansion of argv for use by @@ -741,36 +839,14 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, c->redirectErrorStream = redirectErrorStream; - { -#if USE_CLONE - /* See clone(2). - * Instead of worrying about which direction the stack grows, just - * allocate twice as much and start the stack in the middle. */ - const int stack_size = 64 * 1024; - if ((clone_stack = NEW(char, 2 * stack_size)) == NULL) goto Catch; - resultPid = clone(childProcess, clone_stack + stack_size, - /* CLONE_VFORK | // works, but unnecessary */ - CLONE_VM | SIGCHLD, c); -#else - /* From fork(2): In Solaris 10, a call to fork() is identical - * to a call to fork1(); only the calling thread is replicated - * in the child process. This is the POSIX-specified behavior - * for fork(). */ - resultPid = fork(); - if (resultPid == 0) { - childProcess(c); - assert(0); /* childProcess must not return */ - } -#endif - } + resultPid = startChild(c); + assert(resultPid != 0); if (resultPid < 0) { - throwIOException(env, errno, "Fork failed"); + throwIOException(env, errno, START_CHILD_SYSTEM_CALL " failed"); goto Catch; } - /* parent process */ - close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ switch (readFully(fail[0], &errnum, sizeof(errnum))) { @@ -789,8 +865,8 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, fds[2] = (err[0] != -1) ? err[0] : -1; Finally: -#if USE_CLONE - free(clone_stack); +#if START_CHILD_USE_CLONE + free(c->clone_stack); #endif /* Always clean up the child's side of the pipes */ From 31e53b285c6c2867bdb583e26e38233b4e5f406d Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Tue, 4 Aug 2009 19:18:15 -0700 Subject: [PATCH 047/102] 6856590: (process) Use RESTARTABLE in UNIXProcess_md.c Wrap all system calls with RESTARTABLE Reviewed-by: michaelm --- .../solaris/native/java/lang/UNIXProcess_md.c | 99 +++++++++++++------ 1 file changed, 70 insertions(+), 29 deletions(-) diff --git a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c index 8b0147bdfb7..3e1895926df 100644 --- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c @@ -140,6 +140,13 @@ #define FAIL_FILENO (STDERR_FILENO + 1) +/* TODO: Refactor. */ +#define RESTARTABLE(_cmd, _result) do { \ + do { \ + _result = _cmd; \ + } while((_result == -1) && (errno == EINTR)); \ +} while(0) + /* This is one of the rare times it's more portable to declare an * external symbol explicitly, rather than via a system header. * The declaration is standardized as part of UNIX98, but there is @@ -342,6 +349,36 @@ Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env, } } +static ssize_t +restartableWrite(int fd, const void *buf, size_t count) +{ + ssize_t result; + RESTARTABLE(write(fd, buf, count), result); + return result; +} + +static int +restartableDup2(int fd_from, int fd_to) +{ + int err; + RESTARTABLE(dup2(fd_from, fd_to), err); + return err; +} + +static int +restartableClose(int fd) +{ + int err; + RESTARTABLE(close(fd), err); + return err; +} + +static int +closeSafely(int fd) +{ + return (fd == -1) ? 0 : restartableClose(fd); +} + static int isAsciiDigit(char c) { @@ -362,8 +399,8 @@ closeDescriptors(void) * the lowest numbered file descriptor, just like open(). So we * close a couple explicitly. */ - close(from_fd); /* for possible use by opendir() */ - close(from_fd + 1); /* another one for good luck */ + restartableClose(from_fd); /* for possible use by opendir() */ + restartableClose(from_fd + 1); /* another one for good luck */ if ((dp = opendir("/proc/self/fd")) == NULL) return 0; @@ -375,7 +412,7 @@ closeDescriptors(void) int fd; if (isAsciiDigit(dirp->d_name[0]) && (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2) - close(fd); + restartableClose(fd); } closedir(dp); @@ -383,13 +420,15 @@ closeDescriptors(void) return 1; } -static void +static int moveDescriptor(int fd_from, int fd_to) { if (fd_from != fd_to) { - dup2(fd_from, fd_to); - close(fd_from); + if ((restartableDup2(fd_from, fd_to) == -1) || + (restartableClose(fd_from) == -1)) + return -1; } + return 0; } static const char * @@ -586,13 +625,6 @@ JDK_execvpe(const char *file, } } -static void -closeSafely(int fd) -{ - if (fd != -1) - close(fd); -} - /* * Reads nbyte bytes from file descriptor fd into buf, * The read operation is retried in case of EINTR or partial reads. @@ -661,31 +693,40 @@ childProcess(void *arg) /* Close the parent sides of the pipes. Closing pipe fds here is redundant, since closeDescriptors() would do it anyways, but a little paranoia is a good thing. */ - closeSafely(p->in[1]); - closeSafely(p->out[0]); - closeSafely(p->err[0]); - closeSafely(p->fail[0]); + if ((closeSafely(p->in[1]) == -1) || + (closeSafely(p->out[0]) == -1) || + (closeSafely(p->err[0]) == -1) || + (closeSafely(p->fail[0]) == -1)) + goto WhyCantJohnnyExec; /* Give the child sides of the pipes the right fileno's. */ /* Note: it is possible for in[0] == 0 */ - moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], STDIN_FILENO); - moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], STDOUT_FILENO); + if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], + STDIN_FILENO) == -1) || + (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], + STDOUT_FILENO) == -1)) + goto WhyCantJohnnyExec; if (p->redirectErrorStream) { - closeSafely(p->err[1]); - dup2(STDOUT_FILENO, STDERR_FILENO); + if ((closeSafely(p->err[1]) == -1) || + (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1)) + goto WhyCantJohnnyExec; } else { - moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], STDERR_FILENO); + if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], + STDERR_FILENO) == -1) + goto WhyCantJohnnyExec; } - moveDescriptor(p->fail[1], FAIL_FILENO); + if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1) + goto WhyCantJohnnyExec; /* close everything */ if (closeDescriptors() == 0) { /* failed, close the old way */ int max_fd = (int)sysconf(_SC_OPEN_MAX); - int i; - for (i = FAIL_FILENO + 1; i < max_fd; i++) - close(i); + int fd; + for (fd = FAIL_FILENO + 1; fd < max_fd; fd++) + if (restartableClose(fd) == -1 && errno != EBADF) + goto WhyCantJohnnyExec; } /* change to the new working directory */ @@ -710,9 +751,9 @@ childProcess(void *arg) */ { int errnum = errno; - write(FAIL_FILENO, &errnum, sizeof(errnum)); + restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum)); } - close(FAIL_FILENO); + restartableClose(FAIL_FILENO); _exit(-1); return 0; /* Suppress warning "no return value from function" */ } @@ -847,7 +888,7 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, goto Catch; } - close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ + restartableClose(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ switch (readFully(fail[0], &errnum, sizeof(errnum))) { case 0: break; /* Exec succeeded */ From ea9763ee2450a90e1308d006b6f9a38e1b920376 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 5 Aug 2009 07:43:50 -0700 Subject: [PATCH 048/102] 6868553: 6867671 breaks some tests Reviewed-by: mcimadamore --- .../share/classes/com/sun/tools/javap/AttributeWriter.java | 2 +- langtools/test/tools/javac/code/ArrayClone.java | 2 +- langtools/test/tools/javap/4111861/T4111861.java | 2 +- langtools/test/tools/javap/T4884240.java | 6 +++--- langtools/test/tools/javap/T4975569.java | 4 ++-- langtools/test/tools/javap/stackmap/T6271292.sh | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java index 47c8e460188..42567342b31 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -329,7 +329,7 @@ public class AttributeWriter extends BasicWriter print("InnerClass"); else print("InnerClasses"); - println(": "); + println(":"); indent(+1); } diff --git a/langtools/test/tools/javac/code/ArrayClone.java b/langtools/test/tools/javac/code/ArrayClone.java index ce1126bcf14..650f2604b8d 100644 --- a/langtools/test/tools/javac/code/ArrayClone.java +++ b/langtools/test/tools/javac/code/ArrayClone.java @@ -48,7 +48,7 @@ public class ArrayClone { System.out.println(out); for (String line: out.split("\n")) { - String match = "[ \t]+[0-9]+:[ \t]+invokevirtual[ \t]+#[0-9]+; //Method \"\\[Ljava/lang/String;\".clone:\\(\\)Ljava/lang/Object;"; + String match = "[ \t]+[0-9]+:[ \t]+invokevirtual[ \t]+#[0-9]+;[ \t]+// Method \"\\[Ljava/lang/String;\".clone:\\(\\)Ljava/lang/Object;"; if (line.matches(match)) return; } diff --git a/langtools/test/tools/javap/4111861/T4111861.java b/langtools/test/tools/javap/4111861/T4111861.java index b722d80b41a..6491ed9900d 100644 --- a/langtools/test/tools/javap/4111861/T4111861.java +++ b/langtools/test/tools/javap/4111861/T4111861.java @@ -89,7 +89,7 @@ public class T4111861 { String line; while ((line = in.readLine()) != null) { if (line.indexOf("public static final") > 0) { - sb.append(line); + sb.append(line.trim()); sb.append('\n'); } } diff --git a/langtools/test/tools/javap/T4884240.java b/langtools/test/tools/javap/T4884240.java index f2f36167760..91256aa82ee 100644 --- a/langtools/test/tools/javap/T4884240.java +++ b/langtools/test/tools/javap/T4884240.java @@ -46,9 +46,9 @@ public class T4884240 { pw.close(); String[] lines = sw.toString().split("\n"); if (lines.length < 3 - || !lines[0].startsWith("Classfile") - || !lines[1].startsWith("Last modified") - || !lines[2].startsWith("MD5")) { + || !lines[0].trim().startsWith("Classfile") + || !lines[1].trim().startsWith("Last modified") + || !lines[2].trim().startsWith("MD5")) { System.out.println(sw); throw new Exception("unexpected output"); } diff --git a/langtools/test/tools/javap/T4975569.java b/langtools/test/tools/javap/T4975569.java index 4b029c6c118..48a5777bc70 100644 --- a/langtools/test/tools/javap/T4975569.java +++ b/langtools/test/tools/javap/T4975569.java @@ -40,10 +40,10 @@ public class T4975569 verify("T4975569$Anno", "flags: ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION"); verify("T4975569$E", "flags: ACC_FINAL, ACC_SUPER, ACC_ENUM"); verify("T4975569$S", "flags: ACC_BRIDGE, ACC_SYNTHETIC", - "InnerClasses: \n static"); + "InnerClasses:\n static"); verify("T4975569$V", "void m(java.lang.String...)", "flags: ACC_VARARGS"); - verify("T4975569$Prot", "InnerClasses: \n protected"); + verify("T4975569$Prot", "InnerClasses:\n protected"); //verify("T4975569$Priv", "InnerClasses"); if (errors > 0) throw new Error(errors + " found."); diff --git a/langtools/test/tools/javap/stackmap/T6271292.sh b/langtools/test/tools/javap/stackmap/T6271292.sh index 2726b1acfc4..7a0e1abbf54 100644 --- a/langtools/test/tools/javap/stackmap/T6271292.sh +++ b/langtools/test/tools/javap/stackmap/T6271292.sh @@ -75,7 +75,7 @@ grep "frame_type" "${JAVAPFILE}" > "${OUTFILE}" grep "offset_delta" "${JAVAPFILE}" >> "${OUTFILE}" grep "stack = " "${JAVAPFILE}" >> "${OUTFILE}" grep "locals = " "${JAVAPFILE}" >> "${OUTFILE}" -diff "${OUTFILE}" "${TESTSRC}${FS}T6271292.out" +diff -w "${OUTFILE}" "${TESTSRC}${FS}T6271292.out" result="$?" if [ "$result" -eq 0 ] then From 9e26dc467b2cb282f987e75a5f122ce881b1d0f5 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 5 Aug 2009 08:38:18 -0700 Subject: [PATCH 049/102] 6729471: javap should accept class files on the command line Reviewed-by: mcimadamore --- .../com/sun/tools/javap/JavapTask.java | 131 ++++++++++++++---- langtools/test/tools/javap/T6729471.java | 109 +++++++++++++++ 2 files changed, 216 insertions(+), 24 deletions(-) create mode 100644 langtools/test/tools/javap/T6729471.java diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java index 39e927559bf..1c26fd4028f 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -32,8 +32,10 @@ import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; +import java.io.Reader; import java.io.StringWriter; import java.io.Writer; +import java.net.URI; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -49,6 +51,8 @@ import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.NestingKind; import javax.tools.Diagnostic; import javax.tools.DiagnosticListener; import javax.tools.JavaFileManager; @@ -57,6 +61,9 @@ import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import com.sun.tools.classfile.*; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; /** * "Main" class for javap, normally accessed from the command line @@ -607,30 +614,10 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { protected boolean writeClass(ClassWriter classWriter, String className) throws IOException, ConstantPoolException { - JavaFileObject fo; - if (className.endsWith(".class")) { - if (fileManager instanceof StandardJavaFileManager) { - StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; - fo = sfm.getJavaFileObjects(className).iterator().next(); - } else { - reportError("err.not.standard.file.manager", className); - return false; - } - } else { - fo = getClassFileObject(className); - if (fo == null) { - // see if it is an inner class, by replacing dots to $, starting from the right - String cn = className; - int lastDot; - while (fo == null && (lastDot = cn.lastIndexOf(".")) != -1) { - cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1); - fo = getClassFileObject(cn); - } - } - if (fo == null) { - reportError("err.class.not.found", className); - return false; - } + JavaFileObject fo = open(className); + if (fo == null) { + reportError("err.class.not.found", className); + return false; } ClassFileInfo cfInfo = read(fo); @@ -675,6 +662,102 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages { return true; } + protected JavaFileObject open(String className) throws IOException { + // for compatibility, first see if it is a class name + JavaFileObject fo = getClassFileObject(className); + if (fo != null) + return fo; + + // see if it is an inner class, by replacing dots to $, starting from the right + String cn = className; + int lastDot; + while ((lastDot = cn.lastIndexOf(".")) != -1) { + cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1); + fo = getClassFileObject(cn); + if (fo != null) + return fo; + } + + if (!className.endsWith(".class")) + return null; + + if (fileManager instanceof StandardJavaFileManager) { + StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager; + fo = sfm.getJavaFileObjects(className).iterator().next(); + if (fo != null && fo.getLastModified() != 0) { + return fo; + } + } + + // see if it is a URL, and if so, wrap it in just enough of a JavaFileObject + // to suit javap's needs + if (className.matches("^[A-Za-z]+:.*")) { + try { + final URI uri = new URI(className); + final URL url = uri.toURL(); + final URLConnection conn = url.openConnection(); + return new JavaFileObject() { + public Kind getKind() { + return JavaFileObject.Kind.CLASS; + } + + public boolean isNameCompatible(String simpleName, Kind kind) { + throw new UnsupportedOperationException(); + } + + public NestingKind getNestingKind() { + throw new UnsupportedOperationException(); + } + + public Modifier getAccessLevel() { + throw new UnsupportedOperationException(); + } + + public URI toUri() { + return uri; + } + + public String getName() { + return url.toString(); + } + + public InputStream openInputStream() throws IOException { + return conn.getInputStream(); + } + + public OutputStream openOutputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + public Reader openReader(boolean ignoreEncodingErrors) throws IOException { + throw new UnsupportedOperationException(); + } + + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + throw new UnsupportedOperationException(); + } + + public Writer openWriter() throws IOException { + throw new UnsupportedOperationException(); + } + + public long getLastModified() { + return conn.getLastModified(); + } + + public boolean delete() { + throw new UnsupportedOperationException(); + } + + }; + } catch (URISyntaxException ignore) { + } catch (IOException ignore) { + } + } + + return null; + } + public static class ClassFileInfo { ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) { this.fo = fo; diff --git a/langtools/test/tools/javap/T6729471.java b/langtools/test/tools/javap/T6729471.java new file mode 100644 index 00000000000..964850e42df --- /dev/null +++ b/langtools/test/tools/javap/T6729471.java @@ -0,0 +1,109 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + + +/* + * @test + * @bug 6729471 + * @summary javap does not output inner interfaces of an interface + */ + +import java.io.*; +import java.util.*; + +public class T6729471 +{ + public static void main(String... args) { + new T6729471().run(); + } + + void run() { + // simple class + verify("java.util.Map", + "public abstract boolean containsKey(java.lang.Object)"); + + // inner class + verify("java.util.Map.Entry", + "public abstract K getKey()"); + + // file name + verify("../classes/tools/javap/T6729471.class", + "public static void main(java.lang.String...)"); + + // file url + verify("file:../classes/tools/javap/T6729471.class", + "public static void main(java.lang.String...)"); + + // jar url: rt.jar + File java_home = new File(System.getProperty("java.home")); + if (java_home.getName().equals("jre")) + java_home = java_home.getParentFile(); + File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar"); + verify("jar:file:" + rt_jar + "!/java/util/Map.class", + "public abstract boolean containsKey(java.lang.Object)"); + + // jar url: ct.sym, if it exists + File ct_sym = new File(new File(java_home, "lib"), "ct.sym"); + if (ct_sym.exists()) { + verify("jar:file:" + ct_sym + "!/META-INF/sym/rt.jar/java/util/Map.class", + "public abstract boolean containsKey(java.lang.Object)"); + } else + System.err.println("warning: ct.sym not found"); + + if (errors > 0) + throw new Error(errors + " found."); + } + + void verify(String className, String... expects) { + String output = javap(className); + for (String expect: expects) { + if (output.indexOf(expect)< 0) + error(expect + " not found"); + } + } + + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; + + String javap(String className) { + String testClasses = System.getProperty("test.classes", "."); + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + String[] args = { "-classpath", testClasses, className }; + int rc = com.sun.tools.javap.Main.run(args, out); + out.close(); + String output = sw.toString(); + System.out.println("class " + className); + System.out.println(output); + if (rc != 0) + throw new Error("javap failed. rc=" + rc); + if (output.indexOf("Error:") != -1) + throw new Error("javap reported error."); + return output; + } +} + From 8790c489e1e9fc78ec7976252a32c7455d95ef5d Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 5 Aug 2009 13:17:30 -0600 Subject: [PATCH 050/102] 6868533: 3/4 JDI: remove '-source 1.5' and '-target 1.5' options from com.sun.jdi tests We are long past needing to make sure these tests can build on Tiger/JDK1.5.0. Reviewed-by: tbell --- jdk/test/com/sun/jdi/EnumTest.java | 2 +- jdk/test/com/sun/jdi/GenericsTest.java | 2 +- jdk/test/com/sun/jdi/JdbVarargsTest.sh | 1 - jdk/test/com/sun/jdi/StepTest.java | 2 +- jdk/test/com/sun/jdi/UTF8Test.java | 2 +- jdk/test/com/sun/jdi/VarargsTest.java | 2 +- 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/jdk/test/com/sun/jdi/EnumTest.java b/jdk/test/com/sun/jdi/EnumTest.java index be06c0f4524..51d3a976ad5 100644 --- a/jdk/test/com/sun/jdi/EnumTest.java +++ b/jdk/test/com/sun/jdi/EnumTest.java @@ -29,7 +29,7 @@ * @author jjh * * @run build TestScaffold VMConnection TargetListener TargetAdapter - * @run compile -source 1.5 -target 1.5 -g EnumTest.java + * @run compile -g EnumTest.java * @run main EnumTest */ import com.sun.jdi.*; diff --git a/jdk/test/com/sun/jdi/GenericsTest.java b/jdk/test/com/sun/jdi/GenericsTest.java index 2220dd7bbfc..5156e9d8e09 100644 --- a/jdk/test/com/sun/jdi/GenericsTest.java +++ b/jdk/test/com/sun/jdi/GenericsTest.java @@ -29,7 +29,7 @@ * @author jjh * * @run build TestScaffold VMConnection TargetListener TargetAdapter - * @run compile -source 1.5 -target 1.5 -g GenericsTest.java + * @run compile -g GenericsTest.java * @run main GenericsTest */ import com.sun.jdi.*; diff --git a/jdk/test/com/sun/jdi/JdbVarargsTest.sh b/jdk/test/com/sun/jdi/JdbVarargsTest.sh index 72d9561f54c..82e0b18e60e 100644 --- a/jdk/test/com/sun/jdi/JdbVarargsTest.sh +++ b/jdk/test/com/sun/jdi/JdbVarargsTest.sh @@ -32,7 +32,6 @@ # @run shell JdbVarargsTest.sh classname=JdbVarargsTest -compileOptions="-source 1.5 -target 1.5" createJavaFile() { cat < $classname.java.1 diff --git a/jdk/test/com/sun/jdi/StepTest.java b/jdk/test/com/sun/jdi/StepTest.java index 9c2344d09db..041507a8b9d 100644 --- a/jdk/test/com/sun/jdi/StepTest.java +++ b/jdk/test/com/sun/jdi/StepTest.java @@ -27,7 +27,7 @@ * @author Gordon Hirsch * * @run build TestScaffold VMConnection TargetAdapter TargetListener - * @run compile -g -target 1.5 MethodCalls.java + * @run compile -g MethodCalls.java * @run compile -g MethodCallsReflection.java * @run compile -g ControlFlow.java * @run build StepTest diff --git a/jdk/test/com/sun/jdi/UTF8Test.java b/jdk/test/com/sun/jdi/UTF8Test.java index b7b28665894..4396770e093 100644 --- a/jdk/test/com/sun/jdi/UTF8Test.java +++ b/jdk/test/com/sun/jdi/UTF8Test.java @@ -29,7 +29,7 @@ * @author jjh * * @run build TestScaffold VMConnection TargetListener TargetAdapter - * @run compile -g -source 1.5 UTF8Test.java + * @run compile -g UTF8Test.java * @run main UTF8Test */ diff --git a/jdk/test/com/sun/jdi/VarargsTest.java b/jdk/test/com/sun/jdi/VarargsTest.java index ed4323e2d4f..1ea51ad245b 100644 --- a/jdk/test/com/sun/jdi/VarargsTest.java +++ b/jdk/test/com/sun/jdi/VarargsTest.java @@ -29,7 +29,7 @@ * @author jjh * * @run build TestScaffold VMConnection TargetListener TargetAdapter - * @run compile -g -source 1.5 -target 1.5 VarargsTest.java + * @run compile -g VarargsTest.java * @run main VarargsTest */ import com.sun.jdi.*; From 9130e7d347313d51ad329eaa99d9a22549375f29 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:00 -0700 Subject: [PATCH 051/102] Added tag jdk7-b68 for changeset a3946f62adaa --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 7dc9b1b0dc4..887ebba35be 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -42,3 +42,4 @@ c7ed15ab92ce36a09d264a5e34025884b2d7607f jdk7-b62 e01380cd1de4ce048b87d059d238e5ab5e341947 jdk7-b65 6bad5e3fe50337d95b1416d744780d65bc570da6 jdk7-b66 c4523c6f82048f420bf0d57c4cd47976753b7d2c jdk7-b67 +e1b972ff53cd58f825791f8ed9b2deffd16e768c jdk7-b68 From d66b689a4b09422eaf74d61d89be950c2e193ac2 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:01 -0700 Subject: [PATCH 052/102] Added tag jdk7-b68 for changeset 0589e2ed45b3 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 3e1753626fb..28557923b83 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -42,3 +42,4 @@ d20e45cd539f20405ff843652069cfd7550c5ab3 jdk7-b63 97fd9b42f5c2d342b90d18f0a2b57e4117e39415 jdk7-b65 a821e059a961bcb02830280d51f6dd030425c066 jdk7-b66 a12ea7c7b497b4ba7830550095ef633bd6f43971 jdk7-b67 +5182bcc9c60cac429d1f7988676cec7320752be3 jdk7-b68 From 8fae4c547c8ebb42718b9c31a2ff9cab0273fe1b Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:05 -0700 Subject: [PATCH 053/102] Added tag jdk7-b68 for changeset 4ae7310eb37d --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index ad4c8f2596c..a7ee64a37aa 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -42,3 +42,4 @@ ba36394eb84b949b31212bdb32a518a8f92bab5b jdk7-b64 ba313800759b678979434d6da8ed3bf49eb8bea4 jdk7-b65 57c71ad0341b8b64ed20f81151eb7f06324f8894 jdk7-b66 18f526145aea355a9320b724373386fc2170f183 jdk7-b67 +d07e68298d4e17ebf93d8299e43fcc3ded26472a jdk7-b68 From 314304f9ba59ec1a3a5a16b635bc2d7cfef46230 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:10 -0700 Subject: [PATCH 054/102] Added tag jdk7-b68 for changeset 8cfea160b2e5 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f196582041b..4391dbd2d7d 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -42,3 +42,4 @@ a10eec7a1edf536f39b5828d8623054dbc62c2b7 jdk7-b64 008c662e0ee9a91aebb75e46b97de979083d5c1c jdk7-b65 22f9d5d5b5fe0f47048f41e6c6e54fee5edad0ec jdk7-b66 a033af8d824a408d3ac602205ecdefc128749e1e jdk7-b67 +83b2a9331383f9db7a49350d4cb13b7635f6b861 jdk7-b68 From a79bbfdcfef794597024b86dac830ab7a0041a9f Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:11 -0700 Subject: [PATCH 055/102] Added tag jdk7-b68 for changeset 7df0da9e6d70 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 36dc0d6feff..900795887f8 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -42,3 +42,4 @@ aaa25dfd3de68c6f1a1d3ef8c45fd99f76bca6dd jdk7-b64 aa22a1be5866a6608ba17a7a443945559409ae0f jdk7-b65 fa8712c099edd5c9a6b3ed9729353738004d388f jdk7-b66 faa13cd4d6cdcfb155da5ed23b0da6e0ed0f9ea8 jdk7-b67 +845fa487f0f72a9f232ead8315c0087a477a5a31 jdk7-b68 From ef226d3a7e7cb867684166fecfbc5f429ab7af8c Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Thu, 6 Aug 2009 10:25:29 -0700 Subject: [PATCH 056/102] Added tag jdk7-b68 for changeset 2974ea6ad890 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 2d35b7fcf82..e35171f3f7d 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -42,3 +42,4 @@ d8f23a81d46f47a4186f1044dd9e44841bbeab84 jdk7-b64 7e0056ded28c802609d2bd79bfcda551d72a3fec jdk7-b65 634f519d6f9a602b16bba1c7cd4a17242a8f6889 jdk7-b66 14b1a8ede95493fc53c37ff2626f1f98ce94d108 jdk7-b67 +95c1212b07e33b1b8c689b1d279d82ffd5a56e43 jdk7-b68 From 792cd2a88a9eb88aae1f4b682cbe439513bbd6e2 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Thu, 6 Aug 2009 17:16:31 -0700 Subject: [PATCH 057/102] 6865853: Additional code changes needed to build deploy using WXP SP2 and Visual Studio 2008 Reviewed-by: ohair --- jdk/src/windows/native/sun/jkernel/kernel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/windows/native/sun/jkernel/kernel.cpp b/jdk/src/windows/native/sun/jkernel/kernel.cpp index 354b47cf2b5..e67bb3a0595 100644 --- a/jdk/src/windows/native/sun/jkernel/kernel.cpp +++ b/jdk/src/windows/native/sun/jkernel/kernel.cpp @@ -116,11 +116,11 @@ char* getStringPlatformChars(JNIEnv* env, jstring jstr) { char *result = NULL; size_t len; const jchar* utf16 = env->GetStringChars(jstr, NULL); - len = wcstombs(NULL, utf16, env->GetStringLength(jstr) * 4) + 1; + len = wcstombs(NULL, (const wchar_t*)utf16, env->GetStringLength(jstr) * 4) + 1; if (len == -1) return NULL; result = (char*) malloc(len); - if (wcstombs(result, utf16, len) == -1) + if (wcstombs(result, (const wchar_t*)utf16, len) == -1) return NULL; env->ReleaseStringChars(jstr, utf16); return result; @@ -640,7 +640,7 @@ JNIEXPORT void JNICALL Java_sun_jkernel_DownloadManager_startBackgroundDownloadW } -void getParent(const TCHAR *path, TCHAR *dest) { +void getParent(TCHAR *path, TCHAR *dest) { char* lastSlash = max(strrchr(path, '\\'), strrchr(path, '/')); if (lastSlash == NULL) { *dest = NULL; From fc188b8b292d7f987191f68aba8267a92d892f99 Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Thu, 6 Aug 2009 17:56:59 -0700 Subject: [PATCH 058/102] 6867657: Many JSN tests do not run under cygwin Reviewed-by: ohair --- jdk/test/java/net/Authenticator/B4933582.sh | 10 ++-- .../ADatagramSocket.sh | 4 ++ jdk/test/java/net/Socket/OldSocketImpl.sh | 4 ++ jdk/test/java/net/URL/B5086147.sh | 4 ++ jdk/test/java/net/URL/runconstructor.sh | 4 ++ jdk/test/java/net/URLClassLoader/B5077773.sh | 4 ++ .../net/URLClassLoader/sealing/checksealed.sh | 12 +++-- .../java/net/URLConnection/6212146/test.sh | 4 ++ .../ClassLoaderDeadlock.sh | 6 ++- .../Security/ClassLoaderDeadlock/Deadlock.sh | 6 ++- .../java/security/Security/signedfirst/Dyn.sh | 6 ++- .../security/Security/signedfirst/Static.sh | 8 ++- .../crypto/SecretKeyFactory/FailOverTest.sh | 9 +++- .../javax/security/auth/Subject/doAs/Test.sh | 5 ++ .../lib/security/java.policy/Ext_AllPolicy.sh | 6 +++ jdk/test/sun/net/www/MarkResetTest.sh | 4 ++ .../ChunkedInputStream/ChunkedCharEncoding.sh | 4 ++ .../sun/net/www/http/HttpClient/RetryPost.sh | 4 ++ jdk/test/sun/net/www/protocol/jar/B5105410.sh | 4 ++ .../sun/net/www/protocol/jar/jarbug/run.sh | 49 +++++++++++++++---- .../pkcs11/Provider/ConfigQuotedString.sh | 14 ++++++ .../sun/security/pkcs11/Provider/Login.sh | 14 ++++++ .../PolicyFile/getinstance/getinstance.sh | 4 ++ .../ssl/SSLSocketImpl/NotifyHandshakeTest.sh | 23 ++++++--- .../https/HttpsURLConnection/PostThruProxy.sh | 7 ++- .../PostThruProxyWithAuth.sh | 8 ++- .../security/tools/jarsigner/AlgOptions.sh | 7 +++ .../security/tools/jarsigner/PercentSign.sh | 7 +++ .../sun/security/tools/jarsigner/oldsig.sh | 7 +++ .../security/tools/keytool/AltProviderPath.sh | 31 ++++++++++-- .../tools/keytool/CloneKeyAskPassword.sh | 4 ++ .../sun/security/tools/keytool/NoExtNPE.sh | 3 ++ .../sun/security/tools/keytool/SecretKeyKS.sh | 6 +++ .../security/tools/keytool/StandardAlgName.sh | 6 +++ jdk/test/sun/security/tools/keytool/i18n.sh | 6 +++ .../sun/security/tools/keytool/printssl.sh | 3 ++ .../sun/security/tools/keytool/resource.sh | 5 ++ .../sun/security/tools/keytool/standard.sh | 6 ++- 38 files changed, 280 insertions(+), 38 deletions(-) diff --git a/jdk/test/java/net/Authenticator/B4933582.sh b/jdk/test/java/net/Authenticator/B4933582.sh index b103592f42d..0826063a805 100644 --- a/jdk/test/java/net/Authenticator/B4933582.sh +++ b/jdk/test/java/net/Authenticator/B4933582.sh @@ -30,6 +30,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -39,7 +43,7 @@ case "$OS" in exit 1; ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . -classpath ${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest ${TESTSRC}${FS}B4933582.java +${TESTJAVA}${FS}bin${FS}javac -d . -classpath "${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest" ${TESTSRC}${FS}B4933582.java rm -f cache.ser auth.save -${TESTJAVA}${FS}bin${FS}java -classpath ${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}. B4933582 first -${TESTJAVA}${FS}bin${FS}java -classpath ${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}. B4933582 second +${TESTJAVA}${FS}bin${FS}java -classpath "${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}." B4933582 first +${TESTJAVA}${FS}bin${FS}java -classpath "${TESTSRC}${FS}..${FS}..${FS}..${FS}sun${FS}net${FS}www${FS}httptest${PS}." B4933582 second diff --git a/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh b/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh index ba8b7cb5184..18f7c0ea94c 100644 --- a/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh +++ b/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh @@ -35,6 +35,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" diff --git a/jdk/test/java/net/Socket/OldSocketImpl.sh b/jdk/test/java/net/Socket/OldSocketImpl.sh index 85845464f2b..50692f8e045 100644 --- a/jdk/test/java/net/Socket/OldSocketImpl.sh +++ b/jdk/test/java/net/Socket/OldSocketImpl.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URL/B5086147.sh b/jdk/test/java/net/URL/B5086147.sh index 53034443a80..aaa9eadf31c 100644 --- a/jdk/test/java/net/URL/B5086147.sh +++ b/jdk/test/java/net/URL/B5086147.sh @@ -29,6 +29,10 @@ case "$OS" in SunOS | Linux ) exit 0 ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URL/runconstructor.sh b/jdk/test/java/net/URL/runconstructor.sh index 93a80de4b3c..30ae96a3c10 100644 --- a/jdk/test/java/net/URL/runconstructor.sh +++ b/jdk/test/java/net/URL/runconstructor.sh @@ -31,6 +31,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URLClassLoader/B5077773.sh b/jdk/test/java/net/URLClassLoader/B5077773.sh index 6dcba9c39a9..43bff5ad4a1 100644 --- a/jdk/test/java/net/URLClassLoader/B5077773.sh +++ b/jdk/test/java/net/URLClassLoader/B5077773.sh @@ -42,6 +42,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh b/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh index e46ac2915ce..191ff6f4750 100644 --- a/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh +++ b/jdk/test/java/net/URLClassLoader/sealing/checksealed.sh @@ -35,6 +35,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -49,10 +53,10 @@ esac if [ x"$TESTJAVA" = x ]; then TESTJAVA=$1; fi if [ x"$TESTSRC" = x ]; then TESTSRC=.; fi -CLASSPATH=.${PS}${TESTSRC}${FS}a${PS}${TESTSRC}${FS}b.jar +CLASSPATH=".${PS}${TESTSRC}${FS}a${PS}${TESTSRC}${FS}b.jar" -${TESTJAVA}${FS}bin${FS}javac -classpath ${CLASSPATH} -d . ${TESTSRC}${FS}CheckSealed.java -${TESTJAVA}${FS}bin${FS}java -cp ${CLASSPATH} CheckSealed 1 +${TESTJAVA}${FS}bin${FS}javac -classpath "${CLASSPATH}" -d . ${TESTSRC}${FS}CheckSealed.java +${TESTJAVA}${FS}bin${FS}java -cp "${CLASSPATH}" CheckSealed 1 if [ $? != 0 ]; then exit 1; fi -${TESTJAVA}${FS}bin${FS}java -cp ${CLASSPATH} CheckSealed 2 +${TESTJAVA}${FS}bin${FS}java -cp "${CLASSPATH}" CheckSealed 2 if [ $? != 0 ]; then exit 1; fi diff --git a/jdk/test/java/net/URLConnection/6212146/test.sh b/jdk/test/java/net/URLConnection/6212146/test.sh index 29b187ab307..cdf970db41e 100644 --- a/jdk/test/java/net/URLConnection/6212146/test.sh +++ b/jdk/test/java/net/URLConnection/6212146/test.sh @@ -41,6 +41,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh b/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh index 02ab6fcfd50..a1c1d80d696 100644 --- a/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh +++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh @@ -54,6 +54,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -81,7 +85,7 @@ ${TESTJAVA}${FILESEP}bin${FILESEP}javac \ # run the test ${TESTJAVA}${FILESEP}bin${FILESEP}java \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" \ ClassLoaderDeadlock exit $? diff --git a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh index 4ed9b785e5f..e631389f023 100644 --- a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh +++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh @@ -42,6 +42,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -54,5 +58,5 @@ esac JAVA="${TESTJAVA}${FILESEP}bin${FILESEP}java" -${JAVA} -cp ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar Deadlock +${JAVA} -cp "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}Deadlock.jar" Deadlock diff --git a/jdk/test/java/security/Security/signedfirst/Dyn.sh b/jdk/test/java/security/Security/signedfirst/Dyn.sh index b64a6b6621b..b897d5900a9 100644 --- a/jdk/test/java/security/Security/signedfirst/Dyn.sh +++ b/jdk/test/java/security/Security/signedfirst/Dyn.sh @@ -54,6 +54,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -76,7 +80,7 @@ ${TESTJAVA}${FILESEP}bin${FILESEP}javac \ # run the test ${TESTJAVA}${FILESEP}bin${FILESEP}java \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ DynSignedProvFirst exit $? diff --git a/jdk/test/java/security/Security/signedfirst/Static.sh b/jdk/test/java/security/Security/signedfirst/Static.sh index cec9df72279..519766f9d60 100644 --- a/jdk/test/java/security/Security/signedfirst/Static.sh +++ b/jdk/test/java/security/Security/signedfirst/Static.sh @@ -54,6 +54,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" @@ -70,14 +74,14 @@ rm StaticSignedProvFirst.class # compile the test program ${TESTJAVA}${FILESEP}bin${FILESEP}javac \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ -d ${TESTCLASSES}${FILESEP} \ ${TESTSRC}${FILESEP}StaticSignedProvFirst.java # run the test cd ${TESTSRC}${FILESEP} ${TESTJAVA}${FILESEP}bin${FILESEP}java \ - -classpath ${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar \ + -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ -Djava.security.properties=file:${TESTSRC}${FILESEP}Static.props \ StaticSignedProvFirst diff --git a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh index b433dedb221..6eef3944d9f 100644 --- a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh +++ b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh @@ -56,6 +56,11 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + ;; Windows* ) NULL=NUL PS=";" @@ -69,7 +74,7 @@ esac ${TESTJAVA}${FS}bin${FS}javac \ -d . \ - -classpath ${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar \ + -classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar" \ ${TESTSRC}${FS}FailOverTest.java if [ $? -ne 0 ]; then @@ -77,7 +82,7 @@ if [ $? -ne 0 ]; then fi ${TESTJAVA}${FS}bin${FS}java \ - -classpath ${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}. \ + -classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}." \ FailOverTest result=$? diff --git a/jdk/test/javax/security/auth/Subject/doAs/Test.sh b/jdk/test/javax/security/auth/Subject/doAs/Test.sh index 9844c994968..61c4d7cd6cf 100644 --- a/jdk/test/javax/security/auth/Subject/doAs/Test.sh +++ b/jdk/test/javax/security/auth/Subject/doAs/Test.sh @@ -43,6 +43,11 @@ case "$OS" in FS="/" RM="/bin/rm -f" ;; + CYGWIN* ) + PS=";" + FS="/" + RM="rm" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh b/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh index 357a586b443..288dedf15fa 100644 --- a/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh +++ b/jdk/test/lib/security/java.policy/Ext_AllPolicy.sh @@ -56,6 +56,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_95 | Windows_98 | Windows_NT ) NULL=NUL PS=";" diff --git a/jdk/test/sun/net/www/MarkResetTest.sh b/jdk/test/sun/net/www/MarkResetTest.sh index 61e73344b0a..bf0b0ceb3c1 100644 --- a/jdk/test/sun/net/www/MarkResetTest.sh +++ b/jdk/test/sun/net/www/MarkResetTest.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh index 615d1e5a293..06d10520ebb 100644 --- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh +++ b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh b/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh index b72b168c208..677a13cc69a 100644 --- a/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh +++ b/jdk/test/sun/net/www/http/HttpClient/RetryPost.sh @@ -32,6 +32,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/protocol/jar/B5105410.sh b/jdk/test/sun/net/www/protocol/jar/B5105410.sh index 3250ecba807..7b1d33ea4fb 100644 --- a/jdk/test/sun/net/www/protocol/jar/B5105410.sh +++ b/jdk/test/sun/net/www/protocol/jar/B5105410.sh @@ -39,6 +39,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh b/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh index 7db91d98862..351614dde3d 100644 --- a/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh +++ b/jdk/test/sun/net/www/protocol/jar/jarbug/run.sh @@ -28,23 +28,54 @@ # @summary various resource and classloading bugs related to jar files #set -x DEST=`pwd` + +OS=`uname -s` +case "$OS" in + SunOS ) + PS=":" + FS="/" + ;; + Linux ) + PS=":" + FS="/" + ;; + Windows* ) + PS=";" + FS="\\" + ;; + CYGWIN* ) + PS=";" + FS="/" + # + # javac does not like /cygdrive produced by `pwd`. + # + DEST=`cygpath -d ${DEST}` + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + # # build jar1 # -mkdir ${DEST}/jar1 -cd ${TESTSRC}/etc/jar1 -cp -r . ${DEST}/jar1 -${TESTJAVA}/bin/javac -d ${DEST}/jar1 ${TESTSRC}/src/jar1/LoadResourceBundle.java -${TESTJAVA}/bin/javac -d ${DEST}/jar1 ${TESTSRC}/src/jar1/GetResource.java -cd ${DEST}/jar1 -${TESTJAVA}/bin/jar cfM jar1.jar jar1 res1.txt +mkdir -p ${DEST}${FS}jar1 +cd ${TESTSRC}${FS}etc${FS}jar1 +cp -r . ${DEST}${FS}jar1 +${TESTJAVA}${FS}bin${FS}javac -d ${DEST}${FS}jar1 \ + ${TESTSRC}${FS}src${FS}jar1${FS}LoadResourceBundle.java +${TESTJAVA}${FS}bin${FS}javac -d ${DEST}${FS}jar1 \ + ${TESTSRC}${FS}src${FS}jar1${FS}GetResource.java +cd ${DEST}${FS}jar1 +${TESTJAVA}${FS}bin${FS}jar cfM jar1.jar jar1 res1.txt mv jar1.jar .. # # build the test sources and run them # -${TESTJAVA}/bin/javac -d ${DEST} ${TESTSRC}/src/test/*.java +${TESTJAVA}${FS}bin${FS}javac -d ${DEST} ${TESTSRC}${FS}src${FS}test${FS}*.java cd ${DEST} -${TESTJAVA}/bin/java RunAllTests +${TESTJAVA}${FS}bin${FS}java RunAllTests result=$? if [ "$result" -ne "0" ]; then exit 1 diff --git a/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh b/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh index 4711e7e3cd3..8974fe62d45 100644 --- a/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh +++ b/jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh @@ -68,6 +68,20 @@ case "$OS" in CP="cp" CHMOD="chmod" ;; + CYGWIN* ) + FS="/" + PS=";" + CP="cp" + CHMOD="chmod" + # + # javac does not like /cygdrive produced by `pwd` + # + TESTSRC=`cygpath -d ${TESTSRC}` + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; esac # compile test diff --git a/jdk/test/sun/security/pkcs11/Provider/Login.sh b/jdk/test/sun/security/pkcs11/Provider/Login.sh index a41720b63de..6b285adb82d 100644 --- a/jdk/test/sun/security/pkcs11/Provider/Login.sh +++ b/jdk/test/sun/security/pkcs11/Provider/Login.sh @@ -69,6 +69,20 @@ case "$OS" in CP="cp" CHMOD="chmod" ;; + CYGWIN* ) + FS="/" + PS=";" + CP="cp" + CHMOD="chmod" + # + # javac does not like /cygdrive produced by `pwd` + # + TESTSRC=`cygpath -d ${TESTSRC}` + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; esac # first make cert/key DBs writable diff --git a/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh b/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh index cb4325b464b..9cb9d04de95 100644 --- a/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh +++ b/jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh @@ -55,6 +55,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh index 9ebf5ee3f64..1f49a952fb3 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh @@ -43,10 +43,17 @@ fi OS=`uname -s` case "$OS" in SunOS | Linux ) + FILESEP="/" PATHSEP=":" ;; + CYGWIN* ) + FILESEP="/" + PATHSEP=";" + ;; + Windows* ) + FILESEP="\\" PATHSEP=";" ;; esac @@ -56,11 +63,13 @@ set -ex # # Compile the tests, package into their respective jars # -${TESTJAVA}/bin/javac -d . \ - ${TESTSRC}/NotifyHandshakeTest.java \ - ${TESTSRC}/NotifyHandshakeTestHeyYou.java -${TESTJAVA}/bin/jar -cvf com.jar com/NotifyHandshakeTest*.class -${TESTJAVA}/bin/jar -cvf edu.jar edu/NotifyHandshakeTestHeyYou.class +${TESTJAVA}${FILESEP}bin${FILESEP}javac -d . \ + ${TESTSRC}${FILESEP}NotifyHandshakeTest.java \ + ${TESTSRC}${FILESEP}NotifyHandshakeTestHeyYou.java +${TESTJAVA}${FILESEP}bin${FILESEP}jar -cvf com.jar \ + com${FILESEP}NotifyHandshakeTest*.class +${TESTJAVA}${FILESEP}bin${FILESEP}jar -cvf edu.jar \ + edu${FILESEP}NotifyHandshakeTestHeyYou.class # # Don't want the original class files to be used, because @@ -73,11 +82,11 @@ rm -rf com edu # This is the only thing we really care about as far as # test status goes. # -${TESTJAVA}/bin/java \ +${TESTJAVA}${FILESEP}bin${FILESEP}java \ -Dtest.src=${TESTSRC} \ -classpath "com.jar${PATHSEP}edu.jar" \ -Djava.security.manager \ - -Djava.security.policy=${TESTSRC}/NotifyHandshakeTest.policy \ + -Djava.security.policy=${TESTSRC}${FILESEP}NotifyHandshakeTest.policy \ com.NotifyHandshakeTest retval=$? diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh index 3e66175cf66..de5f0318e8b 100644 --- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh @@ -36,6 +36,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -46,6 +50,7 @@ case "$OS" in ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java ${TESTSRC}${FS}ProxyTunnelServer.java ${TESTSRC}${FS}PostThruProxy.java +${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java \ + ${TESTSRC}${FS}ProxyTunnelServer.java ${TESTSRC}${FS}PostThruProxy.java ${TESTJAVA}${FS}bin${FS}java PostThruProxy ${HOSTNAME} ${TESTSRC} exit diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh index 2a40eb790ce..e9e20336222 100644 --- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh @@ -36,6 +36,10 @@ case "$OS" in PS=":" FS="/" ;; + CYGWIN* ) + PS=";" + FS="/" + ;; Windows* ) PS=";" FS="\\" @@ -46,6 +50,8 @@ case "$OS" in ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java ${TESTSRC}${FS}ProxyTunnelServer.java ${TESTSRC}${FS}PostThruProxyWithAuth.java +${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}OriginServer.java \ + ${TESTSRC}${FS}ProxyTunnelServer.java \ + ${TESTSRC}${FS}PostThruProxyWithAuth.java ${TESTJAVA}${FS}bin${FS}java PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC} exit diff --git a/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh b/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh index 5501116b9c9..3dda55f30c2 100644 --- a/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh +++ b/jdk/test/sun/security/tools/jarsigner/AlgOptions.sh @@ -53,6 +53,13 @@ case "$OS" in CP="${FS}bin${FS}cp -f" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + CP="cp -f" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/jarsigner/PercentSign.sh b/jdk/test/sun/security/tools/jarsigner/PercentSign.sh index a07011f0a2a..3a9f315d015 100644 --- a/jdk/test/sun/security/tools/jarsigner/PercentSign.sh +++ b/jdk/test/sun/security/tools/jarsigner/PercentSign.sh @@ -53,6 +53,13 @@ case "$OS" in CP="${FS}bin${FS}cp -f" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + CP="cp -f" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/jarsigner/oldsig.sh b/jdk/test/sun/security/tools/jarsigner/oldsig.sh index 14668810446..d7420dc4f3e 100644 --- a/jdk/test/sun/security/tools/jarsigner/oldsig.sh +++ b/jdk/test/sun/security/tools/jarsigner/oldsig.sh @@ -49,6 +49,13 @@ case "$OS" in CP="${FS}bin${FS}cp -f" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + CP="cp -f" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh index 7deb733c095..8f253a76c9b 100644 --- a/jdk/test/sun/security/tools/keytool/AltProviderPath.sh +++ b/jdk/test/sun/security/tools/keytool/AltProviderPath.sh @@ -52,6 +52,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" @@ -66,14 +72,21 @@ esac # the test code #genkey -${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias dummyTestCA -keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" -dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 -keypass storepass -keystore keystoreCA.dks -storepass storepass -storetype "dks" -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -genkey -v -alias dummyTestCA \ + -keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" \ + -dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 \ + -keypass storepass -keystore keystoreCA.dks -storepass storepass \ + -storetype "dks" -provider "org.test.dummy.DummyProvider" \ + -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 fi #Change keystore password -${TESTJAVA}${FS}bin${FS}keytool -storepasswd -new storepass2 -keystore keystoreCA.dks -storetype "dks" -storepass storepass -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -storepasswd -new storepass2 \ + -keystore keystoreCA.dks -storetype "dks" -storepass storepass \ + -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 @@ -81,21 +94,29 @@ fi #Change keystore key password -${TESTJAVA}${FS}bin${FS}keytool -keypasswd -alias "dummyTestCA" -keypass storepass -new keypass -keystore keystoreCA.dks -storetype "dks" -storepass storepass2 -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -keypasswd -alias "dummyTestCA" \ + -keypass storepass -new keypass -keystore keystoreCA.dks \ + -storetype "dks" -storepass storepass2 \ + -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 fi #Export certificate -${TESTJAVA}${FS}bin${FS}keytool -v -export -rfc -alias "dummyTestCA" -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dks" -storepass storepass2 -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -v -export -rfc -alias "dummyTestCA" \ + -file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dks" \ + -storepass storepass2 -provider "org.test.dummy.DummyProvider" \ + -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 fi #list keystore -${TESTJAVA}${FS}bin${FS}keytool -v -list -keystore keystoreCA.dks -storetype "dks" -storepass storepass2 -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} +${TESTJAVA}${FS}bin${FS}keytool -v -list -keystore keystoreCA.dks \ + -storetype "dks" -storepass storepass2 \ + -provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES} if [ $? -ne 0 ]; then exit 1 diff --git a/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh b/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh index c5bbca9786c..4934fc7b6ce 100644 --- a/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh +++ b/jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh @@ -55,6 +55,10 @@ case "$OS" in PATHSEP=":" FILESEP="/" ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; Windows* ) PATHSEP=";" FILESEP="\\" diff --git a/jdk/test/sun/security/tools/keytool/NoExtNPE.sh b/jdk/test/sun/security/tools/keytool/NoExtNPE.sh index 3e929b5354f..80cc3c85aea 100644 --- a/jdk/test/sun/security/tools/keytool/NoExtNPE.sh +++ b/jdk/test/sun/security/tools/keytool/NoExtNPE.sh @@ -48,6 +48,9 @@ case "$OS" in Linux ) FILESEP="/" ;; + CYGWIN* ) + FILESEP="/" + ;; Windows* ) FILESEP="\\" ;; diff --git a/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh b/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh index 96a1885db9f..787e37e04a5 100644 --- a/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh +++ b/jdk/test/sun/security/tools/keytool/SecretKeyKS.sh @@ -51,6 +51,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/StandardAlgName.sh b/jdk/test/sun/security/tools/keytool/StandardAlgName.sh index 77e9a98ef93..82e9e208e10 100644 --- a/jdk/test/sun/security/tools/keytool/StandardAlgName.sh +++ b/jdk/test/sun/security/tools/keytool/StandardAlgName.sh @@ -52,6 +52,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/i18n.sh b/jdk/test/sun/security/tools/keytool/i18n.sh index 2d37ae97664..33abf76f62e 100644 --- a/jdk/test/sun/security/tools/keytool/i18n.sh +++ b/jdk/test/sun/security/tools/keytool/i18n.sh @@ -52,6 +52,12 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + PS=";" + FS="/" + TMP=/tmp + ;; Windows* ) NULL=NUL PS=";" diff --git a/jdk/test/sun/security/tools/keytool/printssl.sh b/jdk/test/sun/security/tools/keytool/printssl.sh index 9fc19cd9b20..73bd21cb83b 100644 --- a/jdk/test/sun/security/tools/keytool/printssl.sh +++ b/jdk/test/sun/security/tools/keytool/printssl.sh @@ -40,6 +40,9 @@ case "$OS" in SunOS | Linux ) FS="/" ;; + CYGWIN* ) + FS="/" + ;; Windows_* ) FS="\\" ;; diff --git a/jdk/test/sun/security/tools/keytool/resource.sh b/jdk/test/sun/security/tools/keytool/resource.sh index ab8e9520555..1fc515217ae 100644 --- a/jdk/test/sun/security/tools/keytool/resource.sh +++ b/jdk/test/sun/security/tools/keytool/resource.sh @@ -48,6 +48,11 @@ case "$OS" in FS="/" TMP=/tmp ;; + CYGWIN* ) + NULL=/dev/null + FS="/" + TMP=/tmp + ;; Windows_* ) NULL=NUL FS="\\" diff --git a/jdk/test/sun/security/tools/keytool/standard.sh b/jdk/test/sun/security/tools/keytool/standard.sh index f3e052ed510..4328c681454 100644 --- a/jdk/test/sun/security/tools/keytool/standard.sh +++ b/jdk/test/sun/security/tools/keytool/standard.sh @@ -44,11 +44,15 @@ fi # set platform-dependent variables OS=`uname -s` case "$OS" in + SunOS | Linux | CYGWIN* ) + FS="/" + ;; Windows_* ) FS="\\" ;; * ) - FS="/" + echo "Unrecognized system!" + exit 1; ;; esac From d8b50037deb6faedcaa86d9982ee96fa0427675b Mon Sep 17 00:00:00 2001 From: John R Rose Date: Thu, 6 Aug 2009 18:30:33 -0700 Subject: [PATCH 059/102] 6838598: Legal notice repair: jdk/src/share/classes/sun/dyn/FilterGeneric.java Reviewed-by: xdono --- jdk/src/share/classes/sun/dyn/FilterGeneric.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/dyn/FilterGeneric.java b/jdk/src/share/classes/sun/dyn/FilterGeneric.java index a99eb26c9ee..a746ad21b95 100644 --- a/jdk/src/share/classes/sun/dyn/FilterGeneric.java +++ b/jdk/src/share/classes/sun/dyn/FilterGeneric.java @@ -16,7 +16,7 @@ * * 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 Sf, tifth Floor, Boston, MA 02110-1301 USA. + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or From d78b7fcc9b04134c94242f4368e9f92baa75b330 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 6 Aug 2009 19:35:41 -0700 Subject: [PATCH 060/102] 6858429: javap classfile library a minor bug Reviewed-by: ksrini --- .../src/share/classes/com/sun/tools/classfile/ClassWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java index 96ae0cfa452..8f8a6edab5e 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java @@ -435,7 +435,7 @@ public class ClassWriter { } public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, ClassOutputStream out) { - out.writeByte(attr.local_variable_table.length); + out.writeShort(attr.local_variable_table.length); for (LocalVariableTypeTable_attribute.Entry e: attr.local_variable_table) writeLocalVariableTypeTableEntry(e, out); return null; From 75379fe244cd0b17776116f0ef7ea4496508cfa4 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Aug 2009 10:50:26 +0100 Subject: [PATCH 061/102] 6826780: URLClassPath should use HashMap instead of HashMap Replace URL with a String representation. Reviewed-by: michaelm, jccollet --- jdk/make/sun/net/FILES_java.gmk | 1 + .../share/classes/sun/misc/URLClassPath.java | 28 ++++--- .../share/classes/sun/net/util/URLUtil.java | 80 +++++++++++++++++++ 3 files changed, 97 insertions(+), 12 deletions(-) create mode 100644 jdk/src/share/classes/sun/net/util/URLUtil.java diff --git a/jdk/make/sun/net/FILES_java.gmk b/jdk/make/sun/net/FILES_java.gmk index 3d729947667..5082c3d370f 100644 --- a/jdk/make/sun/net/FILES_java.gmk +++ b/jdk/make/sun/net/FILES_java.gmk @@ -41,6 +41,7 @@ FILES_java = \ sun/net/NetProperties.java \ sun/net/NetHooks.java \ sun/net/util/IPAddressUtil.java \ + sun/net/util/URLUtil.java \ sun/net/dns/ResolverConfiguration.java \ sun/net/dns/ResolverConfigurationImpl.java \ sun/net/ftp/FtpClient.java \ diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java index d9b1035ba6d..5c60e2fe81d 100644 --- a/jdk/src/share/classes/sun/misc/URLClassPath.java +++ b/jdk/src/share/classes/sun/misc/URLClassPath.java @@ -51,6 +51,7 @@ import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.security.cert.Certificate; import sun.misc.FileURLMapper; +import sun.net.util.URLUtil; /** * This class is used to maintain a search path of URLs for loading classes @@ -80,7 +81,7 @@ public class URLClassPath { ArrayList loaders = new ArrayList(); /* Map of each URL opened to its corresponding Loader */ - HashMap lmap = new HashMap(); + HashMap lmap = new HashMap(); /* The jar protocol handler to use when creating new URLs */ private URLStreamHandler jarHandler; @@ -317,7 +318,8 @@ public class URLClassPath { // Skip this URL if it already has a Loader. (Loader // may be null in the case where URL has not been opened // but is referenced by a JAR index.) - if (lmap.containsKey(url)) { + String urlNoFragString = URLUtil.urlNoFragString(url); + if (lmap.containsKey(urlNoFragString)) { continue; } // Otherwise, create a new Loader for the URL. @@ -336,7 +338,7 @@ public class URLClassPath { } // Finally, add the Loader to the search path. loaders.add(loader); - lmap.put(url, loader); + lmap.put(urlNoFragString, loader); } return loaders.get(index); } @@ -576,7 +578,7 @@ public class URLClassPath { private JarIndex index; private MetaIndex metaIndex; private URLStreamHandler handler; - private HashMap lmap; + private HashMap lmap; private boolean closed = false; /* @@ -584,7 +586,7 @@ public class URLClassPath { * a JAR file. */ JarLoader(URL url, URLStreamHandler jarHandler, - HashMap loaderMap) + HashMap loaderMap) throws IOException { super(new URL("jar", "", -1, url + "!/", jarHandler)); @@ -663,8 +665,9 @@ public class URLClassPath { try { URL jarURL = new URL(csu, jarfiles[i]); // If a non-null loader already exists, leave it alone. - if (!lmap.containsKey(jarURL)) { - lmap.put(jarURL, null); + String urlNoFragString = URLUtil.urlNoFragString(jarURL); + if (!lmap.containsKey(urlNoFragString)) { + lmap.put(urlNoFragString, null); } } catch (MalformedURLException e) { continue; @@ -806,7 +809,7 @@ public class URLClassPath { if (index == null) return null; - HashSet visited = new HashSet(); + HashSet visited = new HashSet(); return getResource(name, check, visited); } @@ -818,7 +821,7 @@ public class URLClassPath { * non-existent resource */ Resource getResource(final String name, boolean check, - Set visited) { + Set visited) { Resource res; Object[] jarFiles; @@ -843,7 +846,8 @@ public class URLClassPath { try{ url = new URL(csu, jarName); - if ((newLoader = (JarLoader)lmap.get(url)) == null) { + String urlNoFragString = URLUtil.urlNoFragString(url); + if ((newLoader = (JarLoader)lmap.get(urlNoFragString)) == null) { /* no loader has been set up for this jar file * before */ @@ -867,7 +871,7 @@ public class URLClassPath { } /* put it in the global hashtable */ - lmap.put(url, newLoader); + lmap.put(urlNoFragString, newLoader); } } catch (java.security.PrivilegedActionException pae) { continue; @@ -879,7 +883,7 @@ public class URLClassPath { /* Note that the addition of the url to the list of visited * jars incorporates a check for presence in the hashmap */ - boolean visitedURL = !visited.add(url); + boolean visitedURL = !visited.add(URLUtil.urlNoFragString(url)); if (!visitedURL) { try { newLoader.ensureOpen(); diff --git a/jdk/src/share/classes/sun/net/util/URLUtil.java b/jdk/src/share/classes/sun/net/util/URLUtil.java new file mode 100644 index 00000000000..047df3ebe9a --- /dev/null +++ b/jdk/src/share/classes/sun/net/util/URLUtil.java @@ -0,0 +1,80 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.net.util; + +import java.net.URL; + +/** + * URL Utility class. + */ +public class URLUtil { + /** + * Returns a string form of the url suitable for use as a key in HashMap/Sets. + * + * The string form should be behave in the same manner as the URL when + * compared for equality in a HashMap/Set, except that no nameservice + * lookup is done on the hostname (only string comparison), and the fragment + * is not considered. + * + * @see java.net.URLStreamHandler.sameFile(java.net.URL) + */ + public static String urlNoFragString(URL url) { + StringBuilder strForm = new StringBuilder(); + + String protocol = url.getProtocol(); + if (protocol != null) { + /* protocol is compared case-insensitive, so convert to lowercase */ + protocol = protocol.toLowerCase(); + strForm.append(protocol); + strForm.append("://"); + } + + String host = url.getHost(); + if (host != null) { + /* host is compared case-insensitive, so convert to lowercase */ + host = host.toLowerCase(); + strForm.append(host); + + int port = url.getPort(); + if (port == -1) { + /* if no port is specificed then use the protocols + * default, if there is one */ + port = url.getDefaultPort(); + } + if (port != -1) { + strForm.append(":").append(port); + } + } + + String file = url.getFile(); + if (file != null) { + strForm.append(file); + } + + return strForm.toString(); + } +} + From aca1227406040fd2663b684acc00692d62b342e9 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Aug 2009 10:51:25 +0100 Subject: [PATCH 062/102] 6826801: JarFileFactory should not use HashMap Replace URL with a String representation. Reviewed-by: michaelm, jccollet --- .../net/www/protocol/jar/JarFileFactory.java | 26 ++++++++++--------- .../net/www/protocol/jar/JarFileFactory.java | 26 ++++++++++--------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java index c51f15eaec9..0d1b3099836 100644 --- a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -25,12 +25,14 @@ package sun.net.www.protocol.jar; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.jar.*; -import java.util.zip.ZipFile; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.jar.JarFile; import java.security.Permission; +import sun.net.util.URLUtil; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -41,13 +43,13 @@ import java.security.Permission; class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static HashMap fileCache = new HashMap(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static HashMap urlCache = new HashMap(); URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = (URL)urlCache.get(jarFile); + URL u = urlCache.get(jarFile); if (u != null) return u.openConnection(); @@ -72,7 +74,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { synchronized (this) { result = getCachedJarFile(url); if (result == null) { - fileCache.put(url, local_result); + fileCache.put(URLUtil.urlNoFragString(url), local_result); urlCache.put(local_result, url); result = local_result; } else { @@ -97,15 +99,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = (URL) urlCache.remove(jarFile); + URL urlRemoved = urlCache.remove(jarFile); if( urlRemoved != null) { - fileCache.remove(urlRemoved); + fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } private JarFile getCachedJarFile(URL url) { - JarFile result = (JarFile)fileCache.get(url); + JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ if (result != null) { diff --git a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java index 3192c52d030..9df86326e40 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -25,12 +25,14 @@ package sun.net.www.protocol.jar; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.jar.*; -import java.util.zip.ZipFile; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.jar.JarFile; import java.security.Permission; +import sun.net.util.URLUtil; /* A factory for cached JAR file. This class is used to both retrieve * and cache Jar files. @@ -41,13 +43,13 @@ import java.security.Permission; class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static HashMap fileCache = new HashMap(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static HashMap urlCache = new HashMap(); URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = (URL)urlCache.get(jarFile); + URL u = urlCache.get(jarFile); if (u != null) return u.openConnection(); @@ -82,7 +84,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { synchronized (this) { result = getCachedJarFile(url); if (result == null) { - fileCache.put(url, local_result); + fileCache.put(URLUtil.urlNoFragString(url), local_result); urlCache.put(local_result, url); result = local_result; } else { @@ -107,14 +109,14 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = (URL) urlCache.remove(jarFile); + URL urlRemoved = urlCache.remove(jarFile); if( urlRemoved != null) { - fileCache.remove(urlRemoved); + fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } private JarFile getCachedJarFile(URL url) { - JarFile result = (JarFile)fileCache.get(url); + JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ if (result != null) { From 9a5d0532c5334b2448bff1946250972594c82a9d Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Fri, 7 Aug 2009 18:15:03 +0100 Subject: [PATCH 063/102] 6869697: Missing entry in makefiles for java/lang/ReflectiveOperationException.java Add new dependency explicitly so all compilers pick it up Reviewed-by: darcy, ohair --- jdk/make/java/java/FILES_java.gmk | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index f9dd26383ce..e8a2223f67a 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -77,6 +77,7 @@ JAVA_JAVA_java = \ java/lang/Compiler.java \ java/lang/Throwable.java \ java/lang/Exception.java \ + java/lang/ReflectiveOperationException.java \ java/lang/IllegalAccessException.java \ java/lang/InstantiationException.java \ java/lang/ClassNotFoundException.java \ From 1d2b6d72b22b81cffb041a5668270ef8618d1e92 Mon Sep 17 00:00:00 2001 From: Abhijit Saha Date: Fri, 7 Aug 2009 11:27:00 -0700 Subject: [PATCH 064/102] 6813167: 6u14 JAX-WS audit mutable static bugs 6803688: Integrate latest JAX-WS (2.1.6) in to JDK 6u14 Reviewed-by: darcy, ramap --- jaxws/THIRD_PARTY_README | 2 +- jaxws/jaxws.patch | 81929 ++++++++++++++++ jaxws/patch.out | 1402 + .../sun/codemodel/internal/JAnnotatable.java | 1 + .../codemodel/internal/JAnnotationUse.java | 3 +- .../codemodel/internal/JAnnotationWriter.java | 1 + .../com/sun/codemodel/internal/JBlock.java | 8 + .../sun/codemodel/internal/JCommentPart.java | 20 +- .../sun/codemodel/internal/JDirectClass.java | 1 + .../com/sun/codemodel/internal/JExpr.java | 8 +- .../com/sun/codemodel/internal/JJavaName.java | 1 + .../com/sun/codemodel/internal/JMethod.java | 5 +- .../com/sun/codemodel/internal/JPackage.java | 27 +- .../sun/codemodel/internal/JTypeWildcard.java | 1 + .../internal/TypedAnnotationWriter.java | 1 + .../sun/codemodel/internal/fmt/package.html | 29 - .../sun/codemodel/internal/package-info.java | 1 + .../internal/util/EncoderFactory.java | 3 +- .../internal/util/MS1252Encoder.java | 3 +- .../internal/writer/FilterCodeWriter.java | 1 + .../com/sun/istack/internal/Builder.java | 33 + .../classes/com/sun/istack/internal/Pool.java | 30 +- .../XMLStreamReaderToContentHandler.java | 32 +- .../internal/localization/Localizable.java | 63 + .../localization/LocalizableMessage.java | 56 + .../LocalizableMessageFactory.java} | 25 +- .../internal/localization/Localizer.java | 149 + .../ws/AnnotationProcessorFactoryImpl.java | 5 - .../sun/tools/internal/jxc/ConfigReader.java | 1 + .../internal/jxc/MessageBundle.properties | 5 +- .../com/sun/tools/internal/jxc/Messages.java | 1 + .../tools/internal/jxc/SchemaGenerator.java | 1 + .../internal/jxc/SchemaGeneratorFacade.java | 56 + .../internal/jxc/apt/AnnotationParser.java | 1 + .../apt/AnnotationProcessorFactoryImpl.java | 1 + .../com/sun/tools/internal/jxc/apt/Const.java | 1 + .../internal/jxc/apt/ErrorReceiverImpl.java | 1 + .../jxc/apt/InlineAnnotationReaderImpl.java | 1 + .../internal/jxc/apt/MessageBundle.properties | 1 - .../sun/tools/internal/jxc/apt/Messages.java | 1 + .../sun/tools/internal/jxc/apt/Options.java | 1 + .../internal/jxc/apt/SchemaGenerator.java | 1 + .../internal/jxc/gen/config/Classes.java | 100 +- .../tools/internal/jxc/gen/config/Config.java | 94 +- .../tools/internal/jxc/gen/config/Schema.java | 138 +- .../tools/internal/jxc/gen/config/config.xsd | 2 + .../internal/jxc/model/nav/APTNavigator.java | 3 +- .../com/sun/tools/internal/ws/Invoker.java | 24 +- .../ws/api/TJavaGeneratorExtension.java | 1 + .../tools/internal/ws/api/WsgenExtension.java | 43 + .../tools/internal/ws/api/WsgenProtocol.java | 52 + .../internal/ws/api/wsdl/TWSDLExtensible.java | 2 + .../internal/ws/api/wsdl/TWSDLExtension.java | 1 + .../ws/api/wsdl/TWSDLExtensionHandler.java | 1 + .../internal/ws/api/wsdl/TWSDLOperation.java | 1 + .../ws/api/wsdl/TWSDLParserContext.java | 1 + .../sun/tools/internal/ws/package-info.java | 22 +- .../ws/processor/generator/GeneratorBase.java | 4 +- .../ws/processor/generator/SeiGenerator.java | 34 +- .../processor/generator/ServiceGenerator.java | 217 +- .../W3CAddressingJavaGeneratorExtension.java | 3 - .../internal/ws/processor/model/Port.java | 2 + .../ws/processor/model/java/JavaMethod.java | 30 +- .../ws/processor/model/jaxb/JAXBType.java | 4 +- .../modeler/annotation/WebServiceAP.java | 1 + .../modeler/annotation/WebServiceVisitor.java | 33 +- .../WebServiceWrapperGenerator.java | 8 +- .../modeler/wsdl/ConsoleErrorReporter.java | 7 + .../modeler/wsdl/PseudoSchemaBuilder.java | 3 +- .../processor/modeler/wsdl/WSDLModeler.java | 112 +- .../modeler/wsdl/WSDLModelerBase.java | 30 +- .../ws/processor/util/ClassNameCollector.java | 6 +- .../ws/resources/GeneratorMessages.java | 24 + .../internal/ws/resources/ModelMessages.java | 31 +- .../ws/resources/ModelerMessages.java | 38 +- .../ws/resources/WebserviceapMessages.java | 1242 +- .../ws/resources/WscompileMessages.java | 166 +- .../internal/ws/resources/WsdlMessages.java | 132 +- .../ws/resources/configuration.properties | 1 - .../ws/resources/generator.properties | 3 +- .../ws/resources/javacompiler.properties | 1 - .../internal/ws/resources/model.properties | 10 +- .../internal/ws/resources/modeler.properties | 15 +- .../ws/resources/processor.properties | 1 - .../internal/ws/resources/util.properties | 1 - .../ws/resources/webserviceap.properties | 25 +- .../ws/resources/wscompile.properties | 66 +- .../internal/ws/resources/wsdl.properties | 48 +- .../sun/tools/internal/ws/version.properties | 8 +- .../internal/ws/wscompile/AbortException.java | 1 - .../tools/internal/ws/wscompile/AuthInfo.java | 64 + .../ws/wscompile/BadCommandLineException.java | 1 - .../ws/wscompile/DefaultAuthTester.java | 66 + .../ws/wscompile/DefaultAuthenticator.java | 154 + .../internal/ws/wscompile/ErrorReceiver.java | 5 +- .../ws/wscompile/ErrorReceiverFilter.java | 5 +- .../ws/wscompile/JavaCompilerHelper.java | 9 +- .../tools/internal/ws/wscompile/Options.java | 7 +- .../internal/ws/wscompile/WsgenOptions.java | 45 +- .../internal/ws/wscompile/WsgenTool.java | 47 +- .../ws/wscompile/WsimportListener.java | 3 +- .../ws/wscompile/WsimportOptions.java | 75 +- .../internal/ws/wscompile/WsimportTool.java | 69 +- .../internal/ws/wsdl/document/Message.java | 7 +- .../ws/wsdl/document/jaxws/JAXWSBinding.java | 9 - .../ws/wsdl/framework/AbstractDocument.java | 17 +- .../parser/AbstractReferenceFinderImpl.java | 1 - .../internal/ws/wsdl/parser/DOMBuilder.java | 1 - .../internal/ws/wsdl/parser/DOMForest.java | 118 +- .../ws/wsdl/parser/DOMForestParser.java | 94 + .../ws/wsdl/parser/DOMForestScanner.java | 1 - .../ws/wsdl/parser/InternalizationLogic.java | 1 - .../internal/ws/wsdl/parser/Internalizer.java | 306 +- ...rSubmissionAddressingExtensionHandler.java | 3 - .../ws/wsdl/parser/MetadataFinder.java | 90 +- .../ws/wsdl/parser/NamespaceContextImpl.java | 33 +- .../ws/wsdl/parser/VersionChecker.java | 1 - .../parser/W3CAddressingExtensionHandler.java | 3 - .../wsdl/parser/WSDLInternalizationLogic.java | 8 +- .../internal/ws/wsdl/parser/WSDLParser.java | 9 +- .../ws/wsdl/parser/WhitespaceStripper.java | 1 - .../internal/xjc/ClassLoaderBuilder.java | 122 + .../com/sun/tools/internal/xjc/Driver.java | 15 +- .../com/sun/tools/internal/xjc/Language.java | 1 + .../internal/xjc/MessageBundle.properties | 113 +- .../sun/tools/internal/xjc/ModelLoader.java | 8 +- .../com/sun/tools/internal/xjc/Options.java | 101 +- .../internal/xjc/ProgressCodeWriter.java | 1 + .../sun/tools/internal/xjc/SchemaCache.java | 1 + .../com/sun/tools/internal/xjc/XJCFacade.java | 79 + .../sun/tools/internal/xjc/XJCListener.java | 1 + .../xjc/addon/at_generated/PluginImpl.java | 1 + .../xjc/addon/code_injector/Const.java | 1 + .../xjc/addon/code_injector/PluginImpl.java | 1 + .../xjc/addon/episode/PluginImpl.java | 1 + .../xjc/addon/episode/package-info.java | 1 + .../internal/xjc/api/ClassNameAllocator.java | 1 + .../tools/internal/xjc/api/J2SJAXBModel.java | 1 + .../sun/tools/internal/xjc/api/Reference.java | 1 + .../tools/internal/xjc/api/S2JJAXBModel.java | 1 + .../internal/xjc/api/SchemaCompiler.java | 4 + .../tools/internal/xjc/api/SpecVersion.java | 10 +- .../internal/xjc/api/TypeAndAnnotation.java | 1 + .../xjc/api/impl/j2s/JAXBModelImpl.java | 1 + .../xjc/api/impl/j2s/JavaCompilerImpl.java | 1 + .../xjc/api/impl/s2j/AbstractMappingImpl.java | 1 + .../xjc/api/impl/s2j/BeanMappingImpl.java | 1 + .../api/impl/s2j/DowngradingErrorHandler.java | 1 + .../xjc/api/impl/s2j/ElementAdapter.java | 1 + .../impl/s2j/ElementCollectionAdapter.java | 1 + .../xjc/api/impl/s2j/ElementMappingImpl.java | 1 + .../api/impl/s2j/ElementSingleAdapter.java | 1 + .../xjc/api/impl/s2j/PropertyImpl.java | 1 + .../xjc/api/impl/s2j/SchemaCompilerImpl.java | 7 +- .../api/impl/s2j/TypeAndAnnotationImpl.java | 1 + .../sun/tools/internal/xjc/api/package.html | 2 +- .../internal/xjc/api/util/APTClassLoader.java | 1 + .../xjc/api/util/FilerCodeWriter.java | 1 + .../internal/xjc/api/util/Messages.properties | 2 - .../api/util/ToolsJarNotFoundException.java | 1 + .../ri/OverrideAnnotationOfWriter.java | 37 + .../annotation/spec/XmlElementRefWriter.java | 2 + .../xjc/generator/bean/BeanGenerator.java | 10 +- .../bean/DualObjectFactoryGenerator.java | 1 + .../generator/bean/ElementOutlineImpl.java | 14 +- .../generator/bean/ImplStructureStrategy.java | 1 + .../generator/bean/MessageBundle.properties | 11 +- .../xjc/generator/bean/MethodWriter.java | 1 + .../bean/ObjectFactoryGeneratorImpl.java | 9 +- .../generator/bean/PackageOutlineImpl.java | 7 +- .../bean/PrivateObjectFactoryGenerator.java | 1 + .../bean/PublicObjectFactoryGenerator.java | 1 + .../generator/bean/field/AbstractField.java | 33 +- .../bean/field/AbstractFieldWithVar.java | 15 +- .../bean/field/AbstractListField.java | 4 +- .../xjc/generator/bean/field/ArrayField.java | 101 +- .../bean/field/ConstFieldRenderer.java | 3 +- .../bean/field/ContentListField.java | 176 + .../bean/field/DefaultFieldRenderer.java | 17 +- .../generator/bean/field/DummyListField.java | 152 + .../generator/bean/field/FieldRenderer.java | 2 +- .../bean/field/FieldRendererFactory.java | 7 + .../bean/field/IsSetFieldRenderer.java | 2 +- .../bean/field/MessageBundle.properties | 1 - .../xjc/generator/bean/field/Messages.java | 2 +- .../bean/field/NoExtendedContentField.java | 187 + .../xjc/generator/bean/field/SingleField.java | 6 +- .../field/SinglePrimitiveAccessField.java | 1 + .../generator/bean/field/UnboxedField.java | 6 +- .../bean/field/UntypedListFieldRenderer.java | 18 +- .../internal/xjc/generator/package-info.java | 1 + .../internal/xjc/model/AbstractCElement.java | 1 + .../xjc/model/AbstractCTypeInfoImpl.java | 1 + .../xjc/model/AutoClassNameAllocator.java | 1 + .../tools/internal/xjc/model/CAdapter.java | 1 + .../tools/internal/xjc/model/CArrayInfo.java | 8 +- .../xjc/model/CAttributePropertyInfo.java | 1 + .../internal/xjc/model/CBuiltinLeafInfo.java | 5 +- .../sun/tools/internal/xjc/model/CClass.java | 1 + .../tools/internal/xjc/model/CClassInfo.java | 24 +- .../internal/xjc/model/CClassInfoParent.java | 1 + .../tools/internal/xjc/model/CClassRef.java | 1 + .../internal/xjc/model/CCustomizable.java | 1 + .../internal/xjc/model/CCustomizations.java | 1 + .../internal/xjc/model/CDefaultValue.java | 1 + .../tools/internal/xjc/model/CElement.java | 1 + .../internal/xjc/model/CElementInfo.java | 20 + .../xjc/model/CElementPropertyInfo.java | 1 + .../internal/xjc/model/CEnumConstant.java | 1 + .../tools/internal/xjc/model/CNonElement.java | 1 + .../xjc/model/CPluginCustomization.java | 1 + .../internal/xjc/model/CPropertyInfo.java | 20 +- .../internal/xjc/model/CPropertyVisitor.java | 1 + .../xjc/model/CReferencePropertyInfo.java | 36 +- .../xjc/model/CSingleTypePropertyInfo.java | 2 +- .../tools/internal/xjc/model/CTypeInfo.java | 1 + .../tools/internal/xjc/model/CTypeRef.java | 1 + .../xjc/model/CValuePropertyInfo.java | 1 + .../internal/xjc/model/CWildcardTypeInfo.java | 1 + .../xjc/model/ClassNameAllocatorWrapper.java | 1 + .../sun/tools/internal/xjc/model/Model.java | 1 + .../tools/internal/xjc/model/Populatable.java | 1 + .../sun/tools/internal/xjc/model/TypeUse.java | 1 + .../internal/xjc/model/TypeUseFactory.java | 1 + .../tools/internal/xjc/model/TypeUseImpl.java | 1 + .../internal/xjc/model/nav/EagerNClass.java | 1 + .../internal/xjc/model/nav/EagerNType.java | 1 + .../tools/internal/xjc/model/nav/NClass.java | 1 + .../xjc/model/nav/NClassByJClass.java | 1 + .../xjc/model/nav/NParameterizedType.java | 1 + .../tools/internal/xjc/model/nav/NType.java | 1 + .../internal/xjc/model/nav/NavigatorImpl.java | 1 + .../internal/xjc/model/package-info.java | 1 + .../tools/internal/xjc/outline/Aspect.java | 1 + .../internal/xjc/outline/ClassOutline.java | 3 +- .../internal/xjc/outline/ElementOutline.java | 1 + .../xjc/outline/EnumConstantOutline.java | 1 + .../internal/xjc/outline/EnumOutline.java | 1 + .../sun/tools/internal/xjc/package-info.java | 1 + .../AbstractExtensionBindingChecker.java | 1 + .../sun/tools/internal/xjc/reader/Const.java | 10 +- .../xjc/reader/MessageBundle.properties | 21 +- .../internal/xjc/reader/ModelChecker.java | 1 + .../tools/internal/xjc/reader/RawTypeSet.java | 1 + .../sun/tools/internal/xjc/reader/Ring.java | 1 + .../tools/internal/xjc/reader/dtd/Block.java | 1 + .../internal/xjc/reader/dtd/Element.java | 3 +- .../xjc/reader/dtd/MessageBundle.properties | 21 +- .../internal/xjc/reader/dtd/ModelGroup.java | 1 + .../internal/xjc/reader/dtd/Occurence.java | 1 + .../tools/internal/xjc/reader/dtd/Term.java | 1 + .../xjc/reader/dtd/bindinfo/DOMBuilder.java | 1 + .../xjc/reader/dtd/bindinfo/DOMUtil.java | 1 + .../bindinfo/DTDExtensionBindingChecker.java | 1 + .../dtd/bindinfo/MessageBundle.properties | 5 +- .../xjc/reader/dtd/bindinfo/bindingfile.rng | 1 - .../xjc/reader/dtd/bindinfo/bindingfile.xsd | 3 +- .../internal/xjc/reader/dtd/bindinfo/xjc.xsd | 2 + .../internal/xjc/reader/gbind/Choice.java | 1 + .../xjc/reader/gbind/ConnectedComponent.java | 1 + .../internal/xjc/reader/gbind/Element.java | 14 + .../internal/xjc/reader/gbind/ElementSet.java | 1 + .../xjc/reader/gbind/ElementSets.java | 1 + .../internal/xjc/reader/gbind/Expression.java | 5 +- .../internal/xjc/reader/gbind/Graph.java | 1 + .../internal/xjc/reader/gbind/OneOrMore.java | 1 + .../internal/xjc/reader/gbind/Sequence.java | 1 + .../internal/xjc/reader/gbind/SinkNode.java | 1 + .../internal/xjc/reader/gbind/SourceNode.java | 1 + .../ContentHandlerNamespacePrefixAdapter.java | 1 + .../internalizer/MessageBundle.properties | 29 +- .../internalizer/NamespaceContextImpl.java | 34 +- .../internalizer/SCDBasedBindingSet.java | 1 + .../internalizer/WhitespaceStripper.java | 5 - .../xjc/reader/relaxng/BindStyle.java | 1 + .../reader/relaxng/ContentModelBinder.java | 3 +- .../xjc/reader/relaxng/DatatypeLib.java | 1 + .../xjc/reader/relaxng/DefineFinder.java | 1 + .../xjc/reader/relaxng/NameCalculator.java | 1 + .../xjc/reader/relaxng/RELAXNGCompiler.java | 1 + .../xjc/reader/relaxng/RawTypeSetBuilder.java | 1 + .../xjc/reader/relaxng/TypePatternBinder.java | 1 + .../xjc/reader/relaxng/TypeUseBinder.java | 1 + .../xjc/reader/xmlschema/Abstractifier.java | 1 + .../xjc/reader/xmlschema/BGMBuilder.java | 12 + .../xjc/reader/xmlschema/BindBlue.java | 1 + .../xjc/reader/xmlschema/BindGreen.java | 1 + .../xjc/reader/xmlschema/BindPurple.java | 1 + .../xjc/reader/xmlschema/BindRed.java | 14 +- .../xjc/reader/xmlschema/BindYellow.java | 1 + .../reader/xmlschema/BindingComponent.java | 1 + .../reader/xmlschema/ClassBinderFilter.java | 1 + .../xjc/reader/xmlschema/CollisionInfo.java | 5 - .../xjc/reader/xmlschema/ColorBinder.java | 1 + .../xmlschema/DefaultParticleBinder.java | 11 +- .../reader/xmlschema/ExpressionBuilder.java | 1 + .../xmlschema/ExpressionParticleBinder.java | 1 + .../xjc/reader/xmlschema/GElement.java | 1 + .../xjc/reader/xmlschema/GElementImpl.java | 1 + .../reader/xmlschema/GWildcardElement.java | 1 + .../reader/xmlschema/MessageBundle.properties | 102 +- .../xjc/reader/xmlschema/Messages.java | 6 + .../reader/xmlschema/MultiplicityCounter.java | 1 + .../reader/xmlschema/RawTypeSetBuilder.java | 8 +- .../xjc/reader/xmlschema/RefererFinder.java | 1 + .../reader/xmlschema/SimpleTypeBuilder.java | 37 +- .../xmlschema/UnusedCustomizationChecker.java | 23 + .../bindinfo/AnnotationParserFactoryImpl.java | 16 +- .../xmlschema/bindinfo/BIConversion.java | 18 +- .../xmlschema/bindinfo/BIFactoryMethod.java | 64 + .../xmlschema/bindinfo/BIGlobalBinding.java | 7 + .../bindinfo/BIInlineBinaryData.java | 62 + .../reader/xmlschema/bindinfo/BIProperty.java | 67 +- .../xjc/reader/xmlschema/bindinfo/BIXDom.java | 1 + .../bindinfo/BIXPluginCustomization.java | 1 + .../xmlschema/bindinfo/BIXSubstitutable.java | 1 + .../reader/xmlschema/bindinfo/BindInfo.java | 13 +- .../bindinfo/CollectionTypeAttribute.java | 1 + .../xmlschema/bindinfo/DomHandlerEx.java | 1 + .../xmlschema/bindinfo/EnumMemberMode.java | 1 + .../xmlschema/bindinfo/ForkingFilter.java | 5 + .../xmlschema/bindinfo/LocalScoping.java | 1 + .../bindinfo/MessageBundle.properties | 13 +- .../bindinfo/OptionalPropertyMode.java | 1 + .../xjc/reader/xmlschema/bindinfo/binding.rng | 7 + .../xjc/reader/xmlschema/bindinfo/binding.xsd | 36 + .../xmlschema/bindinfo/package-info.java | 1 + .../reader/xmlschema/bindinfo/package.html | 6 +- .../xjc/reader/xmlschema/bindinfo/xjc.xsd | 4 + .../xjc/reader/xmlschema/bindinfo/xs.xsd | 2 + .../AbstractExtendedComplexTypeBuilder.java | 221 + .../ct/ChoiceContentComplexTypeBuilder.java | 1 + .../xmlschema/ct/ComplexTypeBindingMode.java | 9 +- .../xmlschema/ct/ComplexTypeFieldBuilder.java | 3 +- .../ct/ExtendedComplexTypeBuilder.java | 204 +- .../xmlschema/ct/MessageBundle.properties | 1 - .../xjc/reader/xmlschema/ct/Messages.java | 1 + .../xmlschema/ct/MixedComplexTypeBuilder.java | 58 +- .../ct/MixedExtendedComplexTypeBuilder.java | 92 + .../ct/RestrictedComplexTypeBuilder.java | 36 +- .../xmlschema/parser/LSInputSAXWrapper.java | 1 + .../xmlschema/parser/MessageBundle.properties | 14 +- .../xjc/runtime/JAXBContextFactory.java | 1 + .../xjc/runtime/ZeroOneBooleanAdapter.java | 1 + .../internal/xjc/util/ForkContentHandler.java | 2 +- .../internal/xjc/util/ForkEntityResolver.java | 1 + .../xjc/util/MessageBundle.properties | 9 +- .../internal/xjc/util/MimeTypeRange.java | 1 + .../xjc/util/NamespaceContextAdapter.java | 1 + .../internal/xjc/util/ReadOnlyAdapter.java | 1 + .../tools/internal/xjc/util/StringCutter.java | 1 + .../internal/xjc/util/SubtreeCutter.java | 1 + .../internal/bind/AccessorFactoryImpl.java | 13 +- .../sun/xml/internal/bind/AnyTypeAdapter.java | 1 + .../xml/internal/bind/CycleRecoverable.java | 1 + .../internal/bind/DatatypeConverterImpl.java | 34 +- .../com/sun/xml/internal/bind/IDResolver.java | 1 + .../com/sun/xml/internal/bind/Locatable.java | 5 - .../com/sun/xml/internal/bind/Util.java | 1 + .../bind/ValidationEventLocatorEx.java | 5 - .../xml/internal/bind/XmlAccessorFactory.java | 1 - .../bind/annotation/OverrideAnnotationOf.java | 42 + .../internal/bind/annotation/XmlIsSet.java | 1 + .../internal/bind/annotation/XmlLocation.java | 1 + .../internal/bind/api/AccessorException.java | 1 + .../com/sun/xml/internal/bind/api/Bridge.java | 1 + .../xml/internal/bind/api/BridgeContext.java | 1 + .../xml/internal/bind/api/ClassResolver.java | 1 + .../internal/bind/api/CompositeStructure.java | 1 + .../xml/internal/bind/api/ErrorListener.java | 1 + .../xml/internal/bind/api/JAXBRIContext.java | 31 +- .../internal/bind/api}/Messages.java | 15 +- .../internal/bind/api}/Messages.properties | 3 +- .../xml/internal/bind/api/RawAccessor.java | 1 + .../xml/internal/bind/api/TypeReference.java | 14 +- .../internal/bind/api/impl/NameConverter.java | 1 + .../xml/internal/bind/api/impl/NameUtil.java | 26 +- .../xml/internal/bind/api/package-info.java | 1 + .../internal/bind/marshaller/DataWriter.java | 1 + .../bind/marshaller/Messages.properties | 33 +- .../bind/marshaller/MinimumEscapeHandler.java | 31 +- .../marshaller/NamespacePrefixMapper.java | 25 +- .../internal/bind/marshaller/XMLWriter.java | 1 + .../bind/unmarshaller/DOMScanner.java | 1 - .../bind/unmarshaller/Messages.properties | 34 +- .../internal/bind/unmarshaller/Patcher.java | 1 + .../internal/bind/util/AttributesImpl.java | 1 - .../util/ValidationEventLocatorExImpl.java | 5 - .../com/sun/xml/internal/bind/util/Which.java | 5 - .../xml/internal/bind/v2/ClassFactory.java | 44 +- .../xml/internal/bind/v2/ContextFactory.java | 23 +- .../xml/internal/bind/v2/Messages.properties | 1 - .../com/sun/xml/internal/bind/v2/TODO.java | 1 + .../bind/v2/bytecode/ClassTailor.java | 1 + .../AbstractInlineAnnotationReaderImpl.java | 1 + .../v2/model/annotation/AnnotationReader.java | 1 + .../v2/model/annotation/AnnotationSource.java | 1 + .../v2/model/annotation/ClassLocatable.java | 1 + .../v2/model/annotation/FieldLocatable.java | 1 + .../bind/v2/model/annotation/Init.java | 2 +- .../bind/v2/model/annotation/Locatable.java | 1 + .../model/annotation/LocatableAnnotation.java | 11 +- .../bind/v2/model/annotation/Messages.java | 1 + .../v2/model/annotation/Messages.properties | 1 - .../v2/model/annotation/MethodLocatable.java | 1 + .../bind/v2/model/annotation/Quick.java | 1 + .../annotation/RuntimeAnnotationReader.java | 1 + .../RuntimeInlineAnnotationReader.java | 1 + .../model/annotation/XmlSchemaTypeQuick.java | 66 + .../internal/bind/v2/model/core/Adapter.java | 1 + .../bind/v2/model/core/ArrayInfo.java | 1 + .../v2/model/core/AttributePropertyInfo.java | 1 + .../bind/v2/model/core/BuiltinLeafInfo.java | 1 + .../bind/v2/model/core/ClassInfo.java | 1 + .../internal/bind/v2/model/core/Element.java | 1 + .../bind/v2/model/core/ElementInfo.java | 1 + .../v2/model/core/ElementPropertyInfo.java | 1 + .../bind/v2/model/core/EnumConstant.java | 1 + .../bind/v2/model/core/EnumLeafInfo.java | 1 + .../bind/v2/model/core/ErrorHandler.java | 1 + .../xml/internal/bind/v2/model/core/ID.java | 1 + .../internal/bind/v2/model/core/LeafInfo.java | 1 + .../bind/v2/model/core/MapPropertyInfo.java | 1 + .../bind/v2/model/core/MaybeElement.java | 1 + .../bind/v2/model/core/NonElement.java | 10 +- .../bind/v2/model/core/NonElementRef.java | 1 + .../bind/v2/model/core/PropertyInfo.java | 1 + .../bind/v2/model/core/PropertyKind.java | 1 + .../xml/internal/bind/v2/model/core/Ref.java | 1 + .../v2/model/core/ReferencePropertyInfo.java | 6 + .../bind/v2/model/core/RegistryInfo.java | 1 + .../internal/bind/v2/model/core/TypeInfo.java | 1 + .../bind/v2/model/core/TypeInfoSet.java | 1 + .../internal/bind/v2/model/core/TypeRef.java | 1 + .../bind/v2/model/core/ValuePropertyInfo.java | 1 + .../bind/v2/model/core/WildcardMode.java | 1 + .../bind/v2/model/core/WildcardTypeInfo.java | 1 + .../bind/v2/model/core/package-info.java | 1 + .../bind/v2/model/impl/AnyTypeImpl.java | 5 +- .../bind/v2/model/impl/ArrayInfoImpl.java | 13 +- .../model/impl/AttributePropertyInfoImpl.java | 1 + .../v2/model/impl/BuiltinLeafInfoImpl.java | 1 + .../bind/v2/model/impl/ClassInfoImpl.java | 89 +- .../bind/v2/model/impl/DummyPropertyInfo.java | 35 + .../v2/model/impl/ERPropertyInfoImpl.java | 1 + .../bind/v2/model/impl/ElementInfoImpl.java | 1 + .../model/impl/ElementPropertyInfoImpl.java | 1 + .../bind/v2/model/impl/EnumConstantImpl.java | 1 + .../bind/v2/model/impl/EnumLeafInfoImpl.java | 1 + .../bind/v2/model/impl/FieldPropertySeed.java | 1 + .../model/impl/GetterSetterPropertySeed.java | 1 + .../bind/v2/model/impl/LeafInfoImpl.java | 1 + .../v2/model/impl/MapPropertyInfoImpl.java | 1 + .../internal/bind/v2/model/impl/Messages.java | 16 +- .../bind/v2/model/impl/Messages.properties | 44 +- .../bind/v2/model/impl/ModelBuilder.java | 18 + .../bind/v2/model/impl/PropertyInfoImpl.java | 5 +- .../bind/v2/model/impl/PropertySeed.java | 1 + .../model/impl/ReferencePropertyInfoImpl.java | 125 +- .../bind/v2/model/impl/RegistryInfoImpl.java | 1 + .../v2/model/impl/RuntimeAnyTypeImpl.java | 1 + .../v2/model/impl/RuntimeArrayInfoImpl.java | 1 + .../RuntimeAttributePropertyInfoImpl.java | 1 + .../impl/RuntimeBuiltinLeafInfoImpl.java | 160 +- .../v2/model/impl/RuntimeClassInfoImpl.java | 15 +- .../v2/model/impl/RuntimeElementInfoImpl.java | 1 + .../impl/RuntimeElementPropertyInfoImpl.java | 1 + .../model/impl/RuntimeEnumConstantImpl.java | 1 + .../model/impl/RuntimeEnumLeafInfoImpl.java | 1 + .../impl/RuntimeMapPropertyInfoImpl.java | 1 + .../v2/model/impl/RuntimeModelBuilder.java | 17 +- .../RuntimeReferencePropertyInfoImpl.java | 1 + .../v2/model/impl/RuntimeTypeInfoSetImpl.java | 1 + .../v2/model/impl/RuntimeTypeRefImpl.java | 1 + .../impl/RuntimeValuePropertyInfoImpl.java | 1 + .../impl/SingleTypePropertyInfoImpl.java | 5 +- .../bind/v2/model/impl/TypeInfoImpl.java | 1 + .../bind/v2/model/impl/TypeInfoSetImpl.java | 1 + .../bind/v2/model/impl/TypeRefImpl.java | 1 + .../xml/internal/bind/v2/model/impl/Util.java | 1 + .../v2/model/impl/ValuePropertyInfoImpl.java | 1 + .../v2/model/nav/GenericArrayTypeImpl.java | 1 + .../internal/bind/v2/model/nav/Navigator.java | 4 + .../v2/model/nav/ParameterizedTypeImpl.java | 1 + .../v2/model/nav/ReflectionNavigator.java | 5 +- .../bind/v2/model/nav/TypeVisitor.java | 1 + .../bind/v2/model/nav/WildcardTypeImpl.java | 1 + .../v2/model/runtime/RuntimeArrayInfo.java | 1 + .../runtime/RuntimeAttributePropertyInfo.java | 1 + .../model/runtime/RuntimeBuiltinLeafInfo.java | 1 + .../v2/model/runtime/RuntimeClassInfo.java | 1 + .../bind/v2/model/runtime/RuntimeElement.java | 1 + .../v2/model/runtime/RuntimeElementInfo.java | 1 + .../runtime/RuntimeElementPropertyInfo.java | 1 + .../v2/model/runtime/RuntimeEnumLeafInfo.java | 1 + .../v2/model/runtime/RuntimeLeafInfo.java | 1 + .../model/runtime/RuntimeMapPropertyInfo.java | 1 + .../v2/model/runtime/RuntimeNonElement.java | 1 + .../model/runtime/RuntimeNonElementRef.java | 1 + .../v2/model/runtime/RuntimePropertyInfo.java | 1 + .../runtime/RuntimeReferencePropertyInfo.java | 1 + .../v2/model/runtime/RuntimeTypeInfo.java | 1 + .../v2/model/runtime/RuntimeTypeInfoSet.java | 1 + .../bind/v2/model/runtime/RuntimeTypeRef.java | 1 + .../runtime/RuntimeValuePropertyInfo.java | 1 + .../bind/v2/model/runtime/package-info.java | 1 + .../xml/internal/bind/v2/package-info.java | 1 + .../bind/v2/runtime/AnyTypeBeanInfo.java | 13 +- .../bind/v2/runtime/ArrayBeanInfoImpl.java | 14 +- .../bind/v2/runtime/AttributeAccessor.java | 35 + .../internal/bind/v2/runtime/BinderImpl.java | 2 + .../bind/v2/runtime/BridgeAdapter.java | 1 + .../bind/v2/runtime/BridgeContextImpl.java | 1 + .../internal/bind/v2/runtime/BridgeImpl.java | 3 +- .../bind/v2/runtime/ClassBeanInfoImpl.java | 52 +- .../runtime/CompositeStructureBeanInfo.java | 1 + .../internal/bind/v2/runtime/Coordinator.java | 13 +- .../bind/v2/runtime/DomPostInitAction.java | 1 + .../bind/v2/runtime/ElementBeanInfoImpl.java | 13 +- .../bind/v2/runtime/FilterTransducer.java | 1 + .../runtime/IllegalAnnotationException.java | 1 + .../runtime/IllegalAnnotationsException.java | 1 + .../v2/runtime/InlineBinaryTransducer.java | 1 + .../bind/v2/runtime/InternalBridge.java | 1 + .../bind/v2/runtime/JAXBContextImpl.java | 174 +- .../internal/bind/v2/runtime/JaxBeanInfo.java | 65 +- .../bind/v2/runtime/LeafBeanInfoImpl.java | 1 + .../bind/v2/runtime/LifecycleMethods.java | 1 + .../internal/bind/v2/runtime/Location.java | 1 + .../bind/v2/runtime/MarshallerImpl.java | 26 +- .../internal/bind/v2/runtime/Messages.java | 2 + .../bind/v2/runtime/Messages.properties | 22 +- .../bind/v2/runtime/MimeTypedTransducer.java | 1 + .../xml/internal/bind/v2/runtime/Name.java | 1 + .../internal/bind/v2/runtime/NameBuilder.java | 1 + .../internal/bind/v2/runtime/NameList.java | 1 + .../internal/bind/v2/runtime/RuntimeUtil.java | 1 + .../bind/v2/runtime/SchemaTypeTransducer.java | 1 + .../bind/v2/runtime/StAXPostInitAction.java | 1 + .../bind/v2/runtime/SwaRefAdapter.java | 1 + .../internal/bind/v2/runtime/Transducer.java | 1 + .../v2/runtime/ValueListBeanInfoImpl.java | 1 + .../bind/v2/runtime/XMLSerializer.java | 39 +- .../bind/v2/runtime/output/C14nXmlOutput.java | 1 + .../bind/v2/runtime/output/DOMOutput.java | 1 + .../bind/v2/runtime/output/Encoded.java | 1 + .../output/FastInfosetStreamWriterOutput.java | 39 +- .../bind/v2/runtime/output/ForkXmlOutput.java | 1 + .../v2/runtime/output/InPlaceDOMOutput.java | 1 + .../output/IndentingUTF8XmlOutput.java | 1 + .../bind/v2/runtime/output/MTOMXmlOutput.java | 1 + .../runtime/output/NamespaceContextImpl.java | 6 +- .../bind/v2/runtime/output/Pcdata.java | 1 + .../bind/v2/runtime/output/SAXOutput.java | 11 +- .../output/StAXExStreamWriterOutput.java | 59 + .../bind/v2/runtime/output/UTF8XmlOutput.java | 1 + .../runtime/output/XMLEventWriterOutput.java | 1 + .../runtime/output/XMLStreamWriterOutput.java | 13 +- .../bind/v2/runtime/output/XmlOutput.java | 1 + .../runtime/output/XmlOutputAbstractImpl.java | 1 + .../bind/v2/runtime/output/package-info.java | 1 + .../v2/runtime/property/ArrayERProperty.java | 1 + .../property/ArrayElementLeafProperty.java | 1 + .../property/ArrayElementNodeProperty.java | 3 +- .../property/ArrayElementProperty.java | 3 +- .../v2/runtime/property/ArrayProperty.java | 1 + .../property/ArrayReferenceNodeProperty.java | 10 +- .../runtime/property/AttributeProperty.java | 13 +- .../runtime/property/ListElementProperty.java | 1 + .../bind/v2/runtime/property/Messages.java | 1 + .../v2/runtime/property/Messages.properties | 1 - .../bind/v2/runtime/property/Property.java | 12 + .../v2/runtime/property/PropertyFactory.java | 1 + .../v2/runtime/property/PropertyImpl.java | 9 + .../property/SingleElementLeafProperty.java | 1 + .../property/SingleElementNodeProperty.java | 27 +- .../property/SingleMapNodeProperty.java | 5 +- .../property/SingleReferenceNodeProperty.java | 1 + .../property/StructureLoaderBuilder.java | 1 + .../bind/v2/runtime/property/TagAndType.java | 1 + .../runtime/property/UnmarshallerChain.java | 3 - .../v2/runtime/property/ValueProperty.java | 1 + .../bind/v2/runtime/reflect/Accessor.java | 18 +- .../v2/runtime/reflect/AdaptedAccessor.java | 1 + .../v2/runtime/reflect/AdaptedLister.java | 1 + .../reflect/DefaultTransducedAccessor.java | 1 + .../bind/v2/runtime/reflect/ListIterator.java | 1 + .../reflect/ListTransducedAccessorImpl.java | 1 + .../bind/v2/runtime/reflect/Lister.java | 14 +- .../bind/v2/runtime/reflect/Messages.java | 1 + .../v2/runtime/reflect/Messages.properties | 1 - .../v2/runtime/reflect/NullSafeAccessor.java | 1 + .../reflect/PrimitiveArrayListerBoolean.java | 4 +- .../reflect/PrimitiveArrayListerByte.java | 4 +- .../PrimitiveArrayListerCharacter.java | 4 +- .../reflect/PrimitiveArrayListerDouble.java | 4 +- .../reflect/PrimitiveArrayListerFloat.java | 4 +- .../reflect/PrimitiveArrayListerInteger.java | 4 +- .../reflect/PrimitiveArrayListerLong.java | 4 +- .../reflect/PrimitiveArrayListerShort.java | 4 +- .../runtime/reflect/TransducedAccessor.java | 1 + .../runtime/reflect/opt/AccessorInjector.java | 1 + .../bind/v2/runtime/reflect/opt/Bean.java | 1 + .../bind/v2/runtime/reflect/opt/Const.java | 1 + .../reflect/opt/FieldAccessor_Boolean.java | 1 + .../reflect/opt/FieldAccessor_Byte.java | 1 + .../reflect/opt/FieldAccessor_Character.java | 1 + .../reflect/opt/FieldAccessor_Double.java | 1 + .../reflect/opt/FieldAccessor_Float.java | 1 + .../reflect/opt/FieldAccessor_Integer.java | 1 + .../reflect/opt/FieldAccessor_Long.java | 1 + .../reflect/opt/FieldAccessor_Ref.java | 1 + .../reflect/opt/FieldAccessor_Short.java | 1 + .../bind/v2/runtime/reflect/opt/Injector.java | 21 + .../reflect/opt/MethodAccessor_Boolean.java | 1 + .../reflect/opt/MethodAccessor_Byte.java | 1 + .../reflect/opt/MethodAccessor_Character.java | 1 + .../reflect/opt/MethodAccessor_Double.java | 1 + .../reflect/opt/MethodAccessor_Float.java | 1 + .../reflect/opt/MethodAccessor_Integer.java | 1 + .../reflect/opt/MethodAccessor_Long.java | 1 + .../reflect/opt/MethodAccessor_Ref.java | 1 + .../reflect/opt/MethodAccessor_Short.java | 1 + .../reflect/opt/OptimizedAccessorFactory.java | 6 +- .../OptimizedTransducedAccessorFactory.java | 1 + .../bind/v2/runtime/reflect/opt/Ref.java | 1 + .../opt/TransducedAccessor_field_Boolean.java | 1 + .../opt/TransducedAccessor_field_Byte.java | 1 + .../opt/TransducedAccessor_field_Double.java | 1 + .../opt/TransducedAccessor_field_Float.java | 1 + .../opt/TransducedAccessor_field_Integer.java | 1 + .../opt/TransducedAccessor_field_Long.java | 1 + .../opt/TransducedAccessor_field_Short.java | 1 + .../TransducedAccessor_method_Boolean.java | 1 + .../opt/TransducedAccessor_method_Byte.java | 1 + .../opt/TransducedAccessor_method_Double.java | 1 + .../opt/TransducedAccessor_method_Float.java | 1 + .../TransducedAccessor_method_Integer.java | 1 + .../opt/TransducedAccessor_method_Long.java | 1 + .../opt/TransducedAccessor_method_Short.java | 1 + .../v2/runtime/unmarshaller/AttributesEx.java | 1 + .../unmarshaller/AttributesExImpl.java | 1 + .../v2/runtime/unmarshaller/Base64Data.java | 1 + .../v2/runtime/unmarshaller/ChildLoader.java | 1 + .../unmarshaller/DefaultIDResolver.java | 10 +- .../DefaultValueLoaderDecorator.java | 1 + .../v2/runtime/unmarshaller/Discarder.java | 3 - .../v2/runtime/unmarshaller/DomLoader.java | 1 + .../unmarshaller/FastInfosetConnector.java | 36 +- .../v2/runtime/unmarshaller/IntArrayData.java | 1 + .../bind/v2/runtime/unmarshaller/IntData.java | 1 + .../v2/runtime/unmarshaller/Intercepter.java | 1 + .../unmarshaller/InterningXmlVisitor.java | 1 + .../unmarshaller/LeafPropertyLoader.java | 1 + .../bind/v2/runtime/unmarshaller/Loader.java | 15 +- .../v2/runtime/unmarshaller/LocatorEx.java | 1 + .../unmarshaller/LocatorExWrapper.java | 1 + .../runtime/unmarshaller/MTOMDecorator.java | 3 +- .../v2/runtime/unmarshaller/Messages.java | 2 + .../runtime/unmarshaller/Messages.properties | 6 +- .../bind/v2/runtime/unmarshaller/Patcher.java | 1 + .../v2/runtime/unmarshaller/ProxyLoader.java | 1 + .../v2/runtime/unmarshaller/Receiver.java | 1 + .../v2/runtime/unmarshaller/SAXConnector.java | 14 +- .../bind/v2/runtime/unmarshaller/Scope.java | 1 + .../runtime/unmarshaller/StAXConnector.java | 1 + .../unmarshaller/StAXEventConnector.java | 2 + .../runtime/unmarshaller/StAXExConnector.java | 72 + .../unmarshaller/StAXStreamConnector.java | 10 +- .../runtime/unmarshaller/StructureLoader.java | 5 + .../bind/v2/runtime/unmarshaller/TagName.java | 1 + .../v2/runtime/unmarshaller/TextLoader.java | 1 + .../unmarshaller/UnmarshallerImpl.java | 27 +- .../unmarshaller/UnmarshallingContext.java | 91 +- .../unmarshaller/ValuePropertyLoader.java | 1 + .../runtime/unmarshaller/WildcardLoader.java | 3 - .../v2/runtime/unmarshaller/XmlVisitor.java | 5 +- .../v2/runtime/unmarshaller/XsiNilLoader.java | 25 +- .../runtime/unmarshaller/XsiTypeLoader.java | 1 + .../bind/v2/schemagen/FoolProofResolver.java | 1 + .../xml/internal/bind/v2/schemagen/Form.java | 1 + .../internal/bind/v2/schemagen/GroupKind.java | 1 + .../internal/bind/v2/schemagen/Messages.java | 1 + .../bind/v2/schemagen/Messages.properties | 1 - .../internal/bind/v2/schemagen/MultiMap.java | 1 + .../xml/internal/bind/v2/schemagen/Tree.java | 1 + .../bind/v2/schemagen/XmlSchemaGenerator.java | 57 +- .../bind/v2/schemagen/episode/Bindings.java | 1 + .../bind/v2/schemagen/episode/Klass.java | 1 + .../v2/schemagen/episode/SchemaBindings.java | 1 + .../v2/schemagen/episode/package-info.java | 1 + .../bind/v2/schemagen/package-info.java | 1 + .../xmlschema/ContentModelContainer.java | 1 + .../bind/v2/schemagen/xmlschema/Element.java | 4 +- .../bind/v2/schemagen/xmlschema/Occurs.java | 6 +- .../bind/v2/schemagen/xmlschema/Particle.java | 1 + .../bind/v2/schemagen/xmlschema/Schema.java | 4 +- .../v2/schemagen/xmlschema/SimpleType.java | 4 +- .../bind/v2/schemagen/xmlschema/Wildcard.java | 6 +- .../bind/v2/util/ByteArrayOutputStreamEx.java | 1 + .../bind/v2/util/CollisionCheckStack.java | 1 + .../bind/v2/util/DataSourceSource.java | 17 +- .../internal/bind/v2/util/EditDistance.java | 5 - .../internal/bind/v2/util/FatalAdapter.java | 1 + .../bind/v2/util/FlattenIterator.java | 1 + .../xml/internal/bind/v2/util/QNameMap.java | 1 + .../internal/bind/v2/util/StackRecorder.java | 33 + .../xml/internal/bind/v2/util/TypeCast.java | 1 + .../sun/xml/internal/dtdparser/DTDParser.java | 2 +- .../dtdparser/resources/Messages.properties | 101 +- .../fastinfoset/AbstractResourceBundle.java | 35 +- .../sun/xml/internal/fastinfoset/Decoder.java | 55 +- .../fastinfoset/DecoderStateTables.java | 66 +- .../sun/xml/internal/fastinfoset/Encoder.java | 397 +- .../BuiltInEncodingAlgorithmFactory.java | 6 +- .../HexadecimalEncodingAlgorithm.java | 2 +- .../algorithm/LongEncodingAlgorithm.java | 17 +- .../algorithm/UUIDEncodingAlgorithm.java | 2 +- .../fastinfoset/dom/DOMDocumentParser.java | 197 +- .../dom/DOMDocumentSerializer.java | 2 +- .../org/apache/xerces/util/XMLChar.java | 4 +- .../resources/ResourceBundle.properties | 7 +- .../fastinfoset/sax/AttributesHolder.java | 2 +- .../fastinfoset/sax/SAXDocumentParser.java | 120 +- .../sax/SAXDocumentSerializer.java | 44 +- ...AXDocumentSerializerWithPrefixMapping.java | 31 +- .../fastinfoset/stax/StAXDocumentParser.java | 54 +- .../stax/StAXDocumentSerializer.java | 19 +- .../stax/events/StAXEventAllocator.java | 237 - .../tools/VocabularyGenerator.java | 4 +- .../fastinfoset/util/CharArrayIntMap.java | 22 +- .../util/DuplicateAttributeVerifier.java | 2 +- .../util/NamespaceContextImplementation.java | 13 +- .../fastinfoset/util/StringIntMap.java | 2 +- .../messaging/saaj/SOAPExceptionImpl.java | 5 - .../saaj/client/p2p/HttpSOAPConnection.java | 57 +- .../client/p2p/HttpSOAPConnectionFactory.java | 5 - .../saaj/client/p2p/LocalStrings.properties | 1 - .../saaj/soap/AttachmentPartImpl.java | 7 +- .../messaging/saaj/soap/Envelope.java | 5 - .../messaging/saaj/soap/EnvelopeFactory.java | 8 +- .../soap/FastInfosetDataContentHandler.java | 5 - .../saaj/soap/GifDataContentHandler.java | 6 +- .../saaj/soap/ImageDataContentHandler.java | 5 - .../saaj/soap/JpegDataContentHandler.java | 6 - .../saaj/soap/LocalStrings.properties | 1 - .../saaj/soap/MessageFactoryImpl.java | 5 - .../messaging/saaj/soap/MessageImpl.java | 8 +- .../soap/MultipartDataContentHandler.java | 5 - .../saaj/soap/SAAJMetaFactoryImpl.java | 1 + .../messaging/saaj/soap/SOAPDocument.java | 3 - .../saaj/soap/SOAPDocumentFragment.java | 3 - .../messaging/saaj/soap/SOAPDocumentImpl.java | 5 +- .../messaging/saaj/soap/SOAPFactoryImpl.java | 5 - .../messaging/saaj/soap/SOAPIOException.java | 1 - .../messaging/saaj/soap/SOAPPartImpl.java | 17 +- .../soap/SOAPVersionMismatchException.java | 5 - .../saaj/soap/StringDataContentHandler.java | 225 +- .../saaj/soap/XmlDataContentHandler.java | 15 +- .../soap/dynamic/SOAPFactoryDynamicImpl.java | 3 - .../SOAPMessageFactoryDynamicImpl.java | 3 - .../saaj/soap/impl/BodyElementImpl.java | 5 - .../messaging/saaj/soap/impl/BodyImpl.java | 5 - .../messaging/saaj/soap/impl/CDATAImpl.java | 5 - .../messaging/saaj/soap/impl/CommentImpl.java | 5 - .../saaj/soap/impl/DetailEntryImpl.java | 5 - .../messaging/saaj/soap/impl/DetailImpl.java | 30 +- .../saaj/soap/impl/ElementFactory.java | 5 - .../messaging/saaj/soap/impl/ElementImpl.java | 37 +- .../saaj/soap/impl/EnvelopeImpl.java | 5 - .../saaj/soap/impl/FaultElementImpl.java | 5 - .../messaging/saaj/soap/impl/FaultImpl.java | 11 +- .../saaj/soap/impl/HeaderElementImpl.java | 5 - .../messaging/saaj/soap/impl/HeaderImpl.java | 5 - .../saaj/soap/impl/LocalStrings.properties | 3 +- .../messaging/saaj/soap/impl/TextImpl.java | 5 - .../saaj/soap/impl/TreeException.java | 5 - .../saaj/soap/name/LocalStrings.properties | 1 - .../messaging/saaj/soap/name/NameImpl.java | 20 +- .../saaj/soap/ver1_1/Body1_1Impl.java | 3 - .../saaj/soap/ver1_1/BodyElement1_1Impl.java | 3 - .../saaj/soap/ver1_1/Detail1_1Impl.java | 3 - .../saaj/soap/ver1_1/DetailEntry1_1Impl.java | 3 - .../saaj/soap/ver1_1/Envelope1_1Impl.java | 3 - .../saaj/soap/ver1_1/Fault1_1Impl.java | 64 +- .../saaj/soap/ver1_1/FaultElement1_1Impl.java | 3 - .../saaj/soap/ver1_1/Header1_1Impl.java | 3 - .../soap/ver1_1/HeaderElement1_1Impl.java | 3 - .../saaj/soap/ver1_1/LocalStrings.properties | 6 +- .../saaj/soap/ver1_1/Message1_1Impl.java | 3 - .../saaj/soap/ver1_1/SOAPFactory1_1Impl.java | 7 +- .../ver1_1/SOAPMessageFactory1_1Impl.java | 3 - .../saaj/soap/ver1_1/SOAPPart1_1Impl.java | 3 - .../saaj/soap/ver1_2/Body1_2Impl.java | 5 +- .../saaj/soap/ver1_2/BodyElement1_2Impl.java | 3 - .../saaj/soap/ver1_2/Detail1_2Impl.java | 3 - .../saaj/soap/ver1_2/DetailEntry1_2Impl.java | 3 - .../saaj/soap/ver1_2/Envelope1_2Impl.java | 3 - .../saaj/soap/ver1_2/Fault1_2Impl.java | 3 - .../saaj/soap/ver1_2/FaultElement1_2Impl.java | 3 - .../saaj/soap/ver1_2/Header1_2Impl.java | 3 - .../soap/ver1_2/HeaderElement1_2Impl.java | 3 - .../saaj/soap/ver1_2/LocalStrings.properties | 1 - .../saaj/soap/ver1_2/Message1_2Impl.java | 3 - .../saaj/soap/ver1_2/SOAPFactory1_2Impl.java | 3 - .../ver1_2/SOAPMessageFactory1_2Impl.java | 3 - .../saaj/soap/ver1_2/SOAPPart1_2Impl.java | 3 - .../internal/messaging/saaj/util/Base64.java | 7 +- .../messaging/saaj/util/ByteInputStream.java | 6 - .../messaging/saaj/util/ByteOutputStream.java | 4 - .../messaging/saaj/util/CharReader.java | 5 - .../messaging/saaj/util/CharWriter.java | 5 - .../saaj/util/FastInfosetReflection.java | 5 - .../messaging/saaj/util/FinalArrayList.java | 1 + .../messaging/saaj/util/JAXMStreamSource.java | 5 - .../internal/messaging/saaj/util/JaxmURI.java | 7 +- .../saaj/util/LocalStrings.properties | 1 - .../saaj/util/LogDomainConstants.java | 5 - .../messaging/saaj/util/MimeHeadersUtil.java | 3 - .../saaj/util/NamespaceContextIterator.java | 3 - .../messaging/saaj/util/ParseUtil.java | 5 - .../messaging/saaj/util/ParserPool.java | 5 - .../saaj/util/RejectDoctypeSaxFilter.java | 1 - .../messaging/saaj/util/TeeInputStream.java | 1 - .../saaj/util/XMLDeclarationParser.java | 3 +- .../EfficientStreamingTransformer.java | 35 +- .../fastinfoset/FastInfosetSerializer.java | 118 +- .../EncodingAlgorithmAttributesImpl.java | 12 +- .../internal/org/jvnet/mimepull/Chunk.java | 50 + .../org/jvnet/mimepull/ChunkInputStream.java | 94 + .../xml/internal/org/jvnet/mimepull/Data.java | 70 + .../internal/org/jvnet/mimepull/DataFile.java | 83 + .../internal/org/jvnet/mimepull/DataHead.java | 258 + .../internal/org/jvnet/mimepull/FileData.java | 73 + .../org/jvnet/mimepull/FinalArrayList.java | 49 + .../internal/org/jvnet/mimepull/Header.java | 48 + .../org/jvnet/mimepull/InternetHeaders.java | 238 + .../org/jvnet/mimepull/MIMEConfig.java | 147 + .../org/jvnet/mimepull/MIMEEvent.java | 116 + .../org/jvnet/mimepull/MIMEMessage.java | 248 + .../org/jvnet/mimepull/MIMEParser.java | 500 + .../jvnet/mimepull/MIMEParsingException.java | 87 + .../internal/org/jvnet/mimepull/MIMEPart.java | 206 + .../org/jvnet/mimepull/MemoryData.java | 96 + .../org/jvnet/mimepull/WeakDataFile.java | 116 + .../internal/org/jvnet/staxex/Base64Data.java | 36 +- .../org/jvnet/staxex/Base64Encoder.java | 1 + .../jvnet/staxex/ByteArrayOutputStreamEx.java | 1 + .../org/jvnet/staxex/NamespaceContextEx.java | 1 + .../jvnet/staxex/StreamingDataHandler.java | 143 + .../org/jvnet/staxex/XMLStreamReaderEx.java | 1 + .../org/jvnet/staxex/XMLStreamWriterEx.java | 16 +- .../internal/rngom/binary/Messages.properties | 1 - .../rngom/dt/builtin/Messages.properties | 1 - .../internal/rngom/parse/Messages.properties | 1 - .../rngom/parse/compact/Messages.properties | 1 - .../rngom/parse/xml/Messages.properties | 1 - .../stream/buffer/AbstractProcessor.java | 18 +- .../stream/buffer/MutableXMLStreamBuffer.java | 2 +- .../stream/buffer/sax/SAXBufferCreator.java | 6 +- .../stream/buffer/sax/SAXBufferProcessor.java | 4 +- .../buffer/stax/StreamBufferCreator.java | 29 + .../stax/StreamReaderBufferCreator.java | 31 + .../stax/StreamReaderBufferProcessor.java | 19 +- .../stax/StreamWriterBufferCreator.java | 6 +- .../stax/StreamWriterBufferProcessor.java | 94 +- .../xml/internal/txw2/NamespaceSupport.java | 1 - .../com/sun/xml/internal/txw2/TXW.java | 10 + .../internal/txw2/annotation/XmlValue.java | 4 - .../internal/txw2/output/ResultFactory.java | 2 + .../xml/internal/txw2/output/TXWResult.java | 65 + .../internal/txw2/output/TXWSerializer.java | 86 + .../ws/addressing/EndpointReferenceUtil.java | 3 +- .../ws/addressing/W3CWsaClientTube.java | 69 + .../ws/addressing/W3CWsaServerTube.java | 76 + .../internal/ws/addressing/WsaClientTube.java | 26 +- .../ws/addressing/WsaPropertyBag.java | 126 + .../internal/ws/addressing/WsaServerTube.java | 100 +- .../xml/internal/ws/addressing/WsaTube.java | 107 +- .../internal/ws/addressing/WsaTubeHelper.java | 32 +- .../ws/addressing/WsaTubeHelperImpl.java | 17 +- .../model/ActionNotSupportedException.java | 9 +- .../InvalidAddressingHeaderException.java | 64 + .../MissingAddressingHeaderException.java | 78 + .../MemberSubmissionWsaClientTube.java | 84 + .../MemberSubmissionWsaServerTube.java | 87 + .../addressing/v200408/WsaTubeHelperImpl.java | 17 +- .../sun/xml/internal/ws/api/BindingID.java | 28 +- .../xml/internal/ws/api/EndpointAddress.java | 3 + .../xml/internal/ws/api/ResourceLoader.java | 67 + .../sun/xml/internal/ws/api/SOAPVersion.java | 6 + .../sun/xml/internal/ws/api/WSService.java | 80 + .../ws/api/addressing/AddressingVersion.java | 4 + .../OutboundReferenceParameterHeader.java | 51 +- .../api/addressing/WSEndpointReference.java | 30 +- .../ws/api/handler/MessageHandler.java | 54 + .../ws/api/handler/MessageHandlerContext.java | 88 + .../ws/api/message/FilterMessageImpl.java | 164 + .../xml/internal/ws/api/message/Message.java | 26 + .../xml/internal/ws/api/message/Messages.java | 34 +- .../xml/internal/ws/api/message/Packet.java | 97 +- .../xml/internal/ws/api/model/JavaMethod.java | 18 + .../ws/api/model/wsdl/WSDLBoundFault.java | 73 + .../ws/api/model/wsdl/WSDLBoundOperation.java | 42 +- .../ws/api/model/wsdl/WSDLBoundPortType.java | 9 + .../ws/api/model/wsdl/WSDLExtensible.java | 2 +- .../internal/ws/api/model/wsdl/WSDLFault.java | 19 + .../internal/ws/api/model/wsdl/WSDLInput.java | 28 + .../ws/api/model/wsdl/WSDLMessage.java | 5 + .../internal/ws/api/model/wsdl/WSDLModel.java | 20 +- .../ws/api/model/wsdl/WSDLOperation.java | 2 +- .../ws/api/model/wsdl/WSDLOutput.java | 21 + .../ws/api/model/wsdl/WSDLPortType.java | 2 +- .../api/pipe/ClientPipeAssemblerContext.java | 7 + .../api/pipe/ClientTubeAssemblerContext.java | 90 +- .../sun/xml/internal/ws/api/pipe/Engine.java | 27 +- .../sun/xml/internal/ws/api/pipe/Fiber.java | 26 +- .../xml/internal/ws/api/pipe/NextAction.java | 9 + .../api/pipe/ServerPipeAssemblerContext.java | 7 + .../api/pipe/ServerTubeAssemblerContext.java | 31 +- .../internal/ws/api/pipe/StreamSOAPCodec.java | 11 + .../ws/api/pipe/TransportTubeFactory.java | 2 +- .../pipe/helper/AbstractFilterTubeImpl.java | 6 +- .../ws/api/pipe/helper/AbstractTubeImpl.java | 6 + .../internal/ws/api/server/BoundEndpoint.java | 20 + .../ws/api/server/EndpointComponent.java | 52 + .../internal/ws/api/server/HttpEndpoint.java | 62 + .../ws/api/server/InstanceResolver.java | 38 +- .../ws/api/server/PortAddressResolver.java | 18 + .../internal/ws/api/server/SDDocument.java | 12 + .../internal/ws/api/server/WSEndpoint.java | 33 + .../api/streaming/XMLStreamReaderFactory.java | 111 +- .../api/streaming/XMLStreamWriterFactory.java | 52 +- .../api/wsdl/parser/WSDLParserExtension.java | 18 +- .../parser/WSDLParserExtensionContext.java | 11 + .../xml/internal/ws/binding/BindingImpl.java | 8 + .../internal/ws/binding/HTTPBindingImpl.java | 2 +- .../internal/ws/binding/SOAPBindingImpl.java | 20 +- .../ws/binding/WebServiceFeatureList.java | 9 +- .../xml/internal/ws/client/AsyncInvoker.java | 15 + .../internal/ws/client/AsyncResponseImpl.java | 4 - .../ws/client/BindingProviderProperties.java | 4 - .../internal/ws/client/ClientContainer.java | 55 + .../ws/client/ClientSchemaValidationTube.java | 163 + .../ws/client/HandlerConfiguration.java | 15 +- .../xml/internal/ws/client/ResponseImpl.java | 118 - .../com/sun/xml/internal/ws/client/Stub.java | 73 +- .../internal/ws/client/WSServiceDelegate.java | 145 +- .../client/dispatch/DataSourceDispatch.java | 4 +- .../ws/client/dispatch/DispatchImpl.java | 75 +- .../client/dispatch/RESTSourceDispatch.java | 2 +- .../client/dispatch/SOAPMessageDispatch.java | 29 +- .../internal/ws/client/sei/AsyncBuilder.java | 244 - .../ws/client/sei/AsyncMethodHandler.java | 264 +- .../internal/ws/client/sei/BodyBuilder.java | 16 +- .../ws/client/sei/CallbackMethodHandler.java | 4 +- .../internal/ws/client/sei/MessageFiller.java | 2 +- .../internal/ws/client/sei/MethodHandler.java | 2 +- .../ws/client/sei/PollingMethodHandler.java | 4 +- .../ws/client/sei/ResponseBuilder.java | 34 +- .../ws/client/sei/SEIMethodHandler.java | 214 + .../xml/internal/ws/client/sei/SEIStub.java | 11 +- .../ws/client/sei/SyncMethodHandler.java | 161 +- .../internal/ws/client/sei/ValueGetter.java | 14 +- .../ws/client/sei/ValueGetterFactory.java | 57 + .../internal/ws/client/sei/ValueSetter.java | 67 +- .../ws/client/sei/ValueSetterFactory.java | 70 + .../{package-info.java => pacakge-info.java} | 0 .../ws/developer/BindingTypeFeature.java | 55 + .../ws/developer/JAXBContextFactory.java | 101 + .../ws/developer/JAXWSProperties.java | 141 +- .../developer/MemberSubmissionAddressing.java | 12 +- .../MemberSubmissionAddressingFeature.java | 33 +- .../MemberSubmissionEndpointReference.java | 4 +- .../ws/developer/SchemaValidation.java | 92 + .../ws/developer/SchemaValidationFeature.java | 74 + .../ws/developer/StatefulFeature.java | 1 - .../ws/developer/StreamingAttachment.java | 76 + .../developer/StreamingAttachmentFeature.java | 117 + .../ws/developer/StreamingDataHandler.java | 69 + .../ws/developer/UsesJAXBContext.java | 68 + .../ws/developer/UsesJAXBContextFeature.java | 124 + .../ws/developer/ValidationErrorHandler.java | 58 + .../ws/developer/WSBindingProvider.java | 20 +- .../AbstractXMLStreamWriterExImpl.java | 83 - .../xml/internal/ws/encoding/ContentType.java | 136 + .../internal/ws/encoding/ContentTypeImpl.java | 40 +- .../DataSourceStreamingDataHandler.java | 63 + .../internal/ws/encoding/HeaderTokenizer.java | 382 + .../ws/encoding/ImageDataContentHandler.java | 164 + .../MIMEPartStreamingDataHandler.java | 129 + .../xml/internal/ws/encoding/MimeCodec.java | 78 +- .../ws/encoding/MimeMultipartParser.java | 492 +- .../xml/internal/ws/encoding/MtomCodec.java | 249 +- .../internal/ws/encoding/ParameterList.java | 138 + .../internal/ws/encoding/RootOnlyCodec.java | 71 + .../ws/encoding/SOAPBindingCodec.java | 116 +- .../ws/encoding/StreamSOAP11Codec.java | 2 +- .../ws/encoding/StreamSOAP12Codec.java | 2 +- .../internal/ws/encoding/StreamSOAPCodec.java | 32 +- .../ws/encoding/StringDataContentHandler.java | 148 + .../xml/internal/ws/encoding/SwACodec.java | 21 +- .../xml/internal/ws/encoding/TagInfoset.java | 11 +- .../ws/encoding/XMLHTTPBindingCodec.java | 27 +- .../ws/encoding/XmlDataContentHandler.java | 114 + .../fastinfoset/FastInfosetCodec.java | 7 +- .../internal/ws/encoding/xml/XMLCodec.java | 9 +- .../internal/ws/encoding/xml/XMLMessage.java | 228 +- .../xml/internal/ws/fault/SOAP11Fault.java | 22 +- .../xml/internal/ws/fault/SOAP12Fault.java | 48 +- .../internal/ws/fault/SOAPFaultBuilder.java | 78 +- .../ws/handler/ClientLogicalHandlerTube.java | 69 +- .../ws/handler/ClientMessageHandlerTube.java | 150 + .../ws/handler/ClientSOAPHandlerTube.java | 65 +- .../xml/internal/ws/handler/HandlerTube.java | 121 +- .../ws/handler/MessageHandlerContextImpl.java | 84 + .../ws/handler/SOAPMessageContextImpl.java | 7 +- .../ws/handler/ServerLogicalHandlerTube.java | 87 +- .../ws/handler/ServerMessageHandlerTube.java | 149 + .../ws/handler/ServerSOAPHandlerTube.java | 81 +- .../message/AttachmentUnmarshallerImpl.java | 5 - .../ws/message/ByteArrayAttachment.java | 6 +- .../xml/internal/ws/message/DOMHeader.java | 4 +- .../ws/message/DataHandlerAttachment.java | 7 +- .../xml/internal/ws/message/FaultMessage.java | 55 + .../internal/ws/message/JAXBAttachment.java | 15 +- .../ws/message/MimeAttachmentSet.java | 6 +- .../internal/ws/message/jaxb/JAXBHeader.java | 14 +- .../internal/ws/message/jaxb/JAXBMessage.java | 18 +- .../ws/message/jaxb/MarshallerBridge.java | 4 +- .../internal/ws/message/saaj/SAAJMessage.java | 393 +- .../ws/message/stream/StreamAttachment.java | 3 +- .../ws/message/stream/StreamHeader.java | 6 +- .../ws/message/stream/StreamHeader11.java | 6 +- .../ws/message/stream/StreamHeader12.java | 8 +- .../ws/message/stream/StreamMessage.java | 68 +- .../ws/model/AbstractSEIModelImpl.java | 59 +- .../xml/internal/ws/model/FieldSignature.java | 100 + .../sun/xml/internal/ws/model/Injector.java | 192 + .../xml/internal/ws/model/JavaMethodImpl.java | 26 +- .../xml/internal/ws/model/RuntimeModeler.java | 205 +- .../xml/internal/ws/model/SOAPSEIModel.java | 5 + .../ws/model/WrapperBeanGenerator.java | 659 + .../ws/model/wsdl/WSDLBoundFaultImpl.java | 84 + .../ws/model/wsdl/WSDLBoundOperationImpl.java | 109 +- .../ws/model/wsdl/WSDLBoundPortTypeImpl.java | 16 +- .../internal/ws/model/wsdl/WSDLFaultImpl.java | 16 +- .../internal/ws/model/wsdl/WSDLInputImpl.java | 12 + .../ws/model/wsdl/WSDLMessageImpl.java | 2 +- .../ws/model/wsdl/WSDLOutputImpl.java | 12 + .../org/objectweb/asm/AnnotationVisitor.java | 127 + .../org/objectweb/asm/AnnotationWriter.java | 346 + .../ws/org/objectweb/asm/Attribute.java | 284 + .../ws/org/objectweb/asm/ByteVector.java | 323 + .../ws/org/objectweb/asm/ClassReader.java | 2039 + .../ws/org/objectweb/asm/ClassVisitor.java | 226 + .../ws/org/objectweb/asm/ClassWriter.java | 1374 + .../internal/ws/org/objectweb/asm/Edge.java | 105 + .../ws/org/objectweb/asm/FieldVisitor.java | 94 + .../ws/org/objectweb/asm/FieldWriter.java | 299 + .../internal/ws/org/objectweb/asm/Frame.java | 1432 + .../ws/org/objectweb/asm/Handler.java | 100 + .../internal/ws/org/objectweb/asm/Item.java | 286 + .../internal/ws/org/objectweb/asm/Label.java | 556 + .../ws/org/objectweb/asm/MethodVisitor.java | 425 + .../ws/org/objectweb/asm/MethodWriter.java | 2631 + .../ws/org/objectweb/asm/Opcodes.java | 371 + .../internal/ws/org/objectweb/asm/Type.java | 824 + .../xml/internal/ws/protocol/soap/MUTube.java | 2 +- .../soap/MessageCreationException.java | 60 + .../ws/resources/AddressingMessages.java | 48 + .../internal/ws/resources/ClientMessages.java | 12 + .../ws/resources/ModelerMessages.java | 14 +- .../ws/resources/ProviderApiMessages.java | 12 + .../internal/ws/resources/ServerMessages.java | 79 +- .../ws/resources/WsservletMessages.java | 24 +- .../ws/resources/addressing.properties | 6 +- .../internal/ws/resources/client.properties | 2 +- .../internal/ws/resources/dispatch.properties | 1 - .../internal/ws/resources/encoding.properties | 1 - .../internal/ws/resources/handler.properties | 1 - .../ws/resources/httpserver.properties | 1 - .../internal/ws/resources/modeler.properties | 8 +- .../ws/resources/providerApi.properties | 3 +- .../internal/ws/resources/sender.properties | 1 - .../internal/ws/resources/server.properties | 26 +- .../xml/internal/ws/resources/soap.properties | 3 +- .../ws/resources/streaming.properties | 1 - .../xml/internal/ws/resources/util.properties | 1 - .../ws/resources/wsdlmodel.properties | 1 - .../ws/resources/wsservlet.properties | 7 +- .../ws/resources/xmlmessage.properties | 1 - .../ws/server/AbstractInstanceResolver.java | 46 +- .../DraconianValidationErrorHandler.java | 47 + .../internal/ws/server/EndpointFactory.java | 30 +- .../sun/xml/internal/ws/server/JMXAgent.java | 87 + .../internal/ws/server/SDDocumentImpl.java | 62 +- .../ws/server/ServerSchemaValidationTube.java | 319 + .../ws/server/StatefulInstanceResolver.java | 5 +- .../ws/server/UnsupportedMediaException.java | 4 + .../xml/internal/ws/server/WSDLPatcher.java | 11 +- .../internal/ws/server/WSEndpointImpl.java | 31 +- .../provider/ProviderArgumentsBuilder.java | 2 +- .../provider/XMLProviderArgumentBuilder.java | 13 +- .../server/sei/EndpointArgumentsBuilder.java | 67 +- .../server/sei/EndpointMethodDispatcher.java | 3 - .../sei/EndpointMethodDispatcherGetter.java | 1 + .../ws/server/sei/EndpointMethodHandler.java | 28 +- .../sei/PayloadQNameBasedDispatcher.java | 72 +- .../ws/server/sei/SEIInvokerTube.java | 37 +- .../server/sei/SOAPActionBasedDispatcher.java | 76 + .../sun/xml/internal/ws/spi/ProviderImpl.java | 19 +- .../ws/streaming/DOMStreamReader.java | 66 +- .../ws/streaming/MtomStreamWriter.java | 44 + .../xml/internal/ws/streaming/XMLReader.java | 230 - .../ws/streaming/XMLReaderException.java | 1 - .../ws/streaming/XMLStreamReaderUtil.java | 11 + .../ws/streaming/XMLStreamWriterUtil.java | 45 +- .../xml/internal/ws/transport/Headers.java | 5 + .../http/DeploymentDescriptorParser.java | 9 +- .../ws/transport/http/HttpAdapter.java | 207 +- .../http/HttpDump.java} | 20 +- .../ws/transport/http/HttpDumpMBean.java | 37 + .../transport/http/HttpMetadataPublisher.java | 59 + .../ws/transport/http/WSHTTPConnection.java | 10 + .../http/client/HttpClientTransport.java | 219 +- .../http/client/HttpTransportPipe.java | 94 +- .../transport/http/server/EndpointImpl.java | 12 +- .../transport/http/server/HttpEndpoint.java | 2 +- .../http/server/ServerConnectionImpl.java | 52 +- .../ws/transport/http/server/ServerMgr.java | 10 +- .../transport/http/server/WSHttpHandler.java | 16 +- .../xml/internal/ws/util/ByteArrayBuffer.java | 5 + .../com/sun/xml/internal/ws/util/DOMUtil.java | 6 +- .../ws/util/HandlerAnnotationProcessor.java | 3 +- .../xml/internal/ws/util/MetadataUtil.java | 92 + .../com/sun/xml/internal/ws/util/Pool.java | 24 +- .../sun/xml/internal/ws/util/QNameMap.java | 8 +- .../xml/internal/ws/util/RuntimeVersion.java | 36 +- .../internal/ws/util/RuntimeVersionMBean.java | 43 + .../pipe/AbstractSchemaValidationTube.java | 261 + .../xml/internal/ws/util/pipe/DumpTube.java | 2 + .../ws/util/pipe/StandaloneTubeAssembler.java | 2 + .../ws/util/resources/Messages_en.properties | 1 - .../xml/internal/ws/util/version.properties | 8 +- .../xml/ContentHandlerToXMLStreamWriter.java | 8 +- .../ws/util/xml/MetadataDocument.java | 317 + .../xml/internal/ws/util/xml/StAXSource.java | 57 +- .../xml/XMLStreamReaderToXMLStreamWriter.java | 12 +- .../sun/xml/internal/ws/util/xml/XmlUtil.java | 48 + .../parser/DelegatingParserExtension.java | 19 +- .../wsdl/parser/FoolProofParserExtension.java | 15 +- .../internal/ws/wsdl/parser/ParserUtil.java | 38 +- .../ws/wsdl/parser/RuntimeWSDLParser.java | 119 +- ...AddressingMetadataWSDLParserExtension.java | 106 + .../WSDLParserExtensionContextImpl.java | 10 +- .../parser/WSDLParserExtensionFacade.java | 8 +- .../ws/wsdl/writer/UsingAddressing.java | 3 - .../W3CAddressingWSDLGeneratorExtension.java | 50 +- .../ws/wsdl/writer/WSDLGenerator.java | 17 +- .../xml/internal/xsom/ForeignAttributes.java | 1 + .../com/sun/xml/internal/xsom/SCD.java | 1 + .../sun/xml/internal/xsom/XSAnnotation.java | 2 + .../sun/xml/internal/xsom/XSAttContainer.java | 2 + .../sun/xml/internal/xsom/XSAttGroupDecl.java | 2 + .../xml/internal/xsom/XSAttributeDecl.java | 2 + .../sun/xml/internal/xsom/XSAttributeUse.java | 2 + .../sun/xml/internal/xsom/XSComplexType.java | 19 + .../sun/xml/internal/xsom/XSComponent.java | 2 + .../sun/xml/internal/xsom/XSContentType.java | 2 + .../sun/xml/internal/xsom/XSDeclaration.java | 2 + .../sun/xml/internal/xsom/XSElementDecl.java | 13 + .../com/sun/xml/internal/xsom/XSFacet.java | 2 + .../internal/xsom/XSIdentityConstraint.java | 1 + .../xml/internal/xsom/XSListSimpleType.java | 2 + .../sun/xml/internal/xsom/XSModelGroup.java | 2 + .../xml/internal/xsom/XSModelGroupDecl.java | 2 + .../com/sun/xml/internal/xsom/XSNotation.java | 2 + .../com/sun/xml/internal/xsom/XSParticle.java | 2 + .../xsom/XSRestrictionSimpleType.java | 8 + .../com/sun/xml/internal/xsom/XSSchema.java | 2 + .../sun/xml/internal/xsom/XSSchemaSet.java | 2 + .../sun/xml/internal/xsom/XSSimpleType.java | 14 + .../com/sun/xml/internal/xsom/XSTerm.java | 2 + .../com/sun/xml/internal/xsom/XSType.java | 2 + .../xml/internal/xsom/XSUnionSimpleType.java | 2 + .../com/sun/xml/internal/xsom/XSVariety.java | 2 + .../com/sun/xml/internal/xsom/XSWildcard.java | 2 + .../com/sun/xml/internal/xsom/XSXPath.java | 1 + .../com/sun/xml/internal/xsom/XmlString.java | 1 + .../internal/xsom/impl/AnnotationImpl.java | 26 +- .../internal/xsom/impl/AttGroupDeclImpl.java | 2 + .../internal/xsom/impl/AttributeDeclImpl.java | 2 + .../internal/xsom/impl/AttributeUseImpl.java | 2 + .../internal/xsom/impl/AttributesHolder.java | 9 +- .../internal/xsom/impl/ComplexTypeImpl.java | 55 +- .../xml/internal/xsom/impl/ComponentImpl.java | 2 + .../com/sun/xml/internal/xsom/impl/Const.java | 2 + .../internal/xsom/impl/ContentTypeImpl.java | 2 + .../internal/xsom/impl/DeclarationImpl.java | 2 + .../xml/internal/xsom/impl/ElementDecl.java | 12 +- .../sun/xml/internal/xsom/impl/EmptyImpl.java | 2 + .../sun/xml/internal/xsom/impl/FacetImpl.java | 2 + .../xsom/impl/ForeignAttributesImpl.java | 1 + .../xsom/impl/IdentityConstraintImpl.java | 1 + .../xsom/impl/ListSimpleTypeImpl.java | 5 + .../xsom/impl/ModelGroupDeclImpl.java | 2 + .../internal/xsom/impl/ModelGroupImpl.java | 2 + .../xml/internal/xsom/impl/NotationImpl.java | 2 + .../xml/internal/xsom/impl/ParticleImpl.java | 2 + .../com/sun/xml/internal/xsom/impl/Ref.java | 2 + .../xsom/impl/RestrictionSimpleTypeImpl.java | 10 + .../xml/internal/xsom/impl/SchemaImpl.java | 2 + .../xml/internal/xsom/impl/SchemaSetImpl.java | 29 + .../internal/xsom/impl/SimpleTypeImpl.java | 2 + .../com/sun/xml/internal/xsom/impl/UName.java | 33 + .../xsom/impl/UnionSimpleTypeImpl.java | 7 +- .../com/sun/xml/internal/xsom/impl/Util.java | 2 + .../xml/internal/xsom/impl/WildcardImpl.java | 2 + .../sun/xml/internal/xsom/impl/XPathImpl.java | 1 + .../sun/xml/internal/xsom/impl/package.html | 2 +- .../xsom/impl/parser/BaseContentRef.java | 1 + .../impl/parser/DefaultAnnotationParser.java | 2 + .../internal/xsom/impl/parser/DelayedRef.java | 2 + .../internal/xsom/impl/parser/Messages.java | 2 + .../xsom/impl/parser/Messages.properties | 31 +- .../xsom/impl/parser/Messages_ja.properties | 31 +- .../xsom/impl/parser/NGCCRuntimeEx.java | 1 + .../xsom/impl/parser/ParserContext.java | 1 + .../xml/internal/xsom/impl/parser/Patch.java | 2 + .../xsom/impl/parser/PatcherManager.java | 2 + .../impl/parser/SAXParserFactoryAdaptor.java | 2 + .../xsom/impl/parser/SchemaDocumentImpl.java | 1 + .../impl/parser/SubstGroupBaseTypeRef.java | 2 + .../xsom/impl/parser/state/Schema.java | 1164 +- .../impl/parser/state/SimpleType_List.java | 136 +- .../parser/state/SimpleType_Restriction.java | 112 +- .../impl/parser/state/SimpleType_Union.java | 282 +- .../xsom/impl/parser/state/annotation.java | 10 +- .../impl/parser/state/attributeDeclBody.java | 412 +- .../impl/parser/state/attributeGroupDecl.java | 328 +- .../xsom/impl/parser/state/attributeUses.java | 890 +- .../xsom/impl/parser/state/complexType.java | 1850 +- .../complexType_complexContent_body.java | 22 +- .../impl/parser/state/elementDeclBody.java | 941 +- .../xsom/impl/parser/state/erSet.java | 10 +- .../xsom/impl/parser/state/facet.java | 144 +- .../xsom/impl/parser/state/group.java | 276 +- .../impl/parser/state/identityConstraint.java | 292 +- .../xsom/impl/parser/state/importDecl.java | 204 +- .../xsom/impl/parser/state/includeDecl.java | 84 +- .../impl/parser/state/modelGroupBody.java | 162 +- .../xsom/impl/parser/state/notation.java | 272 +- .../xsom/impl/parser/state/occurs.java | 134 +- .../xsom/impl/parser/state/particle.java | 846 +- .../xsom/impl/parser/state/qname.java | 10 +- .../xsom/impl/parser/state/redefine.java | 168 +- .../xsom/impl/parser/state/simpleType.java | 196 +- .../xsom/impl/parser/state/wildcardBody.java | 204 +- .../xsom/impl/parser/state/xpath.java | 128 +- .../xsom/impl/scd/AbstractAxisImpl.java | 1 + .../sun/xml/internal/xsom/impl/scd/Axis.java | 1 + .../xml/internal/xsom/impl/scd/Iterators.java | 1 + .../xsom/impl/scd/ParseException.java | 10 +- .../xml/internal/xsom/impl/scd/SCDImpl.java | 1 + .../xsom/impl/scd/SCDParserConstants.java | 105 +- .../sun/xml/internal/xsom/impl/scd/Step.java | 1 + .../xsom/impl/util/DraconianErrorHandler.java | 2 + .../impl/util/ResourceEntityResolver.java | 2 + .../xsom/impl/util/SchemaTreeTraverser.java | 1 + .../internal/xsom/impl/util/SchemaWriter.java | 190 +- .../sun/xml/internal/xsom/impl/util/Uri.java | 24 - .../xsom/parser/AnnotationContext.java | 2 + .../xsom/parser/AnnotationParser.java | 2 + .../xsom/parser/AnnotationParserFactory.java | 2 + .../xml/internal/xsom/parser/JAXPParser.java | 2 + .../internal/xsom/parser/SchemaDocument.java | 1 + .../xml/internal/xsom/parser/XMLParser.java | 2 + .../xml/internal/xsom/parser/XSOMParser.java | 2 + .../sun/xml/internal/xsom/parser/package.html | 2 +- .../xsom/util/ComponentNameFunction.java | 2 +- .../internal/xsom/util/DeferedCollection.java | 1 + .../xsom/util/DomAnnotationParserFactory.java | 1 + .../xml/internal/xsom/util/NameGetter.java | 2 + .../internal/xsom/util/NameGetter.properties | 31 +- .../xml/internal/xsom/util/SimpleTypeSet.java | 2 + .../xml/internal/xsom/util/TypeClosure.java | 2 + .../sun/xml/internal/xsom/util/TypeSet.java | 2 + .../sun/xml/internal/xsom/util/XSFinder.java | 2 + .../internal/xsom/util/XSFunctionFilter.java | 2 + .../xsom/visitor/XSContentTypeFunction.java | 2 + .../xsom/visitor/XSContentTypeVisitor.java | 2 + .../xml/internal/xsom/visitor/XSFunction.java | 2 + .../xsom/visitor/XSSimpleTypeFunction.java | 2 + .../xsom/visitor/XSSimpleTypeVisitor.java | 2 + .../internal/xsom/visitor/XSTermFunction.java | 2 + .../xsom/visitor/XSTermFunctionWithParam.java | 1 + .../internal/xsom/visitor/XSTermVisitor.java | 2 + .../xml/internal/xsom/visitor/XSVisitor.java | 2 + .../xsom/visitor/XSWildcardFunction.java | 2 + .../xsom/visitor/XSWildcardVisitor.java | 2 + .../xml/internal/xsom/visitor/package.html | 2 +- .../classes/javax/xml/bind/ContextFinder.java | 47 +- .../javax/xml/bind/DatatypeConverter.java | 2 +- .../javax/xml/bind/DatatypeConverterImpl.java | 2 +- .../xml/bind/DatatypeConverterInterface.java | 2 +- .../share/classes/javax/xml/bind/Element.java | 2 +- .../classes/javax/xml/bind/JAXBContext.java | 2 +- .../classes/javax/xml/bind/JAXBException.java | 2 +- .../javax/xml/bind/MarshalException.java | 2 +- .../classes/javax/xml/bind/Marshaller.java | 2 +- .../javax/xml/bind/Messages.properties | 26 +- .../javax/xml/bind/NotIdentifiableEvent.java | 2 +- .../javax/xml/bind/ParseConversionEvent.java | 2 +- .../javax/xml/bind/PrintConversionEvent.java | 2 +- .../javax/xml/bind/PropertyException.java | 2 +- .../xml/bind/TypeConstraintException.java | 2 +- .../javax/xml/bind/UnmarshalException.java | 2 +- .../classes/javax/xml/bind/Unmarshaller.java | 2 +- .../javax/xml/bind/UnmarshallerHandler.java | 2 +- .../javax/xml/bind/ValidationEvent.java | 2 +- .../xml/bind/ValidationEventHandler.java | 2 +- .../xml/bind/ValidationEventLocator.java | 2 +- .../javax/xml/bind/ValidationException.java | 2 +- .../classes/javax/xml/bind/Validator.java | 2 +- .../xml/bind/annotation/XmlAccessOrder.java | 2 +- .../xml/bind/annotation/XmlAccessType.java | 2 +- .../xml/bind/annotation/XmlAccessorOrder.java | 2 +- .../xml/bind/annotation/XmlAccessorType.java | 2 +- .../xml/bind/annotation/XmlAttribute.java | 2 +- .../javax/xml/bind/annotation/XmlElement.java | 2 +- .../javax/xml/bind/annotation/XmlID.java | 2 +- .../javax/xml/bind/annotation/XmlIDREF.java | 2 +- .../javax/xml/bind/annotation/XmlNs.java | 2 +- .../javax/xml/bind/annotation/XmlNsForm.java | 2 +- .../javax/xml/bind/annotation/XmlSchema.java | 2 +- .../javax/xml/bind/annotation/XmlSeeAlso.java | 2 +- .../xml/bind/annotation/XmlTransient.java | 2 +- .../javax/xml/bind/annotation/XmlType.java | 2 +- .../javax/xml/bind/annotation/XmlValue.java | 2 +- .../adapters/XmlJavaTypeAdapter.java | 2 +- .../xml/bind/annotation/adapters/package.html | 4 +- .../javax/xml/bind/annotation/package.html | 26 +- .../javax/xml/bind/attachment/package.html | 18 +- .../bind/helpers/AbstractMarshallerImpl.java | 2 +- .../helpers/AbstractUnmarshallerImpl.java | 2 +- .../DefaultValidationEventHandler.java | 2 +- .../xml/bind/helpers/Messages.properties | 34 +- .../helpers/NotIdentifiableEventImpl.java | 2 +- .../helpers/ParseConversionEventImpl.java | 2 +- .../helpers/PrintConversionEventImpl.java | 2 +- .../xml/bind/helpers/ValidationEventImpl.java | 2 +- .../helpers/ValidationEventLocatorImpl.java | 2 +- .../javax/xml/bind/helpers/package.html | 16 +- .../share/classes/javax/xml/bind/package.html | 10 +- .../javax/xml/bind/util/Messages.properties | 23 +- .../bind/util/ValidationEventCollector.java | 2 +- .../classes/javax/xml/bind/util/package.html | 10 +- .../javax/xml/soap/AttachmentPart.java | 6 +- .../share/classes/javax/xml/soap/Detail.java | 6 +- .../classes/javax/xml/soap/DetailEntry.java | 6 +- .../classes/javax/xml/soap/FactoryFinder.java | 6 +- .../javax/xml/soap/MessageFactory.java | 6 +- .../classes/javax/xml/soap/MimeHeader.java | 6 +- .../classes/javax/xml/soap/MimeHeaders.java | 6 +- .../share/classes/javax/xml/soap/Name.java | 6 +- .../share/classes/javax/xml/soap/Node.java | 6 +- .../javax/xml/soap/SAAJMetaFactory.java | 6 +- .../classes/javax/xml/soap/SAAJResult.java | 2 +- .../classes/javax/xml/soap/SOAPBody.java | 6 +- .../javax/xml/soap/SOAPBodyElement.java | 6 +- .../javax/xml/soap/SOAPConnection.java | 6 +- .../javax/xml/soap/SOAPConnectionFactory.java | 6 +- .../classes/javax/xml/soap/SOAPConstants.java | 6 +- .../classes/javax/xml/soap/SOAPElement.java | 6 +- .../javax/xml/soap/SOAPElementFactory.java | 6 +- .../classes/javax/xml/soap/SOAPEnvelope.java | 6 +- .../classes/javax/xml/soap/SOAPException.java | 6 +- .../classes/javax/xml/soap/SOAPFactory.java | 4 +- .../classes/javax/xml/soap/SOAPFault.java | 6 +- .../javax/xml/soap/SOAPFaultElement.java | 6 +- .../classes/javax/xml/soap/SOAPHeader.java | 6 +- .../javax/xml/soap/SOAPHeaderElement.java | 6 +- .../classes/javax/xml/soap/SOAPMessage.java | 6 +- .../classes/javax/xml/soap/SOAPPart.java | 6 +- .../share/classes/javax/xml/soap/Text.java | 6 +- .../share/classes/javax/xml/soap/package.html | 12 +- .../javax/xml/ws/spi/FactoryFinder.java | 6 +- .../ws/wsaddressing/W3CEndpointReference.java | 3 +- .../org/relaxng/datatype/Datatype.java | 1 - .../org/relaxng/datatype/DatatypeBuilder.java | 1 - .../relaxng/datatype/DatatypeException.java | 1 - .../org/relaxng/datatype/DatatypeLibrary.java | 1 - .../datatype/DatatypeLibraryFactory.java | 1 - .../datatype/DatatypeStreamingValidator.java | 1 - .../relaxng/datatype/ValidationContext.java | 1 - .../helpers/DatatypeLibraryLoader.java | 3 +- .../helpers/ParameterlessDatatypeBuilder.java | 1 - .../helpers/StreamingValidatorImpl.java | 1 - 1399 files changed, 123816 insertions(+), 12509 deletions(-) create mode 100644 jaxws/jaxws.patch create mode 100644 jaxws/patch.out delete mode 100644 jaxws/src/share/classes/com/sun/codemodel/internal/fmt/package.html create mode 100644 jaxws/src/share/classes/com/sun/istack/internal/Builder.java create mode 100644 jaxws/src/share/classes/com/sun/istack/internal/localization/Localizable.java create mode 100644 jaxws/src/share/classes/com/sun/istack/internal/localization/LocalizableMessage.java rename jaxws/src/share/classes/com/sun/{xml/internal/ws/addressing/model/InvalidMapException.java => istack/internal/localization/LocalizableMessageFactory.java} (71%) create mode 100644 jaxws/src/share/classes/com/sun/istack/internal/localization/Localizer.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/jxc/SchemaGeneratorFacade.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/ws/api/WsgenExtension.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/ws/api/WsgenProtocol.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/ws/wscompile/AuthInfo.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/ws/wscompile/DefaultAuthTester.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/ws/wscompile/DefaultAuthenticator.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForestParser.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/ClassLoaderBuilder.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/XJCFacade.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/generator/annotation/ri/OverrideAnnotationOfWriter.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/generator/bean/field/ContentListField.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/generator/bean/field/DummyListField.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/generator/bean/field/NoExtendedContentField.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/BIFactoryMethod.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/BIInlineBinaryData.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/reader/xmlschema/ct/AbstractExtendedComplexTypeBuilder.java create mode 100644 jaxws/src/share/classes/com/sun/tools/internal/xjc/reader/xmlschema/ct/MixedExtendedComplexTypeBuilder.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/annotation/OverrideAnnotationOf.java rename jaxws/src/share/classes/com/sun/{tools/internal/xjc/api/impl/j2s => xml/internal/bind/api}/Messages.java (91%) rename jaxws/src/share/classes/com/sun/{tools/internal/xjc/api/impl/j2s => xml/internal/bind/api}/Messages.properties (94%) create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/v2/model/annotation/XmlSchemaTypeQuick.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/v2/model/impl/DummyPropertyInfo.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/v2/runtime/AttributeAccessor.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/v2/runtime/output/StAXExStreamWriterOutput.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXExConnector.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/bind/v2/util/StackRecorder.java delete mode 100644 jaxws/src/share/classes/com/sun/xml/internal/fastinfoset/stax/events/StAXEventAllocator.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/Chunk.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/ChunkInputStream.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/Data.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/DataFile.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/DataHead.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/FileData.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/FinalArrayList.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/Header.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/InternetHeaders.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEConfig.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEEvent.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEMessage.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEParser.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEParsingException.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEPart.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/MemoryData.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/mimepull/WeakDataFile.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/org/jvnet/staxex/StreamingDataHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/txw2/output/TXWResult.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/txw2/output/TXWSerializer.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/W3CWsaClientTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/W3CWsaServerTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/WsaPropertyBag.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/model/InvalidAddressingHeaderException.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/model/MissingAddressingHeaderException.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/v200408/MemberSubmissionWsaClientTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/addressing/v200408/MemberSubmissionWsaServerTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/ResourceLoader.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/handler/MessageHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/handler/MessageHandlerContext.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/message/FilterMessageImpl.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/model/wsdl/WSDLBoundFault.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/server/EndpointComponent.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/api/server/HttpEndpoint.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/ClientContainer.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/ClientSchemaValidationTube.java delete mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/ResponseImpl.java delete mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/sei/AsyncBuilder.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/sei/SEIMethodHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/sei/ValueGetterFactory.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/client/sei/ValueSetterFactory.java rename jaxws/src/share/classes/com/sun/xml/internal/ws/client/sei/{package-info.java => pacakge-info.java} (100%) create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/BindingTypeFeature.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/JAXBContextFactory.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/SchemaValidation.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/SchemaValidationFeature.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/StreamingAttachment.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/StreamingAttachmentFeature.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/StreamingDataHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/UsesJAXBContext.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/UsesJAXBContextFeature.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/developer/ValidationErrorHandler.java delete mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/AbstractXMLStreamWriterExImpl.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/ContentType.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/DataSourceStreamingDataHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/HeaderTokenizer.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/ImageDataContentHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/MIMEPartStreamingDataHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/ParameterList.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/RootOnlyCodec.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/StringDataContentHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/encoding/XmlDataContentHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/handler/ClientMessageHandlerTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/handler/MessageHandlerContextImpl.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/handler/ServerMessageHandlerTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/message/FaultMessage.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/model/FieldSignature.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/model/Injector.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/model/WrapperBeanGenerator.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/model/wsdl/WSDLBoundFaultImpl.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/AnnotationVisitor.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/AnnotationWriter.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Attribute.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/ByteVector.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassVisitor.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassWriter.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Edge.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/FieldVisitor.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/FieldWriter.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Frame.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Handler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Item.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Label.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/MethodVisitor.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/MethodWriter.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Opcodes.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/org/objectweb/asm/Type.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/protocol/soap/MessageCreationException.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/server/DraconianValidationErrorHandler.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/server/JMXAgent.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/server/ServerSchemaValidationTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/server/sei/SOAPActionBasedDispatcher.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/streaming/MtomStreamWriter.java delete mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/streaming/XMLReader.java rename jaxws/src/share/classes/com/sun/xml/internal/ws/{addressing/model/MapRequiredException.java => transport/http/HttpDump.java} (77%) create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/transport/http/HttpDumpMBean.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/transport/http/HttpMetadataPublisher.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/util/MetadataUtil.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/util/RuntimeVersionMBean.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/util/pipe/AbstractSchemaValidationTube.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/util/xml/MetadataDocument.java create mode 100644 jaxws/src/share/classes/com/sun/xml/internal/ws/wsdl/parser/W3CAddressingMetadataWSDLParserExtension.java diff --git a/jaxws/THIRD_PARTY_README b/jaxws/THIRD_PARTY_README index 690890548f2..43058486295 100644 --- a/jaxws/THIRD_PARTY_README +++ b/jaxws/THIRD_PARTY_README @@ -32,7 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. --- end of LICENSE file --- %% This notice is provided with respect to ASM, which may be included with this software: -Copyright (c) 2000-2005 INRIA, France Telecom +Copyright (c) 2000-2007 INRIA, France Telecom All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/jaxws/jaxws.patch b/jaxws/jaxws.patch new file mode 100644 index 00000000000..12bd76ee9d9 --- /dev/null +++ b/jaxws/jaxws.patch @@ -0,0 +1,81929 @@ +--- old/./THIRD_PARTY_README Tue Aug 4 09:26:42 2009 ++++ new/./THIRD_PARTY_README Tue Aug 4 09:26:41 2009 +@@ -32,7 +32,7 @@ + + --- end of LICENSE file --- + %% This notice is provided with respect to ASM, which may be included with this software: +-Copyright (c) 2000-2005 INRIA, France Telecom ++Copyright (c) 2000-2007 INRIA, France Telecom + All rights reserved. + + Redistribution and use in source and binary forms, with or without +--- old/src/share/classes/com/sun/codemodel/internal/JAnnotatable.java Tue Aug 4 09:26:44 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JAnnotatable.java Tue Aug 4 09:26:44 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal; + + import java.lang.annotation.Annotation; +--- old/src/share/classes/com/sun/codemodel/internal/JAnnotationUse.java Tue Aug 4 09:26:46 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JAnnotationUse.java Tue Aug 4 09:26:46 2009 +@@ -199,8 +199,7 @@ + * + */ + public JAnnotationUse param(String name, Class value){ +- addValue(name, new JAnnotationStringValue(JExpr.lit(value.getName()))); +- return this; ++ return param(name,clazz.owner().ref(value)); + } + + /** +--- old/src/share/classes/com/sun/codemodel/internal/JAnnotationWriter.java Tue Aug 4 09:26:48 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JAnnotationWriter.java Tue Aug 4 09:26:48 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal; + + import java.lang.annotation.Annotation; +--- old/src/share/classes/com/sun/codemodel/internal/JBlock.java Tue Aug 4 09:26:51 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JBlock.java Tue Aug 4 09:26:50 2009 +@@ -111,7 +111,15 @@ + return r; + } + ++ /** ++ * Returns true if this block is empty and does not contain ++ * any statement. ++ */ ++ public boolean isEmpty() { ++ return content.isEmpty(); ++ } + ++ + /** + * Adds a local variable declaration to this block + * +--- old/src/share/classes/com/sun/codemodel/internal/JCommentPart.java Tue Aug 4 09:26:53 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JCommentPart.java Tue Aug 4 09:26:52 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal; + + import java.util.ArrayList; +@@ -77,7 +78,8 @@ + */ + protected void format( JFormatter f, String indent ) { + if(!f.isPrinting()) { +- // quickly pass the types to JFormatter ++ // quickly pass the types to JFormatter, as that's all we care. ++ // we don't need to worry about the exact formatting of text. + for( Object o : this ) + if(o instanceof JClass) + f.g((JClass)o); +@@ -97,12 +99,12 @@ + while( (idx=s.indexOf('\n'))!=-1 ) { + String line = s.substring(0,idx); + if(line.length()>0) +- f.p(line); ++ f.p(escape(line)); + s = s.substring(idx+1); + f.nl().p(indent); + } + if(s.length()!=0) +- f.p(s); ++ f.p(escape(s)); + } else + if(o instanceof JClass) { + // TODO: this doesn't print the parameterized type properly +@@ -117,4 +119,16 @@ + if(!isEmpty()) + f.nl(); + } ++ ++ /** ++ * Escapes the appearance of the comment terminator. ++ */ ++ private String escape(String s) { ++ while(true) { ++ int idx = s.indexOf("*/"); ++ if(idx <0) return s; ++ ++ s = s.substring(0,idx+1)+""+s.substring(idx+1); ++ } ++ } + } +--- old/src/share/classes/com/sun/codemodel/internal/JDirectClass.java Tue Aug 4 09:26:55 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JDirectClass.java Tue Aug 4 09:26:55 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal; + + import java.util.Iterator; +--- old/src/share/classes/com/sun/codemodel/internal/JExpr.java Tue Aug 4 09:26:57 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JExpr.java Tue Aug 4 09:26:57 2009 +@@ -198,8 +198,12 @@ + char c = s.charAt(i); + int j = charEscape.indexOf(c); + if(j>=0) { +- sb.append('\\'); +- sb.append(charMacro.charAt(j)); ++ if((quote=='"' && c=='\'') || (quote=='\'' && c=='"')) { ++ sb.append(c); ++ } else { ++ sb.append('\\'); ++ sb.append(charMacro.charAt(j)); ++ } + } else { + // technically Unicode escape shouldn't be done here, + // for it's a lexical level handling. +--- old/src/share/classes/com/sun/codemodel/internal/JJavaName.java Tue Aug 4 09:26:59 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JJavaName.java Tue Aug 4 09:26:59 2009 +@@ -231,6 +231,7 @@ + "(.*)basis","$1bases", + "(.*)axis","$1axes", + "(.+)is","$1ises", ++ "(.+)ss","$1sses", + "(.+)us","$1uses", + "(.+)s","$1s", + "(.*)foot","$1feet", +--- old/src/share/classes/com/sun/codemodel/internal/JMethod.java Tue Aug 4 09:27:02 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JMethod.java Tue Aug 4 09:27:01 2009 +@@ -388,10 +388,11 @@ + f.g(a).nl(); + } + +- // declare the generics parameters ++ f.g(mods); ++ ++ // declare the generics parameters + super.declare(f); + +- f.g(mods); + if (!isConstructor()) + f.g(type); + f.id(name).p('(').i(); +--- old/src/share/classes/com/sun/codemodel/internal/JPackage.java Tue Aug 4 09:27:04 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JPackage.java Tue Aug 4 09:27:03 2009 +@@ -98,34 +98,9 @@ + JPackage(String name, JCodeModel cw) { + this.owner = cw; + if (name.equals(".")) { +- String msg = "JPackage name . is not allowed"; ++ String msg = "Package name . is not allowed"; + throw new IllegalArgumentException(msg); + } +- +- int dots = 1; +- for (int i = 0; i < name.length(); i++) { +- char c = name.charAt(i); +- if (c == '.') { +- dots++; +- continue; +- } +- if (dots > 1) { +- String msg = "JPackage name " + name + " missing identifier"; +- throw new IllegalArgumentException(msg); +- } else if (dots == 1 && !Character.isJavaIdentifierStart(c)) { +- String msg = +- "JPackage name " + name + " contains illegal " + "character for beginning of identifier: " + c; +- throw new IllegalArgumentException(msg); +- } else if (!Character.isJavaIdentifierPart(c)) { +- String msg = "JPackage name " + name + "contains illegal " + "character: " + c; +- throw new IllegalArgumentException(msg); +- } +- dots = 0; +- } +- if (!name.trim().equals("") && dots != 0) { +- String msg = "JPackage name not allowed to end with ."; +- throw new IllegalArgumentException(msg); +- } + + if(JCodeModel.isCaseSensitiveFileSystem) + upperCaseClassMap = null; +--- old/src/share/classes/com/sun/codemodel/internal/JTypeWildcard.java Tue Aug 4 09:27:06 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/JTypeWildcard.java Tue Aug 4 09:27:06 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal; + + import java.util.Iterator; +--- old/src/share/classes/com/sun/codemodel/internal/TypedAnnotationWriter.java Tue Aug 4 09:27:08 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/TypedAnnotationWriter.java Tue Aug 4 09:27:08 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal; + + import java.lang.reflect.InvocationHandler; +--- old/src/share/classes/com/sun/codemodel/internal/package-info.java Tue Aug 4 09:27:10 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/package-info.java Tue Aug 4 09:27:10 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + /** + *

    Library for generating Java source code

    . + * +--- old/src/share/classes/com/sun/codemodel/internal/util/EncoderFactory.java Tue Aug 4 09:27:12 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/util/EncoderFactory.java Tue Aug 4 09:27:12 2009 +@@ -22,11 +22,10 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + /* + * @(#)$Id: EncoderFactory.java,v 1.3 2005/09/10 19:07:33 kohsuke Exp $ + */ +- +- + package com.sun.codemodel.internal.util; + + import java.lang.reflect.Constructor; +--- old/src/share/classes/com/sun/codemodel/internal/util/MS1252Encoder.java Tue Aug 4 09:27:15 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/util/MS1252Encoder.java Tue Aug 4 09:27:14 2009 +@@ -22,11 +22,10 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + /* + * @(#)$Id: MS1252Encoder.java,v 1.2 2005/09/10 19:07:33 kohsuke Exp $ + */ +- +- + package com.sun.codemodel.internal.util; + + import java.nio.charset.Charset; +--- old/src/share/classes/com/sun/codemodel/internal/writer/FilterCodeWriter.java Tue Aug 4 09:27:17 2009 ++++ new/src/share/classes/com/sun/codemodel/internal/writer/FilterCodeWriter.java Tue Aug 4 09:27:16 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.codemodel.internal.writer; + + import java.io.OutputStream; +--- old/src/share/classes/com/sun/istack/internal/Pool.java Tue Aug 4 09:27:19 2009 ++++ new/src/share/classes/com/sun/istack/internal/Pool.java Tue Aug 4 09:27:19 2009 +@@ -25,6 +25,7 @@ + package com.sun.istack.internal; + + import java.util.concurrent.ConcurrentLinkedQueue; ++import java.lang.ref.WeakReference; + + /** + * Pool of reusable objects that are indistinguishable from each other, +@@ -33,6 +34,7 @@ + * @author Kohsuke Kawaguchi + */ + public interface Pool { ++ + /** + * Gets a new object from the pool. + * +@@ -46,7 +48,6 @@ + */ + void recycle(@NotNull T t); + +- + /** + * Default implementation that uses {@link ConcurrentLinkedQueue} + * as the data store. +@@ -55,7 +56,10 @@ + *

    + * Don't rely on the fact that this class extends from {@link ConcurrentLinkedQueue}. + */ +- public abstract class Impl extends ConcurrentLinkedQueue implements Pool { ++ public abstract class Impl implements Pool { ++ ++ private volatile WeakReference> queue; ++ + /** + * Gets a new object from the pool. + * +@@ -66,9 +70,10 @@ + * always non-null. + */ + public final @NotNull T take() { +- T t = super.poll(); +- if(t==null) ++ T t = getQueue().poll(); ++ if(t==null) { + return create(); ++ } + return t; + } + +@@ -76,9 +81,24 @@ + * Returns an object back to the pool. + */ + public final void recycle(T t) { +- super.offer(t); ++ getQueue().offer(t); + } + ++ private ConcurrentLinkedQueue getQueue() { ++ WeakReference> q = queue; ++ if (q != null) { ++ ConcurrentLinkedQueue d = q.get(); ++ if (d != null) { ++ return d; ++ } ++ } ++ // overwrite the queue ++ ConcurrentLinkedQueue d = new ConcurrentLinkedQueue(); ++ queue = new WeakReference>(d); ++ ++ return d; ++ } ++ + /** + * Creates a new instance of object. + * +--- old/src/share/classes/com/sun/istack/internal/XMLStreamReaderToContentHandler.java Tue Aug 4 09:27:21 2009 ++++ new/src/share/classes/com/sun/istack/internal/XMLStreamReaderToContentHandler.java Tue Aug 4 09:27:21 2009 +@@ -54,14 +54,24 @@ + + // if true, when the conversion is completed, leave the cursor to the last + // event that was fired (such as end element) +- private boolean eagerQuit; ++ private final boolean eagerQuit; + + /** + * If true, not start/endDocument event. + */ +- private boolean fragment; ++ private final boolean fragment; + ++ // array of the even length of the form { prefix0, uri0, prefix1, uri1, ... } ++ private final String[] inscopeNamespaces; ++ + /** ++ * @see #XMLStreamReaderToContentHandler(XMLStreamReader, ContentHandler, boolean, boolean, String[]) ++ */ ++ public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore, boolean eagerQuit, boolean fragment) { ++ this(staxCore, saxCore, eagerQuit, fragment, new String[0]); ++ } ++ ++ /** + * Construct a new StAX to SAX adapter that will convert a StAX event + * stream into a SAX event stream. + * +@@ -69,14 +79,22 @@ + * StAX event source + * @param saxCore + * SAXevent sink ++ * @param eagerQuit ++ * @param fragment ++ * @param inscopeNamespaces ++ * array of the even length of the form { prefix0, uri0, prefix1, uri1, ... } + */ +- public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore, boolean eagerQuit, boolean fragment) { ++ public XMLStreamReaderToContentHandler(XMLStreamReader staxCore, ContentHandler saxCore, ++ boolean eagerQuit, boolean fragment, String[] inscopeNamespaces) { + this.staxStreamReader = staxCore; + this.saxHandler = saxCore; + this.eagerQuit = eagerQuit; + this.fragment = fragment; ++ this.inscopeNamespaces = inscopeNamespaces; ++ assert inscopeNamespaces.length%2 == 0; + } + ++ + /* + * @see StAXReaderToContentHandler#bridge() + */ +@@ -100,6 +118,10 @@ + + handleStartDocument(); + ++ for(int i=0; i < inscopeNamespaces.length; i+=2) { ++ saxHandler.startPrefixMapping(inscopeNamespaces[i], inscopeNamespaces[i+1]); ++ } ++ + OUTER: + do { + // These are all of the events listed in the javadoc for +@@ -156,6 +178,10 @@ + event=staxStreamReader.next(); + } while (depth!=0); + ++ for(int i=0; i < inscopeNamespaces.length; i+=2) { ++ saxHandler.endPrefixMapping(inscopeNamespaces[i]); ++ } ++ + handleEndDocument(); + } catch (SAXException e) { + throw new XMLStreamException2(e); +--- old/src/share/classes/com/sun/istack/internal/ws/AnnotationProcessorFactoryImpl.java Tue Aug 4 09:27:23 2009 ++++ new/src/share/classes/com/sun/istack/internal/ws/AnnotationProcessorFactoryImpl.java Tue Aug 4 09:27:23 2009 +@@ -66,10 +66,7 @@ + types.add("javax.jws.soap.SOAPBinding"); + types.add("javax.jws.soap.SOAPMessageHandler"); + types.add("javax.jws.soap.SOAPMessageHandlers"); +- types.add("javax.xml.ws.BeginService"); +- types.add("javax.xml.ws.EndService"); + types.add("javax.xml.ws.BindingType"); +- types.add("javax.xml.ws.ParameterIndex"); + types.add("javax.xml.ws.RequestWrapper"); + types.add("javax.xml.ws.ResponseWrapper"); + types.add("javax.xml.ws.ServiceMode"); +@@ -78,8 +75,6 @@ + types.add("javax.xml.ws.WebServiceClient"); + types.add("javax.xml.ws.WebServiceProvider"); + types.add("javax.xml.ws.WebServiceRef"); +- +- types.add("javax.xml.ws.security.MessageSecurity"); + supportedAnnotations = Collections.unmodifiableCollection(types); + } + +--- old/src/share/classes/com/sun/tools/internal/jxc/ConfigReader.java Tue Aug 4 09:27:26 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/ConfigReader.java Tue Aug 4 09:27:25 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc; + + import java.io.File; +--- old/src/share/classes/com/sun/tools/internal/jxc/MessageBundle.properties Tue Aug 4 09:27:28 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/MessageBundle.properties Tue Aug 4 09:27:27 2009 +@@ -30,8 +30,8 @@ + Non-existent directory: {0} + + VERSION = \ +- schemagen version "JAXB 2.1.3" \n\ +- JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.3 in JDK) ++ schemagen version "JAXB 2.1.10 in JDK 6" \n\ ++ JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.10 in JDK 6) + + USAGE = \ + Usage: schemagen [-options ...] \n\ +@@ -42,4 +42,3 @@ + \ \ \ \ -episode : generate episode file for separate compilation\n\ + \ \ \ \ -version : display version information\n\ + \ \ \ \ -help : display this usage message +- +--- old/src/share/classes/com/sun/tools/internal/jxc/Messages.java Tue Aug 4 09:27:30 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/Messages.java Tue Aug 4 09:27:30 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc; + + import java.text.MessageFormat; +--- old/src/share/classes/com/sun/tools/internal/jxc/SchemaGenerator.java Tue Aug 4 09:27:32 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/SchemaGenerator.java Tue Aug 4 09:27:32 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc; + + import java.io.File; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/AnnotationParser.java Tue Aug 4 09:27:34 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/AnnotationParser.java Tue Aug 4 09:27:34 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.io.File; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/AnnotationProcessorFactoryImpl.java Tue Aug 4 09:27:36 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/AnnotationProcessorFactoryImpl.java Tue Aug 4 09:27:36 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.util.Arrays; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/Const.java Tue Aug 4 09:27:39 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/Const.java Tue Aug 4 09:27:38 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.io.File; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/ErrorReceiverImpl.java Tue Aug 4 09:27:41 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/ErrorReceiverImpl.java Tue Aug 4 09:27:40 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import com.sun.mirror.apt.AnnotationProcessorEnvironment; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/InlineAnnotationReaderImpl.java Tue Aug 4 09:27:43 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/InlineAnnotationReaderImpl.java Tue Aug 4 09:27:43 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.lang.annotation.Annotation; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/MessageBundle.properties Tue Aug 4 09:27:45 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/MessageBundle.properties Tue Aug 4 09:27:45 2009 +@@ -31,4 +31,3 @@ + + OPERAND_MISSING = \ + Option "{0}" is missing an operand. +- +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/Messages.java Tue Aug 4 09:27:47 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/Messages.java Tue Aug 4 09:27:47 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.text.MessageFormat; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/Options.java Tue Aug 4 09:27:49 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/Options.java Tue Aug 4 09:27:49 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.io.File; +--- old/src/share/classes/com/sun/tools/internal/jxc/apt/SchemaGenerator.java Tue Aug 4 09:27:52 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/apt/SchemaGenerator.java Tue Aug 4 09:27:51 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.apt; + + import java.io.File; +--- old/src/share/classes/com/sun/tools/internal/jxc/gen/config/Classes.java Tue Aug 4 09:27:54 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/gen/config/Classes.java Tue Aug 4 09:27:53 2009 +@@ -75,6 +75,11 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { ++ case 0: ++ { ++ revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs); ++ } ++ break; + case 12: + { + if(($__uri == "" && $__local == "classes")) { +@@ -92,34 +97,29 @@ + $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); + } + break; +- case 2: ++ case 11: + { +- if(($__uri == "" && $__local == "excludes")) { ++ if(($__uri == "" && $__local == "includes")) { + $runtime.onEnterElementConsumed($__uri, $__local, $__qname, $attrs); +- $_ngcc_current_state = 6; ++ $_ngcc_current_state = 10; + } + else { +- $_ngcc_current_state = 1; +- $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); ++ unexpectedEnterElement($__qname); + } + } + break; +- case 11: ++ case 2: + { +- if(($__uri == "" && $__local == "includes")) { ++ if(($__uri == "" && $__local == "excludes")) { + $runtime.onEnterElementConsumed($__uri, $__local, $__qname, $attrs); +- $_ngcc_current_state = 10; ++ $_ngcc_current_state = 6; + } + else { +- unexpectedEnterElement($__qname); ++ $_ngcc_current_state = 1; ++ $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); + } + } + break; +- case 0: +- { +- revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs); +- } +- break; + default: + { + unexpectedEnterElement($__qname); +@@ -133,6 +133,17 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { ++ case 0: ++ { ++ revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname); ++ } ++ break; ++ case 4: ++ { ++ $_ngcc_current_state = 3; ++ $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); ++ } ++ break; + case 3: + { + if(($__uri == "" && $__local == "excludes")) { +@@ -144,12 +155,6 @@ + } + } + break; +- case 4: +- { +- $_ngcc_current_state = 3; +- $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); +- } +- break; + case 2: + { + $_ngcc_current_state = 1; +@@ -156,11 +161,11 @@ + $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); + } + break; +- case 1: ++ case 8: + { +- if(($__uri == "" && $__local == "classes")) { ++ if(($__uri == "" && $__local == "includes")) { + $runtime.onLeaveElementConsumed($__uri, $__local, $__qname); +- $_ngcc_current_state = 0; ++ $_ngcc_current_state = 2; + } + else { + unexpectedLeaveElement($__qname); +@@ -167,11 +172,11 @@ + } + } + break; +- case 8: ++ case 1: + { +- if(($__uri == "" && $__local == "includes")) { ++ if(($__uri == "" && $__local == "classes")) { + $runtime.onLeaveElementConsumed($__uri, $__local, $__qname); +- $_ngcc_current_state = 2; ++ $_ngcc_current_state = 0; + } + else { + unexpectedLeaveElement($__qname); +@@ -178,11 +183,6 @@ + } + } + break; +- case 0: +- { +- revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname); +- } +- break; + default: + { + unexpectedLeaveElement($__qname); +@@ -196,6 +196,11 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { ++ case 0: ++ { ++ revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname); ++ } ++ break; + case 4: + { + $_ngcc_current_state = 3; +@@ -208,11 +213,6 @@ + $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname); + } + break; +- case 0: +- { +- revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname); +- } +- break; + default: + { + unexpectedEnterAttribute($__qname); +@@ -226,6 +226,11 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { ++ case 0: ++ { ++ revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname); ++ } ++ break; + case 4: + { + $_ngcc_current_state = 3; +@@ -238,11 +243,6 @@ + $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname); + } + break; +- case 0: +- { +- revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname); +- } +- break; + default: + { + unexpectedLeaveAttribute($__qname); +@@ -253,6 +253,11 @@ + + public void text(String $value) throws SAXException { + switch($_ngcc_current_state) { ++ case 0: ++ { ++ revertToParentFromText(this, super._cookie, $value); ++ } ++ break; + case 9: + { + include_content = $value; +@@ -260,7 +265,7 @@ + action2(); + } + break; +- case 3: ++ case 4: + { + exclude_content = $value; + $_ngcc_current_state = 3; +@@ -267,7 +272,7 @@ + action0(); + } + break; +- case 4: ++ case 3: + { + exclude_content = $value; + $_ngcc_current_state = 3; +@@ -301,11 +306,6 @@ + action1(); + } + break; +- case 0: +- { +- revertToParentFromText(this, super._cookie, $value); +- } +- break; + } + } + +--- old/src/share/classes/com/sun/tools/internal/jxc/gen/config/Config.java Tue Aug 4 09:27:56 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/gen/config/Config.java Tue Aug 4 09:27:56 2009 +@@ -70,15 +70,10 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { +- case 0: ++ case 4: + { +- revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs); +- } +- break; +- case 1: +- { +- if(($__uri == "" && $__local == "schema")) { +- NGCCHandler h = new Schema(this, super._source, $runtime, 3, baseDir); ++ if(($__uri == "" && $__local == "classes")) { ++ NGCCHandler h = new Classes(this, super._source, $runtime, 34); + spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs); + } + else { +@@ -97,10 +92,26 @@ + } + } + break; ++ case 1: ++ { ++ if(($__uri == "" && $__local == "schema")) { ++ NGCCHandler h = new Schema(this, super._source, $runtime, 31, baseDir); ++ spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs); ++ } ++ else { ++ unexpectedEnterElement($__qname); ++ } ++ } ++ break; ++ case 0: ++ { ++ revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs); ++ } ++ break; + case 2: + { + if(($__uri == "" && $__local == "schema")) { +- NGCCHandler h = new Schema(this, super._source, $runtime, 4, baseDir); ++ NGCCHandler h = new Schema(this, super._source, $runtime, 32, baseDir); + spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs); + } + else { +@@ -120,17 +131,6 @@ + } + } + break; +- case 4: +- { +- if(($__uri == "" && $__local == "classes")) { +- NGCCHandler h = new Classes(this, super._source, $runtime, 6); +- spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs); +- } +- else { +- unexpectedEnterElement($__qname); +- } +- } +- break; + default: + { + unexpectedEnterElement($__qname); +@@ -145,11 +145,6 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { +- case 0: +- { +- revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname); +- } +- break; + case 1: + { + if(($__uri == "" && $__local == "config")) { +@@ -161,6 +156,11 @@ + } + } + break; ++ case 0: ++ { ++ revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname); ++ } ++ break; + case 2: + { + $_ngcc_current_state = 1; +@@ -257,13 +257,6 @@ + public void text(String $value) throws SAXException { + int $ai; + switch($_ngcc_current_state) { +- case 6: +- { +- bd = $value; +- $_ngcc_current_state = 5; +- action1(); +- } +- break; + case 0: + { + revertToParentFromText(this, super._cookie, $value); +@@ -283,19 +276,32 @@ + } + } + break; ++ case 6: ++ { ++ bd = $value; ++ $_ngcc_current_state = 5; ++ action1(); ++ } ++ break; + } + } + + public void onChildCompleted(Object $__result__, int $__cookie__, boolean $__needAttCheck__)throws SAXException { + switch($__cookie__) { +- case 3: ++ case 34: + { ++ classes = ((Classes)$__result__); ++ $_ngcc_current_state = 2; ++ } ++ break; ++ case 31: ++ { + _schema = ((Schema)$__result__); + action0(); + $_ngcc_current_state = 1; + } + break; +- case 4: ++ case 32: + { + _schema = ((Schema)$__result__); + action0(); +@@ -302,12 +308,6 @@ + $_ngcc_current_state = 1; + } + break; +- case 6: +- { +- classes = ((Classes)$__result__); +- $_ngcc_current_state = 2; +- } +- break; + } + } + +--- old/src/share/classes/com/sun/tools/internal/jxc/gen/config/Schema.java Tue Aug 4 09:27:58 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/gen/config/Schema.java Tue Aug 4 09:27:58 2009 +@@ -65,6 +65,23 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { ++ case 0: ++ { ++ revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs); ++ } ++ break; ++ case 2: ++ { ++ if(($ai = $runtime.getAttributeIndex("","location"))>=0) { ++ $runtime.consumeAttribute($ai); ++ $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); ++ } ++ else { ++ $_ngcc_current_state = 1; ++ $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); ++ } ++ } ++ break; + case 6: + { + if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) { +@@ -88,23 +105,6 @@ + } + } + break; +- case 0: +- { +- revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs); +- } +- break; +- case 2: +- { +- if(($ai = $runtime.getAttributeIndex("","location"))>=0) { +- $runtime.consumeAttribute($ai); +- $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); +- } +- else { +- $_ngcc_current_state = 1; +- $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs); +- } +- } +- break; + default: + { + unexpectedEnterElement($__qname); +@@ -119,23 +119,23 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { +- case 6: ++ case 0: + { +- if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) { ++ revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname); ++ } ++ break; ++ case 2: ++ { ++ if(($ai = $runtime.getAttributeIndex("","location"))>=0) { + $runtime.consumeAttribute($ai); + $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); + } + else { +- $_ngcc_current_state = 2; ++ $_ngcc_current_state = 1; + $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); + } + } + break; +- case 0: +- { +- revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname); +- } +- break; + case 1: + { + if(($__uri == "" && $__local == "schema")) { +@@ -147,14 +147,14 @@ + } + } + break; +- case 2: ++ case 6: + { +- if(($ai = $runtime.getAttributeIndex("","location"))>=0) { ++ if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) { + $runtime.consumeAttribute($ai); + $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); + } + else { +- $_ngcc_current_state = 1; ++ $_ngcc_current_state = 2; + $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname); + } + } +@@ -172,17 +172,6 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { +- case 6: +- { +- if(($__uri == "" && $__local == "namespace")) { +- $_ngcc_current_state = 8; +- } +- else { +- $_ngcc_current_state = 2; +- $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname); +- } +- } +- break; + case 0: + { + revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname); +@@ -199,6 +188,17 @@ + } + } + break; ++ case 6: ++ { ++ if(($__uri == "" && $__local == "namespace")) { ++ $_ngcc_current_state = 8; ++ } ++ else { ++ $_ngcc_current_state = 2; ++ $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname); ++ } ++ } ++ break; + default: + { + unexpectedEnterAttribute($__qname); +@@ -212,15 +212,15 @@ + $localName = $__local; + $qname = $__qname; + switch($_ngcc_current_state) { +- case 6: ++ case 0: + { +- $_ngcc_current_state = 2; +- $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname); ++ revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname); + } + break; +- case 0: ++ case 2: + { +- revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname); ++ $_ngcc_current_state = 1; ++ $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname); + } + break; + case 7: +@@ -233,6 +233,12 @@ + } + } + break; ++ case 6: ++ { ++ $_ngcc_current_state = 2; ++ $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname); ++ } ++ break; + case 3: + { + if(($__uri == "" && $__local == "location")) { +@@ -243,12 +249,6 @@ + } + } + break; +- case 2: +- { +- $_ngcc_current_state = 1; +- $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname); +- } +- break; + default: + { + unexpectedLeaveAttribute($__qname); +@@ -260,24 +260,6 @@ + public void text(String $value) throws SAXException { + int $ai; + switch($_ngcc_current_state) { +- case 8: +- { +- namespace = $value; +- $_ngcc_current_state = 7; +- } +- break; +- case 6: +- { +- if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) { +- $runtime.consumeAttribute($ai); +- $runtime.sendText(super._cookie, $value); +- } +- else { +- $_ngcc_current_state = 2; +- $runtime.sendText(super._cookie, $value); +- } +- } +- break; + case 0: + { + revertToParentFromText(this, super._cookie, $value); +@@ -295,6 +277,12 @@ + } + } + break; ++ case 8: ++ { ++ namespace = $value; ++ $_ngcc_current_state = 7; ++ } ++ break; + case 4: + { + loc = $value; +@@ -302,6 +290,18 @@ + action0(); + } + break; ++ case 6: ++ { ++ if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) { ++ $runtime.consumeAttribute($ai); ++ $runtime.sendText(super._cookie, $value); ++ } ++ else { ++ $_ngcc_current_state = 2; ++ $runtime.sendText(super._cookie, $value); ++ } ++ } ++ break; + } + } + +--- old/src/share/classes/com/sun/tools/internal/jxc/gen/config/config.xsd Tue Aug 4 09:28:01 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/gen/config/config.xsd Tue Aug 4 09:28:00 2009 +@@ -23,6 +23,8 @@ + CA 95054 USA or visit www.sun.com if you need additional information or + have any questions. + --> ++ ++ + + + +--- old/src/share/classes/com/sun/tools/internal/jxc/model/nav/APTNavigator.java Tue Aug 4 09:28:03 2009 ++++ new/src/share/classes/com/sun/tools/internal/jxc/model/nav/APTNavigator.java Tue Aug 4 09:28:02 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.jxc.model.nav; + + import java.util.ArrayList; +@@ -306,7 +307,7 @@ + } + + public boolean isInnerClass(TypeDeclaration clazz) { +- return clazz.getDeclaringType()!=null; ++ return clazz.getDeclaringType()!=null && !clazz.getModifiers().contains(Modifier.STATIC); + } + + public boolean isArray(TypeMirror t) { +--- old/src/share/classes/com/sun/tools/internal/ws/Invoker.java Tue Aug 4 09:28:05 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/Invoker.java Tue Aug 4 09:28:05 2009 +@@ -55,10 +55,12 @@ + static int invoke(String mainClass, String[] args) throws Throwable { + // use the platform default proxy if available. + // see sun.net.spi.DefaultProxySelector for details. +- try { +- System.setProperty("java.net.useSystemProxies","true"); +- } catch (SecurityException e) { +- // failing to set this property isn't fatal ++ if(!noSystemProxies) { ++ try { ++ System.setProperty("java.net.useSystemProxies","true"); ++ } catch (SecurityException e) { ++ // failing to set this property isn't fatal ++ } + } + + ClassLoader oldcc = Thread.currentThread().getContextClassLoader(); +@@ -220,4 +222,18 @@ + "com.sun.xml.internal.bind.", + "com.sun.xml.internal.ws." + }; ++ ++ /** ++ * Escape hatch to work around IBM JDK problem. ++ * See http://www-128.ibm.com/developerworks/forums/dw_thread.jsp?nav=false&forum=367&thread=164718&cat=10 ++ */ ++ public static boolean noSystemProxies = false; ++ ++ static { ++ try { ++ noSystemProxies = Boolean.getBoolean(Invoker.class.getName()+".noSystemProxies"); ++ } catch(SecurityException e) { ++ // ignore ++ } ++ } + } +--- old/src/share/classes/com/sun/tools/internal/ws/api/TJavaGeneratorExtension.java Tue Aug 4 09:28:07 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/api/TJavaGeneratorExtension.java Tue Aug 4 09:28:07 2009 +@@ -34,6 +34,7 @@ + * + * @see JavaGeneratorExtensionFacade + * @author Vivek Pandey ++ * @deprecated This class is deprecated, will be removed in JAX-WS 2.2 RI. + */ + public abstract class TJavaGeneratorExtension { + /** +--- old/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLExtensible.java Tue Aug 4 09:28:09 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLExtensible.java Tue Aug 4 09:28:09 2009 +@@ -32,6 +32,8 @@ + * A WSDL element or attribute that can be extended. + * + * @author Vivek Pandey ++ * @deprecated This interface is deprecated, will be removed in JAX-WS 2.2 RI. ++ * + */ + public interface TWSDLExtensible { + /** +--- old/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLExtension.java Tue Aug 4 09:28:12 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLExtension.java Tue Aug 4 09:28:11 2009 +@@ -29,6 +29,7 @@ + * A WSDL extension + * + * @author Vivek Pandey ++ * @deprecated This interface is deprecated, will be removed in JAX-WS 2.2 RI. + */ + public interface TWSDLExtension { + /** +--- old/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLExtensionHandler.java Tue Aug 4 09:28:14 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLExtensionHandler.java Tue Aug 4 09:28:13 2009 +@@ -33,6 +33,7 @@ + * with it for the WSDL extensibility elements thats not already defined in the WSDL 1.1 spec, such as SOAP or MIME. + * + * @author Vivek Pandey ++ * @deprecated This class is deprecated, will be removed in JAX-WS 2.2 RI. + */ + public abstract class TWSDLExtensionHandler { + /** +--- old/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLOperation.java Tue Aug 4 09:28:16 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLOperation.java Tue Aug 4 09:28:15 2009 +@@ -33,6 +33,7 @@ + * Abstracts wsdl:portType/wsdl:operation + * + * @author Vivek Pandey ++ * @deprecated This interface is deprecated, will be removed in JAX-WS 2.2 RI. + */ + public interface TWSDLOperation extends TWSDLExtensible{ + /** +--- old/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLParserContext.java Tue Aug 4 09:28:18 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/api/wsdl/TWSDLParserContext.java Tue Aug 4 09:28:18 2009 +@@ -33,6 +33,7 @@ + * it can be latter used by other extensions to resolve the namespaces. + * + * @author Vivek Pandey ++ * @deprecated This interface is deprecated, will be removed in JAX-WS 2.2 RI. + */ + public interface TWSDLParserContext { + +--- old/src/share/classes/com/sun/tools/internal/ws/package-info.java Tue Aug 4 09:28:20 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/package-info.java Tue Aug 4 09:28:20 2009 +@@ -24,7 +24,7 @@ + */ + + /** +- *

    JAX-WS 2.0.1 Tools

    ++ *

    JAX-WS 2.1 Tools

    + * This document describes the tools included with JAX-WS 2.0.1. + * + * {@DotDiagram +@@ -42,7 +42,7 @@ + + // libraries + node [style=filled,color=lightblue]; +- CompileTool; "WSAP"; WebServiceAP; Processor; Modeler; ProcessorActions; ++ WsimportTool; WsgenTool;"WSAP"; WebServiceAP; WSDLModeler;WSDLParser;SeiGenerator;ServiceGenerator;ExceptionGenerator;"JAXB XJC APIs";CodeModel; + + // aps + # node [style=filled,color=lightpink]; +@@ -49,15 +49,17 @@ + # "JAX-WS"; tools; runtime; SPI; "Annotation Processor"; + + "Apt ANT Task" -> APT; +- "WsGen ANT Task" -> wsgen -> CompileTool; +- "WsImport ANT Task" -> wsimport -> CompileTool; ++ "WsGen ANT Task" -> wsgen -> WsgenTool; ++ "WsImport ANT Task" -> wsimport -> WsimportTool; + +- CompileTool -> APT -> WSAP -> WebServiceAP; +- CompileTool -> Processor -> Modeler; +- Processor -> ProcessorActions; +- CompileTool -> WebServiceAP; +- +- Modeler -> WSDLModeler; ++ WsgenTool -> APT -> WSAP -> WebServiceAP; ++ WsimportTool -> WSDLModeler; ++ WSDLModeler->WSDLParser; ++ WSDLModeler->"JAXB XJC APIs" ++ WsimportTool->SeiGenerator->CodeModel; ++ WsimportTool->ServiceGenerator->CodeModel; ++ WsimportTool->ExceptionGenerator->CodeModel; ++ WebServiceAP->CodeModel + } + * } + *
    +--- old/src/share/classes/com/sun/tools/internal/ws/processor/generator/GeneratorBase.java Tue Aug 4 09:28:23 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/generator/GeneratorBase.java Tue Aug 4 09:28:22 2009 +@@ -156,12 +156,14 @@ + return comments; + } + +- protected JDefinedClass getClass(String className, ClassType type) { ++ protected JDefinedClass getClass(String className, ClassType type) throws JClassAlreadyExistsException { + JDefinedClass cls; + try { + cls = cm._class(className, type); + } catch (JClassAlreadyExistsException e){ + cls = cm._getClass(className); ++ if(cls == null) ++ throw e; + } + return cls; + } +--- old/src/share/classes/com/sun/tools/internal/ws/processor/generator/SeiGenerator.java Tue Aug 4 09:28:25 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/generator/SeiGenerator.java Tue Aug 4 09:28:24 2009 +@@ -36,7 +36,11 @@ + import com.sun.tools.internal.ws.wscompile.ErrorReceiver; + import com.sun.tools.internal.ws.wscompile.Options; + import com.sun.tools.internal.ws.wscompile.WsimportOptions; ++import com.sun.tools.internal.ws.wscompile.AbortException; + import com.sun.tools.internal.ws.wsdl.document.soap.SOAPStyle; ++import com.sun.tools.internal.ws.wsdl.document.PortType; ++import com.sun.tools.internal.ws.wsdl.document.Kinds; ++import com.sun.tools.internal.ws.resources.GeneratorMessages; + + import javax.jws.WebMethod; + import javax.jws.WebParam; +@@ -48,6 +52,8 @@ + import java.util.ArrayList; + import java.util.List; + ++import org.xml.sax.Locator; ++ + public class SeiGenerator extends GeneratorBase{ + private String serviceNS; + private TJavaGeneratorExtension extension; +@@ -83,10 +89,22 @@ + } + + +- JDefinedClass cls = getClass(className, ClassType.INTERFACE); +- if (cls == null) ++ JDefinedClass cls = null; ++ try { ++ cls = getClass(className, ClassType.INTERFACE); ++ } catch (JClassAlreadyExistsException e) { ++ QName portTypeName = ++ (QName) port.getProperty( ++ ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); ++ Locator loc = null; ++ if(portTypeName != null){ ++ PortType pt = port.portTypes.get(portTypeName); ++ if(pt!=null) ++ loc = pt.getLocator(); ++ } ++ receiver.error(loc, GeneratorMessages.GENERATOR_SEI_CLASS_ALREADY_EXIST(intf.getName(), portTypeName)); + return; +- ++ } + // If the class has methods it has already been defined + // so skip it. + if (!cls.methods().isEmpty()) +@@ -441,15 +459,7 @@ + if (port.isProvider()) { + return; // Not generating for Provider based endpoint + } +- +- +- try { +- write(port); +- } catch (Exception e) { +- throw new GeneratorException( +- "generator.nestedGeneratorError", +- e); +- } ++ write(port); + } + + private void register(TJavaGeneratorExtension h) { +--- old/src/share/classes/com/sun/tools/internal/ws/processor/generator/ServiceGenerator.java Tue Aug 4 09:28:27 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/generator/ServiceGenerator.java Tue Aug 4 09:28:27 2009 +@@ -29,11 +29,13 @@ + import com.sun.tools.internal.ws.processor.model.Model; + import com.sun.tools.internal.ws.processor.model.Port; + import com.sun.tools.internal.ws.processor.model.Service; ++import com.sun.tools.internal.ws.processor.model.ModelProperties; + import com.sun.tools.internal.ws.processor.model.java.JavaInterface; + import com.sun.tools.internal.ws.wscompile.ErrorReceiver; + import com.sun.tools.internal.ws.wscompile.Options; + import com.sun.tools.internal.ws.wscompile.WsimportOptions; + import com.sun.tools.internal.ws.resources.GeneratorMessages; ++import com.sun.tools.internal.ws.wsdl.document.PortType; + import com.sun.xml.internal.bind.api.JAXBRIContext; + import com.sun.xml.internal.ws.util.JAXWSUtils; + +@@ -42,161 +44,174 @@ + import javax.xml.ws.WebServiceClient; + import javax.xml.ws.WebServiceFeature; + import java.io.IOException; ++import java.io.File; + import java.net.MalformedURLException; + import java.net.URL; ++import java.util.logging.Logger; + ++import org.xml.sax.Locator; + ++ + /** +- * + * @author WS Development Team + */ +-public class ServiceGenerator extends GeneratorBase{ ++public class ServiceGenerator extends GeneratorBase { + +- public static void generate(Model model, WsimportOptions options, ErrorReceiver receiver){ ++ public static void generate(Model model, WsimportOptions options, ErrorReceiver receiver) { + ServiceGenerator serviceGenerator = new ServiceGenerator(model, options, receiver); + serviceGenerator.doGeneration(); + } ++ + private ServiceGenerator(Model model, WsimportOptions options, ErrorReceiver receiver) { + super(model, options, receiver); + } + +- private JInvocation createURL(URL url) { +- return JExpr._new(cm.ref(URL.class)).arg(url.toExternalForm()); +- } +- + @Override + public void visit(Service service) { ++ JavaInterface intf = service.getJavaInterface(); ++ String className = Names.customJavaTypeClassName(intf); ++ if (donotOverride && GeneratorUtil.classExists(options, className)) { ++ log("Class " + className + " exists. Not overriding."); ++ return; ++ } ++ ++ JDefinedClass cls; + try { +- JavaInterface intf = service.getJavaInterface(); +- String className = Names.customJavaTypeClassName(intf); +- if (donotOverride && GeneratorUtil.classExists(options, className)) { +- log("Class " + className + " exists. Not overriding."); +- return; +- } ++ cls = getClass(className, ClassType.CLASS); ++ } catch (JClassAlreadyExistsException e) { ++ receiver.error(service.getLocator(), GeneratorMessages.GENERATOR_SERVICE_CLASS_ALREADY_EXIST(className, service.getName())); ++ return; ++ } + +- JDefinedClass cls = getClass(className, ClassType.CLASS); ++ cls._extends(javax.xml.ws.Service.class); ++ String serviceFieldName = JAXBRIContext.mangleNameToClassName(service.getName().getLocalPart()).toUpperCase(); ++ String wsdlLocationName = serviceFieldName + "_WSDL_LOCATION"; ++ JFieldVar urlField = cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, URL.class, wsdlLocationName); + +- cls._extends(javax.xml.ws.Service.class); +- String serviceFieldName = JAXBRIContext.mangleNameToClassName(service.getName().getLocalPart()).toUpperCase(); +- String wsdlLocationName = serviceFieldName+"_WSDL_LOCATION"; +- JFieldVar urlField = cls.field(JMod.PRIVATE|JMod.STATIC|JMod.FINAL, URL.class, wsdlLocationName); +- JClass qNameCls = cm.ref(QName.class); +- JInvocation inv; +- inv = JExpr._new(qNameCls); +- inv.arg("namespace"); +- inv.arg("localpart"); + ++ cls.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, Logger.class, "logger", cm.ref(Logger.class).staticInvoke("getLogger").arg(JExpr.dotclass(cm.ref(className)).invoke("getName"))); + +- JBlock staticBlock = cls.init(); +- URL url = new URL(JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation))); +- JVar urlVar = staticBlock.decl(cm.ref(URL.class),"url", JExpr._null()); +- JTryBlock tryBlock = staticBlock._try(); +- tryBlock.body().assign(urlVar, createURL(url)); +- JCatchBlock catchBlock = tryBlock._catch(cm.ref(MalformedURLException.class)); +- catchBlock.param("e"); +- catchBlock.body().directStatement("e.printStackTrace();"); +- staticBlock.assign(urlField, urlVar); ++ JClass qNameCls = cm.ref(QName.class); ++ JInvocation inv; ++ inv = JExpr._new(qNameCls); ++ inv.arg("namespace"); ++ inv.arg("localpart"); + +- //write class comment - JAXWS warning +- JDocComment comment = cls.javadoc(); + +- if(service.getJavaDoc() != null){ +- comment.add(service.getJavaDoc()); +- comment.add("\n\n"); +- } ++ JBlock staticBlock = cls.init(); ++ JVar urlVar = staticBlock.decl(cm.ref(URL.class), "url", JExpr._null()); ++ JTryBlock tryBlock = staticBlock._try(); ++ JVar baseUrl = tryBlock.body().decl(cm.ref(URL.class), "baseUrl"); ++ tryBlock.body().assign(baseUrl, JExpr.dotclass(cm.ref(className)).invoke("getResource").arg(".")); ++ tryBlock.body().assign(urlVar, JExpr._new(cm.ref(URL.class)).arg(baseUrl).arg(wsdlLocation)); ++ JCatchBlock catchBlock = tryBlock._catch(cm.ref(MalformedURLException.class)); ++ catchBlock.param("e"); + +- for (String doc : getJAXWSClassComment()) { +- comment.add(doc); +- } ++ catchBlock.body().directStatement("logger.warning(\"Failed to create URL for the wsdl Location: " + JExpr.quotify('\'', wsdlLocation) + ", retrying as a local file\");"); ++ catchBlock.body().directStatement("logger.warning(e.getMessage());"); + +- JMethod constructor = cls.constructor(JMod.PUBLIC); +- constructor.param(URL.class, "wsdlLocation"); +- constructor.param(QName.class, "serviceName"); +- constructor.body().directStatement("super(wsdlLocation, serviceName);"); ++ staticBlock.assign(urlField, urlVar); + +- constructor = cls.constructor(JMod.PUBLIC); +- constructor.body().directStatement("super("+wsdlLocationName+", new QName(\""+service.getName().getNamespaceURI()+"\", \""+service.getName().getLocalPart()+"\"));"); ++ //write class comment - JAXWS warning ++ JDocComment comment = cls.javadoc(); + +- //@WebService +- JAnnotationUse webServiceClientAnn = cls.annotate(cm.ref(WebServiceClient.class)); +- writeWebServiceClientAnnotation(service, webServiceClientAnn); ++ if (service.getJavaDoc() != null) { ++ comment.add(service.getJavaDoc()); ++ comment.add("\n\n"); ++ } + +- //@HandlerChain +- writeHandlerConfig(Names.customJavaTypeClassName(service.getJavaInterface()), cls, options); ++ for (String doc : getJAXWSClassComment()) { ++ comment.add(doc); ++ } + +- for (Port port: service.getPorts()) { +- if (port.isProvider()) { +- continue; // No getXYZPort() for porvider based endpoint +- } ++ JMethod constructor = cls.constructor(JMod.PUBLIC); ++ constructor.param(URL.class, "wsdlLocation"); ++ constructor.param(QName.class, "serviceName"); ++ constructor.body().directStatement("super(wsdlLocation, serviceName);"); + +- //write getXyzPort() +- writeDefaultGetPort(port, cls); ++ constructor = cls.constructor(JMod.PUBLIC); ++ constructor.body().directStatement("super(" + wsdlLocationName + ", new QName(\"" + service.getName().getNamespaceURI() + "\", \"" + service.getName().getLocalPart() + "\"));"); + +- //write getXyzPort(WebServicesFeature...) +- if(options.target.isLaterThan(Options.Target.V2_1)) +- writeGetPort(port, cls); ++ //@WebService ++ JAnnotationUse webServiceClientAnn = cls.annotate(cm.ref(WebServiceClient.class)); ++ writeWebServiceClientAnnotation(service, webServiceClientAnn); ++ ++ //@HandlerChain ++ writeHandlerConfig(Names.customJavaTypeClassName(service.getJavaInterface()), cls, options); ++ ++ for (Port port : service.getPorts()) { ++ if (port.isProvider()) { ++ continue; // No getXYZPort() for porvider based endpoint + } +- } catch (IOException e) { +- receiver.error(e); ++ ++ //Get the SEI class ++ JType retType; ++ try { ++ retType = getClass(port.getJavaInterface().getName(), ClassType.INTERFACE); ++ } catch (JClassAlreadyExistsException e) { ++ QName portTypeName = ++ (QName) port.getProperty( ++ ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); ++ Locator loc = null; ++ if (portTypeName != null) { ++ PortType pt = port.portTypes.get(portTypeName); ++ if (pt != null) ++ loc = pt.getLocator(); ++ } ++ receiver.error(loc, GeneratorMessages.GENERATOR_SEI_CLASS_ALREADY_EXIST(port.getJavaInterface().getName(), portTypeName)); ++ return; ++ } ++ ++ //write getXyzPort() ++ writeDefaultGetPort(port, retType, cls); ++ ++ //write getXyzPort(WebServicesFeature...) ++ if (options.target.isLaterThan(Options.Target.V2_1)) ++ writeGetPort(port, retType, cls); + } + } + +- private void writeGetPort(Port port, JDefinedClass cls) { +- JType retType = getClass(port.getJavaInterface().getName(), ClassType.INTERFACE); ++ private void writeGetPort(Port port, JType retType, JDefinedClass cls) { + JMethod m = cls.method(JMod.PUBLIC, retType, port.getPortGetter()); + JDocComment methodDoc = m.javadoc(); +- if(port.getJavaDoc() != null) ++ if (port.getJavaDoc() != null) + methodDoc.add(port.getJavaDoc()); + JCommentPart ret = methodDoc.addReturn(); + JCommentPart paramDoc = methodDoc.addParam("features"); + paramDoc.append("A list of "); +- paramDoc.append("{@link "+WebServiceFeature.class.getName()+"}"); ++ paramDoc.append("{@link " + WebServiceFeature.class.getName() + "}"); + paramDoc.append("to configure on the proxy. Supported features not in the features parameter will have their default values."); +- ret.add("returns "+retType.name()); ++ ret.add("returns " + retType.name()); + m.varParam(WebServiceFeature.class, "features"); + JBlock body = m.body(); +- StringBuffer statement = new StringBuffer("return ("); ++ StringBuffer statement = new StringBuffer("return "); ++ statement.append("super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), "); + statement.append(retType.name()); +- statement.append(")super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), "); +- statement.append(retType.name()); + statement.append(".class, features);"); + body.directStatement(statement.toString()); + writeWebEndpoint(port, m); + } + +- private void writeDefaultGetPort(Port port, JDefinedClass cls) { +- JType retType = getClass(port.getJavaInterface().getName(), ClassType.INTERFACE); ++ private void writeDefaultGetPort(Port port, JType retType, JDefinedClass cls) { + String portGetter = port.getPortGetter(); + JMethod m = cls.method(JMod.PUBLIC, retType, portGetter); + JDocComment methodDoc = m.javadoc(); +- if(port.getJavaDoc() != null) ++ if (port.getJavaDoc() != null) + methodDoc.add(port.getJavaDoc()); + JCommentPart ret = methodDoc.addReturn(); +- ret.add("returns "+retType.name()); ++ ret.add("returns " + retType.name()); + JBlock body = m.body(); +- StringBuffer statement = new StringBuffer("return ("); ++ StringBuffer statement = new StringBuffer("return "); ++ statement.append("super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), "); + statement.append(retType.name()); +- statement.append(")super.getPort(new QName(\"").append(port.getName().getNamespaceURI()).append("\", \"").append(port.getName().getLocalPart()).append("\"), "); +- statement.append(retType.name()); + statement.append(".class);"); + body.directStatement(statement.toString()); + writeWebEndpoint(port, m); + } + +- +- protected JDefinedClass getClass(String className, ClassType type) { +- JDefinedClass cls; +- try { +- cls = cm._class(className, type); +- } catch (JClassAlreadyExistsException e){ +- cls = cm._getClass(className); +- } +- return cls; +- } +- + private void writeWebServiceClientAnnotation(Service service, JAnnotationUse wsa) { + String serviceName = service.getName().getLocalPart(); +- String serviceNS= service.getName().getNamespaceURI(); ++ String serviceNS = service.getName().getNamespaceURI(); + wsa.param("name", serviceName); + wsa.param("targetNamespace", serviceNS); + wsa.param("wsdlLocation", wsdlLocation); +--- old/src/share/classes/com/sun/tools/internal/ws/processor/generator/W3CAddressingJavaGeneratorExtension.java Tue Aug 4 09:28:29 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/generator/W3CAddressingJavaGeneratorExtension.java Tue Aug 4 09:28:29 2009 +@@ -22,9 +22,6 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +-/* +- * $Id: W3CAddressingJavaGeneratorExtension.java,v 1.1.2.4 2006/10/31 19:57:28 vivekp Exp $ +- */ + + package com.sun.tools.internal.ws.processor.generator; + +--- old/src/share/classes/com/sun/tools/internal/ws/processor/model/Port.java Tue Aug 4 09:28:31 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/model/Port.java Tue Aug 4 09:28:31 2009 +@@ -26,6 +26,7 @@ + package com.sun.tools.internal.ws.processor.model; + + import com.sun.tools.internal.ws.processor.model.java.JavaInterface; ++import com.sun.tools.internal.ws.wsdl.document.PortType; + import com.sun.tools.internal.ws.wsdl.document.soap.SOAPStyle; + import com.sun.tools.internal.ws.wsdl.framework.Entity; + +@@ -174,4 +175,5 @@ + private String _address; + private String _serviceImplName; + private Map operationsByName = new HashMap(); ++ public Map portTypes = new HashMap(); + } +--- old/src/share/classes/com/sun/tools/internal/ws/processor/model/java/JavaMethod.java Tue Aug 4 09:28:34 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/model/java/JavaMethod.java Tue Aug 4 09:28:33 2009 +@@ -27,6 +27,7 @@ + + import com.sun.tools.internal.ws.resources.ModelMessages; + import com.sun.tools.internal.ws.wscompile.ErrorReceiver; ++import com.sun.tools.internal.ws.wscompile.WsimportOptions; + import com.sun.tools.internal.ws.processor.model.Parameter; + + import java.util.ArrayList; +@@ -42,12 +43,14 @@ + private final String name; + private final List parameters = new ArrayList(); + private final List exceptions = new ArrayList(); ++ private final WsimportOptions options; + private JavaType returnType; + +- public JavaMethod(String name, ErrorReceiver receiver) { ++ public JavaMethod(String name, WsimportOptions options, ErrorReceiver receiver) { + this.name = name; + this.returnType = null; + this.errorReceiver = receiver; ++ this.options = options; + } + + public String getName() { +@@ -83,10 +86,19 @@ + public void addParameter(JavaParameter param) { + // verify that this member does not already exist + if (hasParameter(param.getName())) { +- errorReceiver.error(param.getParameter().getLocator(), ModelMessages.MODEL_PARAMETER_NOTUNIQUE(param.getName(), param.getParameter().getEntityName())); +- Parameter duplicParam = getParameter(param.getName()); +- errorReceiver.error(duplicParam.getLocator(), ModelMessages.MODEL_PARAMETER_NOTUNIQUE(param.getName(), duplicParam.getEntityName())); +- return; ++ if(options.isExtensionMode()){ ++ param.setName(getUniqueName(param.getName())); ++ }else{ ++ Parameter duplicParam = getParameter(param.getName()); ++ if(param.getParameter().isEmbedded()){ ++ errorReceiver.error(param.getParameter().getLocator(), ModelMessages.MODEL_PARAMETER_NOTUNIQUE_WRAPPER(param.getName(), param.getParameter().getEntityName())); ++ errorReceiver.error(duplicParam.getLocator(), ModelMessages.MODEL_PARAMETER_NOTUNIQUE_WRAPPER(param.getName(), duplicParam.getEntityName())); ++ }else{ ++ errorReceiver.error(param.getParameter().getLocator(), ModelMessages.MODEL_PARAMETER_NOTUNIQUE(param.getName(), param.getParameter().getEntityName())); ++ errorReceiver.error(duplicParam.getLocator(), ModelMessages.MODEL_PARAMETER_NOTUNIQUE(param.getName(), duplicParam.getEntityName())); ++ } ++ return; ++ } + } + parameters.add(param); + } +@@ -106,4 +118,12 @@ + public Iterator getExceptions() { + return exceptions.iterator(); + } ++ ++ private String getUniqueName(String param){ ++ int parmNum = 0; ++ while(hasParameter(param)){ ++ param = param + Integer.toString(parmNum++); ++ } ++ return param; ++ } + } +--- old/src/share/classes/com/sun/tools/internal/ws/processor/model/jaxb/JAXBType.java Tue Aug 4 09:28:36 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/model/jaxb/JAXBType.java Tue Aug 4 09:28:35 2009 +@@ -71,11 +71,11 @@ + } + + public boolean isUnwrappable(){ +- return getJaxbMapping().getWrapperStyleDrilldown() != null; ++ return jaxbMapping != null && jaxbMapping.getWrapperStyleDrilldown() != null; + } + + public boolean hasWrapperChildren(){ +- return (getWrapperChildren().size() > 0) ? true : false; ++ return wrapperChildren.size() > 0; + } + + public boolean isLiteralType() { +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/annotation/WebServiceAP.java Tue Aug 4 09:28:38 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/annotation/WebServiceAP.java Tue Aug 4 09:28:38 2009 +@@ -210,6 +210,7 @@ + public void onError(String message) { + if (messager != null) { + messager.printError(message); ++ throw new AbortException(); + } else { + throw new ModelerException(message); + } +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/annotation/WebServiceVisitor.java Tue Aug 4 09:28:40 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/annotation/WebServiceVisitor.java Tue Aug 4 09:28:40 2009 +@@ -441,10 +441,21 @@ + + protected boolean shouldProcessMethod(MethodDeclaration method, WebMethod webMethod) { + builder.log("should process method: "+method.getSimpleName()+" hasWebMethods: "+ hasWebMethods+" "); ++ /* ++ Fix for https://jax-ws.dev.java.net/issues/show_bug.cgi?id=577 + if (hasWebMethods && webMethod == null) { + builder.log("webMethod == null"); + return false; + } ++ */ ++ Collection modifiers = method.getModifiers(); ++ boolean staticFinal = modifiers.contains(Modifier.STATIC) || modifiers.contains(Modifier.FINAL); ++ if (staticFinal) { ++ if (webMethod != null) { ++ builder.onError(method.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_STATIC_OR_FINAL(method.getDeclaringType(), method)); ++ } ++ return false; ++ } + boolean retval = (endpointReferencesInterface || + method.getDeclaringType().equals(typeDecl) || + (method.getDeclaringType().getAnnotation(WebService.class) != null)); +@@ -474,10 +485,6 @@ + builder.onError(classDecl.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(classDecl.getQualifiedName())); + return false; + } +- if (classDecl.getDeclaringType() != null && !modifiers.contains(Modifier.STATIC) && !isStateful) { +- builder.onError(classDecl.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(classDecl.getQualifiedName())); +- return false; +- } + boolean hasDefaultConstructor = false; + for (ConstructorDeclaration constructor : classDecl.getConstructors()) { + if (constructor.getModifiers().contains(Modifier.PUBLIC) && +@@ -487,6 +494,11 @@ + } + } + if (!hasDefaultConstructor && !isStateful) { ++ if (classDecl.getDeclaringType() != null && !modifiers.contains(Modifier.STATIC)) { ++ builder.onError(classDecl.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(classDecl.getQualifiedName())); ++ return false; ++ } ++ + builder.onError(classDecl.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(classDecl.getQualifiedName())); + return false; + } +@@ -578,7 +590,7 @@ + } + ClassType superClass = classDecl.getSuperclass(); + +- if (!superClass.getDeclaration().getQualifiedName().equals(JAVA_LANG_OBJECT) && superClass != null && !methodsAreLegal(superClass.getDeclaration())) { ++ if (!superClass.getDeclaration().getQualifiedName().equals(JAVA_LANG_OBJECT) && !methodsAreLegal(superClass.getDeclaration())) { + return false; + } + return true; +@@ -596,11 +608,13 @@ + if (!hasWebMethods && (webMethod !=null) && webMethod.exclude()) { + return true; + } ++ /* ++ This check is not needed as Impl class is already checked that it is not abstract. + if (typeDecl instanceof ClassDeclaration && method.getModifiers().contains(Modifier.ABSTRACT)) { + builder.onError(method.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(typeDecl.getQualifiedName(), method.getSimpleName())); + return false; + } +- ++ */ + if (!isLegalType(method.getReturnType())) { + builder.onError(method.getPosition(), WebserviceapMessages.localizableWEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(typeDecl.getQualifiedName(), + method.getSimpleName(), +@@ -750,7 +764,12 @@ + protected boolean isLegalType(TypeMirror type) { + if (!(type instanceof DeclaredType)) + return true; +- return !builder.isRemote(((DeclaredType)type).getDeclaration()); ++ TypeDeclaration typeDecl = ((DeclaredType)type).getDeclaration(); ++ if(typeDecl == null) { ++ // can be null, if this type's declaration is unknown. This may be the result of a processing error, such as a missing class file. ++ builder.onError(WebserviceapMessages.WEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(typeDecl.toString(), context.getRound())); ++ } ++ return !builder.isRemote(typeDecl); + } + + protected ParameterDeclaration getOutParameter(MethodDeclaration method) { +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/annotation/WebServiceWrapperGenerator.java Tue Aug 4 09:28:43 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/annotation/WebServiceWrapperGenerator.java Tue Aug 4 09:28:42 2009 +@@ -127,8 +127,10 @@ + boolean beanGenerated = false; + for (ReferenceType thrownType : method.getThrownTypes()) { + ClassDeclaration typeDecl = ((ClassType)thrownType).getDeclaration(); +- if (typeDecl == null) ++ if (typeDecl == null){ + builder.onError(WebserviceapMessages.WEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(thrownType.toString(), context.getRound())); ++ return false; ++ } + boolean tmp = generateExceptionBean(typeDecl, beanPackage); + beanGenerated = beanGenerated || tmp; + } +@@ -195,7 +197,7 @@ + if (resWrapper.targetNamespace().length() > 0) + resNamespace = resWrapper.targetNamespace(); + } +- canOverwriteResponse = builder.canOverWriteClass(requestClassName); ++ canOverwriteResponse = builder.canOverWriteClass(responseClassName); + if (!canOverwriteResponse) { + builder.log("Class " + responseClassName + " exists. Not overwriting."); + } +@@ -593,7 +595,7 @@ + return; + + String accessorName =JAXBRIContext.mangleNameToPropertyName(paramName); +- String getterPrefix = paramType.equals("boolean") || paramType.equals("java.lang.Boolean") ? "is" : "get"; ++ String getterPrefix = paramType.toString().equals("boolean")? "is" : "get"; + JType propType = getType(paramType); + JMethod m = cls.method(JMod.PUBLIC, propType, getterPrefix+ accessorName); + JDocComment methodDoc = m.javadoc(); +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/ConsoleErrorReporter.java Tue Aug 4 09:28:45 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/ConsoleErrorReporter.java Tue Aug 4 09:28:45 2009 +@@ -57,6 +57,8 @@ + print(WscompileMessages.WSIMPORT_ERROR_MESSAGE(e.getMessage()), e); + } + ++ ++ + public void fatalError(SAXParseException e) { + if(debug) + e.printStackTrace(); +@@ -76,6 +78,11 @@ + print(WscompileMessages.WSIMPORT_INFO_MESSAGE(e.getMessage()), e); + } + ++ public void debug(SAXParseException e){ ++ print(WscompileMessages.WSIMPORT_DEBUG_MESSAGE(e.getMessage()), e); ++ } ++ ++ + private void print(String message, SAXParseException e) { + output.println(message); + output.println(getLocationString(e)); +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/PseudoSchemaBuilder.java Tue Aug 4 09:28:47 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/PseudoSchemaBuilder.java Tue Aug 4 09:28:47 2009 +@@ -28,6 +28,7 @@ + import static com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModelerBase.getExtensionOfType; + import com.sun.tools.internal.ws.wscompile.ErrorReceiver; + import com.sun.tools.internal.ws.wscompile.WsimportOptions; ++import com.sun.tools.internal.ws.wscompile.Options; + import com.sun.tools.internal.ws.wsdl.document.*; + import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBinding; + import com.sun.tools.internal.ws.wsdl.document.schema.SchemaKinds; +@@ -101,7 +102,7 @@ + is.setSystemId(sysId+(i + 1)); + } + //add w3c EPR binding +- if(!(options.noAddressingBbinding && options.isExtensionMode())){ ++ if(!(options.noAddressingBbinding) && options.target.isLaterThan(Options.Target.V2_1)){ + InputSource is = new InputSource(new ByteArrayInputStream(w3ceprSchemaBinding.getBytes())); + is.setSystemId(sysId+(++i +1)); + b.schemas.add(is); +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/WSDLModeler.java Tue Aug 4 09:28:49 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/WSDLModeler.java Tue Aug 4 09:28:49 2009 +@@ -74,7 +74,7 @@ + public class WSDLModeler extends WSDLModelerBase { + + //map of wsdl:operation QName to child, as per BP it must be unique in a port +- private final Map uniqueBodyBlocks = new HashMap(); ++ private final Map uniqueBodyBlocks = new HashMap(); + private final QName VOID_BODYBLOCK = new QName(""); + private ClassNameCollector classNameCollector; + private final String explicitDefaultPackage; +@@ -334,11 +334,12 @@ + || (!soapBinding.getTransport().equals( + SOAPConstants.URI_SOAP_TRANSPORT_HTTP) && !soapBinding.getTransport().equals( + SOAP12Constants.URI_SOAP_TRANSPORT_HTTP)))) { +- warning(wsdlPort, ModelerMessages.WSDLMODELER_WARNING_IGNORING_SOAP_BINDING_NON_HTTP_TRANSPORT(wsdlPort.getName())); + if (!options.isExtensionMode()) { + // cannot deal with non-HTTP ports ++ warning(wsdlPort, ModelerMessages.WSDLMODELER_WARNING_IGNORING_SOAP_BINDING_NON_HTTP_TRANSPORT(wsdlPort.getName())); + return false; + } ++ + } + + /** +@@ -679,7 +680,12 @@ + + if (soapStyle == SOAPStyle.RPC) { + if (soapRequestBody.isEncoded()) { +- error(soapRequestBody, ModelerMessages.WSDLMODELER_20_RPCENC_NOT_SUPPORTED()); ++ if(options.isExtensionMode()){ ++ warning(soapRequestBody, ModelerMessages.WSDLMODELER_20_RPCENC_NOT_SUPPORTED()); ++ processNonSOAPOperation(); ++ }else{ ++ error(soapRequestBody, ModelerMessages.WSDLMODELER_20_RPCENC_NOT_SUPPORTED()); ++ } + } + return processLiteralSOAPOperation(StyleAndUse.RPC_LITERAL); + } +@@ -815,20 +821,71 @@ + QName body = VOID_BODYBLOCK; + QName opName = null; + ++ Operation thatOp; + if (bb.hasNext()) { + body = bb.next().getName(); +- opName = uniqueBodyBlocks.get(body); ++ thatOp = uniqueBodyBlocks.get(body); + } else { + //there is no body block + body = VOID_BODYBLOCK; +- opName = uniqueBodyBlocks.get(VOID_BODYBLOCK); ++ thatOp = uniqueBodyBlocks.get(VOID_BODYBLOCK); + } +- if (opName != null) { +- error(info.port, ModelerMessages.WSDLMODELER_NON_UNIQUE_BODY(info.port.getName(), info.operation.getName(), opName, body)); +- } else { +- uniqueBodyBlocks.put(body, info.operation.getName()); ++ ++ if(thatOp != null){ ++ if(options.isExtensionMode()){ ++ warning(info.port, ModelerMessages.WSDLMODELER_NON_UNIQUE_BODY_WARNING(info.port.getName(), info.operation.getName(), thatOp.getName(), body)); ++ }else{ ++ error(info.port, ModelerMessages.WSDLMODELER_NON_UNIQUE_BODY_ERROR(info.port.getName(), info.operation.getName(), thatOp.getName(), body)); ++ } ++ }else{ ++ uniqueBodyBlocks.put(body, info.operation); + } + ++ //Add additional headers ++ if (options.additionalHeaders) { ++ List additionalHeaders = new ArrayList(); ++ if (inputMessage != null) { ++ for (MessagePart part : getAdditionHeaderParts(inputMessage, true)) { ++ QName name = part.getDescriptor(); ++ JAXBType jaxbType = getJAXBType(part); ++ Block block = new Block(name, jaxbType, part); ++ Parameter param = ModelerUtils.createParameter(part.getName(), jaxbType, block); ++ additionalHeaders.add(param); ++ request.addHeaderBlock(block); ++ request.addParameter(param); ++ definitiveParameterList.add(param); ++ } ++ } ++ ++ if (isRequestResponse && outputMessage != null) { ++ List outParams = new ArrayList(); ++ for (MessagePart part : getAdditionHeaderParts(outputMessage, false)) { ++ QName name = part.getDescriptor(); ++ JAXBType jaxbType = getJAXBType(part); ++ Block block = new Block(name, jaxbType, part); ++ Parameter param = ModelerUtils.createParameter(part.getName(), jaxbType, block); ++ param.setMode(Mode.OUT); ++ outParams.add(param); ++ response.addHeaderBlock(block); ++ response.addParameter(param); ++ } ++ for (Parameter outParam : outParams) { ++ for (Parameter inParam : additionalHeaders) { ++ if (inParam.getName().equals(outParam.getName()) && ++ inParam.getBlock().getName().equals(outParam.getBlock().getName())) { ++ //it is INOUT ++ inParam.setMode(Mode.INOUT); ++ outParam.setMode(Mode.INOUT); ++ break; ++ } ++ } ++ if (outParam.isOUT()) { ++ definitiveParameterList.add(outParam); ++ } ++ } ++ } ++ } ++ + // faults with duplicate names + Set duplicateNames = getDuplicateFaultNames(); + +@@ -848,6 +905,7 @@ + return info.operation; + } + ++ + private boolean validateParameterName(List params) { + if (options.isExtensionMode()) + return true; +@@ -1460,6 +1518,19 @@ + return null; + } + ++ private List getAdditionHeaderParts(Message message, boolean isInput){ ++ List headerParts = new ArrayList(); ++ List parts = message.getParts(); ++ List headers = getHeaderParts(isInput); ++ ++ for(MessagePart part: headers){ ++ if(parts.contains(part)) ++ continue; ++ headerParts.add(part); ++ } ++ return headerParts; ++ } ++ + private List getHeaderPartsFromMessage(Message message, boolean isInput) { + List headerParts = new ArrayList(); + Iterator parts = message.parts(); +@@ -1490,19 +1561,6 @@ + return null; + } + +- private List getHeaderPartsNotFromMessage(Message message, boolean isInput) { +- List headerParts = new ArrayList(); +- List parts = message.getParts(); +- Iterator headers = getHeaderParts(isInput).iterator(); +- while (headers.hasNext()) { +- MessagePart part = headers.next(); +- if (!parts.contains(part)) { +- headerParts.add(part); +- } +- } +- return headerParts; +- } +- + private List getHeaderParts(boolean isInput) { + TWSDLExtensible ext; + if (isInput) { +@@ -2247,6 +2305,10 @@ + (QName) port.getProperty( + ModelProperties.PROPERTY_WSDL_PORT_TYPE_NAME); + PortType pt = (PortType) document.find(Kinds.PORT_TYPE, portTypeName); ++ //populate the portType map here. We should get rid of all these properties ++ // lets not do it as it may break NB ++ //TODO: clean all these stuff part of NB RFE ++ port.portTypes.put(portTypeName, pt); + JAXWSBinding jaxwsCust = (JAXWSBinding) getExtensionOfType(pt, JAXWSBinding.class); + if (jaxwsCust != null && jaxwsCust.getClassName() != null) { + CustomName name = jaxwsCust.getClassName(); +@@ -2271,7 +2333,7 @@ + private void createJavaMethodForAsyncOperation(Port port, Operation operation, + JavaInterface intf) { + String candidateName = getJavaNameForOperation(operation); +- JavaMethod method = new JavaMethod(candidateName, errReceiver); ++ JavaMethod method = new JavaMethod(candidateName, options, errReceiver); + Request request = operation.getRequest(); + Iterator requestBodyBlocks = request.getBodyBlocks(); + Block requestBlock = +@@ -2338,7 +2400,7 @@ + return; + } + String candidateName = getJavaNameForOperation(operation); +- JavaMethod method = new JavaMethod(candidateName, errReceiver); ++ JavaMethod method = new JavaMethod(candidateName, options, errReceiver); + Request request = operation.getRequest(); + Parameter returnParam = (Parameter) operation.getProperty(WSDL_RESULT_PARAMETER); + if (returnParam != null) { +@@ -2718,7 +2780,7 @@ + + private void reportError(Entity entity, + String formattedMsg, Exception nestedException ) { +- Locator locator = (entity == null)?NULL_LOCATOR:entity.getLocator(); ++ Locator locator = (entity == null)?null:entity.getLocator(); + + SAXParseException e = new SAXParseException2( formattedMsg, + locator, +--- old/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/WSDLModelerBase.java Tue Aug 4 09:28:52 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/modeler/wsdl/WSDLModelerBase.java Tue Aug 4 09:28:52 2009 +@@ -288,23 +288,11 @@ + private boolean validateMimeContentPartNames(List mimeContents) { + //validate mime:content(s) in the mime:part as per R2909 + for (MIMEContent mimeContent : mimeContents) { +- String mimeContnetPart = null; ++ String mimeContnetPart; ++ mimeContnetPart = getMimeContentPartName(mimeContent); + if(mimeContnetPart == null) { +- mimeContnetPart = getMimeContentPartName(mimeContent); +- if(mimeContnetPart == null) { +- warning(mimeContent, ModelerMessages.MIMEMODELER_INVALID_MIME_CONTENT_MISSING_PART_ATTRIBUTE(info.operation.getName().getLocalPart())); +- return false; +- } +- }else { +- String newMimeContnetPart = getMimeContentPartName(mimeContent); +- if(newMimeContnetPart == null) { +- warning(mimeContent, ModelerMessages.MIMEMODELER_INVALID_MIME_CONTENT_MISSING_PART_ATTRIBUTE(info.operation.getName().getLocalPart())); +- return false; +- }else if(!newMimeContnetPart.equals(mimeContnetPart)) { +- //throw new ModelerException("mimemodeler.invalidMimeContent.differentPart"); +- warning(mimeContent, ModelerMessages.MIMEMODELER_INVALID_MIME_CONTENT_DIFFERENT_PART()); +- return false; +- } ++ warning(mimeContent, ModelerMessages.MIMEMODELER_INVALID_MIME_CONTENT_MISSING_PART_ATTRIBUTE(info.operation.getName().getLocalPart())); ++ return false; + } + } + return true; +@@ -386,6 +374,9 @@ + protected String getRequestNamespaceURI(SOAPBody body) { + String namespaceURI = body.getNamespace(); + if (namespaceURI == null) { ++ if(options.isExtensionMode()){ ++ return info.modelPort.getName().getNamespaceURI(); ++ } + // the WSDL document is invalid + // at least, that's my interpretation of section 3.5 of the WSDL 1.1 spec! + error(body, ModelerMessages.WSDLMODELER_INVALID_BINDING_OPERATION_INPUT_SOAP_BODY_MISSING_NAMESPACE(info.bindingOperation.getName())); +@@ -396,6 +387,9 @@ + protected String getResponseNamespaceURI(SOAPBody body) { + String namespaceURI = body.getNamespace(); + if (namespaceURI == null) { ++ if(options.isExtensionMode()){ ++ return info.modelPort.getName().getNamespaceURI(); ++ } + // the WSDL document is invalid + // at least, that's my interpretation of section 3.5 of the WSDL 1.1 spec! + error(body, ModelerMessages.WSDLMODELER_INVALID_BINDING_OPERATION_OUTPUT_SOAP_BODY_MISSING_NAMESPACE(info.bindingOperation.getName())); +@@ -703,7 +697,7 @@ + if(numPasses > 1) + return; + if(entity == null) +- errReceiver.warning(NULL_LOCATOR, message); ++ errReceiver.warning(null, message); + else + errReceiver.warning(entity.getLocator(), message); + } +@@ -710,7 +704,7 @@ + + protected void error(Entity entity, String message){ + if(entity == null) +- errReceiver.error(NULL_LOCATOR, message); ++ errReceiver.error(null, message); + else + errReceiver.error(entity.getLocator(), message); + throw new AbortException(); +--- old/src/share/classes/com/sun/tools/internal/ws/processor/util/ClassNameCollector.java Tue Aug 4 09:28:55 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/processor/util/ClassNameCollector.java Tue Aug 4 09:28:54 2009 +@@ -80,8 +80,10 @@ + protected void preVisit(Service service) throws Exception { + registerClassName( + ((JavaInterface)service.getJavaInterface()).getName()); +- registerClassName( +- ((JavaInterface)service.getJavaInterface()).getImpl()); ++ // We don't generate Impl classes, commenting it out. ++ // Otherwise, it would cause naming conflicts ++ //registerClassName( ++ // ((JavaInterface)service.getJavaInterface()).getImpl()); + } + + protected void processPort11x(Port port){ +--- old/src/share/classes/com/sun/tools/internal/ws/resources/GeneratorMessages.java Tue Aug 4 09:28:57 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/GeneratorMessages.java Tue Aug 4 09:28:56 2009 +@@ -38,6 +38,30 @@ + private final static LocalizableMessageFactory messageFactory = new LocalizableMessageFactory("com.sun.tools.internal.ws.resources.generator"); + private final static Localizer localizer = new Localizer(); + ++ public static Localizable localizableGENERATOR_SERVICE_CLASS_ALREADY_EXIST(Object arg0, Object arg1) { ++ return messageFactory.getMessage("generator.service.classAlreadyExist", arg0, arg1); ++ } ++ ++ /** ++ * Could not generate Service, class: {0} already exists. Rename wsdl:Service "{1}" using JAX-WS customization ++ * ++ */ ++ public static String GENERATOR_SERVICE_CLASS_ALREADY_EXIST(Object arg0, Object arg1) { ++ return localizer.localize(localizableGENERATOR_SERVICE_CLASS_ALREADY_EXIST(arg0, arg1)); ++ } ++ ++ public static Localizable localizableGENERATOR_SEI_CLASS_ALREADY_EXIST(Object arg0, Object arg1) { ++ return messageFactory.getMessage("generator.sei.classAlreadyExist", arg0, arg1); ++ } ++ ++ /** ++ * Could not generate SEI, class: {0} already exists. Rename wsdl:portType "{1}" using JAX-WS customization ++ * ++ */ ++ public static String GENERATOR_SEI_CLASS_ALREADY_EXIST(Object arg0, Object arg1) { ++ return localizer.localize(localizableGENERATOR_SEI_CLASS_ALREADY_EXIST(arg0, arg1)); ++ } ++ + public static Localizable localizableGENERATOR_NESTED_GENERATOR_ERROR(Object arg0) { + return messageFactory.getMessage("generator.nestedGeneratorError", arg0); + } +--- old/src/share/classes/com/sun/tools/internal/ws/resources/ModelMessages.java Tue Aug 4 09:28:59 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/ModelMessages.java Tue Aug 4 09:28:59 2009 +@@ -255,18 +255,6 @@ + return localizer.localize(localizableMODEL_SAXPARSER_EXCEPTION(arg0, arg1)); + } + +- public static Localizable localizable_002F_002F_JAXWS() { +- return messageFactory.getMessage("//JAXWS"); +- } +- +- /** +- * 2.0 +- * +- */ +- public static String _002F_002F_JAXWS() { +- return localizer.localize(localizable_002F_002F_JAXWS()); +- } +- + public static Localizable localizableMODEL_DUPLICATE_FAULTMESSAGE(Object arg0) { + return messageFactory.getMessage("model.duplicate.faultmessage", arg0); + } +@@ -536,7 +524,9 @@ + } + + /** +- * Failed to generate Java signature: duplicate parameter names {0}. Use JAXWS binding customization to rename the wsdl:part "{1}" ++ * Failed to generate Java signature: duplicate parameter name "{0}". Try one of these ++ * 1. Use JAXWS binding customization to rename the wsdl:part "{1}" ++ * 2. Run wsimport with -extension switch. + * + */ + public static String MODEL_PARAMETER_NOTUNIQUE(Object arg0, Object arg1) { +@@ -639,6 +629,21 @@ + return localizer.localize(localizableMODEL_IMPORTER_INVALID_LITERAL(arg0)); + } + ++ public static Localizable localizableMODEL_PARAMETER_NOTUNIQUE_WRAPPER(Object arg0, Object arg1) { ++ return messageFactory.getMessage("model.parameter.notunique.wrapper", arg0, arg1); ++ } ++ ++ /** ++ * Failed to generate Java signature: duplicate parameter name "{0}". Try one of these ++ * 1. Use JAXWS binding customization to rename the wsdl:part "{1}" ++ * 2. Run wsimport with -extension switch. ++ * 3. This is wrapper style operation, to resolve parameter name conflict, you can also try disabling wrapper style by using false wsdl customization. ++ * ++ */ ++ public static String MODEL_PARAMETER_NOTUNIQUE_WRAPPER(Object arg0, Object arg1) { ++ return localizer.localize(localizableMODEL_PARAMETER_NOTUNIQUE_WRAPPER(arg0, arg1)); ++ } ++ + public static Localizable localizableMODEL_SCHEMA_NOT_IMPLEMENTED(Object arg0) { + return messageFactory.getMessage("model.schema.notImplemented", arg0); + } +--- old/src/share/classes/com/sun/tools/internal/ws/resources/ModelerMessages.java Tue Aug 4 09:29:01 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/ModelerMessages.java Tue Aug 4 09:29:01 2009 +@@ -331,7 +331,7 @@ + } + + /** +- * Schema descriptor {0} in message part "{1}" could not be bound to Java! ++ * Schema descriptor {0} in message part "{1}" is not defined and could not be bound to Java. Perhaps the schema descriptor {0} is not defined in the schema imported/included in the WSDL. You can either add such imports/includes or run wsimport and provide the schema location using -b switch. + * + */ + public static String WSDLMODELER_JAXB_JAVATYPE_NOTFOUND(Object arg0, Object arg1) { +@@ -590,6 +590,18 @@ + return localizer.localize(localizableWSDLMODELER_WARNING_IGNORING_OPERATION_CANNOT_HANDLE_BODY_PARTS_ATTRIBUTE(arg0)); + } + ++ public static Localizable localizableWSDLMODELER_NON_UNIQUE_BODY_ERROR(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return messageFactory.getMessage("wsdlmodeler.nonUnique.body.error", arg0, arg1, arg2, arg3); ++ } ++ ++ /** ++ * Non unique body parts! In a port, as per BP 1.1 R2710 operations must have unique operation signaure on the wire for successful dispatch. In port {0}, Operations "{1}" and "{2}" have the same request body block {3}. Try running wsimport with -extension switch, runtime will try to dispatch using SOAPAction ++ * ++ */ ++ public static String WSDLMODELER_NON_UNIQUE_BODY_ERROR(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return localizer.localize(localizableWSDLMODELER_NON_UNIQUE_BODY_ERROR(arg0, arg1, arg2, arg3)); ++ } ++ + public static Localizable localizableWSDLMODELER_WARNING_IGNORING_SOAP_BINDING_MIXED_STYLE(Object arg0) { + return messageFactory.getMessage("wsdlmodeler.warning.ignoringSOAPBinding.mixedStyle", arg0); + } +@@ -818,18 +830,6 @@ + return localizer.localize(localizableWSDLMODELER_INVALID_BINDING_OPERATION_MULTIPLE_MATCHING_OPERATIONS(arg0, arg1)); + } + +- public static Localizable localizableWSDLMODELER_NON_UNIQUE_BODY(Object arg0, Object arg1, Object arg2, Object arg3) { +- return messageFactory.getMessage("wsdlmodeler.nonUnique.body", arg0, arg1, arg2, arg3); +- } +- +- /** +- * Non unique body parts! In a port, operations must have unique operation signaure on the wire for successful dispatch. In port {0}, Operations "{1}" and "{2}" have the same request body block {3} +- * +- */ +- public static String WSDLMODELER_NON_UNIQUE_BODY(Object arg0, Object arg1, Object arg2, Object arg3) { +- return localizer.localize(localizableWSDLMODELER_NON_UNIQUE_BODY(arg0, arg1, arg2, arg3)); +- } +- + public static Localizable localizableWSDLMODELER_WARNING_IGNORING_HEADER_CANT_RESOLVE_MESSAGE(Object arg0, Object arg1) { + return messageFactory.getMessage("wsdlmodeler.warning.ignoringHeader.cant.resolve.message", arg0, arg1); + } +@@ -1238,6 +1238,18 @@ + return localizer.localize(localizableWSDLMODELER_WARNING_IGNORING_HEADER_FAULT_NOT_FOUND(arg0, arg1, arg2)); + } + ++ public static Localizable localizableWSDLMODELER_NON_UNIQUE_BODY_WARNING(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return messageFactory.getMessage("wsdlmodeler.nonUnique.body.warning", arg0, arg1, arg2, arg3); ++ } ++ ++ /** ++ * Non unique body parts! In a port, as per BP 1.1 R2710 operations must have unique operation signaure on the wire for successful dispatch. In port {0}, Operations "{1}" and "{2}" have the same request body block {3}. Method dispatching may fail, runtime will try to dispatch using SOAPAction ++ * ++ */ ++ public static String WSDLMODELER_NON_UNIQUE_BODY_WARNING(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return localizer.localize(localizableWSDLMODELER_NON_UNIQUE_BODY_WARNING(arg0, arg1, arg2, arg3)); ++ } ++ + public static Localizable localizableWSDLMODELER_INVALID_OPERATION_JAVA_RESERVED_WORD_NOT_ALLOWED_WRAPPER_STYLE(Object arg0, Object arg1, Object arg2) { + return messageFactory.getMessage("wsdlmodeler.invalid.operation.javaReservedWordNotAllowed.wrapperStyle", arg0, arg1, arg2); + } +--- old/src/share/classes/com/sun/tools/internal/ws/resources/WebserviceapMessages.java Tue Aug 4 09:29:04 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/WebserviceapMessages.java Tue Aug 4 09:29:03 2009 +@@ -38,184 +38,184 @@ + private final static LocalizableMessageFactory messageFactory = new LocalizableMessageFactory("com.sun.tools.internal.ws.resources.webserviceap"); + private final static Localizer localizer = new Localizer(); + +- public static Localizable localizableWEBSERVICEAP_RPC_LITERAL_MUST_NOT_BE_BARE(Object arg0) { +- return messageFactory.getMessage("webserviceap.rpc.literal.must.not.be.bare", arg0); ++ public static Localizable localizableWEBSERVICEAP_ENDPOINTINTERFACES_DO_NOT_MATCH(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.endpointinterfaces.do.not.match", arg0, arg1); + } + + /** +- * RPC literal SOAPBindings must have parameterStyle WRAPPPED. Class: {0}. ++ * The endpoint interface {0} does not match the interface {1}. + * + */ +- public static String WEBSERVICEAP_RPC_LITERAL_MUST_NOT_BE_BARE(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_RPC_LITERAL_MUST_NOT_BE_BARE(arg0)); ++ public static String WEBSERVICEAP_ENDPOINTINTERFACES_DO_NOT_MATCH(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTERFACES_DO_NOT_MATCH(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT_EXCLUDE(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.invalid.sei.annotation.element.exclude", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_INVALID_WEBMETHOD_ELEMENT_WITH_EXCLUDE(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.invalid.webmethod.element.with.exclude", arg0, arg1, arg2); + } + + /** +- * The @javax.jws.WebMethod({0}) cannot be used on a service endpoint interface. Class: {1} method: {2} ++ * The @javax.jws.WebMethod.{0} element cannot be specified with the @javax.jws.WebMethod.exclude element. Class: {1} method: {2} + * + */ +- public static String WEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT_EXCLUDE(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT_EXCLUDE(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_INVALID_WEBMETHOD_ELEMENT_WITH_EXCLUDE(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_INVALID_WEBMETHOD_ELEMENT_WITH_EXCLUDE(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(Object arg0) { +- return messageFactory.getMessage("webserviceap.webservice.class.is.innerclass.not.static", arg0); ++ public static Localizable localizableWEBSERVICEAP_SEI_CANNOT_CONTAIN_CONSTANT_VALUES(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.sei.cannot.contain.constant.values", arg0, arg1); + } + + /** +- * Inner classes annotated with @javax.jws.WebService must be static. Class: {0} ++ * An service endpoint interface cannot contain constant declaration: Interface: {0} field: {1}. + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(arg0)); ++ public static String WEBSERVICEAP_SEI_CANNOT_CONTAIN_CONSTANT_VALUES(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_SEI_CANNOT_CONTAIN_CONSTANT_VALUES(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.webservice.method.is.abstract", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_RPC_LITERAL_PARAMETERS_MUST_HAVE_WEBPARAM(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.rpc.literal.parameters.must.have.webparam", arg0, arg1, arg2); + } + + /** +- * Classes annotated with @javax.jws.WebService must not have abstract methods. Class: {0} Method: {1} ++ * All rpc literal parameters must have a WebParam annotation. Class: {0} method: {1} parameter {2} + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(arg0, arg1)); ++ public static String WEBSERVICEAP_RPC_LITERAL_PARAMETERS_MUST_HAVE_WEBPARAM(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_RPC_LITERAL_PARAMETERS_MUST_HAVE_WEBPARAM(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_RETURN_TYPE(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.oneway.operation.cannot.have.return.type", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.method.exception.bean.name.not.unique", arg0, arg1); + } + + /** +- * The method {1} of class {0} is annotated @Oneway but has a return type. ++ * Exception bean names must be unique and must not clash with other generated classes. Class: {0} exception {1} + * + */ +- public static String WEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_RETURN_TYPE(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_RETURN_TYPE(arg0, arg1)); ++ public static String WEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_WARNING(Object arg0) { +- return messageFactory.getMessage("webserviceap.warning", arg0); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(Object arg0) { ++ return messageFactory.getMessage("webserviceap.webservice.and.webserviceprovider", arg0); + } + + /** +- * warning: {0} ++ * Classes cannot be annotated with both @javax.jws.WebService and @javax.xml.ws.WebServiceProvider. Class: {0} + * + */ +- public static String WEBSERVICEAP_WARNING(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WARNING(arg0)); ++ public static String WEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_RPC_SOAPBINDING_NOT_ALLOWED_ON_METHOD(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.rpc.soapbinding.not.allowed.on.method", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(Object arg0) { ++ return messageFactory.getMessage("webserviceap.webservice.no.default.constructor", arg0); + } + + /** +- * SOAPBinding.Style.RPC binding annotations are not allowed on methods. Class: {0} Method: {1} ++ * Classes annotated with @javax.jws.WebService must have a public default constructor. Class: {0} + * + */ +- public static String WEBSERVICEAP_RPC_SOAPBINDING_NOT_ALLOWED_ON_METHOD(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_RPC_SOAPBINDING_NOT_ALLOWED_ON_METHOD(arg0, arg1)); ++ public static String WEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_COULD_NOT_FIND_HANDLERCHAIN(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.could.not.find.handlerchain", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_DOC_BARE_NO_OUT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.doc.bare.no.out", arg0, arg1); + } + + /** +- * Could not find the handlerchain {0} in the handler file {1} ++ * Document/literal bare methods with no return type or OUT/INOUT parameters must be annotated as @Oneway. Class: {0}, method: {1} + * + */ +- public static String WEBSERVICEAP_COULD_NOT_FIND_HANDLERCHAIN(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_COULD_NOT_FIND_HANDLERCHAIN(arg0, arg1)); ++ public static String WEBSERVICEAP_DOC_BARE_NO_OUT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_NO_OUT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_NO_PACKAGE_CLASS_MUST_HAVE_TARGETNAMESPACE(Object arg0) { +- return messageFactory.getMessage("webserviceap.no.package.class.must.have.targetnamespace", arg0); ++ public static Localizable localizableWEBSERVICEAP_FAILED_TO_PARSE_HANDLERCHAIN_FILE(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.failed.to.parse.handlerchain.file", arg0, arg1); + } + + /** +- * @javax.jws.Webservice annotated classes that do not belong to a package must have the @javax.jws.Webservice.targetNamespace element. Class: {0} ++ * Failed to parse HandlerChain file. Class: {0}, file: {1} + * + */ +- public static String WEBSERVICEAP_NO_PACKAGE_CLASS_MUST_HAVE_TARGETNAMESPACE(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_NO_PACKAGE_CLASS_MUST_HAVE_TARGETNAMESPACE(arg0)); ++ public static String WEBSERVICEAP_FAILED_TO_PARSE_HANDLERCHAIN_FILE(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_FAILED_TO_PARSE_HANDLERCHAIN_FILE(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_CLASS_NOT_FOUND(Object arg0) { +- return messageFactory.getMessage("webserviceap.class.not.found", arg0); ++ public static Localizable localizableWEBSERVICEAP_JAVA_TYPE_NOT_FOUND(Object arg0) { ++ return messageFactory.getMessage("webserviceap.java.typeNotFound", arg0); + } + + /** +- * Class Not Found: {0} ++ * The type: {0} was not found in the mapping + * + */ +- public static String WEBSERVICEAP_CLASS_NOT_FOUND(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_CLASS_NOT_FOUND(arg0)); ++ public static String WEBSERVICEAP_JAVA_TYPE_NOT_FOUND(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_JAVA_TYPE_NOT_FOUND(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_DOC_BARE_NO_RETURN_AND_NO_OUT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.doc.bare.no.return.and.no.out", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_DECLARE_EXCEPTIONS(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.oneway.operation.cannot.declare.exceptions", arg0, arg1, arg2); + } + + /** +- * Document literal bare methods that do not have a return value must have a single OUT/INOUT parameter. Class: {0} Method: {1} ++ * The method {1} of class {0} is annotated @Oneway but declares the exception {2} + * + */ +- public static String WEBSERVICEAP_DOC_BARE_NO_RETURN_AND_NO_OUT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_NO_RETURN_AND_NO_OUT(arg0, arg1)); ++ public static String WEBSERVICEAP_ONEWAY_OPERATION_CANNOT_DECLARE_EXCEPTIONS(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_DECLARE_EXCEPTIONS(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_RETURN_NOT_UNIQUE(Object arg0, Object arg1, Object arg2, Object arg3) { +- return messageFactory.getMessage("webserviceap.document.literal.bare.method.return.not.unique", arg0, arg1, arg2, arg3); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_STATIC_OR_FINAL(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.webservice.method.is.static.or.final", arg0, arg1); + } + + /** +- * Document literal bare methods must have a unique result name return type combination. Class {0} method: {1}, result name: {2} return type: {3} ++ * Method annotated with @javax.jws.WebMethod must not be static or final. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_RETURN_NOT_UNIQUE(Object arg0, Object arg1, Object arg2, Object arg3) { +- return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_RETURN_NOT_UNIQUE(arg0, arg1, arg2, arg3)); ++ public static String WEBSERVICEAP_WEBSERVICE_METHOD_IS_STATIC_OR_FINAL(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_STATIC_OR_FINAL(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_DOC_BARE_NO_OUT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.doc.bare.no.out", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_RETURN_TYPE(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.oneway.operation.cannot.have.return.type", arg0, arg1); + } + + /** +- * Document/literal bare methods with no return type or OUT/INOUT parameters must be annotated as @Oneway. Class: {0}, method: {1} ++ * The method {1} of class {0} is annotated @Oneway but has a return type. + * + */ +- public static String WEBSERVICEAP_DOC_BARE_NO_OUT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_NO_OUT(arg0, arg1)); ++ public static String WEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_RETURN_TYPE(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_RETURN_TYPE(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_RPC_LITERAL_PARAMETERS_MUST_HAVE_WEBPARAM(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.rpc.literal.parameters.must.have.webparam", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_WARNING(Object arg0) { ++ return messageFactory.getMessage("webserviceap.warning", arg0); + } + + /** +- * All rpc literal parameters must have a WebParam annotation. Class: {0} method: {1} parameter {2} ++ * warning: {0} + * + */ +- public static String WEBSERVICEAP_RPC_LITERAL_PARAMETERS_MUST_HAVE_WEBPARAM(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_RPC_LITERAL_PARAMETERS_MUST_HAVE_WEBPARAM(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_WARNING(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WARNING(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_MODEL_ALREADY_EXISTS() { +- return messageFactory.getMessage("webserviceap.model.already.exists"); ++ public static Localizable localizableWEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.method.response.wrapper.bean.name.not.unique", arg0, arg1); + } + + /** +- * model already exists ++ * Response wrapper bean names must be unique and must not clash with other generated classes. Class: {0} method {1} + * + */ +- public static String WEBSERVICEAP_MODEL_ALREADY_EXISTS() { +- return localizer.localize(localizableWEBSERVICEAP_MODEL_ALREADY_EXISTS()); ++ public static String WEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(arg0, arg1)); + } + + public static Localizable localizableWEBSERVICEAP_ENDPOINTINTERFACE_ON_INTERFACE(Object arg0, Object arg1) { +@@ -230,376 +230,376 @@ + return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTERFACE_ON_INTERFACE(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_NOT_ANNOTATED(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.method.not.annotated", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_NESTED_MODEL_ERROR(Object arg0) { ++ return messageFactory.getMessage("webserviceap.nestedModelError", arg0); + } + + /** +- * The method {0} on class {1} is not annotated. ++ * modeler error: {0} + * + */ +- public static String WEBSERVICEAP_METHOD_NOT_ANNOTATED(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_NOT_ANNOTATED(arg0, arg1)); ++ public static String WEBSERVICEAP_NESTED_MODEL_ERROR(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_NESTED_MODEL_ERROR(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_NON_IN_PARAMETERS_MUST_BE_HOLDER(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.non.in.parameters.must.be.holder", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_ONEWAY_AND_OUT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.oneway.and.out", arg0, arg1); + } + + /** +- * Class: {0}, method: {1}, parameter: {2} is not WebParam.Mode.IN and is not of type javax.xml.ws.Holder. ++ * @Oneway methods cannot have out parameters. Class: {0} method {1} + * + */ +- public static String WEBSERVICEAP_NON_IN_PARAMETERS_MUST_BE_HOLDER(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_NON_IN_PARAMETERS_MUST_BE_HOLDER(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_ONEWAY_AND_OUT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_ONEWAY_AND_OUT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_FAILED_TO_FIND_HANDLERCHAIN_FILE(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.failed.to.find.handlerchain.file", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_RPC_LITERAL_WEBPARAMS_MUST_SPECIFY_NAME(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.rpc.literal.webparams.must.specify.name", arg0, arg1, arg2); + } + + /** +- * Cannot find HandlerChain file. class: {0}, file: {1} ++ * All rpc literal WebParams must specify a name. Class: {0} method {1} paramter {2} + * + */ +- public static String WEBSERVICEAP_FAILED_TO_FIND_HANDLERCHAIN_FILE(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_FAILED_TO_FIND_HANDLERCHAIN_FILE(arg0, arg1)); ++ public static String WEBSERVICEAP_RPC_LITERAL_WEBPARAMS_MUST_SPECIFY_NAME(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_RPC_LITERAL_WEBPARAMS_MUST_SPECIFY_NAME(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_OPERATION_NAME_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.operation.name.not.unique", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT_EXCLUDE(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.invalid.sei.annotation.element.exclude", arg0, arg1, arg2); + } + + /** +- * Operation names must be unique. Class: {0} method: {1} operation name: {2} ++ * The @javax.jws.WebMethod({0}) cannot be used on a service endpoint interface. Class: {1} method: {2} + * + */ +- public static String WEBSERVICEAP_OPERATION_NAME_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_OPERATION_NAME_NOT_UNIQUE(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT_EXCLUDE(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT_EXCLUDE(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_NOT_IMPLEMENTED(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.method.not.implemented", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_CLASS_NOT_FOUND(Object arg0) { ++ return messageFactory.getMessage("webserviceap.class.not.found", arg0); + } + + /** +- * Methods in an endpointInterface must be implemented in the implementation class. Interface Class:{0} Implementation Class:{1} Method: {2} ++ * Class Not Found: {0} + * + */ +- public static String WEBSERVICEAP_METHOD_NOT_IMPLEMENTED(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_NOT_IMPLEMENTED(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_CLASS_NOT_FOUND(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_CLASS_NOT_FOUND(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_HEADER_PARAMETERS_MUST_HAVE_WEBPARAM_NAME(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.header.parameters.must.have.webparam.name", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ELEMENT(Object arg0) { ++ return messageFactory.getMessage("webserviceap.endpointinteface.plus.element", arg0); + } + + /** +- * All WebParam annotations on header parameters must specify a name. Class: {0} method {1} paramter {2} ++ * The @javax.jws.WebService.{0} element cannot be used in with @javax.jws.WebService.endpointInterface element. + * + */ +- public static String WEBSERVICEAP_HEADER_PARAMETERS_MUST_HAVE_WEBPARAM_NAME(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_HEADER_PARAMETERS_MUST_HAVE_WEBPARAM_NAME(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ELEMENT(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ELEMENT(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_INVALID_HANDLERCHAIN_FILE_NOHANDLER_CONFIG(Object arg0) { +- return messageFactory.getMessage("webserviceap.invalid.handlerchain.file.nohandler-config", arg0); ++ public static Localizable localizableWEBSERVICEAP_CANNOT_COMBINE_HANDLERCHAIN_SOAPMESSAGEHANDLERS() { ++ return messageFactory.getMessage("webserviceap.cannot.combine.handlerchain.soapmessagehandlers"); + } + + /** +- * The handlerchain file {0} is invalid, it does not contain a handler-config element ++ * You cannot specify both HanlderChain and SOAPMessageHandlers annotations + * + */ +- public static String WEBSERVICEAP_INVALID_HANDLERCHAIN_FILE_NOHANDLER_CONFIG(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_INVALID_HANDLERCHAIN_FILE_NOHANDLER_CONFIG(arg0)); ++ public static String WEBSERVICEAP_CANNOT_COMBINE_HANDLERCHAIN_SOAPMESSAGEHANDLERS() { ++ return localizer.localize(localizableWEBSERVICEAP_CANNOT_COMBINE_HANDLERCHAIN_SOAPMESSAGEHANDLERS()); + } + +- public static Localizable localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_DECLARE_EXCEPTIONS(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.oneway.operation.cannot.declare.exceptions", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(Object arg0) { ++ return messageFactory.getMessage("webserviceap.webservice.class.is.innerclass.not.static", arg0); + } + + /** +- * The method {1} of class {0} is annotated @Oneway but declares the exception {2} ++ * Inner classes annotated with @javax.jws.WebService must be static. Class: {0} + * + */ +- public static String WEBSERVICEAP_ONEWAY_OPERATION_CANNOT_DECLARE_EXCEPTIONS(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_DECLARE_EXCEPTIONS(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_INNERCLASS_NOT_STATIC(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_HOLDERS(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.oneway.operation.cannot.have.holders", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_NON_IN_PARAMETERS_MUST_BE_HOLDER(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.non.in.parameters.must.be.holder", arg0, arg1, arg2); + } + + /** +- * The method {1} of class {0} is annotated @Oneway but contains inout or out paramerters (javax.xml.ws.Holder) ++ * Class: {0}, method: {1}, parameter: {2} is not WebParam.Mode.IN and is not of type javax.xml.ws.Holder. + * + */ +- public static String WEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_HOLDERS(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_HOLDERS(arg0, arg1)); ++ public static String WEBSERVICEAP_NON_IN_PARAMETERS_MUST_BE_HOLDER(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_NON_IN_PARAMETERS_MUST_BE_HOLDER(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_ONEWAY_AND_NOT_ONE_IN(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.oneway.and.not.one.in", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.invalid.sei.annotation.element", arg0, arg1); + } + + /** +- * Document literal bare methods annotated with @javax.jws.Oneway must have one non-header IN parameter. Class: {0} Method: {1} ++ * The @javax.jws.WebService.{0} element cannot be specified on a service endpoint interface. Class: {1} + * + */ +- public static String WEBSERVICEAP_ONEWAY_AND_NOT_ONE_IN(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_ONEWAY_AND_NOT_ONE_IN(arg0, arg1)); ++ public static String WEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_RPC_ENCODED_NOT_SUPPORTED(Object arg0) { +- return messageFactory.getMessage("webserviceap.rpc.encoded.not.supported", arg0); ++ public static Localizable localizableWEBSERVICEAP_SUCCEEDED() { ++ return messageFactory.getMessage("webserviceap.succeeded"); + } + + /** +- * The {0} class has a rpc/encoded SOAPBinding. Rpc/encoded SOAPBindings are not supported in JAXWS 2.0. ++ * Success + * + */ +- public static String WEBSERVICEAP_RPC_ENCODED_NOT_SUPPORTED(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_RPC_ENCODED_NOT_SUPPORTED(arg0)); ++ public static String WEBSERVICEAP_SUCCEEDED() { ++ return localizer.localize(localizableWEBSERVICEAP_SUCCEEDED()); + } + +- public static Localizable localizableWEBSERVICEAP_JAVA_TYPE_NOT_FOUND(Object arg0) { +- return messageFactory.getMessage("webserviceap.java.typeNotFound", arg0); ++ public static Localizable localizableWEBSERVICEAP_DOC_BARE_AND_NO_ONE_IN(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.doc.bare.and.no.one.in", arg0, arg1); + } + + /** +- * The type: {0} was not found in the mapping ++ * Document literal bare methods must have one non-header, IN/INOUT parameter. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_JAVA_TYPE_NOT_FOUND(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_JAVA_TYPE_NOT_FOUND(arg0)); ++ public static String WEBSERVICEAP_DOC_BARE_AND_NO_ONE_IN(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_AND_NO_ONE_IN(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.invalid.sei.annotation", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.webservice.method.is.abstract", arg0, arg1); + } + + /** +- * The @{0} annotation cannot be used on a service endpoint interface. Class: {1} ++ * Classes annotated with @javax.jws.WebService must not have abstract methods. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_INVALID_SEI_ANNOTATION(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION(arg0, arg1)); ++ public static String WEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_METHOD_IS_ABSTRACT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND() { +- return messageFactory.getMessage("webserviceap.no.webservice.endpoint.found"); ++ public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_RETURN_NOT_UNIQUE(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return messageFactory.getMessage("webserviceap.document.literal.bare.method.return.not.unique", arg0, arg1, arg2, arg3); + } + + /** +- * A web service endpoint could not be found ++ * Document literal bare methods must have a unique result name return type combination. Class {0} method: {1}, result name: {2} return type: {3} + * + */ +- public static String WEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND() { +- return localizer.localize(localizableWEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND()); ++ public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_RETURN_NOT_UNIQUE(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_RETURN_NOT_UNIQUE(arg0, arg1, arg2, arg3)); + } + +- public static Localizable localizableWEBSERVICEAP_INVALID_WEBMETHOD_ELEMENT_WITH_EXCLUDE(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.invalid.webmethod.element.with.exclude", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND() { ++ return messageFactory.getMessage("webserviceap.no.webservice.endpoint.found"); + } + + /** +- * The @javax.jws.WebMethod.{0} element cannot be specified with the @javax.jws.WebMethod.exclude element. Class: {1} method: {2} ++ * A web service endpoint could not be found + * + */ +- public static String WEBSERVICEAP_INVALID_WEBMETHOD_ELEMENT_WITH_EXCLUDE(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_INVALID_WEBMETHOD_ELEMENT_WITH_EXCLUDE(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND() { ++ return localizer.localize(localizableWEBSERVICEAP_NO_WEBSERVICE_ENDPOINT_FOUND()); + } + +- public static Localizable localizableWEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.could.not.find.typedecl", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_FILE_NOT_FOUND(Object arg0) { ++ return messageFactory.getMessage("webserviceap.fileNotFound", arg0); + } + + /** +- * Could not get TypeDeclaration for: {0} in apt round: {1} ++ * error: file not found: {0} + * + */ +- public static String WEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(arg0, arg1)); ++ public static String WEBSERVICEAP_FILE_NOT_FOUND(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_FILE_NOT_FOUND(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_CANNOT_HAVE_MORE_THAN_ONE_OUT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.document.literal.bare.cannot.have.more.than.one.out", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_INVALID_HANDLERCHAIN_FILE_NOHANDLER_CONFIG(Object arg0) { ++ return messageFactory.getMessage("webserviceap.invalid.handlerchain.file.nohandler-config", arg0); + } + + /** +- * Document literal bare methods must have a return value or one out parameter. Class: {0} Method: {1} ++ * The handlerchain file {0} is invalid, it does not contain a handler-config element + * + */ +- public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_CANNOT_HAVE_MORE_THAN_ONE_OUT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_CANNOT_HAVE_MORE_THAN_ONE_OUT(arg0, arg1)); ++ public static String WEBSERVICEAP_INVALID_HANDLERCHAIN_FILE_NOHANDLER_CONFIG(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_INVALID_HANDLERCHAIN_FILE_NOHANDLER_CONFIG(arg0)); + } + +- public static Localizable localizableWEBSERVICE_ENCODED_NOT_SUPPORTED(Object arg0, Object arg1) { +- return messageFactory.getMessage("webservice.encoded.not.supported", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_HEADER_PARAMETERS_MUST_HAVE_WEBPARAM_NAME(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.header.parameters.must.have.webparam.name", arg0, arg1, arg2); + } + + /** +- * The {0} class has invalid SOAPBinding annotation. {1}/encoded SOAPBinding is not supported ++ * All WebParam annotations on header parameters must specify a name. Class: {0} method {1} paramter {2} + * + */ +- public static String WEBSERVICE_ENCODED_NOT_SUPPORTED(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICE_ENCODED_NOT_SUPPORTED(arg0, arg1)); ++ public static String WEBSERVICEAP_HEADER_PARAMETERS_MUST_HAVE_WEBPARAM_NAME(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_HEADER_PARAMETERS_MUST_HAVE_WEBPARAM_NAME(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_FINAL(Object arg0) { +- return messageFactory.getMessage("webserviceap.webservice.class.is.final", arg0); ++ public static Localizable localizableWEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.method.return.type.cannot.implement.remote", arg0, arg1, arg2); + } + + /** +- * Classes annotated with @javax.jws.WebService must not be final. Class: {0} ++ * Method return types cannot implement java.rmi.Remote. Class: {0} method: {1} return type: {2} + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_CLASS_IS_FINAL(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_FINAL(arg0)); ++ public static String WEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(Object arg0) { +- return messageFactory.getMessage("webserviceap.webservice.no.default.constructor", arg0); ++ public static Localizable localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ANNOTATION(Object arg0) { ++ return messageFactory.getMessage("webserviceap.endpointinteface.plus.annotation", arg0); + } + + /** +- * Classes annotated with @javax.jws.WebService must have a public default constructor. Class: {0} ++ * The @{0} annotation cannot be used in with @javax.jws.WebService.endpointInterface element. + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_NO_DEFAULT_CONSTRUCTOR(arg0)); ++ public static String WEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ANNOTATION(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ANNOTATION(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_SEI_CANNOT_CONTAIN_CONSTANT_VALUES(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.sei.cannot.contain.constant.values", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_HOLDER_PARAMETERS_MUST_NOT_BE_IN_ONLY(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.holder.parameters.must.not.be.in.only", arg0, arg1, arg2); + } + + /** +- * An service endpoint interface cannot contain constant declaration: Interface: {0} field: {1}. ++ * javax.xml.ws.Holder parameters must not be annotated with the WebParam.Mode.IN property. Class: {0} method: {1} parameter: {2} + * + */ +- public static String WEBSERVICEAP_SEI_CANNOT_CONTAIN_CONSTANT_VALUES(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_SEI_CANNOT_CONTAIN_CONSTANT_VALUES(arg0, arg1)); ++ public static String WEBSERVICEAP_HOLDER_PARAMETERS_MUST_NOT_BE_IN_ONLY(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_HOLDER_PARAMETERS_MUST_NOT_BE_IN_ONLY(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_ENDPOINTINTERFACE_CLASS_NOT_FOUND(Object arg0) { +- return messageFactory.getMessage("webserviceap.endpointinterface.class.not.found", arg0); ++ public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONLY_ONE_IN_PARAMETER(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.document.literal.bare.must.have.only.one.in.parameter", arg0, arg1, arg2); + } + + /** +- * The endpointInterface class {0} could not be found ++ * Document literal bare methods must have no more than 1 non-header in parameter. Class: {0} method: {1} number of non-header parameters: {2} + * + */ +- public static String WEBSERVICEAP_ENDPOINTINTERFACE_CLASS_NOT_FOUND(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTERFACE_CLASS_NOT_FOUND(arg0)); ++ public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONLY_ONE_IN_PARAMETER(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONLY_ONE_IN_PARAMETER(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONLY_ONE_IN_PARAMETER(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.document.literal.bare.must.have.only.one.in.parameter", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_DOC_BARE_RETURN_AND_OUT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.doc.bare.return.and.out", arg0, arg1); + } + + /** +- * Document literal bare methods must have no more than 1 non-header in parameter. Class: {0} method: {1} number of non-header parameters: {2} ++ * Document/literal bare methods cannot have a return type and out parameters. Class: {0}, method: {1} + * + */ +- public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONLY_ONE_IN_PARAMETER(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONLY_ONE_IN_PARAMETER(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_DOC_BARE_RETURN_AND_OUT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_RETURN_AND_OUT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_INFO(Object arg0) { +- return messageFactory.getMessage("webserviceap.info", arg0); ++ public static Localizable localizableWEBSERVICEAP_METHOD_PARAMETER_TYPES_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return messageFactory.getMessage("webserviceap.method.parameter.types.cannot.implement.remote", arg0, arg1, arg2, arg3); + } + + /** +- * info: {0} ++ * Method parameter types cannot implement java.rmi.Remote. Class: {0} method: {1} parameter: {2} type: {3} + * + */ +- public static String WEBSERVICEAP_INFO(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_INFO(arg0)); ++ public static String WEBSERVICEAP_METHOD_PARAMETER_TYPES_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_PARAMETER_TYPES_CANNOT_IMPLEMENT_REMOTE(arg0, arg1, arg2, arg3)); + } + +- public static Localizable localizableWEBSERVICEAP_HANDLERCLASS_NOTSPECIFIED(Object arg0) { +- return messageFactory.getMessage("webserviceap.handlerclass.notspecified", arg0); ++ public static Localizable localizableWEBSERVICEAP_COMPILATION_FAILED() { ++ return messageFactory.getMessage("webserviceap.compilationFailed"); + } + + /** +- * A handler in the HandlerChain file: {0} does not specify a handler-class ++ * compilation failed, errors should have been reported + * + */ +- public static String WEBSERVICEAP_HANDLERCLASS_NOTSPECIFIED(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_HANDLERCLASS_NOTSPECIFIED(arg0)); ++ public static String WEBSERVICEAP_COMPILATION_FAILED() { ++ return localizer.localize(localizableWEBSERVICEAP_COMPILATION_FAILED()); + } + +- public static Localizable localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.invalid.sei.annotation.element", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_MODEL_ALREADY_EXISTS() { ++ return messageFactory.getMessage("webserviceap.model.already.exists"); + } + + /** +- * The @javax.jws.WebService.{0} element cannot be specified on a service endpoint interface. Class: {1} ++ * model already exists + * + */ +- public static String WEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION_ELEMENT(arg0, arg1)); ++ public static String WEBSERVICEAP_MODEL_ALREADY_EXISTS() { ++ return localizer.localize(localizableWEBSERVICEAP_MODEL_ALREADY_EXISTS()); + } + +- public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.document.literal.bare.method.not.unique", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.could.not.find.typedecl", arg0, arg1); + } + + /** +- * Document literal bare methods must have unique parameter names. Class: {0} method: {1} parameter name: {2} ++ * Could not get TypeDeclaration for: {0} in apt round: {1} + * + */ +- public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_NOT_UNIQUE(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_COULD_NOT_FIND_TYPEDECL(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.method.exception.bean.name.not.unique", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_NOT_PUBLIC(Object arg0) { ++ return messageFactory.getMessage("webserviceap.webservice.class.not.public", arg0); + } + + /** +- * Exception bean names must be unique and must not clash with other generated classes. Class: {0} exception {1} ++ * Classes annotated with @javax.jws.WebService must be public. Class: {0} + * + */ +- public static String WEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_EXCEPTION_BEAN_NAME_NOT_UNIQUE(arg0, arg1)); ++ public static String WEBSERVICEAP_WEBSERVICE_CLASS_NOT_PUBLIC(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_NOT_PUBLIC(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_HOLDER_PARAMETERS_MUST_NOT_BE_IN_ONLY(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.holder.parameters.must.not.be.in.only", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.document.literal.bare.method.not.unique", arg0, arg1, arg2); + } + + /** +- * javax.xml.ws.Holder parameters must not be annotated with the WebParam.Mode.IN property. Class: {0} method: {1} parameter: {2} ++ * Document literal bare methods must have unique parameter names. Class: {0} method: {1} parameter name: {2} + * + */ +- public static String WEBSERVICEAP_HOLDER_PARAMETERS_MUST_NOT_BE_IN_ONLY(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_HOLDER_PARAMETERS_MUST_NOT_BE_IN_ONLY(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_METHOD_NOT_UNIQUE(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_DOC_BARE_AND_NO_ONE_IN(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.doc.bare.and.no.one.in", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_RPC_SOAPBINDING_NOT_ALLOWED_ON_METHOD(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.rpc.soapbinding.not.allowed.on.method", arg0, arg1); + } + + /** +- * Document literal bare methods must have one non-header, IN/INOUT parameter. Class: {0} Method: {1} ++ * SOAPBinding.Style.RPC binding annotations are not allowed on methods. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_DOC_BARE_AND_NO_ONE_IN(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_AND_NO_ONE_IN(arg0, arg1)); ++ public static String WEBSERVICEAP_RPC_SOAPBINDING_NOT_ALLOWED_ON_METHOD(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_RPC_SOAPBINDING_NOT_ALLOWED_ON_METHOD(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_RPC_LITERAL_WEBPARAMS_MUST_SPECIFY_NAME(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.rpc.literal.webparams.must.specify.name", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_NO_PACKAGE_CLASS_MUST_HAVE_TARGETNAMESPACE(Object arg0) { ++ return messageFactory.getMessage("webserviceap.no.package.class.must.have.targetnamespace", arg0); + } + + /** +- * All rpc literal WebParams must specify a name. Class: {0} method {1} paramter {2} ++ * @javax.jws.Webservice annotated classes that do not belong to a package must have the @javax.jws.Webservice.targetNamespace element. Class: {0} + * + */ +- public static String WEBSERVICEAP_RPC_LITERAL_WEBPARAMS_MUST_SPECIFY_NAME(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_RPC_LITERAL_WEBPARAMS_MUST_SPECIFY_NAME(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_NO_PACKAGE_CLASS_MUST_HAVE_TARGETNAMESPACE(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_NO_PACKAGE_CLASS_MUST_HAVE_TARGETNAMESPACE(arg0)); + } + + public static Localizable localizableWEBSERVICEAP_ENDPOINTINTERFACE_HAS_NO_WEBSERVICE_ANNOTATION(Object arg0) { +@@ -614,280 +614,292 @@ + return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTERFACE_HAS_NO_WEBSERVICE_ANNOTATION(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_CANNOT_COMBINE_HANDLERCHAIN_SOAPMESSAGEHANDLERS() { +- return messageFactory.getMessage("webserviceap.cannot.combine.handlerchain.soapmessagehandlers"); ++ public static Localizable localizableWEBSERVICEAP_INFO(Object arg0) { ++ return messageFactory.getMessage("webserviceap.info", arg0); + } + + /** +- * You cannot specify both HanlderChain and SOAPMessageHandlers annotations ++ * info: {0} + * + */ +- public static String WEBSERVICEAP_CANNOT_COMBINE_HANDLERCHAIN_SOAPMESSAGEHANDLERS() { +- return localizer.localize(localizableWEBSERVICEAP_CANNOT_COMBINE_HANDLERCHAIN_SOAPMESSAGEHANDLERS()); ++ public static String WEBSERVICEAP_INFO(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_INFO(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_NESTED_MODEL_ERROR(Object arg0) { +- return messageFactory.getMessage("webserviceap.nestedModelError", arg0); ++ public static Localizable localizableWEBSERVICEAP_RPC_LITERAL_MUST_NOT_BE_BARE(Object arg0) { ++ return messageFactory.getMessage("webserviceap.rpc.literal.must.not.be.bare", arg0); + } + + /** +- * modeler error: {0} ++ * RPC literal SOAPBindings must have parameterStyle WRAPPPED. Class: {0}. + * + */ +- public static String WEBSERVICEAP_NESTED_MODEL_ERROR(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_NESTED_MODEL_ERROR(arg0)); ++ public static String WEBSERVICEAP_RPC_LITERAL_MUST_NOT_BE_BARE(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_RPC_LITERAL_MUST_NOT_BE_BARE(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.method.request.wrapper.bean.name.not.unique", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_COULD_NOT_FIND_HANDLERCHAIN(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.could.not.find.handlerchain", arg0, arg1); + } + + /** +- * Request wrapper bean names must be unique and must not clash with other generated classes. Class: {0} method {1} ++ * Could not find the handlerchain {0} in the handler file {1} + * + */ +- public static String WEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(arg0, arg1)); ++ public static String WEBSERVICEAP_COULD_NOT_FIND_HANDLERCHAIN(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_COULD_NOT_FIND_HANDLERCHAIN(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_NOT_PUBLIC(Object arg0) { +- return messageFactory.getMessage("webserviceap.webservice.class.not.public", arg0); ++ public static Localizable localizableWEBSERVICEAP_RPC_ENCODED_NOT_SUPPORTED(Object arg0) { ++ return messageFactory.getMessage("webserviceap.rpc.encoded.not.supported", arg0); + } + + /** +- * Classes annotated with @javax.jws.WebService must be public. Class: {0} ++ * The {0} class has a rpc/encoded SOAPBinding. Rpc/encoded SOAPBindings are not supported in JAXWS 2.0. + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_CLASS_NOT_PUBLIC(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_NOT_PUBLIC(arg0)); ++ public static String WEBSERVICEAP_RPC_ENCODED_NOT_SUPPORTED(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_RPC_ENCODED_NOT_SUPPORTED(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_MIXED_BINDING_STYLE(Object arg0) { +- return messageFactory.getMessage("webserviceap.mixed.binding.style", arg0); ++ public static Localizable localizableWEBSERVICEAP_ERROR(Object arg0) { ++ return messageFactory.getMessage("webserviceap.error", arg0); + } + + /** +- * Class: {0} contains mixed bindings. SOAPBinding.Style.RPC and SOAPBinding.Style.DOCUMENT cannot be mixed. ++ * error: {0} + * + */ +- public static String WEBSERVICEAP_MIXED_BINDING_STYLE(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_MIXED_BINDING_STYLE(arg0)); ++ public static String WEBSERVICEAP_ERROR(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_ERROR(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_FILE_NOT_FOUND(Object arg0) { +- return messageFactory.getMessage("webserviceap.fileNotFound", arg0); ++ public static Localizable localizableWEBSERVICEAP_ENDPOINTINTERFACE_CLASS_NOT_FOUND(Object arg0) { ++ return messageFactory.getMessage("webserviceap.endpointinterface.class.not.found", arg0); + } + + /** +- * error: file not found: {0} ++ * The endpointInterface class {0} could not be found + * + */ +- public static String WEBSERVICEAP_FILE_NOT_FOUND(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_FILE_NOT_FOUND(arg0)); ++ public static String WEBSERVICEAP_ENDPOINTINTERFACE_CLASS_NOT_FOUND(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTERFACE_CLASS_NOT_FOUND(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_ONEWAY_AND_OUT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.oneway.and.out", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_METHOD_NOT_IMPLEMENTED(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.method.not.implemented", arg0, arg1, arg2); + } + + /** +- * @Oneway methods cannot have out parameters. Class: {0} method {1} ++ * Methods in an endpointInterface must be implemented in the implementation class. Interface Class:{0} Implementation Class:{1} Method: {2} + * + */ +- public static String WEBSERVICEAP_ONEWAY_AND_OUT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_ONEWAY_AND_OUT(arg0, arg1)); ++ public static String WEBSERVICEAP_METHOD_NOT_IMPLEMENTED(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_NOT_IMPLEMENTED(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.method.response.wrapper.bean.name.not.unique", arg0, arg1); ++ public static Localizable localizableWEBSERVICE_ENCODED_NOT_SUPPORTED(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webservice.encoded.not.supported", arg0, arg1); + } + + /** +- * Response wrapper bean names must be unique and must not clash with other generated classes. Class: {0} method {1} ++ * The {0} class has invalid SOAPBinding annotation. {1}/encoded SOAPBinding is not supported + * + */ +- public static String WEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_RESPONSE_WRAPPER_BEAN_NAME_NOT_UNIQUE(arg0, arg1)); ++ public static String WEBSERVICE_ENCODED_NOT_SUPPORTED(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICE_ENCODED_NOT_SUPPORTED(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_COMPILATION_FAILED() { +- return messageFactory.getMessage("webserviceap.compilationFailed"); ++ public static Localizable localizableWEBSERVICEAP_HANDLERCLASS_NOTSPECIFIED(Object arg0) { ++ return messageFactory.getMessage("webserviceap.handlerclass.notspecified", arg0); + } + + /** +- * compilation failed, errors should have been reported ++ * A handler in the HandlerChain file: {0} does not specify a handler-class + * + */ +- public static String WEBSERVICEAP_COMPILATION_FAILED() { +- return localizer.localize(localizableWEBSERVICEAP_COMPILATION_FAILED()); ++ public static String WEBSERVICEAP_HANDLERCLASS_NOTSPECIFIED(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_HANDLERCLASS_NOTSPECIFIED(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONE_IN_OR_OUT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.document.literal.bare.must.have.one.in.or.out", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_FAILED_TO_FIND_HANDLERCHAIN_FILE(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.failed.to.find.handlerchain.file", arg0, arg1); + } + + /** +- * Document literal bare methods must have at least one of: a return, an in parameter or an out parameter. Class: {0} Method: {1} ++ * Cannot find HandlerChain file. class: {0}, file: {1} + * + */ +- public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONE_IN_OR_OUT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONE_IN_OR_OUT(arg0, arg1)); ++ public static String WEBSERVICEAP_FAILED_TO_FIND_HANDLERCHAIN_FILE(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_FAILED_TO_FIND_HANDLERCHAIN_FILE(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ELEMENT(Object arg0) { +- return messageFactory.getMessage("webserviceap.endpointinteface.plus.element", arg0); ++ public static Localizable localizableWEBSERVICEAP_DOC_BARE_NO_RETURN_AND_NO_OUT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.doc.bare.no.return.and.no.out", arg0, arg1); + } + + /** +- * The @javax.jws.WebService.{0} element cannot be used in with @javax.jws.WebService.endpointInterface element. ++ * Document literal bare methods that do not have a return value must have a single OUT/INOUT parameter. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ELEMENT(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ELEMENT(arg0)); ++ public static String WEBSERVICEAP_DOC_BARE_NO_RETURN_AND_NO_OUT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_NO_RETURN_AND_NO_OUT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_DOC_BARE_RETURN_AND_OUT(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.doc.bare.return.and.out", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(Object arg0) { ++ return messageFactory.getMessage("webserviceap.webservice.class.is.abstract", arg0); + } + + /** +- * Document/literal bare methods cannot have a return type and out parameters. Class: {0}, method: {1} ++ * Classes annotated with @javax.jws.WebService must not be abstract. Class: {0} + * + */ +- public static String WEBSERVICEAP_DOC_BARE_RETURN_AND_OUT(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_DOC_BARE_RETURN_AND_OUT(arg0, arg1)); ++ public static String WEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_SUCCEEDED() { +- return messageFactory.getMessage("webserviceap.succeeded"); ++ public static Localizable localizableWEBSERVICEAP_INIT_PARAM_FORMAT_ERROR() { ++ return messageFactory.getMessage("webserviceap.init_param.format.error"); + } + + /** +- * Success ++ * a element must have exactly 1 and 1 + * + */ +- public static String WEBSERVICEAP_SUCCEEDED() { +- return localizer.localize(localizableWEBSERVICEAP_SUCCEEDED()); ++ public static String WEBSERVICEAP_INIT_PARAM_FORMAT_ERROR() { ++ return localizer.localize(localizableWEBSERVICEAP_INIT_PARAM_FORMAT_ERROR()); + } + +- public static Localizable localizableWEBSERVICEAP_DOCUMENT_BARE_HOLDER_PARAMETERS_MUST_NOT_BE_INOUT(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.document.bare.holder.parameters.must.not.be.inout", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_MIXED_BINDING_STYLE(Object arg0) { ++ return messageFactory.getMessage("webserviceap.mixed.binding.style", arg0); + } + + /** +- * javax.xml.ws.Holder parameters in document bare operations must be WebParam.Mode.INOUT; Class: {0} method: {1} parameter: {2} ++ * Class: {0} contains mixed bindings. SOAPBinding.Style.RPC and SOAPBinding.Style.DOCUMENT cannot be mixed. + * + */ +- public static String WEBSERVICEAP_DOCUMENT_BARE_HOLDER_PARAMETERS_MUST_NOT_BE_INOUT(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_BARE_HOLDER_PARAMETERS_MUST_NOT_BE_INOUT(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_MIXED_BINDING_STYLE(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_MIXED_BINDING_STYLE(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(Object arg0) { +- return messageFactory.getMessage("webserviceap.webservice.and.webserviceprovider", arg0); ++ public static Localizable localizableWEBSERVICEAP_METHOD_NOT_ANNOTATED(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.method.not.annotated", arg0, arg1); + } + + /** +- * Classes cannot be annotated with both @javax.jws.WebService and @javax.xml.ws.WebServiceProvider. Class: {0} ++ * The method {0} on class {1} is not annotated. + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_AND_WEBSERVICEPROVIDER(arg0)); ++ public static String WEBSERVICEAP_METHOD_NOT_ANNOTATED(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_NOT_ANNOTATED(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_ENDPOINTINTERFACES_DO_NOT_MATCH(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.endpointinterfaces.do.not.match", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_HOLDERS(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.oneway.operation.cannot.have.holders", arg0, arg1); + } + + /** +- * The endpoint interface {0} does not match the interface {1}. ++ * The method {1} of class {0} is annotated @Oneway but contains inout or out paramerters (javax.xml.ws.Holder) + * + */ +- public static String WEBSERVICEAP_ENDPOINTINTERFACES_DO_NOT_MATCH(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTERFACES_DO_NOT_MATCH(arg0, arg1)); ++ public static String WEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_HOLDERS(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_ONEWAY_OPERATION_CANNOT_HAVE_HOLDERS(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ANNOTATION(Object arg0) { +- return messageFactory.getMessage("webserviceap.endpointinteface.plus.annotation", arg0); ++ public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_CANNOT_HAVE_MORE_THAN_ONE_OUT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.document.literal.bare.cannot.have.more.than.one.out", arg0, arg1); + } + + /** +- * The @{0} annotation cannot be used in with @javax.jws.WebService.endpointInterface element. ++ * Document literal bare methods must have a return value or one out parameter. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ANNOTATION(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_ENDPOINTINTEFACE_PLUS_ANNOTATION(arg0)); ++ public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_CANNOT_HAVE_MORE_THAN_ONE_OUT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_CANNOT_HAVE_MORE_THAN_ONE_OUT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_FAILED_TO_PARSE_HANDLERCHAIN_FILE(Object arg0, Object arg1) { +- return messageFactory.getMessage("webserviceap.failed.to.parse.handlerchain.file", arg0, arg1); ++ public static Localizable localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.invalid.sei.annotation", arg0, arg1); + } + + /** +- * Failed to parse HandlerChain file. Class: {0}, file: {1} ++ * The @{0} annotation cannot be used on a service endpoint interface. Class: {1} + * + */ +- public static String WEBSERVICEAP_FAILED_TO_PARSE_HANDLERCHAIN_FILE(Object arg0, Object arg1) { +- return localizer.localize(localizableWEBSERVICEAP_FAILED_TO_PARSE_HANDLERCHAIN_FILE(arg0, arg1)); ++ public static String WEBSERVICEAP_INVALID_SEI_ANNOTATION(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_INVALID_SEI_ANNOTATION(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_PARAMETER_TYPES_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2, Object arg3) { +- return messageFactory.getMessage("webserviceap.method.parameter.types.cannot.implement.remote", arg0, arg1, arg2, arg3); ++ public static Localizable localizableWEBSERVICEAP_OPERATION_NAME_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.operation.name.not.unique", arg0, arg1, arg2); + } + + /** +- * Method parameter types cannot implement java.rmi.Remote. Class: {0} method: {1} parameter: {2} type: {3} ++ * Operation names must be unique. Class: {0} method: {1} operation name: {2} + * + */ +- public static String WEBSERVICEAP_METHOD_PARAMETER_TYPES_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2, Object arg3) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_PARAMETER_TYPES_CANNOT_IMPLEMENT_REMOTE(arg0, arg1, arg2, arg3)); ++ public static String WEBSERVICEAP_OPERATION_NAME_NOT_UNIQUE(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_OPERATION_NAME_NOT_UNIQUE(arg0, arg1, arg2)); + } + +- public static Localizable localizableWEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2) { +- return messageFactory.getMessage("webserviceap.method.return.type.cannot.implement.remote", arg0, arg1, arg2); ++ public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_FINAL(Object arg0) { ++ return messageFactory.getMessage("webserviceap.webservice.class.is.final", arg0); + } + + /** +- * Method return types cannot implement java.rmi.Remote. Class: {0} method: {1} return type: {2} ++ * Classes annotated with @javax.jws.WebService must not be final. Class: {0} + * + */ +- public static String WEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(Object arg0, Object arg1, Object arg2) { +- return localizer.localize(localizableWEBSERVICEAP_METHOD_RETURN_TYPE_CANNOT_IMPLEMENT_REMOTE(arg0, arg1, arg2)); ++ public static String WEBSERVICEAP_WEBSERVICE_CLASS_IS_FINAL(Object arg0) { ++ return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_FINAL(arg0)); + } + +- public static Localizable localizableWEBSERVICEAP_ERROR(Object arg0) { +- return messageFactory.getMessage("webserviceap.error", arg0); ++ public static Localizable localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONE_IN_OR_OUT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.document.literal.bare.must.have.one.in.or.out", arg0, arg1); + } + + /** +- * error: {0} ++ * Document literal bare methods must have at least one of: a return, an in parameter or an out parameter. Class: {0} Method: {1} + * + */ +- public static String WEBSERVICEAP_ERROR(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_ERROR(arg0)); ++ public static String WEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONE_IN_OR_OUT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_LITERAL_BARE_MUST_HAVE_ONE_IN_OR_OUT(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(Object arg0) { +- return messageFactory.getMessage("webserviceap.webservice.class.is.abstract", arg0); ++ public static Localizable localizableWEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.method.request.wrapper.bean.name.not.unique", arg0, arg1); + } + + /** +- * Classes annotated with @javax.jws.WebService must not be abstract. Class: {0} ++ * Request wrapper bean names must be unique and must not clash with other generated classes. Class: {0} method {1} + * + */ +- public static String WEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(Object arg0) { +- return localizer.localize(localizableWEBSERVICEAP_WEBSERVICE_CLASS_IS_ABSTRACT(arg0)); ++ public static String WEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_METHOD_REQUEST_WRAPPER_BEAN_NAME_NOT_UNIQUE(arg0, arg1)); + } + +- public static Localizable localizableWEBSERVICEAP_INIT_PARAM_FORMAT_ERROR() { +- return messageFactory.getMessage("webserviceap.init_param.format.error"); ++ public static Localizable localizableWEBSERVICEAP_DOCUMENT_BARE_HOLDER_PARAMETERS_MUST_NOT_BE_INOUT(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("webserviceap.document.bare.holder.parameters.must.not.be.inout", arg0, arg1, arg2); + } + + /** +- * a element must have exactly 1 and 1 ++ * javax.xml.ws.Holder parameters in document bare operations must be WebParam.Mode.INOUT; Class: {0} method: {1} parameter: {2} + * + */ +- public static String WEBSERVICEAP_INIT_PARAM_FORMAT_ERROR() { +- return localizer.localize(localizableWEBSERVICEAP_INIT_PARAM_FORMAT_ERROR()); ++ public static String WEBSERVICEAP_DOCUMENT_BARE_HOLDER_PARAMETERS_MUST_NOT_BE_INOUT(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWEBSERVICEAP_DOCUMENT_BARE_HOLDER_PARAMETERS_MUST_NOT_BE_INOUT(arg0, arg1, arg2)); + } + ++ public static Localizable localizableWEBSERVICEAP_ONEWAY_AND_NOT_ONE_IN(Object arg0, Object arg1) { ++ return messageFactory.getMessage("webserviceap.oneway.and.not.one.in", arg0, arg1); ++ } ++ ++ /** ++ * Document literal bare methods annotated with @javax.jws.Oneway must have one non-header IN parameter. Class: {0} Method: {1} ++ * ++ */ ++ public static String WEBSERVICEAP_ONEWAY_AND_NOT_ONE_IN(Object arg0, Object arg1) { ++ return localizer.localize(localizableWEBSERVICEAP_ONEWAY_AND_NOT_ONE_IN(arg0, arg1)); ++ } ++ + } +--- old/src/share/classes/com/sun/tools/internal/ws/resources/WscompileMessages.java Tue Aug 4 09:29:06 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/WscompileMessages.java Tue Aug 4 09:29:06 2009 +@@ -62,6 +62,30 @@ + return localizer.localize(localizableWSGEN_CLASS_NOT_FOUND(arg0)); + } + ++ public static Localizable localizableWSIMPORT_HTTP_REDIRECT(Object arg0, Object arg1) { ++ return messageFactory.getMessage("wsimport.httpRedirect", arg0, arg1); ++ } ++ ++ /** ++ * Server returned HTTP Status code: "{0}", retrying with "{1}" ++ * ++ */ ++ public static String WSIMPORT_HTTP_REDIRECT(Object arg0, Object arg1) { ++ return localizer.localize(localizableWSIMPORT_HTTP_REDIRECT(arg0, arg1)); ++ } ++ ++ public static Localizable localizableWSIMPORT_AUTH_INFO_NEEDED(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("wsimport.authInfoNeeded", arg0, arg1, arg2); ++ } ++ ++ /** ++ * {0}, "{1}" needs authorization, please provide authorization file with read access at {2} or use -Xauthfile to give the authorization file and on each line provide authorization information using this format : http[s]://user:password@host:port// ++ * ++ */ ++ public static String WSIMPORT_AUTH_INFO_NEEDED(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWSIMPORT_AUTH_INFO_NEEDED(arg0, arg1, arg2)); ++ } ++ + public static Localizable localizableWSGEN_USAGE_EXAMPLES() { + return messageFactory.getMessage("wsgen.usage.examples"); + } +@@ -142,6 +166,27 @@ + return localizer.localize(localizableWSIMPORT_MISSING_FILE()); + } + ++ public static Localizable localizableWSIMPORT_USAGE_EXTENSIONS() { ++ return messageFactory.getMessage("wsimport.usage.extensions"); ++ } ++ ++ /** ++ * ++ * Extensions: ++ * -XadditionalHeaders map headers not bound to request or response message to ++ * Java method parameters ++ * -Xauthfile file to carry authorization information in the format ++ * http://username:password@example.org/stock?wsdl ++ * -Xdebug print debug information ++ * -Xno-addressing-databinding enable binding of W3C EndpointReferenceType to Java ++ * -Xnocompile do not compile generated Java files ++ * ++ * ++ */ ++ public static String WSIMPORT_USAGE_EXTENSIONS() { ++ return localizer.localize(localizableWSIMPORT_USAGE_EXTENSIONS()); ++ } ++ + public static Localizable localizableWSIMPORT_USAGE(Object arg0) { + return messageFactory.getMessage("wsimport.usage", arg0); + } +@@ -221,8 +266,8 @@ + * -p specifies the target package + * -quiet suppress wsimport output + * -s specify where to place generated source files +- * -target generate code as per the given JAXWS specification version. +- * version 2.0 will generate compliant code for JAXWS 2.0 spec. ++ * -target generate code as per the given JAXWS spec version ++ * e.g. 2.0 will generate compliant code for JAXWS 2.0 spec + * -verbose output messages about what the compiler is doing + * -version print version information + * -wsdllocation @WebServiceClient.wsdlLocation value +@@ -245,6 +290,44 @@ + return localizer.localize(localizableWSCOMPILE_ERROR(arg0)); + } + ++ public static Localizable localizableWSGEN_PROTOCOL_WITHOUT_EXTENSION(Object arg0) { ++ return messageFactory.getMessage("wsgen.protocol.without.extension", arg0); ++ } ++ ++ /** ++ * The optional protocol "{0}" must be used in conjunction with the "-extension" option. ++ * ++ */ ++ public static String WSGEN_PROTOCOL_WITHOUT_EXTENSION(Object arg0) { ++ return localizer.localize(localizableWSGEN_PROTOCOL_WITHOUT_EXTENSION(arg0)); ++ } ++ ++ public static Localizable localizableWSIMPORT_COMPILING_CODE() { ++ return messageFactory.getMessage("wsimport.CompilingCode"); ++ } ++ ++ /** ++ * ++ * compiling code... ++ * ++ * ++ */ ++ public static String WSIMPORT_COMPILING_CODE() { ++ return localizer.localize(localizableWSIMPORT_COMPILING_CODE()); ++ } ++ ++ public static Localizable localizableWSIMPORT_READING_AUTH_FILE(Object arg0) { ++ return messageFactory.getMessage("wsimport.readingAuthFile", arg0); ++ } ++ ++ /** ++ * Trying to read authorization file : "{0}"... ++ * ++ */ ++ public static String WSIMPORT_READING_AUTH_FILE(Object arg0) { ++ return localizer.localize(localizableWSIMPORT_READING_AUTH_FILE(arg0)); ++ } ++ + public static Localizable localizableWSGEN_NO_WEBSERVICES_CLASS(Object arg0) { + return messageFactory.getMessage("wsgen.no.webservices.class", arg0); + } +@@ -281,6 +364,18 @@ + return localizer.localize(localizableWSCOMPILE_INFO(arg0)); + } + ++ public static Localizable localizableWSIMPORT_MAX_REDIRECT_ATTEMPT() { ++ return messageFactory.getMessage("wsimport.maxRedirectAttempt"); ++ } ++ ++ /** ++ * Can not get a WSDL maximum number of redirects(5) reached ++ * ++ */ ++ public static String WSIMPORT_MAX_REDIRECT_ATTEMPT() { ++ return localizer.localize(localizableWSIMPORT_MAX_REDIRECT_ATTEMPT()); ++ } ++ + public static Localizable localizableWSIMPORT_WARNING_MESSAGE(Object arg0) { + return messageFactory.getMessage("wsimport.WarningMessage", arg0); + } +@@ -324,6 +419,7 @@ + /** + * generating code... + * ++ * + */ + public static String WSIMPORT_GENERATING_CODE() { + return localizer.localize(localizableWSIMPORT_GENERATING_CODE()); +@@ -389,6 +485,30 @@ + return localizer.localize(localizableWSIMPORT_NO_SUCH_JAXB_OPTION(arg0)); + } + ++ public static Localizable localizableWSIMPORT_AUTH_FILE_NOT_FOUND(Object arg0, Object arg1) { ++ return messageFactory.getMessage("wsimport.authFileNotFound", arg0, arg1); ++ } ++ ++ /** ++ * Authorization file "{0}" not found. If the WSDL access needs Basic Authentication, please provide authorization file with read access at {1} or use -Xauthfile to give the authorization file and on each line provide authorization information using this format : http[s]://user:password@host:port// ++ * ++ */ ++ public static String WSIMPORT_AUTH_FILE_NOT_FOUND(Object arg0, Object arg1) { ++ return localizer.localize(localizableWSIMPORT_AUTH_FILE_NOT_FOUND(arg0, arg1)); ++ } ++ ++ public static Localizable localizableWSIMPORT_DEBUG_MESSAGE(Object arg0) { ++ return messageFactory.getMessage("wsimport.DebugMessage", arg0); ++ } ++ ++ /** ++ * [DEBUG] {0} ++ * ++ */ ++ public static String WSIMPORT_DEBUG_MESSAGE(Object arg0) { ++ return localizer.localize(localizableWSIMPORT_DEBUG_MESSAGE(arg0)); ++ } ++ + public static Localizable localizableWSGEN_COULD_NOT_CREATE_FILE(Object arg0) { + return messageFactory.getMessage("wsgen.could.not.create.file", arg0); + } +@@ -413,8 +533,8 @@ + return localizer.localize(localizableWSGEN_WSDL_ARG_NO_GENWSDL(arg0)); + } + +- public static Localizable localizableWSGEN_HELP(Object arg0) { +- return messageFactory.getMessage("wsgen.help", arg0); ++ public static Localizable localizableWSGEN_HELP(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("wsgen.help", arg0, arg1, arg2); + } + + /** +@@ -436,10 +556,12 @@ + * -s specify where to place generated source files + * -verbose output messages about what the compiler is doing + * -version print version information +- * -wsdl[:protocol] generate a WSDL file. The protocol is optional. +- * Valid protocols are soap1.1 and Xsoap1.2, the default +- * is soap1.1. Xsoap1.2 is not standard and can only be +- * used in conjunction with the -extension option ++ * -wsdl[:protocol] generate a WSDL file. The protocol is optional. ++ * Valid protocols are {1}, ++ * the default is soap1.1. ++ * The non stanadard protocols {2} ++ * can only be used in conjunction with the ++ * -extension option. + * -servicename specify the Service name to use in the generated WSDL + * Used in conjunction with the -wsdl option. + * -portname specify the Port name to use in the generated WSDL +@@ -446,8 +568,8 @@ + * Used in conjunction with the -wsdl option. + * + */ +- public static String WSGEN_HELP(Object arg0) { +- return localizer.localize(localizableWSGEN_HELP(arg0)); ++ public static String WSGEN_HELP(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableWSGEN_HELP(arg0, arg1, arg2)); + } + + public static Localizable localizableWSIMPORT_INFO_MESSAGE(Object arg0) { +@@ -474,6 +596,18 @@ + return localizer.localize(localizableWSGEN_SOAP_12_WITHOUT_EXTENSION()); + } + ++ public static Localizable localizableWSIMPORT_ILLEGAL_AUTH_INFO(Object arg0) { ++ return messageFactory.getMessage("wsimport.ILLEGAL_AUTH_INFO", arg0); ++ } ++ ++ /** ++ * "{0}" is not a valid authorization information format. The format is http[s]://user:password@host:port//. ++ * ++ */ ++ public static String WSIMPORT_ILLEGAL_AUTH_INFO(Object arg0) { ++ return localizer.localize(localizableWSIMPORT_ILLEGAL_AUTH_INFO(arg0)); ++ } ++ + public static Localizable localizableWSCOMPILE_COMPILATION_FAILED() { + return messageFactory.getMessage("wscompile.compilationFailed"); + } +@@ -546,6 +680,18 @@ + return localizer.localize(localizableWSIMPORT_NO_WSDL(arg0)); + } + ++ public static Localizable localizableWSIMPORT_AUTH_INFO_LINENO(Object arg0, Object arg1) { ++ return messageFactory.getMessage("wsimport.AUTH_INFO_LINENO", arg0, arg1); ++ } ++ ++ /** ++ * "line {0} of {1} ++ * ++ */ ++ public static String WSIMPORT_AUTH_INFO_LINENO(Object arg0, Object arg1) { ++ return localizer.localize(localizableWSIMPORT_AUTH_INFO_LINENO(arg0, arg1)); ++ } ++ + public static Localizable localizableWSGEN_USAGE(Object arg0) { + return messageFactory.getMessage("wsgen.usage", arg0); + } +--- old/src/share/classes/com/sun/tools/internal/ws/resources/WsdlMessages.java Tue Aug 4 09:29:09 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/WsdlMessages.java Tue Aug 4 09:29:08 2009 +@@ -55,7 +55,7 @@ + } + + /** +- * wsdl:binding "{0}" referenced by wsdl:port "{1}", but its not found in the wsdl ++ * wsdl:binding "{0}" referenced by wsdl:port "{1}", but it's not found in the wsdl + * + */ + public static String ENTITY_NOT_FOUND_BINDING(Object arg0, Object arg1) { +@@ -62,28 +62,30 @@ + return localizer.localize(localizableENTITY_NOT_FOUND_BINDING(arg0, arg1)); + } + +- public static Localizable localizablePARSING_PARSE_FAILED() { +- return messageFactory.getMessage("Parsing.ParseFailed"); ++ public static Localizable localizablePARSING_UNABLE_TO_GET_METADATA(Object arg0, Object arg1) { ++ return messageFactory.getMessage("parsing.unableToGetMetadata", arg0, arg1); + } + + /** +- * Failed to parse the WSDL. ++ * {0} + * ++ * {1} ++ * + */ +- public static String PARSING_PARSE_FAILED() { +- return localizer.localize(localizablePARSING_PARSE_FAILED()); ++ public static String PARSING_UNABLE_TO_GET_METADATA(Object arg0, Object arg1) { ++ return localizer.localize(localizablePARSING_UNABLE_TO_GET_METADATA(arg0, arg1)); + } + +- public static Localizable localizablePARSING_UNABLE_TO_GET_METADATA(Object arg0) { +- return messageFactory.getMessage("parsing.unableToGetMetadata", arg0); ++ public static Localizable localizablePARSING_PARSE_FAILED() { ++ return messageFactory.getMessage("Parsing.ParseFailed"); + } + + /** +- * Unable to get Metadata from: {0} ++ * Failed to parse the WSDL. + * + */ +- public static String PARSING_UNABLE_TO_GET_METADATA(Object arg0) { +- return localizer.localize(localizablePARSING_UNABLE_TO_GET_METADATA(arg0)); ++ public static String PARSING_PARSE_FAILED() { ++ return localizer.localize(localizablePARSING_PARSE_FAILED()); + } + + public static Localizable localizableVALIDATION_INVALID_PREFIX(Object arg0) { +@@ -151,7 +153,7 @@ + } + + /** +- * wsdl:portType "{0}" referenced by wsdl:binding "{1}", but its not found in the wsdl ++ * wsdl:portType "{0}" referenced by wsdl:binding "{1}", but it's not found in the wsdl + * + */ + public static String ENTITY_NOT_FOUND_PORT_TYPE(Object arg0, Object arg1) { +@@ -199,7 +201,7 @@ + } + + /** +- * Both jaxws:version and version are present ++ * Both jaxws:version and version are present + * + */ + public static String INTERNALIZER_TWO_VERSION_ATTRIBUTES() { +@@ -212,7 +214,7 @@ + + /** + * Invalid WSDL, duplicate parts in a wsdl:message is not allowed. +- * wsdl:message {0} has duplicated part name: "{1}" ++ * wsdl:message {0} has a duplicated part name: "{1}" + * + */ + public static String VALIDATION_DUPLICATE_PART_NAME(Object arg0, Object arg1) { +@@ -248,7 +250,7 @@ + } + + /** +- * found unexpected non whitespace text: "{0}" ++ * found unexpected non-whitespace text: "{0}" + * + */ + public static String PARSING_NON_WHITESPACE_TEXT_FOUND(Object arg0) { +@@ -260,7 +262,7 @@ + } + + /** +- * No target found for the wsdlLocation: {0} ++ * No target found for the wsdlLocation: {0} + * + */ + public static String INTERNALIZER_TARGET_NOT_FOUND(Object arg0) { +@@ -344,7 +346,7 @@ + } + + /** +- * JAXWS version attribute must be "2.0" ++ * JAXWS version attribute must be "2.0" + * + */ + public static String INTERNALIZER_INCORRECT_VERSION() { +@@ -399,6 +401,20 @@ + return localizer.localize(localizablePARSING_INCORRECT_ROOT_ELEMENT(arg0, arg1, arg2, arg3)); + } + ++ public static Localizable localizableTRY_WITH_MEX(Object arg0) { ++ return messageFactory.getMessage("try.with.mex", arg0); ++ } ++ ++ /** ++ * {0} ++ * ++ * retrying with MEX... ++ * ++ */ ++ public static String TRY_WITH_MEX(Object arg0) { ++ return localizer.localize(localizableTRY_WITH_MEX(arg0)); ++ } ++ + public static Localizable localizableVALIDATION_MISSING_REQUIRED_ATTRIBUTE(Object arg0, Object arg1) { + return messageFactory.getMessage("validation.missingRequiredAttribute", arg0, arg1); + } +@@ -440,7 +456,7 @@ + } + + /** +- * not an external binding file. The root element must be '{'http://java.sun.com/xml/ns/jaxws'}'bindings but it is '{'{0}'}'{1} ++ * not an external binding file. The root element must be '{'http://java.sun.com/xml/ns/jaxws'}'bindings but it is '{'{0}'}'{1} + * + */ + public static String PARSER_NOT_A_BINDING_FILE(Object arg0, Object arg1) { +@@ -548,7 +564,7 @@ + } + + /** +- * Unable to parse "{0}" : {1} ++ * Unable to parse "{0}" : {1} + * + */ + public static String ABSTRACT_REFERENCE_FINDER_IMPL_UNABLE_TO_PARSE(Object arg0, Object arg1) { +@@ -596,7 +612,7 @@ + } + + /** +- * XPath evaluation of "{0}" results in empty target node ++ * XPath evaluation of "{0}" results in an empty target node + * + */ + public static String INTERNALIZER_X_PATH_EVALUATES_TO_NO_TARGET(Object arg0) { +@@ -620,7 +636,7 @@ + } + + /** +- * Ignoring customization: "{0}", it has no namespace. It must belong to the customization namespace. ++ * Ignoring customization: "{0}", because it has no namespace. It must belong to the customization namespace. + * + */ + public static String INVALID_CUSTOMIZATION_NAMESPACE(Object arg0) { +@@ -687,28 +703,28 @@ + return localizer.localize(localizableVALIDATION_INCORRECT_TARGET_NAMESPACE(arg0, arg1)); + } + +- public static Localizable localizableENTITY_NOT_FOUND_BY_Q_NAME(Object arg0, Object arg1) { +- return messageFactory.getMessage("entity.notFoundByQName", arg0, arg1); ++ public static Localizable localizableENTITY_NOT_FOUND_BY_Q_NAME(Object arg0, Object arg1, Object arg2) { ++ return messageFactory.getMessage("entity.notFoundByQName", arg0, arg1, arg2); + } + + /** +- * invalid entity name: "{0}" (in namespace: "{1}") ++ * {0} "{1}" not found in the wsdl: {2} + * + */ +- public static String ENTITY_NOT_FOUND_BY_Q_NAME(Object arg0, Object arg1) { +- return localizer.localize(localizableENTITY_NOT_FOUND_BY_Q_NAME(arg0, arg1)); ++ public static String ENTITY_NOT_FOUND_BY_Q_NAME(Object arg0, Object arg1, Object arg2) { ++ return localizer.localize(localizableENTITY_NOT_FOUND_BY_Q_NAME(arg0, arg1, arg2)); + } + +- public static Localizable localizableINVALID_WSDL(Object arg0) { +- return messageFactory.getMessage("invalid.wsdl", arg0); ++ public static Localizable localizableINVALID_WSDL(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return messageFactory.getMessage("invalid.wsdl", arg0, arg1, arg2, arg3); + } + + /** +- * "{0} does not look like a WSDL document, retrying with MEX..." ++ * Invalid WSDL {0}, expected {1} found {2} at (line {3}) + * + */ +- public static String INVALID_WSDL(Object arg0) { +- return localizer.localize(localizableINVALID_WSDL(arg0)); ++ public static String INVALID_WSDL(Object arg0, Object arg1, Object arg2, Object arg3) { ++ return localizer.localize(localizableINVALID_WSDL(arg0, arg1, arg2, arg3)); + } + + public static Localizable localizableVALIDATION_UNSUPPORTED_SCHEMA_FEATURE(Object arg0) { +@@ -788,7 +804,7 @@ + } + + /** +- * Target node is not an element ++ * Target node is not an element + * + */ + public static String INTERNALIZER_TARGET_NOT_AN_ELEMENT() { +@@ -860,7 +876,7 @@ + } + + /** +- * Not a WSI-BP compliant WSDL (R2001, R2004). xsd:import must not import XML Schema definition emmbedded inline within WSDLDocument. ++ * Not a WSI-BP compliant WSDL (R2001, R2004). xsd:import must not import XML Schema definitions embedded inline within the WSDL document. + * + */ + public static String WARNING_WSI_R_2004() { +@@ -872,7 +888,7 @@ + } + + /** +- * Not a WSI-BP compliant WSDL (R2003). xsd:import must only be used inside xsd:schema element. ++ * Not a WSI-BP compliant WSDL (R2003). xsd:import must only be used inside xsd:schema elements. + * + */ + public static String WARNING_WSI_R_2003() { +@@ -884,7 +900,7 @@ + } + + /** +- * Not a WSI-BP compliant WSDL (R2002). wsdl:import must not be used to import XML Schema embedded in the WSDL document. Expected wsdl namesapce: {0}, found: {1} ++ * Not a WSI-BP compliant WSDL (R2002). wsdl:import must not be used to import XML Schema embedded in the WSDL document. Expected wsdl namespace: {0}, found: {1} + * + */ + public static String WARNING_WSI_R_2002(Object arg0, Object arg1) { +@@ -903,18 +919,30 @@ + return localizer.localize(localizablePARSING_ELEMENT_OR_TYPE_REQUIRED(arg0)); + } + +- public static Localizable localizableWARNING_WSI_R_2001(Object arg0) { +- return messageFactory.getMessage("warning.wsi.r2001", arg0); ++ public static Localizable localizableWARNING_WSI_R_2001() { ++ return messageFactory.getMessage("warning.wsi.r2001"); + } + + /** +- * Not a WSI-BP compliant WSDL (R2001, R2002). wsdl:import must only import WSDL document. Its trying to import: "{0}" ++ * Not a WSI-BP compliant WSDL (R2001, R2002). wsdl:import must import only WSDL documents. It's trying to import: "{0}" + * + */ +- public static String WARNING_WSI_R_2001(Object arg0) { +- return localizer.localize(localizableWARNING_WSI_R_2001(arg0)); ++ public static String WARNING_WSI_R_2001() { ++ return localizer.localize(localizableWARNING_WSI_R_2001()); + } + ++ public static Localizable localizableFILE_NOT_FOUND(Object arg0) { ++ return messageFactory.getMessage("file.not.found", arg0); ++ } ++ ++ /** ++ * {0} is unreachable ++ * ++ */ ++ public static String FILE_NOT_FOUND(Object arg0) { ++ return localizer.localize(localizableFILE_NOT_FOUND(arg0)); ++ } ++ + public static Localizable localizableVALIDATION_INVALID_SIMPLE_TYPE_IN_ELEMENT(Object arg0, Object arg1) { + return messageFactory.getMessage("validation.invalidSimpleTypeInElement", arg0, arg1); + } +@@ -944,7 +972,7 @@ + } + + /** +- * JAXWS version attribute must be present ++ * JAXWS version attribute must be present + * + */ + public static String INTERNALIZER_VERSION_NOT_PRESENT() { +@@ -951,6 +979,20 @@ + return localizer.localize(localizableINTERNALIZER_VERSION_NOT_PRESENT()); + } + ++ public static Localizable localizableFAILED_NOSERVICE(Object arg0) { ++ return messageFactory.getMessage("failed.noservice", arg0); ++ } ++ ++ /** ++ * failed.noservice=Could not find wsdl:service in the provided WSDL(s): ++ * ++ * {0} At least one WSDL with at least one service definition needs to be provided. ++ * ++ */ ++ public static String FAILED_NOSERVICE(Object arg0) { ++ return localizer.localize(localizableFAILED_NOSERVICE(arg0)); ++ } ++ + public static Localizable localizablePARSING_TOO_MANY_ELEMENTS(Object arg0, Object arg1, Object arg2) { + return messageFactory.getMessage("parsing.tooManyElements", arg0, arg1, arg2); + } +@@ -968,7 +1010,7 @@ + } + + /** +- * "{0}" is not a part of this compilation. Is this a mistake for "{1}"? ++ * "{0}" is not a part of this compilation. Is this a mistake for "{1}"? + * + */ + public static String INTERNALIZER_INCORRECT_SCHEMA_REFERENCE(Object arg0, Object arg1) { +--- old/src/share/classes/com/sun/tools/internal/ws/resources/configuration.properties Tue Aug 4 09:29:11 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/configuration.properties Tue Aug 4 09:29:10 2009 +@@ -25,4 +25,3 @@ + + configuration.invalidElement=invalid element \"{2}\" in file \"{0}\" (line {1}) + configuration.notBindingFile=Ignoring: binding file "\"{0}\". It is not a jaxws or a jaxb binding file. +- +--- old/src/share/classes/com/sun/tools/internal/ws/resources/generator.properties Tue Aug 4 09:29:13 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/generator.properties Tue Aug 4 09:29:13 2009 +@@ -32,4 +32,5 @@ + + #IndentingWriter + generator.indentingwriter.charset.cantencode=WSDL has some characters which native java encoder can''t encode: \"{0}\" +- ++generator.sei.classAlreadyExist=Could not generate SEI, class: {0} already exists. Rename wsdl:portType \"{1}\" using JAX-WS customization ++generator.service.classAlreadyExist=Could not generate Service, class: {0} already exists. Rename wsdl:Service \"{1}\" using JAX-WS customization +--- old/src/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties Tue Aug 4 09:29:15 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties Tue Aug 4 09:29:15 2009 +@@ -29,4 +29,3 @@ + javacompiler.classpath.error={0} is not available in the classpath, requires Sun's JDK version 5.0 or latter. + javacompiler.nosuchmethod.error=There is no such method {0} available, requires Sun's JDK version 5.0 or latter. + javacompiler.error=error : {0}. +- +--- old/src/share/classes/com/sun/tools/internal/ws/resources/model.properties Tue Aug 4 09:29:17 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/model.properties Tue Aug 4 09:29:17 2009 +@@ -58,7 +58,6 @@ + + model.uniqueness=uniqueness constraint violation + model.part.notUnique=parts in wsdl:message \"{0}\", reference \"{1}\", they must reference unique global elements. +-model.parameter.notunique=Failed to generate Java signature: duplicate parameter names {0}. Use JAXWS binding customization to rename the wsdl:part \"{1}\" + model.exception.notunique=Failed to generate Java signature: duplicate exception names {0}. Use JAXWS binding customization to rename the wsdl:part \"{1}\" + model.uniqueness.javastructuretype=uniqueness constraint violation, duplicate member \"{0}\" added to JavaStructureType \"{1}\" + model.parent.type.already.set=parent of type \"{0}\" already set to \"{1}\", new value = \"{2}\" +@@ -78,15 +77,16 @@ + model.arraywrapper.no.subtypes=LiteralArrayWrapper cannot have subtypes + model.arraywrapper.no.content.member=LiteralArrayWrapper cannot have a content member + model.complexType.simpleContent.reservedName=invalid attribute name: "_value" in complexType: \"{0}\", _value is JAXWS reserved name, this name is generated in the generated javabean class to hold content value in the generated javabean class for complexType/simpleContent. ++model.parameter.notunique.wrapper=Failed to generate Java signature: duplicate parameter name \"{0}\". Try one of these\n\t1. Use JAXWS binding customization to rename the wsdl:part \"{1}\"\n\t2. Run wsimport with -extension switch.\n\t3. This is wrapper style operation, to resolve parameter name conflict, you can also try disabling wrapper style by using false wsdl customization. ++model.parameter.notunique=Failed to generate Java signature: duplicate parameter name \"{0}\". Try one of these\n\t1. Use JAXWS binding customization to rename the wsdl:part \"{1}\"\n\t2. Run wsimport with -extension switch. + +-//JAXWS 2.0 ++#JAXWS 2.0 + model.schema.elementNotFound=Element \"{0}\" not found. + model.schema.jaxbException.message="{0}" + model.saxparser.exception:{0}\n{1} + + ConsoleErrorReporter.UnknownLocation = \ +- unknown location ++ unknown location + + ConsoleErrorReporter.LineXOfY = \ +- \ \ line {0} of {1} +- ++ \ \ line {0} of {1} +--- old/src/share/classes/com/sun/tools/internal/ws/resources/modeler.properties Tue Aug 4 09:29:20 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/modeler.properties Tue Aug 4 09:29:19 2009 +@@ -65,9 +65,9 @@ + wsdlmodeler.warning.noPortsInService=Service \"{0}\" does not contain any usable ports. try running wsimport with -extension switch. + wsdlmodeler.warning.noOperationsInPort=Port \"{0}\" does not contain any usable operations + wsdlmodeler.warning.ignoringNonSOAPPort=ignoring port \"{0}\": not a standard SOAP port. try running wsimport with -extension switch. +-wsdlmodeler.warning.nonSOAPPort=port \"{0}\": not a standard SOAP port. The generated artifacts may not work with JAXWS runtime. ++wsdlmodeler.warning.nonSOAPPort=port \"{0}\": not a standard SOAP port. The generated artifacts may not work with JAXWS runtime. + wsdlmodeler.warning.ignoringNonSOAPPort.noAddress=ignoring port \"{0}\": no SOAP address specified. try running wsimport with -extension switch. +-wsdlmodeler.warning.noSOAPAddress=port \"{0}\" is not a SOAP port, it has no soap:address ++wsdlmodeler.warning.noSOAPAddress=port \"{0}\" is not a SOAP port, it has no soap:address + wsdlmodeler.warning.ignoringSOAPBinding.nonHTTPTransport:ignoring SOAP port \"{0}\": unrecognized transport. try running wsimport with -extension switch. + + #BP1.1 R2705 +@@ -189,7 +189,7 @@ + mimemodeler.invalidMimePart.nameNotAllowed=name attribute on wsdl:part in Operation \"{0}\" is ignored. Its not allowed as per WS-I AP 1.0. + + +-wsdlmodeler20.rpcenc.not.supported=rpc/encoded wsdl's are not supported in JAXWS 2.0. ++wsdlmodeler20.rpcenc.not.supported=rpc/encoded wsdl's are not supported in JAXWS 2.0. + wsdlmodeler.warning.ignoringOperation.notNCName=Ignoring operation \"{0}\", it has illegal character ''{1}'' in its name. Its rpc-literal operation - jaxws won't be able to serialize it! + + wsdlmodeler.warning.ignoringOperation.javaReservedWordNotAllowed.nonWrapperStyle=Ignoring operation \"{0}\", can''t generate java method. Parameter: part "{2}\" in wsdl:message \"{1}\", is a java keyword. Use customization to change the parameter name or change the wsdl:part name. +@@ -207,11 +207,12 @@ + wsdlmodeler.warning.ignoringOperation.javaReservedWordNotAllowed.customizedOperationName=Ignoring operation \"{0}\", can''t generate java method ,customized name \"{1}\" of the wsdl:operation is a java keyword. + wsdlmodeler.invalid.operation.javaReservedWordNotAllowed.customizedOperationName=Invalid operation \"{0}\", can''t generate java method ,customized name \"{1}\" of the wsdl:operation is a java keyword. + +-wsdlmodeler.jaxb.javatype.notfound=Schema descriptor {0} in message part \"{1}\" could not be bound to Java! ++wsdlmodeler.jaxb.javatype.notfound=Schema descriptor {0} in message part \"{1}\" is not defined and could not be bound to Java. Perhaps the schema descriptor {0} is not defined in the schema imported/included in the WSDL. You can either add such imports/includes or run wsimport and provide the schema location using -b switch. + wsdlmodeler.unsupportedBinding.mime=WSDL MIME binding is not currently supported! + +-wsdlmodeler.nonUnique.body=Non unique body parts! In a port, operations must have unique operation signaure on the wire for successful dispatch. In port {0}, Operations \"{1}\" and \"{2}\" have the same request body block {3} +-wsdlmodeler.rpclit.unkownschematype=XML type \"{0}\" could not be resolved, XML to JAVA binding failed! Please check the wsdl:part \"{1}\" in the wsdl:message \"{2}\". ++wsdlmodeler.nonUnique.body.error=Non unique body parts! In a port, as per BP 1.1 R2710 operations must have unique operation signaure on the wire for successful dispatch. In port {0}, Operations \"{1}\" and \"{2}\" have the same request body block {3}. Try running wsimport with -extension switch, runtime will try to dispatch using SOAPAction ++wsdlmodeler.nonUnique.body.warning=Non unique body parts! In a port, as per BP 1.1 R2710 operations must have unique operation signaure on the wire for successful dispatch. In port {0}, Operations \"{1}\" and \"{2}\" have the same request body block {3}. Method dispatching may fail, runtime will try to dispatch using SOAPAction + ++wsdlmodeler.rpclit.unkownschematype=XML type \"{0}\" could not be resolved, XML to JAVA binding failed! Please check the wsdl:part \"{1}\" in the wsdl:message \"{2}\". ++ + wsdlmodeler.responsebean.notfound=wsimport failed to generate async response bean for operation: {0} +- +--- old/src/share/classes/com/sun/tools/internal/ws/resources/processor.properties Tue Aug 4 09:29:22 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/processor.properties Tue Aug 4 09:29:21 2009 +@@ -24,4 +24,3 @@ + # + + processor.missing.model=model is missing +- +--- old/src/share/classes/com/sun/tools/internal/ws/resources/util.properties Tue Aug 4 09:29:24 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/util.properties Tue Aug 4 09:29:24 2009 +@@ -26,4 +26,3 @@ + holder.valuefield.not.found=Could not find the field in the Holder that contains the Holder''s value: {0} + null.namespace.found=Encountered error in wsdl. Check namespace of element <{0}> + sax2dom.notsupported.createelement=SAX2DOMEx.DomImplDoesntSupportCreateElementNs: {0} +- +--- old/src/share/classes/com/sun/tools/internal/ws/resources/webserviceap.properties Tue Aug 4 09:29:26 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/webserviceap.properties Tue Aug 4 09:29:26 2009 +@@ -50,7 +50,7 @@ + webserviceap.oneway.operation.cannot.have.holders=The method {1} of class {0} is annotated @Oneway but contains inout or out paramerters (javax.xml.ws.Holder) + + webserviceap.oneway.operation.cannot.declare.exceptions=The method {1} of class {0} is annotated @Oneway but declares the exception {2} +- ++ + webserviceap.cannot.combine.handlerchain.soapmessagehandlers=You cannot specify both HanlderChain and SOAPMessageHandlers annotations + + webserviceap.invalid.handlerchain.file.nohandler-config=The handlerchain file {0} is invalid, it does not contain a handler-config element +@@ -109,19 +109,19 @@ + + webserviceap.mixed.binding.style=Class\: {0} contains mixed bindings. SOAPBinding.Style.RPC and SOAPBinding.Style.DOCUMENT cannot be mixed. + +-webserviceap.endpointinteface.plus.annotation=The @{0} annotation cannot be used in with @javax.jws.WebService.endpointInterface element. ++webserviceap.endpointinteface.plus.annotation=The @{0} annotation cannot be used in with @javax.jws.WebService.endpointInterface element. + +-webserviceap.endpointinteface.plus.element=The @javax.jws.WebService.{0} element cannot be used in with @javax.jws.WebService.endpointInterface element. ++webserviceap.endpointinteface.plus.element=The @javax.jws.WebService.{0} element cannot be used in with @javax.jws.WebService.endpointInterface element. + +-webserviceap.non.in.parameters.must.be.holder=Class:\ {0}, method: {1}, parameter: {2} is not WebParam.Mode.IN and is not of type javax.xml.ws.Holder. ++webserviceap.non.in.parameters.must.be.holder=Class:\ {0}, method: {1}, parameter: {2} is not WebParam.Mode.IN and is not of type javax.xml.ws.Holder. + +-webserviceap.invalid.sei.annotation.element=The @javax.jws.WebService.{0} element cannot be specified on a service endpoint interface. Class\: {1} ++webserviceap.invalid.sei.annotation.element=The @javax.jws.WebService.{0} element cannot be specified on a service endpoint interface. Class\: {1} + +-webserviceap.invalid.sei.annotation=The @{0} annotation cannot be used on a service endpoint interface. Class\: {1} ++webserviceap.invalid.sei.annotation=The @{0} annotation cannot be used on a service endpoint interface. Class\: {1} + + webserviceap.invalid.sei.annotation.element.exclude=The @javax.jws.WebMethod({0}) cannot be used on a service endpoint interface. Class\: {1} method\: {2} + +-webserviceap.invalid.webmethod.element.with.exclude=The @javax.jws.WebMethod.{0} element cannot be specified with the @javax.jws.WebMethod.exclude element. Class\: {1} method\: {2} ++webserviceap.invalid.webmethod.element.with.exclude=The @javax.jws.WebMethod.{0} element cannot be specified with the @javax.jws.WebMethod.exclude element. Class\: {1} method\: {2} + + webserviceap.doc.bare.no.out=Document/literal bare methods with no return type or OUT/INOUT parameters must be annotated as @Oneway. Class\: {0}, method: {1} + webserviceap.doc.bare.return.and.out=Document/literal bare methods cannot have a return type and out parameters. Class\: {0}, method: {1} +@@ -137,15 +137,17 @@ + + webserviceap.webservice.method.is.abstract=Classes annotated with @javax.jws.WebService must not have abstract methods. Class\: {0} Method: {1} + +-#webserviceap.doc.bare.return.and.out=Document literal bare methods must not have a return value and an OUT/INOUT parameter. Class\: {0} Method\: {1} ++webserviceap.webservice.method.is.static.or.final=Method annotated with @javax.jws.WebMethod must not be static or final. Class\: {0} Method: {1} + ++#webserviceap.doc.bare.return.and.out=Document literal bare methods must not have a return value and an OUT/INOUT parameter. Class\: {0} Method\: {1} ++ + webserviceap.webservice.no.default.constructor=Classes annotated with @javax.jws.WebService must have a public default constructor. Class\: {0} + +-webserviceap.oneway.and.not.one.in=Document literal bare methods annotated with @javax.jws.Oneway must have one non-header IN parameter. Class\: {0} Method\: {1} ++webserviceap.oneway.and.not.one.in=Document literal bare methods annotated with @javax.jws.Oneway must have one non-header IN parameter. Class\: {0} Method\: {1} + +-webserviceap.doc.bare.no.return.and.no.out=Document literal bare methods that do not have a return value must have a single OUT/INOUT parameter. Class\: {0} Method\: {1} ++webserviceap.doc.bare.no.return.and.no.out=Document literal bare methods that do not have a return value must have a single OUT/INOUT parameter. Class\: {0} Method\: {1} + +-webserviceap.doc.bare.and.no.one.in=Document literal bare methods must have one non-header, IN/INOUT parameter. Class\: {0} Method\: {1} ++webserviceap.doc.bare.and.no.one.in=Document literal bare methods must have one non-header, IN/INOUT parameter. Class\: {0} Method\: {1} + + webserviceap.method.not.implemented=Methods in an endpointInterface must be implemented in the implementation class. Interface Class\:{0} Implementation Class\:{1} Method\: {2} + +@@ -152,4 +154,3 @@ + webserviceap.no.package.class.must.have.targetnamespace=@javax.jws.Webservice annotated classes that do not belong to a package must have the @javax.jws.Webservice.targetNamespace element. Class\: {0} + + webserviceap.webservice.and.webserviceprovider=Classes cannot be annotated with both @javax.jws.WebService and @javax.xml.ws.WebServiceProvider. Class\: {0} +- +--- old/src/share/classes/com/sun/tools/internal/ws/resources/wscompile.properties Tue Aug 4 09:29:28 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/wscompile.properties Tue Aug 4 09:29:28 2009 +@@ -44,13 +44,23 @@ + \ -p specifies the target package\n\ + \ -quiet suppress wsimport output\n\ + \ -s specify where to place generated source files\n\ +-\ -target generate code as per the given JAXWS specification version.\n\ +-\ version 2.0 will generate compliant code for JAXWS 2.0 spec.\n\ ++\ -target generate code as per the given JAXWS spec version\n\ ++\ e.g. 2.0 will generate compliant code for JAXWS 2.0 spec\n\ + \ -verbose output messages about what the compiler is doing\n\ + \ -version print version information\n\ + \ -wsdllocation @WebServiceClient.wsdlLocation value\n\ + ++wsimport.usage.extensions=\n\ ++\Extensions:\n\ ++\ -XadditionalHeaders map headers not bound to request or response message to \n\ ++\ Java method parameters\n\ ++\ -Xauthfile file to carry authorization information in the format \n\ ++\ http://username:password@example.org/stock?wsdl\n\ ++\ -Xdebug print debug information\n\ ++\ -Xno-addressing-databinding enable binding of W3C EndpointReferenceType to Java\n\ ++\ -Xnocompile do not compile generated Java files\n\ + ++ + wsimport.usage.examples=\n\ + \Examples:\n\ + \ wsimport stock.wsdl -b stock.xml -b stock.xjb\n\ +@@ -76,15 +86,18 @@ + \ -s specify where to place generated source files\n\ + \ -verbose output messages about what the compiler is doing\n\ + \ -version print version information\n\ +-\ -wsdl[:protocol] generate a WSDL file. The protocol is optional.\n\ +-\ Valid protocols are soap1.1 and Xsoap1.2, the default\n\ +-\ is soap1.1. Xsoap1.2 is not standard and can only be\n\ +-\ used in conjunction with the -extension option\n\ ++\ -wsdl[:protocol] generate a WSDL file. The protocol is optional.\n\ ++\ Valid protocols are {1},\n\ ++\ the default is soap1.1.\n\ ++\ The non stanadard protocols {2}\n\ ++\ can only be used in conjunction with the\n\ ++\ -extension option.\n\ + \ -servicename specify the Service name to use in the generated WSDL\n\ + \ Used in conjunction with the -wsdl option.\n\ + \ -portname specify the Port name to use in the generated WSDL\n\ + \ Used in conjunction with the -wsdl option. + ++ + wsgen.usage.examples=\n\ + \Examples:\n\ + \ wsgen -cp . example.Stock\n\ +@@ -93,7 +106,7 @@ + wrapperTask.needEndorsed=\ + You are running on JDK6 which comes with JAX-WS 2.0 API, but this tool requires JAX-WS 2.1 API. \ + Use the endorsed standards override mechanism (http://java.sun.com/javase/6/docs/technotes/guides/standards/), \ +-or set xendorsed="true" on <{0}>. ++or set xendorsed="true" on <{0}>. + + wrapperTask.loading20Api=\ + You are loading JAX-WS 2.0 API from {0} but this tool requires JAX-WS 2.1 API. +@@ -126,7 +139,8 @@ + wsgen.could.not.create.file="Could not create file: "\{0}\" + wsgen.missingFile=Missing SEI + wsgen.soap12.without.extension=The optional protocol \"Xsoap1.2\" must be used in conjunction with the \"-extension\" option. +-wsgen.wsdl.arg.no.genwsdl=The \"{0}\" option can only be in conjunction with the "-wsdl" option. ++wsgen.protocol.without.extension=The optional protocol \"{0}\" must be used in conjunction with the \"-extension\" option. ++wsgen.wsdl.arg.no.genwsdl=The \"{0}\" option can only be in conjunction with the "-wsdl" option. + wsgen.servicename.missing.namespace=The service name \"{0}\" is missing a namespace. + wsgen.servicename.missing.localname=The service name \"{0}\" is missing a localname. + wsgen.portname.missing.namespace=The port name \"{0}\" is missing a namespace. +@@ -151,17 +165,41 @@ + Failed to parse "{0}": {1} + + wsimport.ParsingWSDL=parsing WSDL...\n\n +-wsimport.GeneratingCode=generating code... +- ++wsimport.GeneratingCode=generating code...\n ++wsimport.CompilingCode=\ncompiling code...\n + wsimport.ILLEGAL_TARGET_VERSION = \ + "{0}" is not a valid target version. "2.0" and "2.1" are supported. + ++wsimport.ILLEGAL_AUTH_INFO = \ ++ "{0}" is not a valid authorization information format. The format is http[s]://user:password@host:port//. ++ ++wsimport.readingAuthFile = \ ++ Trying to read authorization file : "{0}"... ++ ++wsimport.authFileNotFound = \ ++ Authorization file "{0}" not found. If the WSDL access needs Basic Authentication, please provide authorization file with read access at {1} or use -Xauthfile to give the authorization file and on each line provide authorization information using this format : http[s]://user:password@host:port// ++ ++wsimport.authInfoNeeded = \ ++ {0}, "{1}" needs authorization, please provide authorization file with read access at {2} or use -Xauthfile to give the authorization file and on each line provide authorization information using this format : http[s]://user:password@host:port// ++ ++wsimport.AUTH_INFO_LINENO = \ ++ "line {0} of {1} ++ ++ + wsimport.ErrorMessage = \ +- [ERROR] {0} ++ [ERROR] {0} + + wsimport.WarningMessage = \ +- [WARNING] {0} ++ [WARNING] {0} + + wsimport.InfoMessage = \ +- [INFO] {0} +- ++ [INFO] {0} ++ ++wsimport.DebugMessage = \ ++ [DEBUG] {0} ++ ++wsimport.httpRedirect = \ ++ Server returned HTTP Status code: "{0}", retrying with "{1}" ++ ++wsimport.maxRedirectAttempt = \ ++ Can not get a WSDL maximum number of redirects(5) reached +--- old/src/share/classes/com/sun/tools/internal/ws/resources/wsdl.properties Tue Aug 4 09:29:31 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/resources/wsdl.properties Tue Aug 4 09:29:30 2009 +@@ -41,7 +41,6 @@ + parsing.unknownNamespacePrefix=undeclared namespace prefix: \"{0}\" + parsing.invalidURI=invalid URI: {0} + parsing.ioExceptionWithSystemId=failed to parse document at \"{0}\" +-parsing.unableToGetMetadata= Unable to get Metadata from: {0} + parsing.ioException=parsing failed: {0} + parsing.saxExceptionWithSystemId=invalid WSDL file! failed to parse document at \"{0}\" + parsing.saxException=invalid WSDL file! parsing failed: {0} +@@ -52,7 +51,7 @@ + parsing.missingRequiredAttribute=missing required attribute \"{1}\" of element \"{0}\" + parsing.invalidTag=expected element \"{1}\", found \"{0}\" + parsing.invalidTagNS=Invalid WSDL at {4}: expected element \"{2}\" (in namespace \"{3}\"), found element \"{0}\" (in namespace \"{1}\") +-parsing.nonWhitespaceTextFound=found unexpected non whitespace text: \"{0}\" ++parsing.nonWhitespaceTextFound=found unexpected non-whitespace text: \"{0}\" + parsing.elementExpected=unexpected non-element found + # + entity.duplicate=duplicate entity: \"{0}\" +@@ -59,9 +58,9 @@ + entity.duplicateWithType=duplicate \"{0}\" entity: \"{1}\" + + entity.notFoundByID=invalid entity id: \"{0}\" +-entity.notFoundByQName=invalid entity name: \"{0}\" (in namespace: \"{1}\") +-entity.notFound.portType=wsdl:portType \"{0}\" referenced by wsdl:binding \"{1}\", but its not found in the wsdl +-entity.notFound.binding=wsdl:binding \"{0}" referenced by wsdl:port \"{1}\", but its not found in the wsdl ++entity.notFoundByQName={0} \"{1}\" not found in the wsdl: {2} ++entity.notFound.portType=wsdl:portType \"{0}\" referenced by wsdl:binding \"{1}\", but it's not found in the wsdl ++entity.notFound.binding=wsdl:binding \"{0}" referenced by wsdl:port \"{1}\", but it's not found in the wsdl + + # + validation.missingRequiredAttribute=missing required attribute \"{0}\" of element \"{1}\" +@@ -71,7 +70,7 @@ + validation.invalidComplexTypeInElement=invalid element: \"{1}\", has named complexType: \"{0}\" + validation.invalidSimpleTypeInElement=invalid element: \"{1}\", has named simpleType: \"{0}\" + validation.duplicatedElement=duplicated element: \"{0}\" +-validation.duplicatePartName=Invalid WSDL, duplicate parts in a wsdl:message is not allowed. \nwsdl:message {0} has duplicated part name: \"{1}\" ++validation.duplicatePartName=Invalid WSDL, duplicate parts in a wsdl:message is not allowed. \nwsdl:message {0} has a duplicated part name: \"{1}\" + validation.invalidSubEntity=invalid sub-element \"{0}\" of element \"{1}\" + validation.invalidAttribute=invalid attribute \"{0}\" of element \"{1}\" + validation.invalidAttributeValue=invalid value \"{1}\" for attribute \"{0}\" +@@ -88,51 +87,54 @@ + warning.inputOutputEmptyAction=ignoring empty Action in {0} element of \"{1}\" operation, using default instead + + #wsi compliant WSDL warnings +-warning.wsi.r2001=Not a WSI-BP compliant WSDL (R2001, R2002). wsdl:import must only import WSDL document. Its trying to import: \"{0}\" +-warning.wsi.r2002=Not a WSI-BP compliant WSDL (R2002). wsdl:import must not be used to import XML Schema embedded in the WSDL document. Expected wsdl namesapce: {0}, found: {1} +-warning.wsi.r2003=Not a WSI-BP compliant WSDL (R2003). xsd:import must only be used inside xsd:schema element. +-warning.wsi.r2004=Not a WSI-BP compliant WSDL (R2001, R2004). xsd:import must not import XML Schema definition emmbedded inline within WSDLDocument. ++warning.wsi.r2001=Not a WSI-BP compliant WSDL (R2001, R2002). wsdl:import must import only WSDL documents. It's trying to import: \"{0}\" ++warning.wsi.r2002=Not a WSI-BP compliant WSDL (R2002). wsdl:import must not be used to import XML Schema embedded in the WSDL document. Expected wsdl namespace: {0}, found: {1} ++warning.wsi.r2003=Not a WSI-BP compliant WSDL (R2003). xsd:import must only be used inside xsd:schema elements. ++warning.wsi.r2004=Not a WSI-BP compliant WSDL (R2001, R2004). xsd:import must not import XML Schema definitions embedded inline within the WSDL document. + + #Parser + Parsing.ParseFailed = \ +- Failed to parse the WSDL. ++\tFailed to parse the WSDL. + + Parsing.NotAWSDL=Failed to get WSDL components, probably {0} is not a valid WSDL file. + + AbstractReferenceFinderImpl.UnableToParse = \ +- Unable to parse "{0}" : {1} ++\tUnable to parse "{0}" : {1} + + Parser.NotABindingFile = \ +- not an external binding file. The root element must be '{'http://java.sun.com/xml/ns/jaxws'}'bindings but it is '{'{0}'}'{1} ++\tnot an external binding file. The root element must be '{'http://java.sun.com/xml/ns/jaxws'}'bindings but it is '{'{0}'}'{1} + + + #Internalizer + Internalizer.TwoVersionAttributes = \ +- Both jaxws:version and version are present ++\tBoth jaxws:version and version are present + Internalizer.IncorrectVersion = \ +- JAXWS version attribute must be "2.0" ++\tJAXWS version attribute must be "2.0" + + Internalizer.VersionNotPresent = \ +- JAXWS version attribute must be present ++\tJAXWS version attribute must be present + + internalizer.targetNotAnElement= \ +- Target node is not an element ++\tTarget node is not an element + internalizer.targetNotFound= \ +- No target found for the wsdlLocation: {0} ++\tNo target found for the wsdlLocation: {0} + + Internalizer.IncorrectSchemaReference= \ +- "{0}" is not a part of this compilation. Is this a mistake for "{1}"? ++\t"{0}" is not a part of this compilation. Is this a mistake for "{1}"? + + internalizer.XPathEvaluationError = \ + XPath error: {0} + internalizer.XPathEvaluatesToNoTarget = \ +- XPath evaluation of "{0}" results in empty target node ++ XPath evaluation of "{0}" results in an empty target node + internalizer.XPathEvaulatesToTooManyTargets = \ + XPath evaluation of "{0}" results in too many ({1}) target nodes + internalizer.XPathEvaluatesToNonElement = \ + XPath evaluation of "{0}" needs to result in an element. +-invalid.customization.namespace=Ignoring customization: \"{0}\", it has no namespace. It must belong to the customization namespace. ++invalid.customization.namespace=Ignoring customization: \"{0}\", because it has no namespace. It must belong to the customization namespace. + + invalid.wsdl.with.dooc="Not a WSDL document: {0}, it gives \"{1}\", retrying with MEX..." +-invalid.wsdl="{0} does not look like a WSDL document, retrying with MEX..." +- ++invalid.wsdl=Invalid WSDL {0}, expected {1} found {2} at (line {3}) ++try.with.mex= {0} \n\nretrying with MEX... ++file.not.found={0} is unreachable ++parsing.unableToGetMetadata= {0}\n\n{1} ++failed.noservice=failed.noservice=Could not find wsdl:service in the provided WSDL(s): \n\n{0} At least one WSDL with at least one service definition needs to be provided. +--- old/src/share/classes/com/sun/tools/internal/ws/version.properties Tue Aug 4 09:29:33 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/version.properties Tue Aug 4 09:29:33 2009 +@@ -23,7 +23,7 @@ + # have any questions. + # + +-build-id=JAX-WS RI 2.1.1 +-build-version=JAX-WS RI 2.1.1 +-major-version=2.1.1 +- ++#Fri May 15 16:16:14 CEST 2009 ++build-id=JAX-WS RI 2.1.6 ++major-version=2.1.6 ++build-version=JAX-WS RI 2.1.6 +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/AbortException.java Tue Aug 4 09:29:35 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/AbortException.java Tue Aug 4 09:29:35 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + /** +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/BadCommandLineException.java Tue Aug 4 09:29:37 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/BadCommandLineException.java Tue Aug 4 09:29:37 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.istack.internal.Nullable; +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/ErrorReceiver.java Tue Aug 4 09:29:39 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/ErrorReceiver.java Tue Aug 4 09:29:39 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.istack.internal.Nullable; +@@ -126,6 +125,8 @@ + info( new SAXParseException(msg,null) ); + } + ++ public abstract void debug(SAXParseException exception); ++ + // + // + // convenience methods for derived classes +@@ -145,7 +146,7 @@ + return ModelMessages.CONSOLE_ERROR_REPORTER_LINE_X_OF_Y(line==-1?"?":Integer.toString( line ), + getShortName( e.getSystemId())); + } else { +- return ModelMessages.CONSOLE_ERROR_REPORTER_UNKNOWN_LOCATION(); ++ return ""; //for unkown location just return empty string + } + } + +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/ErrorReceiverFilter.java Tue Aug 4 09:29:42 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/ErrorReceiverFilter.java Tue Aug 4 09:29:41 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.tools.internal.xjc.api.ErrorListener; +@@ -66,6 +65,10 @@ + if(core!=null) core.info(exception); + } + ++ public void debug(SAXParseException exception) { ++ ++ } ++ + public void warning(SAXParseException exception) { + if(core!=null) core.warning(exception); + } +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java Tue Aug 4 09:29:44 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java Tue Aug 4 09:29:43 2009 +@@ -35,6 +35,7 @@ + import java.lang.reflect.Method; + import java.net.MalformedURLException; + import java.net.URL; ++import java.net.URISyntaxException; + + /** + * A helper class to invoke javac. +@@ -43,9 +44,10 @@ + */ + class JavaCompilerHelper{ + static File getJarFile(Class clazz) { ++ URL url = null; + try { +- URL url = ParallelWorldClassLoader.toJarUrl(clazz.getResource('/'+clazz.getName().replace('.','/')+".class")); +- return new File(url.getPath()); // this code is assuming that url is a file URL ++ url = ParallelWorldClassLoader.toJarUrl(clazz.getResource('/'+clazz.getName().replace('.','/')+".class")); ++ return new File(url.toURI()); + } catch (ClassNotFoundException e) { + // if we can't figure out where JAXB/JAX-WS API are, we couldn't have been executing this code. + throw new Error(e); +@@ -52,6 +54,9 @@ + } catch (MalformedURLException e) { + // if we can't figure out where JAXB/JAX-WS API are, we couldn't have been executing this code. + throw new Error(e); ++ } catch (URISyntaxException e) { ++ // url.toURI() is picky and doesn't like ' ' in URL, so this is the fallback ++ return new File(url.getPath()); + } + } + +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/Options.java Tue Aug 4 09:29:46 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/Options.java Tue Aug 4 09:29:46 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.tools.internal.ws.resources.WscompileMessages; +@@ -150,6 +149,10 @@ + + + public boolean debug = false; ++ ++ /** ++ * -Xdebug - gives complete stack trace ++ */ + public boolean debugMode = false; + + +@@ -206,7 +209,7 @@ + * @exception BadCommandLineException + * thrown when there's a problem in the command-line arguments + */ +- public final void parseArguments( String[] args ) throws BadCommandLineException { ++ public void parseArguments( String[] args ) throws BadCommandLineException { + + for (int i = 0; i < args.length; i++) { + if(args[i].length()==0) +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/WsgenOptions.java Tue Aug 4 09:29:48 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/WsgenOptions.java Tue Aug 4 09:29:48 2009 +@@ -24,18 +24,20 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.mirror.apt.Filer; + import com.sun.tools.internal.ws.resources.WscompileMessages; ++import com.sun.tools.internal.ws.api.WsgenExtension; ++import com.sun.tools.internal.ws.api.WsgenProtocol; + import com.sun.xml.internal.ws.api.BindingID; ++import com.sun.xml.internal.ws.util.ServiceFinder; ++import com.sun.xml.internal.ws.binding.SOAPBindingImpl; + + import javax.jws.WebService; + import javax.xml.namespace.QName; + import java.io.File; +-import java.util.ArrayList; +-import java.util.List; ++import java.util.*; + + /** + * @author Vivek Pandey +@@ -66,8 +68,10 @@ + * protocol value + */ + public String protocol = "soap1.1"; +- public String transport; + ++ public Set protocols = new LinkedHashSet(); ++ public Map nonstdProtocols = new LinkedHashMap(); ++ + /** + * -XwsgenReport + */ +@@ -92,8 +96,22 @@ + private static final String SOAP11 = "soap1.1"; + public static final String X_SOAP12 = "Xsoap1.2"; + ++ public WsgenOptions() { ++ protocols.add(SOAP11); ++ protocols.add(X_SOAP12); ++ nonstdProtocols.put(X_SOAP12, SOAPBindingImpl.X_SOAP12HTTP_BINDING); ++ ServiceFinder extn = ServiceFinder.find(WsgenExtension.class); ++ for(WsgenExtension ext : extn) { ++ Class clazz = ext.getClass(); ++ WsgenProtocol pro = (WsgenProtocol)clazz.getAnnotation(WsgenProtocol.class); ++ protocols.add(pro.token()); ++ nonstdProtocols.put(pro.token(), pro.lexical()); ++ } ++ } ++ + @Override + protected int parseArguments(String[] args, int i) throws BadCommandLineException { ++ + int j = super.parseArguments(args, i); + if (args[i].equals(SERVICENAME_OPTION)) { + serviceName = QName.valueOf(requireArgument(SERVICENAME_OPTION, args, ++i)); +@@ -132,10 +150,8 @@ + index = value.indexOf('/'); + if (index == -1) { + protocol = value; +- transport = HTTP; + } else { + protocol = value.substring(0, index); +- transport = value.substring(index + 1); + } + protocolSet = true; + } +@@ -168,13 +184,9 @@ + public void validate() throws BadCommandLineException { + if(nonclassDestDir == null) + nonclassDestDir = destDir; +- if (!protocol.equalsIgnoreCase(SOAP11) && +- !protocol.equalsIgnoreCase(X_SOAP12)) { +- throw new BadCommandLineException(WscompileMessages.WSGEN_INVALID_PROTOCOL(protocol, SOAP11 + ", " + X_SOAP12)); +- } + +- if (transport != null && !transport.equalsIgnoreCase(HTTP)) { +- throw new BadCommandLineException(WscompileMessages.WSGEN_INVALID_TRANSPORT(transport, HTTP)); ++ if (!protocols.contains(protocol)) { ++ throw new BadCommandLineException(WscompileMessages.WSGEN_INVALID_PROTOCOL(protocol, protocols)); + } + + if (endpoints.isEmpty()) { +@@ -184,6 +196,10 @@ + throw new BadCommandLineException(WscompileMessages.WSGEN_SOAP_12_WITHOUT_EXTENSION()); + } + ++ if (nonstdProtocols.containsKey(protocol) && !isExtensionMode()) { ++ throw new BadCommandLineException(WscompileMessages.WSGEN_PROTOCOL_WITHOUT_EXTENSION(protocol)); ++ } ++ + validateEndpointClass(); + validateArguments(); + } +@@ -245,12 +261,13 @@ + } + } + +- public static BindingID getBindingID(String protocol) { ++ BindingID getBindingID(String protocol) { + if (protocol.equals(SOAP11)) + return BindingID.SOAP11_HTTP; + if (protocol.equals(X_SOAP12)) + return BindingID.SOAP12_HTTP; +- return null; ++ String lexical = nonstdProtocols.get(protocol); ++ return (lexical != null) ? BindingID.parse(lexical) : null; + } + + +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java Tue Aug 4 09:29:50 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java Tue Aug 4 09:29:50 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.mirror.apt.AnnotationProcessor; +@@ -32,6 +31,8 @@ + import com.sun.mirror.apt.AnnotationProcessorFactory; + import com.sun.mirror.declaration.AnnotationTypeDeclaration; + import com.sun.tools.internal.ws.ToolVersion; ++import com.sun.tools.internal.ws.api.WsgenExtension; ++import com.sun.tools.internal.ws.api.WsgenProtocol; + import com.sun.tools.internal.ws.processor.modeler.annotation.AnnotationProcessorContext; + import com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAP; + import com.sun.tools.internal.ws.processor.modeler.wsdl.ConsoleErrorReporter; +@@ -46,11 +47,13 @@ + import com.sun.xml.internal.ws.api.server.Container; + import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension; + import com.sun.xml.internal.ws.binding.WebServiceFeatureList; ++import com.sun.xml.internal.ws.binding.SOAPBindingImpl; + import com.sun.xml.internal.ws.model.AbstractSEIModelImpl; + import com.sun.xml.internal.ws.model.RuntimeModeler; + import com.sun.xml.internal.ws.util.ServiceFinder; + import com.sun.xml.internal.ws.wsdl.writer.WSDLGenerator; + import com.sun.xml.internal.ws.wsdl.writer.WSDLResolver; ++import com.sun.istack.internal.tools.ParallelWorldClassLoader; + import org.xml.sax.SAXParseException; + + import javax.xml.bind.annotation.XmlSeeAlso; +@@ -110,14 +113,16 @@ + return false; + } + }catch (Options.WeAreDone done){ +- usage(done.getOptions()); ++ usage((WsgenOptions)done.getOptions()); + }catch (BadCommandLineException e) { + if(e.getMessage()!=null) { + System.out.println(e.getMessage()); + System.out.println(); + } +- usage(e.getOptions()); ++ usage((WsgenOptions)e.getOptions()); + return false; ++ }catch(AbortException e){ ++ //error might have been reported + }finally{ + if(!options.keep){ + options.removeGeneratedFiles(); +@@ -161,12 +166,27 @@ + } + } + ++ /* ++ * To take care of JDK6-JDK6u3, where 2.1 API classes are not there ++ */ ++ private static boolean useBootClasspath(Class clazz) { ++ try { ++ ParallelWorldClassLoader.toJarUrl(clazz.getResource('/'+clazz.getName().replace('.','/')+".class")); ++ return true; ++ } catch(Exception e) { ++ return false; ++ } ++ } ++ ++ + public boolean buildModel(String endpoint, Listener listener) throws BadCommandLineException { + final ErrorReceiverFilter errReceiver = new ErrorReceiverFilter(listener); + context = new AnnotationProcessorContext(); + webServiceAP = new WebServiceAP(options, context, errReceiver, out); + +- String[] args = new String[9]; ++ boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class); ++ ++ String[] args = new String[8 + (bootCP ? 1 :0)]; + args[0] = "-d"; + args[1] = options.destDir.getAbsolutePath(); + args[2] = "-classpath"; +@@ -175,7 +195,9 @@ + args[5] = options.sourceDir.getAbsolutePath(); + args[6] = "-XclassesAsDecls"; + args[7] = endpoint; +- args[8] = "-Xbootclasspath/p:"+JavaCompilerHelper.getJarFile(EndpointReference.class)+File.pathSeparator+JavaCompilerHelper.getJarFile(XmlSeeAlso.class); ++ if (bootCP) { ++ args[8] = "-Xbootclasspath/p:"+JavaCompilerHelper.getJarFile(EndpointReference.class)+File.pathSeparator+JavaCompilerHelper.getJarFile(XmlSeeAlso.class); ++ } + + // Workaround for bug 6499165: issue with javac debug option + workAroundJavacDebug(); +@@ -195,11 +217,12 @@ + throw new BadCommandLineException(WscompileMessages.WSGEN_CLASS_NOT_FOUND(endpoint)); + } + +- BindingID bindingID = WsgenOptions.getBindingID(options.protocol); ++ BindingID bindingID = options.getBindingID(options.protocol); + if (!options.protocolSet) { + bindingID = BindingID.parse(endpointClass); + } +- RuntimeModeler rtModeler = new RuntimeModeler(endpointClass, options.serviceName, bindingID); ++ WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass); ++ RuntimeModeler rtModeler = new RuntimeModeler(endpointClass, options.serviceName, bindingID, wsfeatures.toArray()); + rtModeler.setClassLoader(classLoader); + if (options.portName != null) + rtModeler.setPortName(options.portName); +@@ -207,7 +230,7 @@ + + final File[] wsdlFileName = new File[1]; // used to capture the generated WSDL file. + final Map schemaFiles = new HashMap(); +- WebServiceFeatureList wsfeatures = new WebServiceFeatureList(endpointClass); ++ + WSDLGenerator wsdlGenerator = new WSDLGenerator(rtModel, + new WSDLResolver() { + private File toFile(String suggestedFilename) { +@@ -327,8 +350,12 @@ + } + } + +- protected void usage(Options options) { +- System.out.println(WscompileMessages.WSGEN_HELP("WSGEN")); ++ protected void usage(WsgenOptions options) { ++ // Just don't see any point in passing WsgenOptions ++ // BadCommandLineException also shouldn't have options ++ if (options == null) ++ options = this.options; ++ System.out.println(WscompileMessages.WSGEN_HELP("WSGEN", options.protocols, options.nonstdProtocols.keySet())); + System.out.println(WscompileMessages.WSGEN_USAGE_EXAMPLES()); + } + +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/WsimportListener.java Tue Aug 4 09:29:53 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/WsimportListener.java Tue Aug 4 09:29:52 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.tools.internal.xjc.api.ErrorListener; +@@ -75,6 +74,8 @@ + + } + ++ public void debug(SAXParseException exception){} ++ + /** + * wsimport will periodically invoke this method to see if it should cancel a compilation. + * +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/WsimportOptions.java Tue Aug 4 09:29:55 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/WsimportOptions.java Tue Aug 4 09:29:54 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.codemodel.internal.JCodeModel; +@@ -50,6 +49,7 @@ + import javax.xml.stream.XMLStreamReader; + import java.io.File; + import java.io.IOException; ++import java.net.Authenticator; + import java.net.MalformedURLException; + import java.net.URL; + import java.util.ArrayList; +@@ -78,11 +78,27 @@ + public String defaultPackage = null; + + /** ++ * -XadditionalHeaders ++ */ ++ public boolean additionalHeaders; ++ ++ /** ++ * Setting disableSSLHostVerification to true disables the SSL Hostname verification while fetching the wsdls. ++ * -XdisableSSLHostVerification ++ */ ++ public boolean disableSSLHostnameVerification; ++ ++ /** + * JAXB's {@link SchemaCompiler} to be used for handling the schema portion. + * This object is also configured through options. + */ + private SchemaCompiler schemaCompiler = XJC.createSchemaCompiler(); + ++ /** ++ * Authentication file ++ */ ++ public File authFile; ++ + public JCodeModel getCodeModel() { + if(codeModel == null) + codeModel = new JCodeModel(); +@@ -101,6 +117,50 @@ + + private JCodeModel codeModel; + ++ /** ++ * This captures jars passed on the commandline and passes them to XJC and puts them in the classpath for compilation ++ */ ++ public List cmdlineJars = new ArrayList(); ++ ++ /** ++ * Parses arguments and fill fields of this object. ++ * ++ * @exception BadCommandLineException ++ * thrown when there's a problem in the command-line arguments ++ */ ++ @Override ++ public final void parseArguments( String[] args ) throws BadCommandLineException { ++ ++ for (int i = 0; i < args.length; i++) { ++ if(args[i].length()==0) ++ throw new BadCommandLineException(); ++ if (args[i].charAt(0) == '-') { ++ int j = parseArguments(args,i); ++ if(j==0) ++ throw new BadCommandLineException(WscompileMessages.WSCOMPILE_INVALID_OPTION(args[i])); ++ i += (j-1); ++ } else { ++ if(args[i].endsWith(".jar")) { ++ ++ try { ++ cmdlineJars.add(args[i]); ++ schemaCompiler.getOptions().scanEpisodeFile(new File(args[i])); ++ ++ } catch (com.sun.tools.internal.xjc.BadCommandLineException e) { ++ //Driver.usage(jaxbOptions,false); ++ throw new BadCommandLineException(e.getMessage(), e); ++ } ++ } else{ ++ addFile(args[i]); ++ } ++ } ++ } ++ if(destDir == null) ++ destDir = new File("."); ++ if(sourceDir == null) ++ sourceDir = destDir; ++ } ++ + /** -Xno-addressing-databinding option to disable addressing namespace data binding. This is + * experimental switch and will be working as a temporary workaround till + * jaxb can provide a better way to selelctively disable compiling of an +@@ -119,6 +179,12 @@ + } else if (args[i].equals("-wsdllocation")) { + wsdlLocation = requireArgument("-wsdllocation", args, ++i); + return 2; ++ } else if (args[i].equals("-XadditionalHeaders")) { ++ additionalHeaders = true; ++ return 1; ++ } else if (args[i].equals("-XdisableSSLHostnameVerification")) { ++ disableSSLHostnameVerification = true; ++ return 1; + } else if (args[i].equals("-p")) { + defaultPackage = requireArgument("-p", args, ++i); + return 2; +@@ -173,6 +239,10 @@ + //Driver.usage(jaxbOptions,false); + throw new BadCommandLineException(e.getMessage(),e); + } ++ } else if (args[i].equals("-Xauthfile")) { ++ String authfile = requireArgument("-Xauthfile", args, ++i); ++ authFile = new File(authfile); ++ return 2; + } + + return 0; // what's this option? +@@ -182,12 +252,12 @@ + if (wsdls.isEmpty()) { + throw new BadCommandLineException(WscompileMessages.WSIMPORT_MISSING_FILE()); + } ++ + if(wsdlLocation == null){ + wsdlLocation = wsdls.get(0).getSystemId(); + } + } + +- + @Override + protected void addFile(String arg) throws BadCommandLineException { + addFile(arg, wsdls, "*.wsdl"); +@@ -360,5 +430,4 @@ + } + } + } +- + } +--- old/src/share/classes/com/sun/tools/internal/ws/wscompile/WsimportTool.java Tue Aug 4 09:29:57 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wscompile/WsimportTool.java Tue Aug 4 09:29:57 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wscompile; + + import com.sun.codemodel.internal.CodeWriter; +@@ -42,6 +41,7 @@ + import com.sun.tools.internal.xjc.util.NullStream; + import com.sun.xml.internal.ws.api.server.Container; + import com.sun.xml.internal.ws.util.ServiceFinder; ++import com.sun.istack.internal.tools.ParallelWorldClassLoader; + import org.xml.sax.EntityResolver; + import org.xml.sax.SAXParseException; + +@@ -53,6 +53,7 @@ + import java.io.PrintStream; + import java.util.ArrayList; + import java.util.List; ++import java.net.Authenticator; + + /** + * @author Vivek Pandey +@@ -76,7 +77,6 @@ + this.container = container; + } + +- + public boolean run(String[] args) { + class Listener extends WsimportListener { + ConsoleErrorReporter cer = new ConsoleErrorReporter(out == null ? new PrintStream(new NullStream()) : out); +@@ -107,6 +107,11 @@ + } + + @Override ++ public void debug(SAXParseException exception) { ++ cer.debug(exception); ++ } ++ ++ @Override + public void info(SAXParseException exception) { + cer.info(exception); + } +@@ -132,6 +137,13 @@ + if (listener.isCanceled()) + throw new AbortException(); + } ++ ++ @Override ++ public void debug(SAXParseException exception){ ++ if(options.debugMode){ ++ listener.debug(exception); ++ } ++ } + }; + + for (String arg : args) { +@@ -151,6 +163,11 @@ + if( !options.quiet ) + listener.message(WscompileMessages.WSIMPORT_PARSING_WSDL()); + ++ //set auth info ++ //if(options.authFile != null) ++ Authenticator.setDefault(new DefaultAuthenticator(receiver, options.authFile)); ++ ++ + WSDLModeler wsdlModeler = new WSDLModeler(options, receiver); + Model wsdlModel = wsdlModeler.buildModel(); + if (wsdlModel == null) { +@@ -165,10 +182,13 @@ + TJavaGeneratorExtension[] genExtn = ServiceFinder.find(TJavaGeneratorExtension.class).toArray(); + CustomExceptionGenerator.generate(wsdlModel, options, receiver); + SeiGenerator.generate(wsdlModel, options, receiver, genExtn); ++ if(receiver.hadError()){ ++ throw new AbortException(); ++ } + ServiceGenerator.generate(wsdlModel, options, receiver); + CodeWriter cw = new WSCodeWriter(options.sourceDir, options); + if (options.verbose) +- cw = new ProgressCodeWriter(cw, System.out); ++ cw = new ProgressCodeWriter(cw, out); + options.getCodeModel().build(cw); + } catch(AbortException e){ + //error might have been reported +@@ -177,7 +197,7 @@ + } + + if (!options.nocompile){ +- if(!compileGeneratedClasses(receiver)){ ++ if(!compileGeneratedClasses(receiver, listener)){ + listener.message(WscompileMessages.WSCOMPILE_COMPILATION_FAILED()); + return false; + } +@@ -204,7 +224,20 @@ + this.options.entityResolver = resolver; + } + +- protected boolean compileGeneratedClasses(ErrorReceiver receiver){ ++ /* ++ * To take care of JDK6-JDK6u3, where 2.1 API classes are not there ++ */ ++ private static boolean useBootClasspath(Class clazz) { ++ try { ++ ParallelWorldClassLoader.toJarUrl(clazz.getResource('/'+clazz.getName().replace('.','/')+".class")); ++ return true; ++ } catch(Exception e) { ++ return false; ++ } ++ } ++ ++ ++ protected boolean compileGeneratedClasses(ErrorReceiver receiver, WsimportListener listener){ + List sourceFiles = new ArrayList(); + + for (File f : options.getGeneratedFiles()) { +@@ -216,14 +249,18 @@ + if (sourceFiles.size() > 0) { + String classDir = options.destDir.getAbsolutePath(); + String classpathString = createClasspathString(); +- String[] args = new String[5 + (options.debug ? 1 : 0) ++ boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class); ++ String[] args = new String[4 + (bootCP ? 1 : 0) + (options.debug ? 1 : 0) + + sourceFiles.size()]; + args[0] = "-d"; + args[1] = classDir; + args[2] = "-classpath"; + args[3] = classpathString; +- args[4] = "-Xbootclasspath/p:"+JavaCompilerHelper.getJarFile(EndpointReference.class)+File.pathSeparator+JavaCompilerHelper.getJarFile(XmlSeeAlso.class); +- int baseIndex = 5; ++ int baseIndex = 4; ++ if (bootCP) { ++ args[baseIndex++] = "-Xbootclasspath/p:"+JavaCompilerHelper.getJarFile(EndpointReference.class)+File.pathSeparator+JavaCompilerHelper.getJarFile(XmlSeeAlso.class); ++ } ++ + if (options.debug) { + args[baseIndex++] = "-g"; + } +@@ -231,6 +268,15 @@ + args[baseIndex + i] = sourceFiles.get(i); + } + ++ listener.message(WscompileMessages.WSIMPORT_COMPILING_CODE()); ++ if(options.verbose){ ++ StringBuffer argstr = new StringBuffer(); ++ for(String arg:args){ ++ argstr.append(arg).append(" "); ++ } ++ listener.message("javac "+ argstr.toString()); ++ } ++ + return JavaCompilerHelper.compile(args, out, receiver); + } + //there are no files to compile, so return true? +@@ -238,11 +284,16 @@ + } + + private String createClasspathString() { +- return System.getProperty("java.class.path"); ++ String classpathStr = System.getProperty("java.class.path"); ++ for(String s: options.cmdlineJars) { ++ classpathStr = classpathStr+File.pathSeparator+new File(s); ++ } ++ return classpathStr; + } + + protected void usage(Options options) { + System.out.println(WscompileMessages.WSIMPORT_HELP(WSIMPORT)); ++ System.out.println(WscompileMessages.WSIMPORT_USAGE_EXTENSIONS()); + System.out.println(WscompileMessages.WSIMPORT_USAGE_EXAMPLES()); + } + } +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/document/Message.java Tue Aug 4 09:29:59 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/document/Message.java Tue Aug 4 09:29:59 2009 +@@ -53,8 +53,11 @@ + throw new AbortException(); + } + +- _partsByName.put(part.getName(), part); +- _parts.add(part); ++ if(part.getDescriptor() != null && part.getDescriptorKind() != null) { ++ _partsByName.put(part.getName(), part); ++ _parts.add(part); ++ } else ++ errorReceiver.warning(part.getLocator(), WsdlMessages.PARSING_ELEMENT_OR_TYPE_REQUIRED(part.getName())); + } + + public Iterator parts() { +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/document/jaxws/JAXWSBinding.java Tue Aug 4 09:30:02 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/document/jaxws/JAXWSBinding.java Tue Aug 4 09:30:01 2009 +@@ -232,15 +232,6 @@ + this.isProvider = isProvider; + } + +- /* (non-Javadoc) +- * @see Entity#getProperty(java.lang.String) +- */ +- public Object getProperty(String key) { +- if(key.equals(JAXWSBindingsConstants.JAXB_BINDINGS)) +- return jaxbBindings; +- return null; +- } +- + /** + * @return Returns the methodName. + */ +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/framework/AbstractDocument.java Tue Aug 4 09:30:04 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/framework/AbstractDocument.java Tue Aug 4 09:30:03 2009 +@@ -134,26 +134,11 @@ + } + } + +- public void undefine(GloballyKnown e) { +- Map map = getMap(e.getKind()); +- if (e.getName() == null) +- return; +- QName name = +- new QName(e.getDefining().getTargetNamespaceURI(), e.getName()); +- +- if (map.containsKey(name)){ +- errReceiver.error(e.getLocator(), WsdlMessages.ENTITY_NOT_FOUND_BY_Q_NAME(e.getElementName().getLocalPart(), e.getElementName().getNamespaceURI())); +- throw new AbortException(); +- } else{ +- map.remove(name); +- } +- } +- + public GloballyKnown find(Kind k, QName name) { + Map map = getMap(k); + Object result = map.get(name); + if (result == null){ +- errReceiver.error(new LocatorImpl(), WsdlMessages.ENTITY_NOT_FOUND_BY_Q_NAME(name.getLocalPart(), name.getNamespaceURI())); ++ errReceiver.error(null, WsdlMessages.ENTITY_NOT_FOUND_BY_Q_NAME(k.getName(), name, _systemId)); + throw new AbortException(); + } + return (GloballyKnown) result; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/AbstractReferenceFinderImpl.java Tue Aug 4 09:30:06 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/AbstractReferenceFinderImpl.java Tue Aug 4 09:30:06 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.istack.internal.SAXParseException2; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMBuilder.java Tue Aug 4 09:30:08 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMBuilder.java Tue Aug 4 09:30:08 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBindingsConstants; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java Tue Aug 4 09:30:10 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForest.java Tue Aug 4 09:30:10 2009 +@@ -24,22 +24,23 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + ++import com.sun.istack.internal.NotNull; ++import com.sun.tools.internal.ws.resources.WscompileMessages; ++import com.sun.tools.internal.ws.wscompile.AbortException; ++import com.sun.tools.internal.ws.wscompile.DefaultAuthenticator; + import com.sun.tools.internal.ws.wscompile.ErrorReceiver; + import com.sun.tools.internal.ws.wscompile.WsimportOptions; + import com.sun.tools.internal.ws.wsdl.document.schema.SchemaConstants; +-import com.sun.tools.internal.ws.resources.WscompileMessages; + import com.sun.tools.internal.xjc.reader.internalizer.LocatorTable; + import com.sun.xml.internal.bind.marshaller.DataWriter; ++import com.sun.xml.internal.ws.util.JAXWSUtils; + import org.w3c.dom.Document; + import org.w3c.dom.Element; + import org.w3c.dom.NodeList; + import org.xml.sax.ContentHandler; +-import org.xml.sax.InputSource; +-import org.xml.sax.SAXException; +-import org.xml.sax.XMLReader; ++import org.xml.sax.*; + import org.xml.sax.helpers.XMLFilterImpl; + + import javax.xml.parsers.DocumentBuilder; +@@ -51,17 +52,15 @@ + import javax.xml.transform.TransformerFactory; + import javax.xml.transform.dom.DOMSource; + import javax.xml.transform.sax.SAXResult; ++import javax.net.ssl.HttpsURLConnection; ++import javax.net.ssl.HostnameVerifier; ++import javax.net.ssl.SSLSession; + import java.io.IOException; ++import java.io.InputStream; + import java.io.OutputStream; + import java.io.OutputStreamWriter; +-import java.net.URI; +-import java.net.URISyntaxException; +-import java.util.ArrayList; +-import java.util.HashMap; +-import java.util.HashSet; +-import java.util.List; +-import java.util.Map; +-import java.util.Set; ++import java.net.*; ++import java.util.*; + + /** + * @author Vivek Pandey +@@ -134,10 +133,9 @@ + return inlinedSchemaElements; + } + +- public Document parse(InputSource source, boolean root) throws SAXException { ++ public @NotNull Document parse(InputSource source, boolean root) throws SAXException, IOException { + if (source.getSystemId() == null) + throw new IllegalArgumentException(); +- + return parse(source.getSystemId(), source, root); + } + +@@ -148,7 +146,7 @@ + * + * @return the parsed DOM document object. + */ +- public Document parse(String systemId, boolean root) throws SAXException, IOException { ++ public Document parse(String systemId, boolean root) throws SAXException, IOException{ + + systemId = normalizeSystemId(systemId); + +@@ -179,13 +177,11 @@ + * + * @return null if there was a parse error. otherwise non-null. + */ +- public Document parse(String systemId, InputSource inputSource, boolean root) throws SAXException { ++ public @NotNull Document parse(String systemId, InputSource inputSource, boolean root) throws SAXException, IOException{ + Document dom = documentBuilder.newDocument(); + + systemId = normalizeSystemId(systemId); + +- boolean retryMex = false; +- Exception exception = null; + // put into the map before growing a tree, to + // prevent recursive reference from causing infinite loop. + core.put(systemId, dom); +@@ -201,8 +197,70 @@ + reader.setErrorHandler(errorReceiver); + if (options.entityResolver != null) + reader.setEntityResolver(options.entityResolver); ++ ++ InputStream is = null; ++ if(inputSource.getByteStream() != null){ ++ is = inputSource.getByteStream(); ++ } ++ if(is == null){ ++ int redirects=0; ++ boolean redirect; ++ URL url = JAXWSUtils.getFileOrURL(inputSource.getSystemId()); ++ URLConnection conn = url.openConnection(); ++ if (conn instanceof HttpsURLConnection) { ++ if (options.disableSSLHostnameVerification) { ++ ((HttpsURLConnection) conn).setHostnameVerifier(new HttpClientVerifier()); ++ } ++ } ++ ++ do { ++ redirect = false; ++ try { ++ is = conn.getInputStream(); ++ //is = sun.net.www.protocol.http.HttpURLConnection.openConnectionCheckRedirects(conn); ++ } catch (IOException e) { ++ if (conn instanceof HttpURLConnection) { ++ HttpURLConnection httpConn = ((HttpURLConnection) conn); ++ int code = httpConn.getResponseCode(); ++ if (code == 401) { ++ errorReceiver.error(new SAXParseException(WscompileMessages.WSIMPORT_AUTH_INFO_NEEDED(e.getMessage(), systemId, DefaultAuthenticator.defaultAuthfile), null, e)); ++ throw new AbortException(); ++ } ++ //FOR other code we will retry with MEX ++ } ++ throw e; ++ } ++ ++ //handle 302 or 303, JDK does not seem to handle 302 very well. ++ //Need to redesign this a bit as we need to throw better error message for IOException in this case ++ if (conn instanceof HttpURLConnection) { ++ HttpURLConnection httpConn = ((HttpURLConnection) conn); ++ int code = httpConn.getResponseCode(); ++ if (code == 302 || code == 303) { ++ //retry with the value in Location header ++ List seeOther = httpConn.getHeaderFields().get("Location"); ++ if (seeOther != null && seeOther.size() > 0) { ++ URL newurl = new URL(url, seeOther.get(0)); ++ if (!newurl.equals(url)){ ++ errorReceiver.info(new SAXParseException(WscompileMessages.WSIMPORT_HTTP_REDIRECT(code, seeOther.get(0)), null)); ++ url = newurl; ++ httpConn.disconnect(); ++ if(redirects >= 5){ ++ errorReceiver.error(new SAXParseException(WscompileMessages.WSIMPORT_MAX_REDIRECT_ATTEMPT(), null)); ++ throw new AbortException(); ++ } ++ conn = url.openConnection(); ++ redirects++; ++ redirect = true; ++ } ++ } ++ } ++ } ++ } while (redirect); ++ } ++ inputSource.setByteStream(is); + reader.parse(inputSource); +- Element doc = dom.getDocumentElement(); ++ Element doc = dom.getDocumentElement(); + if (doc == null) { + return null; + } +@@ -211,18 +269,10 @@ + inlinedSchemaElements.add((Element) schemas.item(i)); + } + } catch (ParserConfigurationException e) { +- exception = e; +- } catch (IOException e) { +- exception = e; +- } catch (SAXException e) { +- exception = e; ++ errorReceiver.error(e); ++ throw new SAXException(e.getMessage()); + } + +- if (exception != null) { +- errorReceiver.error(WscompileMessages.WSIMPORT_NO_WSDL(systemId), exception); +- core.remove(systemId); +- rootDocuments.remove(systemId); +- } + return dom; + } + +@@ -236,6 +286,14 @@ + return externalReferences; + } + ++ // overide default SSL HttpClientVerifier to always return true ++ // effectively overiding Hostname client verification when using SSL ++ private static class HttpClientVerifier implements HostnameVerifier { ++ public boolean verify(String s, SSLSession sslSession) { ++ return true; ++ } ++ } ++ + public interface Handler extends ContentHandler { + /** + * Gets the DOM that was built. +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForestScanner.java Tue Aug 4 09:30:13 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/DOMForestScanner.java Tue Aug 4 09:30:12 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.xml.internal.bind.unmarshaller.DOMScanner; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/InternalizationLogic.java Tue Aug 4 09:30:15 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/InternalizationLogic.java Tue Aug 4 09:30:14 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import org.w3c.dom.Element; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java Tue Aug 4 09:30:17 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/Internalizer.java Tue Aug 4 09:30:17 2009 +@@ -33,9 +33,14 @@ + import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBindingsConstants; + import com.sun.tools.internal.xjc.util.DOMUtils; + import com.sun.xml.internal.bind.v2.util.EditDistance; +-import com.sun.xml.internal.ws.util.JAXWSUtils; + import com.sun.xml.internal.ws.util.DOMUtil; +-import org.w3c.dom.*; ++import com.sun.xml.internal.ws.util.JAXWSUtils; ++import org.w3c.dom.Attr; ++import org.w3c.dom.Document; ++import org.w3c.dom.Element; ++import org.w3c.dom.NamedNodeMap; ++import org.w3c.dom.Node; ++import org.w3c.dom.NodeList; + import org.xml.sax.SAXParseException; + + import javax.xml.namespace.NamespaceContext; +@@ -45,11 +50,17 @@ + import javax.xml.xpath.XPathFactory; + import java.net.MalformedURLException; + import java.net.URL; +-import java.util.*; ++import java.util.ArrayList; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Iterator; ++import java.util.Map; ++import java.util.Set; + + + /** + * Internalizes external binding declarations. ++ * + * @author Vivek Pandey + */ + public class Internalizer { +@@ -66,13 +77,13 @@ + this.errorReceiver = errorReceiver; + } + +- public void transform(){ +- Map targetNodes = new HashMap(); +- for(Element jaxwsBinding : forest.outerMostBindings){ +- buildTargetNodeMap(jaxwsBinding, jaxwsBinding, targetNodes ); ++ public void transform() { ++ Map targetNodes = new HashMap(); ++ for (Element jaxwsBinding : forest.outerMostBindings) { ++ buildTargetNodeMap(jaxwsBinding, jaxwsBinding, targetNodes); + } +- for(Element jaxwsBinding : forest.outerMostBindings){ +- move(jaxwsBinding, targetNodes ); ++ for (Element jaxwsBinding : forest.outerMostBindings) { ++ move(jaxwsBinding, targetNodes); + } + } + +@@ -79,15 +90,15 @@ + /** + * Validates attributes of a <JAXWS:bindings> element. + */ +- private void validate( Element bindings ) { ++ private void validate(Element bindings) { + NamedNodeMap atts = bindings.getAttributes(); +- for( int i=0; i result ) { ++ private void buildTargetNodeMap(Element bindings, Node inheritedTarget, Map result) { + // start by the inherited target + Node target = inheritedTarget; + +@@ -106,22 +117,27 @@ + validate(bindings); // validate this node + + // look for @wsdlLocation +- if( bindings.getAttributeNode("wsdlLocation")!=null ) { +- String wsdlLocation = bindings.getAttribute("wsdlLocation"); ++ if (isTopLevelBinding(bindings)) { ++ String wsdlLocation; ++ if (bindings.getAttributeNode("wsdlLocation") != null) { ++ wsdlLocation = bindings.getAttribute("wsdlLocation"); + +- try { +- // absolutize this URI. +- // TODO: use the URI class +- // TODO: honor xml:base +- wsdlLocation = new URL(new URL(forest.getSystemId(bindings.getOwnerDocument())), +- wsdlLocation ).toExternalForm(); +- } catch( MalformedURLException e ) { +- wsdlLocation = JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation)); ++ try { ++ // absolutize this URI. ++ // TODO: use the URI class ++ // TODO: honor xml:base ++ wsdlLocation = new URL(new URL(forest.getSystemId(bindings.getOwnerDocument())), ++ wsdlLocation).toExternalForm(); ++ } catch (MalformedURLException e) { ++ wsdlLocation = JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation)); ++ } ++ } else { ++ //the node does not have ++ wsdlLocation = forest.getFirstRootDocument(); + } +- +- //target = wsdlDocuments.get(wsdlLocation); + target = forest.get(wsdlLocation); +- if(target==null) { ++ ++ if (target == null) { + reportError(bindings, WsdlMessages.INTERNALIZER_INCORRECT_SCHEMA_REFERENCE(wsdlLocation, EditDistance.findNearest(wsdlLocation, forest.listSystemIDs()))); + return; // abort processing this + } +@@ -134,7 +150,7 @@ + if (element != null && element.getNamespaceURI().equals(Constants.NS_WSDL) && element.getLocalName().equals("definitions")) { + //get all schema elements + Element type = DOMUtils.getFirstChildElement(element, Constants.NS_WSDL, "types"); +- if(type != null){ ++ if (type != null) { + for (Element schemaElement : DOMUtils.getChildElements(type, Constants.NS_XSD, "schema")) { + if (!schemaElement.hasAttributeNS(Constants.NS_XMLNS, "jaxb")) { + schemaElement.setAttributeNS(Constants.NS_XMLNS, "xmlns:jaxb", JAXWSBindingsConstants.NS_JAXB_BINDINGS); +@@ -150,45 +166,50 @@ + + + boolean hasNode = true; +- if((isJAXWSBindings(bindings) || isJAXBBindings(bindings)) && bindings.getAttributeNode("node")!=null ) { ++ if ((isJAXWSBindings(bindings) || isJAXBBindings(bindings)) && bindings.getAttributeNode("node") != null) { + target = evaluateXPathNode(bindings, target, bindings.getAttribute("node"), new NamespaceContextImpl(bindings)); +- }else if(isJAXWSBindings(bindings) && (bindings.getAttributeNode("node")==null) && !isTopLevelBinding(bindings)) { ++ } else ++ if (isJAXWSBindings(bindings) && (bindings.getAttributeNode("node") == null) && !isTopLevelBinding(bindings)) { + hasNode = false; +- }else if(isGlobalBinding(bindings) && !isWSDLDefinition(target) && isTopLevelBinding(bindings.getParentNode())){ ++ } else ++ if (isGlobalBinding(bindings) && !isWSDLDefinition(target) && isTopLevelBinding(bindings.getParentNode())) { + target = getWSDLDefintionNode(bindings, target); + } + + //if target is null it means the xpath evaluation has some problem, + // just return +- if(target == null) ++ if (target == null) + return; + + // update the result map +- if(hasNode) +- result.put( bindings, target ); ++ if (hasNode) ++ result.put(bindings, target); + + // look for child and process them recursively +- Element[] children = getChildElements( bindings); ++ Element[] children = getChildElements(bindings); + for (Element child : children) + buildTargetNodeMap(child, target, result); + } + +- private Node getWSDLDefintionNode(Node bindings, Node target){ ++ private Node getWSDLDefintionNode(Node bindings, Node target) { + return evaluateXPathNode(bindings, target, "wsdl:definitions", +- new NamespaceContext(){ +- public String getNamespaceURI(String prefix){ +- return "http://schemas.xmlsoap.org/wsdl/"; +- } +- public String getPrefix(String nsURI){ +- throw new UnsupportedOperationException(); +- } +- public Iterator getPrefixes(String namespaceURI) { +- throw new UnsupportedOperationException(); +- }}); ++ new NamespaceContext() { ++ public String getNamespaceURI(String prefix) { ++ return "http://schemas.xmlsoap.org/wsdl/"; ++ } ++ ++ public String getPrefix(String nsURI) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ public Iterator getPrefixes(String namespaceURI) { ++ throw new UnsupportedOperationException(); ++ } ++ }); + } + +- private boolean isWSDLDefinition(Node target){ +- if(target == null) ++ private boolean isWSDLDefinition(Node target) { ++ if (target == null) + return false; + String localName = target.getLocalName(); + String nsURI = target.getNamespaceURI(); +@@ -195,43 +216,41 @@ + return fixNull(localName).equals("definitions") && fixNull(nsURI).equals("http://schemas.xmlsoap.org/wsdl/"); + } + +- private boolean isTopLevelBinding(Node node){ +- if(node instanceof Document) +- node = ((Document)node).getDocumentElement(); +- return ((node != null) && (((Element)node).getAttributeNode("wsdlLocation") != null)); ++ private boolean isTopLevelBinding(Node node) { ++ return node.getOwnerDocument().getDocumentElement() == node; + } + +- private boolean isJAXWSBindings(Node bindings){ ++ private boolean isJAXWSBindings(Node bindings) { + return (bindings.getNamespaceURI().equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS) && bindings.getLocalName().equals("bindings")); + } + +- private boolean isJAXBBindings(Node bindings){ ++ private boolean isJAXBBindings(Node bindings) { + return (bindings.getNamespaceURI().equals(JAXWSBindingsConstants.NS_JAXB_BINDINGS) && bindings.getLocalName().equals("bindings")); + } + +- private boolean isGlobalBinding(Node bindings){ +- if(bindings.getNamespaceURI() == null){ ++ private boolean isGlobalBinding(Node bindings) { ++ if (bindings.getNamespaceURI() == null) { + errorReceiver.warning(forest.locatorTable.getStartLocation((Element) bindings), WsdlMessages.INVALID_CUSTOMIZATION_NAMESPACE(bindings.getLocalName())); + return false; + } +- return (bindings.getNamespaceURI().equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS) && ++ return (bindings.getNamespaceURI().equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS) && + (bindings.getLocalName().equals("package") || +- bindings.getLocalName().equals("enableAsyncMapping") || +- bindings.getLocalName().equals("enableAdditionalSOAPHeaderMapping") || +- bindings.getLocalName().equals("enableWrapperStyle") || +- bindings.getLocalName().equals("enableMIMEContent"))); ++ bindings.getLocalName().equals("enableAsyncMapping") || ++ bindings.getLocalName().equals("enableAdditionalSOAPHeaderMapping") || ++ bindings.getLocalName().equals("enableWrapperStyle") || ++ bindings.getLocalName().equals("enableMIMEContent"))); + } + + private static Element[] getChildElements(Element parent) { + ArrayList a = new ArrayList(); + NodeList children = parent.getChildNodes(); +- for( int i=0; i + } + +- if( nlst.getLength()==0 ) { ++ if (nlst.getLength() == 0) { + reportError((Element) bindings, WsdlMessages.INTERNALIZER_X_PATH_EVALUATES_TO_NO_TARGET(expression)); + return null; // abort + } + +- if( nlst.getLength()!=1 ) { ++ if (nlst.getLength() != 1) { + reportError((Element) bindings, WsdlMessages.INTERNALIZER_X_PATH_EVAULATES_TO_TOO_MANY_TARGETS(expression, nlst.getLength())); + return null; // abort + } + + Node rnode = nlst.item(0); +- if(!(rnode instanceof Element )) { ++ if (!(rnode instanceof Element)) { + reportError((Element) bindings, WsdlMessages.INTERNALIZER_X_PATH_EVALUATES_TO_NON_ELEMENT(expression)); + return null; // abort + } +@@ -267,9 +286,9 @@ + /** + * Moves JAXWS customizations under their respective target nodes. + */ +- private void move( Element bindings, Map targetNodes ) { ++ private void move(Element bindings, Map targetNodes) { + Node target = targetNodes.get(bindings); +- if(target==null) ++ if (target == null) + // this must be the result of an error on the external binding. + // recover from the error by ignoring this node + return; +@@ -277,27 +296,27 @@ + Element[] children = DOMUtils.getChildElements(bindings); + + for (Element item : children) { +- if ("bindings".equals(item.getLocalName())){ +- // process child recursively ++ if ("bindings".equals(item.getLocalName())) { ++ // process child recursively + move(item, targetNodes); +- }else if(isGlobalBinding(item)){ ++ } else if (isGlobalBinding(item)) { + target = targetNodes.get(item); +- moveUnder(item,(Element)target); +- }else { ++ moveUnder(item, (Element) target); ++ } else { + if (!(target instanceof Element)) { + return; // abort + } + // move this node under the target +- moveUnder(item,(Element)target); ++ moveUnder(item, (Element) target); + } + } + } + +- private boolean isJAXBBindingElement(Element e){ ++ private boolean isJAXBBindingElement(Element e) { + return fixNull(e.getNamespaceURI()).equals(JAXWSBindingsConstants.NS_JAXB_BINDINGS); + } + +- private boolean isJAXWSBindingElement(Element e){ ++ private boolean isJAXWSBindingElement(Element e) { + return fixNull(e.getNamespaceURI()).equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS); + } + +@@ -304,25 +323,22 @@ + /** + * Moves the "decl" node under the "target" node. + * +- * @param decl +- * A JAXWS customization element (e.g., <JAXWS:class>) +- * +- * @param target +- * XML wsdl element under which the declaration should move. +- * For example, <xs:element> ++ * @param decl A JAXWS customization element (e.g., <JAXWS:class>) ++ * @param target XML wsdl element under which the declaration should move. ++ * For example, <xs:element> + */ +- private void moveUnder( Element decl, Element target ) { ++ private void moveUnder(Element decl, Element target) { + + //if there is @node on decl and has a child element jaxb:bindings, move it under the target + //Element jaxb = getJAXBBindingElement(decl); +- if(isJAXBBindingElement(decl)){ ++ if (isJAXBBindingElement(decl)) { + //add jaxb namespace declaration +- if(!target.hasAttributeNS(Constants.NS_XMLNS, "jaxb")){ ++ if (!target.hasAttributeNS(Constants.NS_XMLNS, "jaxb")) { + target.setAttributeNS(Constants.NS_XMLNS, "xmlns:jaxb", JAXWSBindingsConstants.NS_JAXB_BINDINGS); + } + + //add jaxb:bindings version info. Lets put it to 1.0, may need to change latter +- if(!target.hasAttributeNS(JAXWSBindingsConstants.NS_JAXB_BINDINGS, "version")){ ++ if (!target.hasAttributeNS(JAXWSBindingsConstants.NS_JAXB_BINDINGS, "version")) { + target.setAttributeNS(JAXWSBindingsConstants.NS_JAXB_BINDINGS, "jaxb:version", JAXWSBindingsConstants.JAXB_BINDING_VERSION); + } + +@@ -334,7 +350,7 @@ + // it can't support user-defined extensions. This needs more careful thought. + + //JAXB doesn't allow writing jaxb:extensionbindingPrefix anywhere other than root element so lets write only on +- if(target.getLocalName().equals("schema") && target.getNamespaceURI().equals(Constants.NS_XSD)&& !target.hasAttributeNS(JAXWSBindingsConstants.NS_JAXB_BINDINGS, "extensionBindingPrefixes")){ ++ if (target.getLocalName().equals("schema") && target.getNamespaceURI().equals(Constants.NS_XSD) && !target.hasAttributeNS(JAXWSBindingsConstants.NS_JAXB_BINDINGS, "extensionBindingPrefixes")) { + target.setAttributeNS(JAXWSBindingsConstants.NS_JAXB_BINDINGS, "jaxb:extensionBindingPrefixes", "xjc"); + target.setAttributeNS(Constants.NS_XMLNS, "xmlns:xjc", JAXWSBindingsConstants.NS_XJC_BINDINGS); + } +@@ -342,9 +358,9 @@ + //insert xs:annotation/xs:appinfo where in jaxb:binding will be put + target = refineSchemaTarget(target); + copyInscopeNSAttributes(decl); +- }else if(isJAXWSBindingElement(decl)){ ++ } else if (isJAXWSBindingElement(decl)) { + //add jaxb namespace declaration +- if(!target.hasAttributeNS(Constants.NS_XMLNS, "JAXWS")){ ++ if (!target.hasAttributeNS(Constants.NS_XMLNS, "JAXWS")) { + target.setAttributeNS(Constants.NS_XMLNS, "xmlns:JAXWS", JAXWSBindingsConstants.NS_JAXWS_BINDINGS); + } + +@@ -351,59 +367,59 @@ + //insert xs:annotation/xs:appinfo where in jaxb:binding will be put + target = refineWSDLTarget(target); + copyInscopeNSAttributes(decl); +- }else{ ++ } else { + return; + } + + // finally move the declaration to the target node. +- if( target.getOwnerDocument()!=decl.getOwnerDocument() ) { ++ if (target.getOwnerDocument() != decl.getOwnerDocument()) { + // if they belong to different DOM documents, we need to clone them +- decl = (Element)target.getOwnerDocument().importNode(decl,true); ++ decl = (Element) target.getOwnerDocument().importNode(decl, true); + + } + +- target.appendChild( decl ); ++ target.appendChild(decl); + } + + /** +- * Copy in-scope namespace declarations of the decl node +- * to the decl node itself so that this move won't change +- * the in-scope namespace bindings. ++ * Copy in-scope namespace declarations of the decl node ++ * to the decl node itself so that this move won't change ++ * the in-scope namespace bindings. + */ +- private void copyInscopeNSAttributes(Element e){ ++ private void copyInscopeNSAttributes(Element e) { + Element p = e; + Set inscopes = new HashSet(); +- while(true) { ++ while (true) { + NamedNodeMap atts = p.getAttributes(); +- for( int i=0; i mexWsdls = serviceDescriptor.getWSDLs(); + List mexSchemas = serviceDescriptor.getSchemas(); + Document root = null; +@@ -220,8 +232,8 @@ + } + } + NodeList nl = doc.getDocumentElement().getElementsByTagNameNS(WSDLConstants.NS_WSDL, "import"); +- if (nl.getLength() > 0) { +- Element imp = (Element) nl.item(0); ++ for(int i = 0; i < nl.getLength(); i++){ ++ Element imp = (Element) nl.item(i); + String loc = imp.getAttribute("location"); + if (loc != null) { + if (!externalReferences.contains(loc)) +@@ -247,6 +259,6 @@ + //TODO:handle SAXSource + //TODO:handler StreamSource + } +- return root; ++ return root.getDocumentElement(); + } + } +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/NamespaceContextImpl.java Tue Aug 4 09:30:24 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/NamespaceContextImpl.java Tue Aug 4 09:30:24 2009 +@@ -2,7 +2,7 @@ + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +-/* ++ /* + * Portions Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * +@@ -29,6 +29,22 @@ + * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC. + */ + ++/* ++ * Copyright 1999-2004 The Apache Software Foundation. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.xml.internal.bind.v2.WellKnownNamespace; +@@ -47,21 +63,6 @@ + this.e = e; + } + +- /* +- * Copyright 1999-2004 The Apache Software Foundation. +- * +- * Licensed under the Apache License, Version 2.0 (the "License"); +- * you may not use this file except in compliance with the License. +- * You may obtain a copy of the License at +- * +- * http://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, +- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- * See the License for the specific language governing permissions and +- * limitations under the License. +- */ + public String getNamespaceURI(String prefix) { + Node parent = e; + String namespace = null; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/VersionChecker.java Tue Aug 4 09:30:26 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/VersionChecker.java Tue Aug 4 09:30:26 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.tools.internal.ws.resources.WsdlMessages; +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/W3CAddressingExtensionHandler.java Tue Aug 4 09:30:28 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/W3CAddressingExtensionHandler.java Tue Aug 4 09:30:28 2009 +@@ -22,9 +22,6 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +-/* +- * $Id: W3CAddressingExtensionHandler.java,v 1.1.2.9 2007/02/06 00:33:38 kohsuke Exp $ +- */ + + package com.sun.tools.internal.ws.wsdl.parser; + +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/WSDLInternalizationLogic.java Tue Aug 4 09:30:31 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/WSDLInternalizationLogic.java Tue Aug 4 09:30:30 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.tools.internal.ws.wsdl.document.WSDLConstants; +@@ -56,9 +55,14 @@ + //TODO: add support for importing schema using wsdl:import + } + return atts.getValue("location"); +- }else if(SchemaConstants.NS_XSD.equals(nsURI) && "import".equals(localName)){ ++ } ++ /* ++ We don't need to do this anymore, JAXB handles the schema imports, includes etc. ++ ++ else if(SchemaConstants.NS_XSD.equals(nsURI) && "import".equals(localName)){ + return atts.getValue("schemaLocation"); + } ++ */ + return null; + } + } +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/WSDLParser.java Tue Aug 4 09:30:33 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/WSDLParser.java Tue Aug 4 09:30:32 2009 +@@ -29,9 +29,8 @@ + import com.sun.tools.internal.ws.api.wsdl.TWSDLExtensionHandler; + import com.sun.tools.internal.ws.resources.WsdlMessages; + import com.sun.tools.internal.ws.util.xml.XmlUtil; +-import com.sun.tools.internal.ws.wscompile.ErrorReceiver; +-import com.sun.tools.internal.ws.wscompile.WsimportOptions; + import com.sun.tools.internal.ws.wscompile.ErrorReceiverFilter; ++import com.sun.tools.internal.ws.wscompile.WsimportOptions; + import com.sun.tools.internal.ws.wsdl.document.Binding; + import com.sun.tools.internal.ws.wsdl.document.BindingFault; + import com.sun.tools.internal.ws.wsdl.document.BindingInput; +@@ -68,11 +67,11 @@ + import org.xml.sax.Locator; + import org.xml.sax.SAXException; + ++import java.io.IOException; + import java.util.ArrayList; + import java.util.HashMap; + import java.util.Iterator; + import java.util.Map; +-import java.io.IOException; + + /** + * A parser for WSDL documents. This parser is used only at the tool time. +@@ -135,7 +134,7 @@ + // parse external binding files + for (InputSource value : options.getWSDLBindings()) { + errReceiver.pollAbort(); +- Document root = forest.parse(value, true); // TODO: I think this should be false - KK ++ Document root = forest.parse(value, false); + if(root==null) continue; // error must have been reported + Element binding = root.getDocumentElement(); + if (!fixNull(binding.getNamespaceURI()).equals(JAXWSBindingsConstants.NS_JAXWS_BINDINGS) +@@ -168,7 +167,7 @@ + private WSDLDocument buildWSDLDocument(){ + /** + * Currently we are working off first WSDL document +- * TODO: add support of creating WSDLDocument from collection of WSDL documents ++ * TODO: add support of creating WSDLDocument from fromjava.collection of WSDL documents + */ + + String location = forest.getRootWSDL(); +--- old/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/WhitespaceStripper.java Tue Aug 4 09:30:35 2009 ++++ new/src/share/classes/com/sun/tools/internal/ws/wsdl/parser/WhitespaceStripper.java Tue Aug 4 09:30:35 2009 +@@ -24,7 +24,6 @@ + */ + + +- + package com.sun.tools.internal.ws.wsdl.parser; + + import com.sun.xml.internal.bind.WhiteSpaceProcessor; +--- old/src/share/classes/com/sun/tools/internal/xjc/Driver.java Tue Aug 4 09:30:37 2009 ++++ new/src/share/classes/com/sun/tools/internal/xjc/Driver.java Tue Aug 4 09:30:37 2009 +@@ -24,6 +24,7 @@ + */ + package com.sun.tools.internal.xjc; + ++import java.io.File; + import java.io.FileOutputStream; + import java.io.IOException; + import java.io.OutputStream; +@@ -101,7 +102,7 @@ + + private static void _main( String[] args ) throws Exception { + try { +- System.exit(run( args, System.err, System.out )); ++ System.exit(run( args, System.out, System.out )); + } catch (BadCommandLineException e) { + // there was an error in the command line. + // print usage and abort. +@@ -240,6 +241,8 @@ + listener.message(Messages.format(Messages.PARSING_SCHEMA)); + } + ++ final boolean[] hadWarning = new boolean[1]; ++ + ErrorReceiver receiver = new ErrorReceiverFilter(listener) { + public void info(SAXParseException exception) { + if(opt.verbose) +@@ -246,6 +249,7 @@ + super.info(exception); + } + public void warning(SAXParseException exception) { ++ hadWarning[0] = true; + if(!opt.quiet) + super.warning(exception); + } +@@ -367,6 +371,15 @@ + assert false; + } + ++ if(opt.debugMode) { ++ try { ++ new FileOutputStream(new File(opt.targetDir,hadWarning[0]?"hadWarning":"noWarning")).close(); ++ } catch (IOException e) { ++ receiver.error(e); ++ return -1; ++ } ++ } ++ + return 0; + } catch( StackOverflowError e ) { + if(opt.verbose) +--- old/src/share/classes/com/sun/tools/internal/xjc/Language.java Tue Aug 4 09:30:40 2009 ++++ new/src/share/classes/com/sun/tools/internal/xjc/Language.java Tue Aug 4 09:30:39 2009 +@@ -22,6 +22,7 @@ + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ ++ + package com.sun.tools.internal.xjc; + + /** +--- old/src/share/classes/com/sun/tools/internal/xjc/MessageBundle.properties Tue Aug 4 09:30:42 2009 ++++ new/src/share/classes/com/sun/tools/internal/xjc/MessageBundle.properties Tue Aug 4 09:30:41 2009 +@@ -24,20 +24,20 @@ + # + + ConsoleErrorReporter.UnknownLocation = \ +- unknown location +- ++ unknown location ++ + ConsoleErrorReporter.LineXOfY = \ +- \ \ line {0} of {1} ++ \ \ line {0} of {1} + + ConsoleErrorReporter.UnknownFile = \ +- unknown file +- ++ unknown file ++ + Driver.Private.Usage = \ + Usage: xjc [-options ...] ... [-b ] ...\n\ + If dir is specified, all schema files in it will be compiled.\n\ + If jar is specified, /META-INF/sun-jaxb.episode binding file will be compiled.\n\ + Options:\n\ +-\ \ -debug : run in the debug mode\n\ ++\ \ -debug : run in debug mode (includes -verbose)\n\ + \ \ -nv : do not perform strict validation of the input schema(s)\n\ + \ \ -extension : allow vendor extensions - do not strictly follow the\n\ + \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Compatibility Rules and App E.2 from the JAXB Spec\n\ +@@ -106,27 +106,30 @@ + Driver.AddonUsage = \nExtensions: + + Driver.ExperimentalLanguageWarning = \ +- Are you trying to compile {0}? Support for {0} is experimental. \ +- You may enable it by using the {1} option. ++ Are you trying to compile {0}? Support for {0} is experimental. \ ++ You may enable it by using the {1} option. + + Driver.NonExistentDir = \ + cowardly refuses to write to a non-existent directory "{0}" +- ++ + Driver.MissingRuntimePackageName = \ +- the -use-runtime option is missing a package name +- ++ the -use-runtime option is missing a package name ++ + Driver.MissingModeOperand = \ +- the -mode option is missing an operand +- ++ the -mode option is missing an operand ++ + Driver.MissingCompatibilityOperand = \ +- the -compatibility option is missing an operand ++ the -compatibility option is missing an operand + ++Driver.MissingOperand = \ ++ an operand is missing ++ + Driver.MissingProxyHost = \ +- either the -host option is missing an operand \n\ ++ either the -host option is missing an operand \n\ + or -port was specified but not -host +- ++ + Driver.MissingProxyPort = \ +- either the -port option is missing an operand \n\ ++ either the -port option is missing an operand \n\ + or -host was specified but not -port + + Driver.ILLEGAL_PROXY = \ +@@ -145,77 +148,80 @@ + "{0}" is not a valid proxy format. The format is [user[:password]@]proxyHost:proxyPort + + Driver.UnrecognizedMode = \ +- unrecognized mode {0} ++ unrecognized mode {0} + + Driver.UnrecognizedParameter = \ +- unrecognized parameter {0} +- ++ unrecognized parameter {0} ++ + Driver.MissingGrammar = \ +- grammar is not specified ++ grammar is not specified + + Driver.NotABindingFile = \ +- not an external binding file. The root element must be '{'http://java.sun.com/xml/ns/jaxb'}'bindings but it is '{'{0}'}'{1} +- ++ not an external binding file. The root element must be '{'http://java.sun.com/xml/ns/jaxb'}'bindings but it is '{'{0}'}'{1} ++ + Driver.ParsingSchema = \ +- parsing a schema... +- ++ parsing a schema... ++ + Driver.ParseFailed = \ +- Failed to parse a schema. ++ Failed to parse a schema. + + Driver.StackOverflow = \ +- Stack overflow. Either you are compiling a large schema that requires more resource, or \ +- XJC has a bug. First, please extend the stack size by using the -Xss JVM option. If this \ +- doesn'''t solve the problem, please use the -debug option to obtain the stack trace and \ +- contact Sun. +- ++ Stack overflow. Either you are compiling a large schema that requires more resources, or \ ++ XJC has a bug. First, please extend the stack size by using the -Xss JVM option. If this \ ++ doesn'''t solve the problem, please use the -debug option to obtain the stack trace and \ ++ contact Sun. ++ + Driver.CompilingSchema = \ +- compiling a schema... ++ compiling a schema... + + Driver.FailedToGenerateCode = \ +- Failed to produce code. ++ Failed to produce code. + +-# DO NOT localize the JAXB 2.1.3 in JDK string - it is a token for an ant ++# DO NOT localize the JAXB 2.1.10 string - it is a token for an ant + Driver.FilePrologComment = \ +- This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK \n\ +- See http://java.sun.com/xml/jaxb \n\ +- Any modifications to this file will be lost upon recompilation of the source schema. \n\ +- Generated on: {0} \n ++ This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 \n\ ++ See http://java.sun.com/xml/jaxb \n\ ++ Any modifications to this file will be lost upon recompilation of the source schema. \n\ ++ Generated on: {0} \n + + Driver.Version = \ +- xjc version "JAXB 2.1.3" \n\ +- JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.3 in JDK) ++ xjc version "JAXB 2.1.10" \n\ ++ JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build JAXB 2.1.10) + +-Driver.BuildID = JAXB 2.1.3 in JDK +- ++Driver.BuildID = JAXB 2.1.10 ++ ++# for JDK integration - include version in source zip ++jaxb.jdk.version=2.1.10 ++ + # see java.text.SimpleDateFormat for format syntax + Driver.DateFormat = \ +- yyyy.MM.dd ++ yyyy.MM.dd + + # see java.text.SimpleDateFormat for format syntax + Driver.TimeFormat = \ +- hh:mm:ss a z ++ hh:mm:ss a z + +-# as in: "generated on at