提交 2ea3abb0 编写于 作者: L lana

Merge

......@@ -86,3 +86,5 @@ b91ef6b60f4e19bf4592c6dd594c9bac62487519 jdk7-b106
ab0d3f54a63f2aadfcdd2e14b81f79362ce454e2 jdk7-b109
176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110
fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111
b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112
61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113
......@@ -31,7 +31,7 @@ BUILDDIR = ..
PRODUCT = demos
include $(BUILDDIR)/common/Defs.gmk
SUBDIRS = jni
SUBDIRS = jni nio
SUBDIRS_desktop = applets jfc
SUBDIRS_management = management
SUBDIRS_misc = scripting
......
#
# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for building the jfc demos
#
BUILDDIR = ../..
PRODUCT = demos
include $(BUILDDIR)/common/Defs.gmk
SUBDIRS = zipfs
include $(BUILDDIR)/common/Subdirs.gmk
all build clean clobber::
$(SUBDIRS-loop)
#
# Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile to build the ZipFileSystem demo.
#
BUILDDIR = ../../..
PRODUCT = demo/zipfs
DEMONAME = zipfs
include $(BUILDDIR)/common/Defs.gmk
DEMO_ROOT = $(SHARE_SRC)/demo/nio/$(DEMONAME)
DEMO_TOPFILES = ./README.txt
DEMO_SRCDIR = $(DEMO_ROOT)
DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME)
#
# Demo jar building rules.
#
include $(BUILDDIR)/common/Demo.gmk
......@@ -80,7 +80,12 @@ vpath %.c $(SHARE_SRC)/native/$(PKGDIR)
vpath %.c $(SHARE_SRC)/native/sun/java2d
ifeq ($(PLATFORM), windows)
OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt
OTHER_CFLAGS += -DCMS_IS_WINDOWS_
ifeq ($(COMPILER_VERSION), VS2003)
OTHER_CFLAGS += -Dsqrtf=sqrt
endif
OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib
OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \
-I$(SHARE_SRC)/native/sun/awt/debug
......
......@@ -1068,7 +1068,7 @@ public class Dialog extends Window {
modalityPushed();
try {
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
if (!secondaryLoop.enter()) {
secondaryLoop = null;
}
......
......@@ -142,6 +142,9 @@ public abstract class KeyboardFocusManager
public void removeLastFocusRequest(Component heavyweight) {
KeyboardFocusManager.removeLastFocusRequest(heavyweight);
}
public void setMostRecentFocusOwner(Window window, Component component) {
KeyboardFocusManager.setMostRecentFocusOwner(window, component);
}
}
);
}
......
......@@ -51,7 +51,7 @@ import java.awt.Event;
* in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
*
* @see ActionListener
* @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a>
* @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
*
* @author Carl Quinn
* @since 1.1
......
......@@ -937,14 +937,22 @@ public abstract class SampleModel
int iArray[], DataBuffer data) {
int pixels[];
int Offset=0;
int x1 = x + w;
int y1 = y + h;
if (x < 0 || x1 < x || x1 > width ||
y < 0 || y1 < y || y1 > height)
{
throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
}
if (iArray != null)
pixels = iArray;
else
pixels = new int[w * h];
for(int i=y; i<(h+y); i++) {
for (int j=x; j<(w+x); j++) {
for(int i=y; i<y1; i++) {
for (int j=x; j<x1; j++) {
pixels[Offset++] = getSample(j, i, b, data);
}
}
......@@ -978,14 +986,22 @@ public abstract class SampleModel
DataBuffer data) {
float pixels[];
int Offset=0;
int x1 = x + w;
int y1 = y + h;
if (x < 0 || x1 < x || x1 > width ||
y < 0 || y1 < y || y1 > height)
{
throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
}
if (fArray != null)
pixels = fArray;
else
pixels = new float[w * h];
for (int i=y; i<(h+y); i++) {
for (int j=x; j<(w+x); j++) {
for (int i=y; i<y1; i++) {
for (int j=x; j<x1; j++) {
pixels[Offset++] = getSampleFloat(j, i, b, data);
}
}
......@@ -1019,14 +1035,22 @@ public abstract class SampleModel
DataBuffer data) {
double pixels[];
int Offset=0;
int x1 = x + w;
int y1 = y + h;
if (x < 0 || x1 < x || x1 > width ||
y < 0 || y1 < y || y1 > height)
{
throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
}
if (dArray != null)
pixels = dArray;
else
pixels = new double[w * h];
for (int i=y; i<(y+h); i++) {
for (int j=x; j<(x+w); j++) {
for (int i=y; i<y1; i++) {
for (int j=x; j<x1; j++) {
pixels[Offset++] = getSampleDouble(j, i, b, data);
}
}
......
......@@ -176,8 +176,9 @@ public class EventSetDescriptor extends FeatureDescriptor {
setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
// Be more forgiving of not finding the getListener method.
if (getListenerMethodName != null) {
setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
if (method != null) {
setGetListenerMethod(method);
}
}
......
......@@ -189,11 +189,13 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor {
indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
}
}
indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
Class[] args = { int.class };
indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
if (indexedReadMethod == null) {
// no "is" method, so look for a "get" method.
indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
}
setIndexedReadMethod0(indexedReadMethod);
}
......@@ -265,7 +267,9 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor {
if (indexedWriteMethodName == null) {
indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
}
indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
Class[] args = (type == null) ? null : new Class[] { int.class, type };
indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
if (indexedWriteMethod != null) {
if (!indexedWriteMethod.getReturnType().equals(void.class)) {
indexedWriteMethod = null;
......
......@@ -28,7 +28,6 @@ package java.beans;
import com.sun.beans.WeakCache;
import com.sun.beans.finder.BeanInfoFinder;
import com.sun.beans.finder.ClassFinder;
import com.sun.beans.finder.MethodFinder;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
......@@ -843,8 +842,8 @@ public class Introspector {
Method read = result.getReadMethod();
if (read == null && write != null) {
read = findInstanceMethod(result.getClass0(),
GET_PREFIX + NameGenerator.capitalize(result.getName()));
read = findMethod(result.getClass0(),
GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
if (read != null) {
try {
result.setReadMethod(read);
......@@ -854,9 +853,9 @@ public class Introspector {
}
}
if (write == null && read != null) {
write = findInstanceMethod(result.getClass0(),
SET_PREFIX + NameGenerator.capitalize(result.getName()),
FeatureDescriptor.getReturnType(result.getClass0(), read));
write = findMethod(result.getClass0(),
SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
if (write != null) {
try {
result.setWriteMethod(write);
......@@ -1280,27 +1279,90 @@ public class Introspector {
// Package private support methods.
//======================================================================
static Method findMethod(Class<?> type, String name, int args) {
for (Method method : type.getMethods()) {
if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
try {
return MethodFinder.findAccessibleMethod(method);
/**
* Internal support for finding a target methodName with a given
* parameter list on a given class.
*/
private static Method internalFindMethod(Class start, String methodName,
int argCount, Class args[]) {
// For overriden methods we need to find the most derived version.
// So we start with the given class and walk up the superclass chain.
Method method = null;
for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
Method methods[] = getPublicDeclaredMethods(cl);
for (int i = 0; i < methods.length; i++) {
method = methods[i];
if (method == null) {
continue;
}
catch (NoSuchMethodException exception) {
// continue search for a method with the specified count of parameters
// make sure method signature matches.
Class params[] = FeatureDescriptor.getParameterTypes(start, method);
if (method.getName().equals(methodName) &&
params.length == argCount) {
if (args != null) {
boolean different = false;
if (argCount > 0) {
for (int j = 0; j < argCount; j++) {
if (params[j] != args[j]) {
different = true;
continue;
}
}
if (different) {
continue;
}
}
}
return method;
}
}
}
return null;
method = null;
// Now check any inherited interfaces. This is necessary both when
// the argument class is itself an interface, and when the argument
// class is an abstract class.
Class ifcs[] = start.getInterfaces();
for (int i = 0 ; i < ifcs.length; i++) {
// Note: The original implementation had both methods calling
// the 3 arg method. This is preserved but perhaps it should
// pass the args array instead of null.
method = internalFindMethod(ifcs[i], methodName, argCount, null);
if (method != null) {
break;
}
}
return method;
}
static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
try {
return MethodFinder.findInstanceMethod(type, name, args);
}
catch (NoSuchMethodException exception) {
/**
* Find a target methodName on a given class.
*/
static Method findMethod(Class cls, String methodName, int argCount) {
return findMethod(cls, methodName, argCount, null);
}
/**
* Find a target methodName with specific parameter list on a given class.
* <p>
* Used in the contructors of the EventSetDescriptor,
* PropertyDescriptor and the IndexedPropertyDescriptor.
* <p>
* @param cls The Class object on which to retrieve the method.
* @param methodName Name of the method.
* @param argCount Number of arguments for the desired method.
* @param args Array of argument types for the method.
* @return the method or null if not found
*/
static Method findMethod(Class cls, String methodName, int argCount,
Class args[]) {
if (methodName == null) {
return null;
}
return internalFindMethod(cls, methodName, argCount, args);
}
/**
......
......@@ -90,13 +90,13 @@ public class MethodDescriptor extends FeatureDescriptor {
// Find methods for up to 2 params. We are guessing here.
// This block should never execute unless the classloader
// that loaded the argument classes disappears.
method = Introspector.findMethod(cls, name, i);
method = Introspector.findMethod(cls, name, i, null);
if (method != null) {
break;
}
}
} else {
method = Statement.getMethod(cls, name, params);
method = Introspector.findMethod(cls, name, params.length, params);
}
setMethod(method);
}
......
......@@ -112,7 +112,8 @@ public class PropertyDescriptor extends FeatureDescriptor {
// If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method.
this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
Class[] args = { PropertyChangeListener.class };
this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
}
/**
......@@ -223,10 +224,10 @@ public class PropertyDescriptor extends FeatureDescriptor {
// property type is. For booleans, there can be "is" and "get"
// methods. If an "is" method exists, this is the official
// reader method so look for this one first.
readMethod = Introspector.findInstanceMethod(cls, readMethodName);
readMethod = Introspector.findMethod(cls, readMethodName, 0);
if (readMethod == null) {
readMethodName = Introspector.GET_PREFIX + getBaseName();
readMethod = Introspector.findInstanceMethod(cls, readMethodName);
readMethod = Introspector.findMethod(cls, readMethodName, 0);
}
try {
setReadMethod(readMethod);
......@@ -291,7 +292,8 @@ public class PropertyDescriptor extends FeatureDescriptor {
writeMethodName = Introspector.SET_PREFIX + getBaseName();
}
writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
Class[] args = (type == null) ? null : new Class[] { type };
writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
if (writeMethod != null) {
if (!writeMethod.getReturnType().equals(void.class)) {
writeMethod = null;
......
......@@ -569,6 +569,9 @@ public final class Locale implements Cloneable, Serializable {
* @exception NullPointerException thrown if any argument is null.
*/
public Locale(String language, String country, String variant) {
if (language== null || country == null || variant == null) {
throw new NullPointerException();
}
_baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
_extensions = getCompatibilityExtensions(language, "", country, variant);
}
......
......@@ -292,16 +292,6 @@ public abstract class ResourceBundle {
private static final ConcurrentMap<CacheKey, BundleReference> cacheList
= new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE);
/**
* This ConcurrentMap is used to keep multiple threads from loading the
* same bundle concurrently. The table entries are <CacheKey, Thread>
* where CacheKey is the key for the bundle that is under construction
* and Thread is the thread that is constructing the bundle.
* This list is manipulated in findBundleInCache and putBundleInCache.
*/
private static final ConcurrentMap<CacheKey, Thread> underConstruction
= new ConcurrentHashMap<CacheKey, Thread>();
/**
* Queue for reference objects referring to class loaders or bundles.
*/
......@@ -1381,7 +1371,7 @@ public abstract class ResourceBundle {
boolean expiredBundle = false;
// First, look up the cache to see if it's in the cache, without
// declaring beginLoading.
// attempting to load bundle.
cacheKey.setLocale(targetLocale);
ResourceBundle bundle = findBundleInCache(cacheKey, control);
if (isValidBundle(bundle)) {
......@@ -1408,56 +1398,25 @@ public abstract class ResourceBundle {
CacheKey constKey = (CacheKey) cacheKey.clone();
try {
// Try declaring loading. If beginLoading() returns true,
// then we can proceed. Otherwise, we need to take a look
// at the cache again to see if someone else has loaded
// the bundle and put it in the cache while we've been
// waiting for other loading work to complete.
while (!beginLoading(constKey)) {
bundle = findBundleInCache(cacheKey, control);
if (bundle == null) {
continue;
}
if (bundle == NONEXISTENT_BUNDLE) {
// If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist.
return parent;
}
expiredBundle = bundle.expired;
if (!expiredBundle) {
if (bundle.parent == parent) {
return bundle;
}
BundleReference bundleRef = cacheList.get(cacheKey);
if (bundleRef != null && bundleRef.get() == bundle) {
cacheList.remove(cacheKey, bundleRef);
}
bundle = loadBundle(cacheKey, formats, control, expiredBundle);
if (bundle != null) {
if (bundle.parent == null) {
bundle.setParent(parent);
}
bundle.locale = targetLocale;
bundle = putBundleInCache(cacheKey, bundle, control);
return bundle;
}
try {
bundle = loadBundle(cacheKey, formats, control, expiredBundle);
if (bundle != null) {
if (bundle.parent == null) {
bundle.setParent(parent);
}
bundle.locale = targetLocale;
bundle = putBundleInCache(cacheKey, bundle, control);
return bundle;
}
// Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
// instance for the locale.
putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
} finally {
endLoading(constKey);
}
// Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
// instance for the locale.
putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
} finally {
if (constKey.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
}
assert underConstruction.get(cacheKey) != Thread.currentThread();
return parent;
}
......@@ -1465,7 +1424,6 @@ public abstract class ResourceBundle {
List<String> formats,
Control control,
boolean reload) {
assert underConstruction.get(cacheKey) == Thread.currentThread();
// Here we actually load the bundle in the order of formats
// specified by the getFormats() value.
......@@ -1498,7 +1456,6 @@ public abstract class ResourceBundle {
break;
}
}
assert underConstruction.get(cacheKey) == Thread.currentThread();
return bundle;
}
......@@ -1529,57 +1486,6 @@ public abstract class ResourceBundle {
return true;
}
/**
* Declares the beginning of actual resource bundle loading. This method
* returns true if the declaration is successful and the current thread has
* been put in underConstruction. If someone else has already begun
* loading, this method waits until that loading work is complete and
* returns false.
*/
private static final boolean beginLoading(CacheKey constKey) {
Thread me = Thread.currentThread();
Thread worker;
// We need to declare by putting the current Thread (me) to
// underConstruction that we are working on loading the specified
// resource bundle. If we are already working the loading, it means
// that the resource loading requires a recursive call. In that case,
// we have to proceed. (4300693)
if (((worker = underConstruction.putIfAbsent(constKey, me)) == null)
|| worker == me) {
return true;
}
// If someone else is working on the loading, wait until
// the Thread finishes the bundle loading.
synchronized (worker) {
while (underConstruction.get(constKey) == worker) {
try {
worker.wait();
} catch (InterruptedException e) {
// record the interruption
constKey.setCause(e);
}
}
}
return false;
}
/**
* Declares the end of the bundle loading. This method calls notifyAll
* for those who are waiting for this completion.
*/
private static final void endLoading(CacheKey constKey) {
// Remove this Thread from the underConstruction map and wake up
// those who have been waiting for me to complete this bundle
// loading.
Thread me = Thread.currentThread();
assert (underConstruction.get(constKey) == me);
underConstruction.remove(constKey);
synchronized (me) {
me.notifyAll();
}
}
/**
* Throw a MissingResourceException with proper message
*/
......
......@@ -1464,8 +1464,8 @@ public class GroupLayout implements LayoutManager2 {
* &lt;= {@code pref} &lt;= {@code max}.
* <p>
* Similarly any methods that take a {@code Component} throw a
* {@code NullPointerException} if passed {@code null} and any methods
* that take a {@code Group} throw an {@code IllegalArgumentException} if
* {@code IllegalArgumentException} if passed {@code null} and any methods
* that take a {@code Group} throw an {@code NullPointerException} if
* passed {@code null}.
*
* @see #createSequentialGroup
......
......@@ -4787,6 +4787,17 @@ public abstract class JComponent extends Container implements Serializable,
* @see RepaintManager#addDirtyRegion
*/
public void repaint(long tm, int x, int y, int width, int height) {
Container p = this;
while ((p = p.getParent()) instanceof JComponent) {
JComponent jp = (JComponent) p;
if (jp.isPaintingOrigin()) {
Rectangle rectangle = SwingUtilities.convertRectangle(
this, new Rectangle(x, y, width, height), jp);
jp.repaint(tm,
rectangle.x, rectangle.y, rectangle.width, rectangle.height);
return;
}
}
RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
}
......
......@@ -215,7 +215,8 @@ public class JDesktopPane extends JLayeredPane implements Accessible
/**
* Sets the <code>DesktopManger</code> that will handle
* desktop-specific UI actions.
* desktop-specific UI actions. This may be overridden by
* {@code LookAndFeel}.
*
* @param d the <code>DesktopManager</code> to use
*
......
......@@ -25,17 +25,17 @@
package javax.swing;
import sun.awt.AWTAccessor;
import javax.swing.plaf.LayerUI;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.security.AccessController;
import java.security.PrivilegedAction;
......@@ -156,8 +156,6 @@ public final class JLayer<V extends Component>
private LayerUI<? super V> layerUI;
private JPanel glassPane;
private boolean isPainting;
private static final DefaultLayerLayout sharedLayoutInstance =
new DefaultLayerLayout();
private long eventMask;
private static final LayerEventController eventController =
......@@ -165,7 +163,7 @@ public final class JLayer<V extends Component>
/**
* Creates a new {@code JLayer} object with a {@code null} view component
* and {@code null} {@link javax.swing.plaf.LayerUI}.
* and default {@link javax.swing.plaf.LayerUI}.
*
* @see #setView
* @see #setUI
......@@ -176,14 +174,14 @@ public final class JLayer<V extends Component>
/**
* Creates a new {@code JLayer} object
* with {@code null} {@link javax.swing.plaf.LayerUI}.
* with default {@link javax.swing.plaf.LayerUI}.
*
* @param view the component to be decorated by this {@code JLayer}
*
* @see #setUI
*/
public JLayer(V view) {
this(view, null);
this(view, new LayerUI<V>());
}
/**
......@@ -195,7 +193,6 @@ public final class JLayer<V extends Component>
* to be used by this {@code JLayer}
*/
public JLayer(V view, LayerUI<V> ui) {
setLayout(sharedLayoutInstance);
setGlassPane(createGlassPane());
setView(view);
setUI(ui);
......@@ -279,10 +276,15 @@ public final class JLayer<V extends Component>
*/
public void setGlassPane(JPanel glassPane) {
Component oldGlassPane = getGlassPane();
boolean isGlassPaneVisible = false;
if (oldGlassPane != null) {
isGlassPaneVisible = oldGlassPane.isVisible();
super.remove(oldGlassPane);
}
if (glassPane != null) {
AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
new Rectangle());
glassPane.setVisible(isGlassPaneVisible);
super.addImpl(glassPane, null, 0);
}
this.glassPane = glassPane;
......@@ -302,6 +304,40 @@ public final class JLayer<V extends Component>
return new DefaultLayerGlassPane();
}
/**
* Sets the layout manager for this container. This method is
* overridden to prevent the layout manager from being set.
* <p/>Note: If {@code mgr} is non-{@code null}, this
* method will throw an exception as layout managers are not supported on
* a {@code JLayer}.
*
* @param mgr the specified layout manager
* @exception IllegalArgumentException this method is not supported
*/
public void setLayout(LayoutManager mgr) {
if (mgr != null) {
throw new IllegalArgumentException("JLayer.setLayout() not supported");
}
}
/**
* A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry
* of this component from becoming complex enough to inhibit
* subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border,
* add it to a {@code JPanel} that has a border.
* <p/>Note: If {@code border} is non-{@code null}, this
* method will throw an exception as borders are not supported on
* a {@code JLayer}.
*
* @param border the {@code Border} to set
* @exception IllegalArgumentException this method is not supported
*/
public void setBorder(Border border) {
if (border != null) {
throw new IllegalArgumentException("JLayer.setBorder() not supported");
}
}
/**
* This method is not supported by {@code JLayer}
* and always throws {@code UnsupportedOperationException}
......@@ -340,6 +376,32 @@ public final class JLayer<V extends Component>
setGlassPane(null);
}
/**
* Always returns {@code true} to cause painting to originate from {@code JLayer},
* or one of its ancestors.
*
* @return true
* @see JComponent#isPaintingOrigin()
*/
boolean isPaintingOrigin() {
return true;
}
/**
* Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
*
* @param tm this parameter is not used
* @param x the x value of the dirty region
* @param y the y value of the dirty region
* @param width the width of the dirty region
* @param height the height of the dirty region
*/
public void repaint(long tm, int x, int y, int width, int height) {
if (getUI() != null) {
getUI().repaint(tm, x, y, width, height, this);
}
}
/**
* Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
*
......@@ -364,14 +426,18 @@ public final class JLayer<V extends Component>
}
/**
* To enable the correct painting of the {@code glassPane} and view component,
* the {@code JLayer} overrides the default implementation of
* this method to return {@code false} when the {@code glassPane} is visible.
*
* @return false if {@code JLayer}'s {@code glassPane} is visible
* The {@code JLayer} overrides the default implementation of
* this method (in {@code JComponent}) to return {@code false}.
* This ensures
* that the drawing machinery will call the {@code JLayer}'s
* {@code paint}
* implementation rather than messaging the {@code JLayer}'s
* children directly.
*
* @return false
*/
public boolean isOptimizedDrawingEnabled() {
return glassPane == null || !glassPane.isVisible();
return false;
}
/**
......@@ -461,17 +527,16 @@ public final class JLayer<V extends Component>
/**
* Returns the preferred size of the viewport for a view component.
* <p/>
* If the ui delegate of this layer is not {@code null}, this method delegates its
* implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
* If the view component of this layer implements {@link Scrollable}, this method delegates its
* implementation to the view component.
*
* @return the preferred size of the viewport for a view component
*
* @see Scrollable
* @see LayerUI#getPreferredScrollableViewportSize(JLayer)
*/
public Dimension getPreferredScrollableViewportSize() {
if (getUI() != null) {
return getUI().getPreferredScrollableViewportSize(this);
if (getView() instanceof Scrollable) {
return ((Scrollable)getView()).getPreferredScrollableViewportSize();
}
return getPreferredSize();
}
......@@ -481,18 +546,17 @@ public final class JLayer<V extends Component>
* that display logical rows or columns in order to completely expose
* one block of rows or columns, depending on the value of orientation.
* <p/>
* If the ui delegate of this layer is not {@code null}, this method delegates its
* implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
* If the view component of this layer implements {@link Scrollable}, this method delegates its
* implementation to the view component.
*
* @return the "block" increment for scrolling in the specified direction
*
* @see Scrollable
* @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
*/
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation, int direction) {
if (getUI() != null) {
return getUI().getScrollableBlockIncrement(this, visibleRect,
if (getView() instanceof Scrollable) {
return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
orientation, direction);
}
return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
......@@ -504,17 +568,16 @@ public final class JLayer<V extends Component>
* determine the height of the layer, unless the preferred height
* of the layer is smaller than the height of the viewport.
* <p/>
* If the ui delegate of this layer is not null, this method delegates its
* implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
* If the view component of this layer implements {@link Scrollable}, this method delegates its
* implementation to the view component.
*
* @return whether the layer should track the height of the viewport
*
* @see Scrollable
* @see LayerUI#getScrollableTracksViewportHeight(JLayer)
*/
public boolean getScrollableTracksViewportHeight() {
if (getUI() != null) {
return getUI().getScrollableTracksViewportHeight(this);
if (getView() instanceof Scrollable) {
return ((Scrollable)getView()).getScrollableTracksViewportHeight();
}
return false;
}
......@@ -524,17 +587,16 @@ public final class JLayer<V extends Component>
* determine the width of the layer, unless the preferred width
* of the layer is smaller than the width of the viewport.
* <p/>
* If the ui delegate of this layer is not null, this method delegates its
* implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
* If the view component of this layer implements {@link Scrollable}, this method delegates its
* implementation to the view component.
*
* @return whether the layer should track the width of the viewport
*
* @see Scrollable
* @see LayerUI#getScrollableTracksViewportWidth(JLayer)
*/
public boolean getScrollableTracksViewportWidth() {
if (getUI() != null) {
return getUI().getScrollableTracksViewportWidth(this);
if (getView() instanceof Scrollable) {
return ((Scrollable)getView()).getScrollableTracksViewportWidth();
}
return false;
}
......@@ -549,20 +611,19 @@ public final class JLayer<V extends Component>
* Scrolling containers, like {@code JScrollPane}, will use this method
* each time the user requests a unit scroll.
* <p/>
* If the ui delegate of this layer is not {@code null}, this method delegates its
* implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
* If the view component of this layer implements {@link Scrollable}, this method delegates its
* implementation to the view component.
*
* @return The "unit" increment for scrolling in the specified direction.
* This value should always be positive.
*
* @see Scrollable
* @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
*/
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
int direction) {
if (getUI() != null) {
return getUI().getScrollableUnitIncrement(
this, visibleRect, orientation, direction);
if (getView() instanceof Scrollable) {
return ((Scrollable) getView()).getScrollableUnitIncrement(
visibleRect, orientation, direction);
}
return 1;
}
......@@ -594,6 +655,16 @@ public final class JLayer<V extends Component>
eventController.updateAWTEventListener(eventMask, 0);
}
/**
* Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
* if {@code LayerUI} is set.
*/
public void doLayout() {
if (getUI() != null) {
getUI().doLayout(this);
}
}
/**
* static AWTEventListener to be shared with all AbstractLayerUIs
*/
......@@ -625,8 +696,8 @@ public final class JLayer<V extends Component>
JLayer l = (JLayer) component;
LayerUI ui = l.getUI();
if (ui != null &&
isEventEnabled(l.getLayerEventMask(),
event.getID())) {
isEventEnabled(l.getLayerEventMask(), event.getID()) &&
(!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
ui.eventDispatched(event, l);
}
}
......@@ -758,82 +829,4 @@ public final class JLayer<V extends Component>
return super.contains(x, y);
}
}
/**
* The default layout manager for the {@link javax.swing.JLayer}.<br/>
* It places the glassPane on top of the view component
* and makes it the same size as {@code JLayer},
* it also makes the view component the same size but minus layer's insets<br/>
*/
private static class DefaultLayerLayout implements LayoutManager, Serializable {
/**
* {@inheritDoc}
*/
public void layoutContainer(Container parent) {
JLayer layer = (JLayer) parent;
Component view = layer.getView();
Component glassPane = layer.getGlassPane();
if (view != null) {
Insets insets = layer.getInsets();
view.setLocation(insets.left, insets.top);
view.setSize(layer.getWidth() - insets.left - insets.right,
layer.getHeight() - insets.top - insets.bottom);
}
if (glassPane != null) {
glassPane.setLocation(0, 0);
glassPane.setSize(layer.getWidth(), layer.getHeight());
}
}
/**
* {@inheritDoc}
*/
public Dimension minimumLayoutSize(Container parent) {
JLayer layer = (JLayer) parent;
Insets insets = layer.getInsets();
Dimension ret = new Dimension(insets.left + insets.right,
insets.top + insets.bottom);
Component view = layer.getView();
if (view != null) {
Dimension size = view.getMinimumSize();
ret.width += size.width;
ret.height += size.height;
}
if (ret.width == 0 || ret.height == 0) {
ret.width = ret.height = 4;
}
return ret;
}
/**
* {@inheritDoc}
*/
public Dimension preferredLayoutSize(Container parent) {
JLayer layer = (JLayer) parent;
Insets insets = layer.getInsets();
Dimension ret = new Dimension(insets.left + insets.right,
insets.top + insets.bottom);
Component view = layer.getView();
if (view != null) {
Dimension size = view.getPreferredSize();
if (size.width > 0 && size.height > 0) {
ret.width += size.width;
ret.height += size.height;
}
}
return ret;
}
/**
* {@inheritDoc}
*/
public void addLayoutComponent(String name, Component comp) {
}
/**
* {@inheritDoc}
*/
public void removeLayoutComponent(Component comp) {
}
}
}
......@@ -4574,9 +4574,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @see TableColumnModelListener
*/
public void columnMoved(TableColumnModelEvent e) {
// If I'm currently editing, then I should stop editing
if (isEditing()) {
removeEditor();
if (isEditing() && !getCellEditor().stopCellEditing()) {
getCellEditor().cancelCellEditing();
}
repaint();
}
......@@ -4593,8 +4592,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @see TableColumnModelListener
*/
public void columnMarginChanged(ChangeEvent e) {
if (isEditing()) {
removeEditor();
if (isEditing() && !getCellEditor().stopCellEditing()) {
getCellEditor().cancelCellEditing();
}
TableColumn resizingColumn = getResizingColumn();
// Need to do this here, before the parent's
......
......@@ -459,7 +459,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
if (insideComponent == null) {
// Drag exit
}
if (window != null && event.getSource() == window) {
if (window != null && event.getSource() == window && insideComponent != null) {
// if we get an exit and have a heavy window
// we need to check if it if overlapping the inside component
Container insideComponentWindow = insideComponent.getTopLevelAncestor();
......
......@@ -600,136 +600,124 @@ public class LayerUI<V extends Component>
}
/**
* Returns the preferred size of the viewport for a view component.
* If the {@code JLayer}'s view component is not {@code null},
* this calls the view's {@code getBaseline()} method.
* Otherwise, the default implementation is called.
*
* @param l the {@code JLayer} component where this UI delegate is being installed
* @return the preferred size of the viewport for a view component
* @see Scrollable#getPreferredScrollableViewportSize()
* @param c {@code JLayer} to return baseline resize behavior for
* @param width the width to get the baseline for
* @param height the height to get the baseline for
* @return baseline or a value &lt; 0 indicating there is no reasonable
* baseline
*/
public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
if (l.getView() instanceof Scrollable) {
return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
public int getBaseline(JComponent c, int width, int height) {
JLayer l = (JLayer) c;
if (l.getView() != null) {
return l.getView().getBaseline(width, height);
}
return l.getPreferredSize();
}
return super.getBaseline(c, width, height);
}
/**
* Returns a scroll increment, which is required for components
* that display logical rows or columns in order to completely expose
* one block of rows or columns, depending on the value of orientation.
* If the {@code JLayer}'s view component is not {@code null},
* this returns the result of the view's {@code getBaselineResizeBehavior()} method.
* Otherwise, the default implementation is called.
*
* @param l the {@code JLayer} component where this UI delegate is being installed
* @param visibleRect The view area visible within the viewport
* @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
* @param direction Less than zero to scroll up/left, greater than zero for down/right.
* @return the "block" increment for scrolling in the specified direction
* @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
* @param c {@code JLayer} to return baseline resize behavior for
* @return an enum indicating how the baseline changes as the component
* size changes
*/
public int getScrollableBlockIncrement(JLayer<? extends V> l,
Rectangle visibleRect,
int orientation, int direction) {
if (l.getView() instanceof Scrollable) {
return ((Scrollable)l.getView()).getScrollableBlockIncrement(
visibleRect,orientation, direction);
public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) {
JLayer l = (JLayer) c;
if (l.getView() != null) {
return l.getView().getBaselineResizeBehavior();
}
return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
visibleRect.width;
return super.getBaselineResizeBehavior(c);
}
/**
* Returns {@code false} to indicate that the height of the viewport does not
* determine the height of the layer, unless the preferred height
* of the layer is smaller than the height of the viewport.
* Causes the passed instance of {@code JLayer} to lay out its components.
*
* @param l the {@code JLayer} component where this UI delegate is being installed
* @return whether the layer should track the height of the viewport
* @see Scrollable#getScrollableTracksViewportHeight()
*/
public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
if (l.getView() instanceof Scrollable) {
return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
public void doLayout(JLayer<? extends V> l) {
Component view = l.getView();
if (view != null) {
view.setBounds(0, 0, l.getWidth(), l.getHeight());
}
Component glassPane = l.getGlassPane();
if (glassPane != null) {
glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
}
return false;
}
/**
* Returns {@code false} to indicate that the width of the viewport does not
* determine the width of the layer, unless the preferred width
* of the layer is smaller than the width of the viewport.
* If the {@code JLayer}'s view component is not {@code null},
* this returns the result of the view's {@code getPreferredSize()} method.
* Otherwise, the default implementation is used.
*
* @param l the {@code JLayer} component where this UI delegate is being installed
* @return whether the layer should track the width of the viewport
* @see Scrollable
* @see LayerUI#getScrollableTracksViewportWidth(JLayer)
* @param c {@code JLayer} to return preferred size for
* @return preferred size for the passed {@code JLayer}
*/
public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
if (l.getView() instanceof Scrollable) {
return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
public Dimension getPreferredSize(JComponent c) {
JLayer l = (JLayer) c;
Component view = l.getView();
if (view != null) {
return view.getPreferredSize();
}
return false;
return super.getPreferredSize(c);
}
/**
* Returns a scroll increment, which is required for components
* that display logical rows or columns in order to completely expose
* one new row or column, depending on the value of orientation.
* Ideally, components should handle a partially exposed row or column
* by returning the distance required to completely expose the item.
* <p>
* Scrolling containers, like JScrollPane, will use this method
* each time the user requests a unit scroll.
* If the {@code JLayer}'s view component is not {@code null},
* this returns the result of the view's {@code getMinimalSize()} method.
* Otherwise, the default implementation is used.
*
* @param l the {@code JLayer} component where this UI delegate is being installed
* @param visibleRect The view area visible within the viewport
* @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
* @param direction Less than zero to scroll up/left, greater than zero for down/right.
* @return The "unit" increment for scrolling in the specified direction.
* This value should always be positive.
* @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
* @param c {@code JLayer} to return preferred size for
* @return minimal size for the passed {@code JLayer}
*/
public int getScrollableUnitIncrement(JLayer<? extends V> l,
Rectangle visibleRect,
int orientation, int direction) {
if (l.getView() instanceof Scrollable) {
return ((Scrollable)l.getView()).getScrollableUnitIncrement(
visibleRect, orientation, direction);
public Dimension getMinimumSize(JComponent c) {
JLayer l = (JLayer) c;
Component view = l.getView();
if (view != null) {
return view.getMinimumSize();
}
return 1;
return super.getMinimumSize(c);
}
/**
* If the {@code JLayer}'s view component is not {@code null},
* this calls the view's {@code getBaseline()} method.
* Otherwise, the default implementation is called.
* this returns the result of the view's {@code getMaximumSize()} method.
* Otherwise, the default implementation is used.
*
* @param c {@code JLayer} to return baseline resize behavior for
* @param width the width to get the baseline for
* @param height the height to get the baseline for
* @return baseline or a value &lt; 0 indicating there is no reasonable
* baseline
* @param c {@code JLayer} to return preferred size for
* @return maximun size for the passed {@code JLayer}
*/
public int getBaseline(JComponent c, int width, int height) {
public Dimension getMaximumSize(JComponent c) {
JLayer l = (JLayer) c;
if (l.getView() != null) {
return l.getView().getBaseline(width, height);
Component view = l.getView();
if (view != null) {
return view.getMaximumSize();
}
return super.getBaseline(c, width, height);
}
return super.getMaximumSize(c);
}
/**
* If the {@code JLayer}'s view component is not {@code null},
* this calls the view's {@code getBaselineResizeBehavior()} method.
* Otherwise, the default implementation is called.
*
* @param c {@code JLayer} to return baseline resize behavior for
* @return an enum indicating how the baseline changes as the component
* size changes
* Adds the specified region to the dirty region list if the component
* is showing. The component will be repainted after all of the
* currently pending events have been dispatched.
* <p/>
* This method is to be overridden when the dirty region needs to be changed.
*
* @param tm this parameter is not used
* @param x the x value of the dirty region
* @param y the y value of the dirty region
* @param width the width of the dirty region
* @param height the height of the dirty region
* @see java.awt.Component#isShowing
* @see RepaintManager#addDirtyRegion
*/
public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) {
JLayer l = (JLayer) c;
if (l.getView() != null) {
return l.getView().getBaselineResizeBehavior();
}
return super.getBaselineResizeBehavior(c);
public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
}
}
......@@ -1603,6 +1603,7 @@ public class BasicScrollBarUI
BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
oldModel.removeChangeListener(modelListener);
newModel.addChangeListener(modelListener);
scrollBarValue = scrollbar.getValue();
scrollbar.repaint();
scrollbar.revalidate();
} else if ("orientation" == propertyName) {
......
......@@ -144,7 +144,7 @@ public class MetalComboBoxUI extends BasicComboBoxUI {
*/
public int getBaseline(JComponent c, int width, int height) {
int baseline;
if (MetalLookAndFeel.usingOcean()) {
if (MetalLookAndFeel.usingOcean() && height >= 4) {
height -= 4;
baseline = super.getBaseline(c, width, height);
if (baseline >= 0) {
......
......@@ -115,6 +115,9 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI
return new SynthTabbedPaneUI();
}
private SynthTabbedPaneUI() {
}
private boolean scrollableTabLayoutEnabled() {
return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
}
......
......@@ -344,6 +344,11 @@ public final class AWTAccessor {
* Removes the last focus request for the heavyweight from the queue.
*/
void removeLastFocusRequest(Component heavyweight);
/*
* Sets the most recent focus owner in the window.
*/
void setMostRecentFocusOwner(Window window, Component component);
}
/*
......
......@@ -70,7 +70,10 @@ public abstract class EmbeddedFrame extends Frame
// JDK 1.1 compatibility
private static final long serialVersionUID = 2967042741780317130L;
// Use these in traverseOut method to determine directions
/*
* The constants define focus traversal directions.
* Use them in {@code traverseIn}, {@code traverseOut} methods.
*/
protected static final boolean FORWARD = true;
protected static final boolean BACKWARD = false;
......@@ -283,6 +286,41 @@ public abstract class EmbeddedFrame extends Frame
return false;
}
/**
* This method is called by the embedder when we should receive focus as element
* of the traversal chain. The method requests focus on:
* 1. the first Component of this EmbeddedFrame if user moves focus forward
* in the focus traversal cycle.
* 2. the last Component of this EmbeddedFrame if user moves focus backward
* in the focus traversal cycle.
*
* The direction parameter specifies which of the two mentioned cases is
* happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
* to avoid confusing boolean values.
*
* A concrete implementation of this method is defined in the platform-dependent
* subclasses.
*
* @param direction FORWARD or BACKWARD
* @return true, if the EmbeddedFrame wants to get focus, false otherwise.
*/
public boolean traverseIn(boolean direction) {
Component comp = null;
if (direction == FORWARD) {
comp = getFocusTraversalPolicy().getFirstComponent(this);
} else {
comp = getFocusTraversalPolicy().getLastComponent(this);
}
if (comp != null) {
// comp.requestFocus(); - Leads to a hung.
AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
synthesizeWindowActivation(true);
}
return (null != comp);
}
/**
* This method is called from dispatchKeyEvent in the following two cases:
* 1. The focus is on the first Component of this EmbeddedFrame and we are
......
......@@ -64,12 +64,14 @@ public final class BaseLocale {
public static BaseLocale getInstance(String language, String script, String region, String variant) {
// JDK uses deprecated ISO639.1 language codes for he, yi and id
if (AsciiUtil.caseIgnoreMatch(language, "he")) {
language = "iw";
} else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
language = "ji";
} else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
language = "in";
if (language != null) {
if (AsciiUtil.caseIgnoreMatch(language, "he")) {
language = "iw";
} else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
language = "ji";
} else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
language = "in";
}
}
Key key = new Key(language, script, region, variant);
......
此差异已折叠。
com.sun.nio.zipfs.ZipFileSystemProvider
com.sun.nio.zipfs.JarFileSystemProvider
ZipFileSystem is a file system provider that treats the contents of a zip or
JAR file as a java.nio.file.FileSystem.
To deploy the provider you must copy zipfs.jar into your extensions
directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
to your class path.
The factory methods defined by the java.nio.file.FileSystems class can be
used to create a FileSystem, eg:
// use file type detection
Map<String,?> env = Collections.emptyMap();
Path jarfile = Path.get("foo.jar");
FileSystem fs = FileSystems.newFileSystem(jarfile, env);
-or
// locate file system by URI
Map<String,?> env = Collections.emptyMap();
URI uri = URI.create("zip:///mydir/foo.jar");
FileSystem fs = FileSystems.newFileSystem(uri, env);
Once a FileSystem is created then classes in the java.nio.file package
can be used to access files in the zip/JAR file, eg:
Path mf = fs.getPath("/META-INF/MANIFEST.MF");
InputStream in = mf.newInputStream();
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.nio.file.*;
import java.nio.file.spi.*;
import java.nio.file.attribute.*;
import java.nio.file.spi.FileSystemProvider;
import java.net.URI;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class JarFileSystemProvider extends ZipFileSystemProvider
{
@Override
public String getScheme() {
return "jar";
}
@Override
protected Path uriToPath(URI uri) {
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
}
try {
String uristr = uri.toString();
int end = uristr.indexOf("!/");
uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
uri = new URI(uristr);
return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
.toAbsolutePath();
} catch (URISyntaxException e) {
throw new AssertionError(e); //never thrown
}
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.util.Arrays;
/**
* Utility class for zipfile name and comment decoding and encoding
*
* @author Xueming Shen
*/
final class ZipCoder {
String toString(byte[] ba, int length) {
CharsetDecoder cd = decoder().reset();
int len = (int)(length * cd.maxCharsPerByte());
char[] ca = new char[len];
if (len == 0)
return new String(ca);
ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
CharBuffer cb = CharBuffer.wrap(ca);
CoderResult cr = cd.decode(bb, cb, true);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
cr = cd.flush(cb);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
return new String(ca, 0, cb.position());
}
String toString(byte[] ba) {
return toString(ba, ba.length);
}
byte[] getBytes(String s) {
CharsetEncoder ce = encoder().reset();
char[] ca = s.toCharArray();
int len = (int)(ca.length * ce.maxBytesPerChar());
byte[] ba = new byte[len];
if (len == 0)
return ba;
ByteBuffer bb = ByteBuffer.wrap(ba);
CharBuffer cb = CharBuffer.wrap(ca);
CoderResult cr = ce.encode(cb, bb, true);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
cr = ce.flush(bb);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
if (bb.position() == ba.length) // defensive copy?
return ba;
else
return Arrays.copyOf(ba, bb.position());
}
// assume invoked only if "this" is not utf8
byte[] getBytesUTF8(String s) {
if (isutf8)
return getBytes(s);
if (utf8 == null)
utf8 = new ZipCoder(Charset.forName("UTF-8"));
return utf8.getBytes(s);
}
String toStringUTF8(byte[] ba, int len) {
if (isutf8)
return toString(ba, len);
if (utf8 == null)
utf8 = new ZipCoder(Charset.forName("UTF-8"));
return utf8.toString(ba, len);
}
boolean isUTF8() {
return isutf8;
}
private Charset cs;
private boolean isutf8;
private ZipCoder utf8;
private ZipCoder(Charset cs) {
this.cs = cs;
this.isutf8 = cs.name().equals("UTF-8");
}
static ZipCoder get(Charset charset) {
return new ZipCoder(charset);
}
static ZipCoder get(String csn) {
try {
return new ZipCoder(Charset.forName(csn));
} catch (Throwable t) {
t.printStackTrace();
}
return new ZipCoder(Charset.defaultCharset());
}
private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
private CharsetDecoder decoder() {
CharsetDecoder dec = decTL.get();
if (dec == null) {
dec = cs.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
decTL.set(dec);
}
return dec;
}
private CharsetEncoder encoder() {
CharsetEncoder enc = encTL.get();
if (enc == null) {
enc = cs.newEncoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
encTL.set(enc);
}
return enc;
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.nio.ByteBuffer;
/**
*
* @author Xueming Shen
*/
class ZipConstants {
/*
* Compression methods
*/
static final int METHOD_STORED = 0;
static final int METHOD_DEFLATED = 8;
static final int METHOD_DEFLATED64 = 9;
static final int METHOD_BZIP2 = 12;
static final int METHOD_LZMA = 14;
static final int METHOD_LZ77 = 19;
/*
* General purpose big flag
*/
static final int FLAG_ENCRYPTED = 0x01;
static final int FLAG_DATADESCR = 0x08; // crc, size and csize in dd
static final int FLAG_EFS = 0x800; // If this bit is set the filename and
// comment fields for this file must be
// encoded using UTF-8.
/*
* Header signatures
*/
static long LOCSIG = 0x04034b50L; // "PK\003\004"
static long EXTSIG = 0x08074b50L; // "PK\007\008"
static long CENSIG = 0x02014b50L; // "PK\001\002"
static long ENDSIG = 0x06054b50L; // "PK\005\006"
/*
* Header sizes in bytes (including signatures)
*/
static final int LOCHDR = 30; // LOC header size
static final int EXTHDR = 16; // EXT header size
static final int CENHDR = 46; // CEN header size
static final int ENDHDR = 22; // END header size
/*
* Local file (LOC) header field offsets
*/
static final int LOCVER = 4; // version needed to extract
static final int LOCFLG = 6; // general purpose bit flag
static final int LOCHOW = 8; // compression method
static final int LOCTIM = 10; // modification time
static final int LOCCRC = 14; // uncompressed file crc-32 value
static final int LOCSIZ = 18; // compressed size
static final int LOCLEN = 22; // uncompressed size
static final int LOCNAM = 26; // filename length
static final int LOCEXT = 28; // extra field length
/*
* Extra local (EXT) header field offsets
*/
static final int EXTCRC = 4; // uncompressed file crc-32 value
static final int EXTSIZ = 8; // compressed size
static final int EXTLEN = 12; // uncompressed size
/*
* Central directory (CEN) header field offsets
*/
static final int CENVEM = 4; // version made by
static final int CENVER = 6; // version needed to extract
static final int CENFLG = 8; // encrypt, decrypt flags
static final int CENHOW = 10; // compression method
static final int CENTIM = 12; // modification time
static final int CENCRC = 16; // uncompressed file crc-32 value
static final int CENSIZ = 20; // compressed size
static final int CENLEN = 24; // uncompressed size
static final int CENNAM = 28; // filename length
static final int CENEXT = 30; // extra field length
static final int CENCOM = 32; // comment length
static final int CENDSK = 34; // disk number start
static final int CENATT = 36; // internal file attributes
static final int CENATX = 38; // external file attributes
static final int CENOFF = 42; // LOC header offset
/*
* End of central directory (END) header field offsets
*/
static final int ENDSUB = 8; // number of entries on this disk
static final int ENDTOT = 10; // total number of entries
static final int ENDSIZ = 12; // central directory size in bytes
static final int ENDOFF = 16; // offset of first CEN header
static final int ENDCOM = 20; // zip file comment length
/*
* ZIP64 constants
*/
static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
static final int ZIP64_EXTHDR = 24; // EXT header size
static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
static final int ZIP64_MINVAL32 = 0xFFFF;
static final long ZIP64_MINVAL = 0xFFFFFFFFL;
/*
* Zip64 End of central directory (END) header field offsets
*/
static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
static final int ZIP64_ENDVEM = 12; // version made by
static final int ZIP64_ENDVER = 14; // version needed to extract
static final int ZIP64_ENDNMD = 16; // number of this disk
static final int ZIP64_ENDDSK = 20; // disk number of start
static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
static final int ZIP64_ENDTOT = 32; // total number of entries
static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
static final int ZIP64_ENDOFF = 48; // offset of first CEN header
static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
/*
* Zip64 End of central directory locator field offsets
*/
static final int ZIP64_LOCDSK = 4; // disk number start
static final int ZIP64_LOCOFF = 8; // offset of zip64 end
static final int ZIP64_LOCTOT = 16; // total number of disks
/*
* Zip64 Extra local (EXT) header field offsets
*/
static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
/*
* Extra field header ID
*/
static final int EXTID_ZIP64 = 0x0001; // ZIP64
static final int EXTID_NTFS = 0x000a; // NTFS
static final int EXTID_UNIX = 0x000d; // UNIX
/*
* fields access methods
*/
///////////////////////////////////////////////////////
static final int CH(byte[] b, int n) {
return b[n] & 0xff;
}
static final int SH(byte[] b, int n) {
return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
}
static final long LG(byte[] b, int n) {
return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
}
static final long LL(byte[] b, int n) {
return (LG(b, n)) | (LG(b, n + 4) << 32);
}
static final long GETSIG(byte[] b) {
return LG(b, 0);
}
// local file (LOC) header fields
static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method
static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length
static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
// extra local (EXT) header fields
static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data
static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size
static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
// end of central directory header (END) fields
static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk
static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries
static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size
static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset
static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment
static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
// zip64 end of central directory recoder fields
static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk
static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries
static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size
static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset
static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset
//////////////////////////////////////////
static final int CH(ByteBuffer b, int pos) {
return b.get(pos) & 0xff;
}
static final int SH(ByteBuffer b, int pos) {
return b.getShort(pos) & 0xffff;
}
static final long LG(ByteBuffer b, int pos) {
return b.getInt(pos) & 0xffffffffL;
}
// central directory header (END) fields
static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
static final int CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
static final int CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
static final int CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
static final int CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
static final int CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
static final int CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
static final int CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
static final int CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
static final int CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
/* The END header is followed by a variable length comment of size < 64k. */
static final long END_MAXLEN = 0xFFFF + ENDHDR;
static final int READBLOCKSZ = 128;
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.nio.file.DirectoryStream;
import java.nio.file.ClosedDirectoryStreamException;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.io.IOException;
import static com.sun.nio.zipfs.ZipUtils.*;
/**
*
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
*/
public class ZipDirectoryStream implements DirectoryStream<Path> {
private final ZipFileSystem zipfs;
private final byte[] path;
private final DirectoryStream.Filter<? super Path> filter;
private volatile boolean isClosed;
private volatile Iterator<Path> itr;
ZipDirectoryStream(ZipPath zipPath,
DirectoryStream.Filter<? super java.nio.file.Path> filter)
throws IOException
{
this.zipfs = zipPath.getFileSystem();
this.path = zipPath.getResolvedPath();
this.filter = filter;
// sanity check
if (!zipfs.isDirectory(path))
throw new NotDirectoryException(zipPath.toString());
}
@Override
public synchronized Iterator<Path> iterator() {
if (isClosed)
throw new ClosedDirectoryStreamException();
if (itr != null)
throw new IllegalStateException("Iterator has already been returned");
try {
itr = zipfs.iteratorOf(path, filter);
} catch (IOException e) {
throw new IllegalStateException(e);
}
return new Iterator<Path>() {
private Path next;
@Override
public boolean hasNext() {
if (isClosed)
return false;
return itr.hasNext();
}
@Override
public synchronized Path next() {
if (isClosed)
throw new NoSuchElementException();
return itr.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public synchronized void close() throws IOException {
isClosed = true;
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.nio.file.ReadOnlyFileSystemException;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.io.IOException;
import java.util.LinkedHashMap;
/*
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
*/
public class ZipFileAttributeView implements BasicFileAttributeView
{
private static enum AttrID {
size,
creationTime,
lastAccessTime,
lastModifiedTime,
isDirectory,
isRegularFile,
isSymbolicLink,
isOther,
fileKey,
compressedSize,
crc,
method
};
private final ZipPath path;
private final boolean isZipView;
private ZipFileAttributeView(ZipPath path, boolean isZipView) {
this.path = path;
this.isZipView = isZipView;
}
static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
if (type == null)
throw new NullPointerException();
if (type == BasicFileAttributeView.class)
return (V)new ZipFileAttributeView(path, false);
if (type == ZipFileAttributeView.class)
return (V)new ZipFileAttributeView(path, true);
return null;
}
static ZipFileAttributeView get(ZipPath path, String type) {
if (type == null)
throw new NullPointerException();
if (type.equals("basic"))
return new ZipFileAttributeView(path, false);
if (type.equals("zip"))
return new ZipFileAttributeView(path, true);
return null;
}
@Override
public String name() {
return isZipView ? "zip" : "basic";
}
public ZipFileAttributes readAttributes() throws IOException
{
return path.getAttributes();
}
@Override
public void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
FileTime createTime)
throws IOException
{
path.setTimes(lastModifiedTime, lastAccessTime, createTime);
}
void setAttribute(String attribute, Object value)
throws IOException
{
try {
if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
setTimes ((FileTime)value, null, null);
return;
} catch (IllegalArgumentException x) {}
throw new UnsupportedOperationException("'" + attribute +
"' is unknown or read-only attribute");
}
public Object getAttribute(String attribute, boolean domap)
throws IOException
{
ZipFileAttributes zfas = readAttributes();
if (!domap) {
try {
return attribute(AttrID.valueOf(attribute), zfas);
} catch (IllegalArgumentException x) {}
return null;
}
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
if ("*".equals(attribute)) {
for (AttrID id : AttrID.values()) {
try {
map.put(id.name(), attribute(id, zfas));
} catch (IllegalArgumentException x) {}
}
} else {
String[] as = attribute.split(",");
for (String a : as) {
try {
map.put(a, attribute(AttrID.valueOf(a), zfas));
} catch (IllegalArgumentException x) {}
}
}
return map;
}
Object attribute(AttrID id, ZipFileAttributes zfas) {
switch (id) {
case size:
return zfas.size();
case creationTime:
return zfas.creationTime();
case lastAccessTime:
return zfas.lastAccessTime();
case lastModifiedTime:
return zfas.lastModifiedTime();
case isDirectory:
return zfas.isDirectory();
case isRegularFile:
return zfas.isRegularFile();
case isSymbolicLink:
return zfas.isSymbolicLink();
case isOther:
return zfas.isOther();
case fileKey:
return zfas.fileKey();
case compressedSize:
if (isZipView)
return zfas.compressedSize();
break;
case crc:
if (isZipView)
return zfas.crc();
break;
case method:
if (isZipView)
return zfas.method();
break;
}
return null;
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.Arrays;
import java.util.Formatter;
import static com.sun.nio.zipfs.ZipUtils.*;
/**
*
* @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
*/
public class ZipFileAttributes implements BasicFileAttributes
{
private final ZipFileSystem.Entry e;
ZipFileAttributes(ZipFileSystem.Entry e) {
this.e = e;
}
///////// basic attributes ///////////
@Override
public FileTime creationTime() {
if (e.ctime != -1)
return FileTime.fromMillis(dosToJavaTime(e.ctime));
return null;
}
@Override
public boolean isDirectory() {
return e.isDir();
}
@Override
public boolean isOther() {
return false;
}
@Override
public boolean isRegularFile() {
return !e.isDir();
}
@Override
public FileTime lastAccessTime() {
if (e.atime != -1)
return FileTime.fromMillis(dosToJavaTime(e.atime));
return null;
}
@Override
public FileTime lastModifiedTime() {
return FileTime.fromMillis(dosToJavaTime(e.mtime));
}
@Override
public long size() {
return e.size;
}
@Override
public boolean isSymbolicLink() {
return false;
}
@Override
public Object fileKey() {
return null;
}
///////// zip entry attributes ///////////
public byte[] name() {
return Arrays.copyOf(e.name, e.name.length);
}
public long compressedSize() {
return e.csize;
}
public long crc() {
return e.crc;
}
public int method() {
return e.method;
}
public byte[] extra() {
if (e.extra != null)
return Arrays.copyOf(e.extra, e.extra.length);
return null;
}
public byte[] comment() {
if (e.comment != null)
return Arrays.copyOf(e.comment, e.comment.length);
return null;
}
public String toString() {
StringBuilder sb = new StringBuilder();
Formatter fm = new Formatter(sb);
fm.format("[/%s]%n", new String(e.name)); // TBD encoding
fm.format(" creationTime : %s%n", creationTime());
if (lastAccessTime() != null)
fm.format(" lastAccessTime : %tc%n", lastAccessTime().toMillis());
else
fm.format(" lastAccessTime : null%n");
fm.format(" lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
fm.format(" isRegularFile : %b%n", isRegularFile());
fm.format(" isDirectory : %b%n", isDirectory());
fm.format(" isSymbolicLink : %b%n", isSymbolicLink());
fm.format(" isOther : %b%n", isOther());
fm.format(" fileKey : %s%n", fileKey());
fm.format(" size : %d%n", size());
fm.format(" compressedSize : %d%n", compressedSize());
fm.format(" crc : %x%n", crc());
fm.format(" method : %d%n", method());
fm.close();
return sb.toString();
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileStoreAttributeView;
import java.nio.file.attribute.FileStoreSpaceAttributeView;
import java.nio.file.attribute.FileStoreSpaceAttributes;
import java.nio.file.attribute.Attributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.util.Formatter;
/*
*
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
*/
public class ZipFileStore extends FileStore {
private final ZipFileSystem zfs;
ZipFileStore(ZipPath zpath) {
this.zfs = (ZipFileSystem)zpath.getFileSystem();
}
@Override
public String name() {
return zfs.toString() + "/";
}
@Override
public String type() {
return "zipfs";
}
@Override
public boolean isReadOnly() {
return zfs.isReadOnly();
}
@Override
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
return (type == BasicFileAttributeView.class ||
type == ZipFileAttributeView.class);
}
@Override
public boolean supportsFileAttributeView(String name) {
return name.equals("basic") || name.equals("zip");
}
@Override
@SuppressWarnings("unchecked")
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
if (type == FileStoreSpaceAttributeView.class)
return (V) new ZipFileStoreAttributeView(this);
return null;
}
@Override
public Object getAttribute(String attribute) throws IOException {
if (attribute.equals("space:totalSpace"))
return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
if (attribute.equals("space:usableSpace"))
return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
if (attribute.equals("space:unallocatedSpace"))
return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
throw new UnsupportedOperationException("does not support the given attribute");
}
private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
private final ZipFileStore fileStore;
public ZipFileStoreAttributeView(ZipFileStore fileStore) {
this.fileStore = fileStore;
}
@Override
public String name() {
return "space";
}
@Override
public FileStoreSpaceAttributes readAttributes() throws IOException {
final String file = fileStore.name();
Path path = FileSystems.getDefault().getPath(file);
final long size = Attributes.readBasicFileAttributes(path).size();
final FileStore fstore = path.getFileStore();
final FileStoreSpaceAttributes fstoreAttrs =
Attributes.readFileStoreSpaceAttributes(fstore);
return new FileStoreSpaceAttributes() {
public long totalSpace() {
return size;
}
public long usableSpace() {
if (!fstore.isReadOnly())
return fstoreAttrs.usableSpace();
return 0;
}
public long unallocatedSpace() {
if (!fstore.isReadOnly())
return fstoreAttrs.unallocatedSpace();
return 0;
}
public String toString() {
StringBuilder sb = new StringBuilder();
Formatter fm = new Formatter(sb);
fm.format("FileStoreSpaceAttributes[%s]%n", file);
fm.format(" totalSpace: %d%n", totalSpace());
fm.format(" usableSpace: %d%n", usableSpace());
fm.format(" unallocSpace: %d%n", unallocatedSpace());
fm.close();
return sb.toString();
}
};
}
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.FileRef;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderMismatchException;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.spi.FileSystemProvider;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
*
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
*/
public class ZipFileSystemProvider extends FileSystemProvider {
private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
public ZipFileSystemProvider() {}
@Override
public String getScheme() {
return "zip";
}
protected Path uriToPath(URI uri) {
String scheme = uri.getScheme();
if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
}
try {
return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
.toAbsolutePath();
} catch (URISyntaxException e) {
throw new AssertionError(e); //never thrown
}
}
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env)
throws IOException
{
return newFileSystem(uriToPath(uri), env);
}
@Override
public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
throws IOException
{
if (!(file instanceof Path))
throw new UnsupportedOperationException();
Path path = (Path)file;
if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
throw new UnsupportedOperationException();
}
return newFileSystem(path, env);
}
private FileSystem newFileSystem(Path path, Map<String, ?> env)
throws IOException
{
synchronized(filesystems) {
if (filesystems.containsKey(path))
throw new FileSystemAlreadyExistsException();
ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
filesystems.put(path, zipfs);
return zipfs;
}
}
@Override
public Path getPath(URI uri) {
FileSystem fs = getFileSystem(uri);
String fragment = uri.getFragment();
if (fragment == null) {
throw new IllegalArgumentException("URI: "
+ uri
+ " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
}
return fs.getPath(fragment);
}
@Override
public FileChannel newFileChannel(Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs)
throws IOException
{
if (path == null)
throw new NullPointerException("path is null");
if (path instanceof ZipPath)
return ((ZipPath)path).newFileChannel(options, attrs);
throw new ProviderMismatchException();
}
@Override
public FileSystem getFileSystem(URI uri) {
synchronized (filesystems) {
ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
if (zipfs == null)
throw new FileSystemNotFoundException();
return zipfs;
}
}
void removeFileSystem(Path zfpath) {
synchronized (filesystems) {
filesystems.remove(zfpath);
}
}
}
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.io.PrintStream;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import com.sun.nio.zipfs.ZipFileSystem.Entry;
import static com.sun.nio.zipfs.ZipConstants.*;
import static com.sun.nio.zipfs.ZipUtils.*;
/**
* Print the loc and cen tables of the ZIP file
*
* @author Xueming Shen
*/
public class ZipInfo {
public static void main(String[] args) throws Throwable {
if (args.length < 2) {
print("Usage: java ZipInfo [cen|loc] zfname");
} else {
Map<String, ?> env = Collections.emptyMap();
ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
.newFileSystem(Paths.get(args[1]), env));
long pos = 0;
if ("loc".equals(args[0])) {
print("[Local File Header]%n");
byte[] buf = new byte[1024];
for (int i = 0; i < zfs.getEntryNames().length; i++) {
Entry loc = Entry.readLOC(zfs, pos, buf);
print("--------loc[%x]--------%n", pos);
printLOC(loc);
pos = loc.endPos;
}
} if ("cen".equals(args[0])) {
int i = 0;
Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
print("[Central Directory Header]%n");
while (itr.hasNext()) {
Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
print("--------cen[%d]--------%n", i);
printCEN(cen);
i++;
}
}
zfs.close();
}
}
static void print(String fmt, Object... objs) {
System.out.printf(fmt, objs);
}
static void printLOC(Entry loc) {
print(" [%x, %x]%n", loc.startPos, loc.endPos);
print(" Signature : %8x%n", LOCSIG);
print(" Version : %4x [%d.%d]%n",
loc.version, loc. version/10, loc. version%10);
print(" Flag : %4x%n", loc.flag);
print(" Method : %4x%n", loc. method);
print(" LastMTime : %8x [%tc]%n",
loc.mtime, dosToJavaTime(loc.mtime));
print(" CRC : %8x%n", loc.crc);
print(" CSize : %8x%n", loc.csize);
print(" Size : %8x%n", loc.size);
print(" NameLength : %4x [%s]%n",
loc.nlen, new String(loc.name));
print(" ExtraLength : %4x%n", loc.elen);
if (loc.hasZip64)
print(" *ZIP64*%n");
}
static void printCEN(Entry cen) {
print(" Signature : %08x%n", CENSIG);
print(" VerMadeby : %4x [%d.%d]%n",
cen.versionMade, cen.versionMade/10, cen.versionMade%10);
print(" VerExtract : %4x [%d.%d]%n",
cen.version, cen.version/10, cen.version%10);
print(" Flag : %4x%n", cen.flag);
print(" Method : %4x%n", cen.method);
print(" LastMTime : %8x [%tc]%n",
cen.mtime, dosToJavaTime(cen.mtime));
print(" CRC : %8x%n", cen.crc);
print(" CSize : %8x%n", cen.csize);
print(" Size : %8x%n", cen.size);
print(" NameLen : %4x [%s]%n",
cen.nlen, new String(cen.name));
print(" ExtraLen : %4x%n", cen.elen);
print(" CommentLen : %4x%n", cen.clen);
print(" DiskStart : %4x%n", cen.disk);
print(" Attrs : %4x%n", cen.attrs);
print(" AttrsEx : %8x%n", cen.attrsEx);
print(" LocOff : %8x%n", cen.locoff);
if (cen.hasZip64)
print(" *ZIP64*%n");
}
}
此差异已折叠。
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.nio.zipfs;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.regex.PatternSyntaxException;
/**
*
* @author Xueming Shen
*/
class ZipUtils {
/*
* Writes a 16-bit short to the output stream in little-endian byte order.
*/
public static void writeShort(OutputStream os, int v) throws IOException {
os.write((v >>> 0) & 0xff);
os.write((v >>> 8) & 0xff);
}
/*
* Writes a 32-bit int to the output stream in little-endian byte order.
*/
public static void writeInt(OutputStream os, long v) throws IOException {
os.write((int)((v >>> 0) & 0xff));
os.write((int)((v >>> 8) & 0xff));
os.write((int)((v >>> 16) & 0xff));
os.write((int)((v >>> 24) & 0xff));
}
/*
* Writes a 64-bit int to the output stream in little-endian byte order.
*/
public static void writeLong(OutputStream os, long v) throws IOException {
os.write((int)((v >>> 0) & 0xff));
os.write((int)((v >>> 8) & 0xff));
os.write((int)((v >>> 16) & 0xff));
os.write((int)((v >>> 24) & 0xff));
os.write((int)((v >>> 32) & 0xff));
os.write((int)((v >>> 40) & 0xff));
os.write((int)((v >>> 48) & 0xff));
os.write((int)((v >>> 56) & 0xff));
}
/*
* Writes an array of bytes to the output stream.
*/
public static void writeBytes(OutputStream os, byte[] b)
throws IOException
{
os.write(b, 0, b.length);
}
/*
* Writes an array of bytes to the output stream.
*/
public static void writeBytes(OutputStream os, byte[] b, int off, int len)
throws IOException
{
os.write(b, off, len);
}
/*
* Append a slash at the end, if it does not have one yet
*/
public static byte[] toDirectoryPath(byte[] dir) {
if (dir.length != 0 && dir[dir.length - 1] != '/') {
dir = Arrays.copyOf(dir, dir.length + 1);
dir[dir.length - 1] = '/';
}
return dir;
}
/*
* Converts DOS time to Java time (number of milliseconds since epoch).
*/
public static long dosToJavaTime(long dtime) {
Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
(int)(((dtime >> 21) & 0x0f) - 1),
(int)((dtime >> 16) & 0x1f),
(int)((dtime >> 11) & 0x1f),
(int)((dtime >> 5) & 0x3f),
(int)((dtime << 1) & 0x3e));
return d.getTime();
}
/*
* Converts Java time to DOS time.
*/
public static long javaToDosTime(long time) {
Date d = new Date(time);
int year = d.getYear() + 1900;
if (year < 1980) {
return (1 << 21) | (1 << 16);
}
return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
d.getSeconds() >> 1;
}
private static final String regexMetaChars = ".^$+{[]|()";
private static final String globMetaChars = "\\*?[{";
private static boolean isRegexMeta(char c) {
return regexMetaChars.indexOf(c) != -1;
}
private static boolean isGlobMeta(char c) {
return globMetaChars.indexOf(c) != -1;
}
private static char EOL = 0; //TBD
private static char next(String glob, int i) {
if (i < glob.length()) {
return glob.charAt(i);
}
return EOL;
}
/*
* Creates a regex pattern from the given glob expression.
*
* @throws PatternSyntaxException
*/
public static String toRegexPattern(String globPattern) {
boolean inGroup = false;
StringBuilder regex = new StringBuilder("^");
int i = 0;
while (i < globPattern.length()) {
char c = globPattern.charAt(i++);
switch (c) {
case '\\':
// escape special characters
if (i == globPattern.length()) {
throw new PatternSyntaxException("No character to escape",
globPattern, i - 1);
}
char next = globPattern.charAt(i++);
if (isGlobMeta(next) || isRegexMeta(next)) {
regex.append('\\');
}
regex.append(next);
break;
case '/':
regex.append(c);
break;
case '[':
// don't match name separator in class
regex.append("[[^/]&&[");
if (next(globPattern, i) == '^') {
// escape the regex negation char if it appears
regex.append("\\^");
i++;
} else {
// negation
if (next(globPattern, i) == '!') {
regex.append('^');
i++;
}
// hyphen allowed at start
if (next(globPattern, i) == '-') {
regex.append('-');
i++;
}
}
boolean hasRangeStart = false;
char last = 0;
while (i < globPattern.length()) {
c = globPattern.charAt(i++);
if (c == ']') {
break;
}
if (c == '/') {
throw new PatternSyntaxException("Explicit 'name separator' in class",
globPattern, i - 1);
}
// TBD: how to specify ']' in a class?
if (c == '\\' || c == '[' ||
c == '&' && next(globPattern, i) == '&') {
// escape '\', '[' or "&&" for regex class
regex.append('\\');
}
regex.append(c);
if (c == '-') {
if (!hasRangeStart) {
throw new PatternSyntaxException("Invalid range",
globPattern, i - 1);
}
if ((c = next(globPattern, i++)) == EOL || c == ']') {
break;
}
if (c < last) {
throw new PatternSyntaxException("Invalid range",
globPattern, i - 3);
}
regex.append(c);
hasRangeStart = false;
} else {
hasRangeStart = true;
last = c;
}
}
if (c != ']') {
throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
}
regex.append("]]");
break;
case '{':
if (inGroup) {
throw new PatternSyntaxException("Cannot nest groups",
globPattern, i - 1);
}
regex.append("(?:(?:");
inGroup = true;
break;
case '}':
if (inGroup) {
regex.append("))");
inGroup = false;
} else {
regex.append('}');
}
break;
case ',':
if (inGroup) {
regex.append(")|(?:");
} else {
regex.append(',');
}
break;
case '*':
if (next(globPattern, i) == '*') {
// crosses directory boundaries
regex.append(".*");
i++;
} else {
// within directory boundary
regex.append("[^/]*");
}
break;
case '?':
regex.append("[^/]");
break;
default:
if (isRegexMeta(c)) {
regex.append('\\');
}
regex.append(c);
}
}
if (inGroup) {
throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
}
return regex.append('$').toString();
}
}
......@@ -64,7 +64,10 @@ class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer {
accessor.setFile(fd, null);
accessor.setFiles(fd, null, null);
} else {
accessor.setDirectory(fd, directory);
// Fix 6987233: add the trailing slash if it's absent
accessor.setDirectory(fd, directory +
(directory.endsWith(File.separator) ?
"" : File.separator));
accessor.setFile(fd, filenames[0]);
accessor.setFiles(fd, directory, filenames);
}
......
......@@ -705,12 +705,8 @@ public class XBaseWindow {
throw new IllegalStateException("Attempt to resize uncreated window");
}
insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
if (width <= 0) {
width = 1;
}
if (height <= 0) {
height = 1;
}
width = Math.max(MIN_SIZE, width);
height = Math.max(MIN_SIZE, height);
XToolkit.awtLock();
try {
XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
......
......@@ -763,12 +763,8 @@ abstract class XDecoratedPeer extends XWindowPeer {
}
private void checkShellRectSize(Rectangle shellRect) {
if (shellRect.width < 0) {
shellRect.width = 1;
}
if (shellRect.height < 0) {
shellRect.height = 1;
}
shellRect.width = Math.max(MIN_SIZE, shellRect.width);
shellRect.height = Math.max(MIN_SIZE, shellRect.height);
}
private void checkShellRectPos(Rectangle shellRect) {
......
......@@ -28,9 +28,12 @@ package sun.awt.X11;
import sun.awt.EmbeddedFrame;
import java.awt.*;
import java.awt.AWTKeyStroke;
import java.util.logging.Logger;
public class XEmbeddedFrame extends EmbeddedFrame {
private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName());
long handle;
public XEmbeddedFrame() {
}
......@@ -70,6 +73,21 @@ public class XEmbeddedFrame extends EmbeddedFrame {
this(handle, supportsXEmbed, false);
}
/*
* The method shouldn't be called in case of active XEmbed.
*/
public boolean traverseIn(boolean direction) {
XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
if (peer != null) {
if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
log.fine("The method shouldn't be called when XEmbed is active!");
} else {
return super.traverseIn(direction);
}
}
return false;
}
protected boolean traverseOut(boolean direction) {
XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
if (direction == FORWARD) {
......@@ -81,6 +99,20 @@ public class XEmbeddedFrame extends EmbeddedFrame {
return true;
}
/*
* The method shouldn't be called in case of active XEmbed.
*/
public void synthesizeWindowActivation(boolean doActivate) {
XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
if (peer != null) {
if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
log.fine("The method shouldn't be called when XEmbed is active!");
} else {
peer.synthesizeFocusInOut(doActivate);
}
}
}
public void registerAccelerator(AWTKeyStroke stroke) {
XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
if (xefp != null) {
......
......@@ -35,6 +35,8 @@ import sun.util.logging.PlatformLogger;
import sun.awt.EmbeddedFrame;
import sun.awt.SunToolkit;
import static sun.awt.X11.XConstants.*;
public class XEmbeddedFramePeer extends XFramePeer {
private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
......@@ -305,4 +307,20 @@ public class XEmbeddedFramePeer extends XFramePeer {
EmbeddedFrame frame = (EmbeddedFrame)target;
frame.notifyModalBlocked(blocker, blocked);
}
public void synthesizeFocusInOut(boolean doFocus) {
XFocusChangeEvent xev = new XFocusChangeEvent();
XToolkit.awtLock();
try {
xev.set_type(doFocus ? FocusIn : FocusOut);
xev.set_window(getFocusProxy().getWindow());
xev.set_mode(NotifyNormal);
XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false,
NoEventMask, xev.pData);
} finally {
XToolkit.awtUnlock();
xev.dispose();
}
}
}
......@@ -1482,8 +1482,19 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
try {
if (numberOfButtons == 0) {
numberOfButtons = getNumberOfButtonsImpl();
numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
//4th and 5th buttons are for wheel and shouldn't be reported as buttons.
//If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
//If we have 3 physical buttons and a wheel, we report 3 buttons.
//If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
if (numberOfButtons >=5) {
numberOfButtons -= 2;
} else if (numberOfButtons == 4 || numberOfButtons ==5){
numberOfButtons = 3;
}
}
return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
//Assume don't have to re-query the number again and again.
return numberOfButtons;
} finally {
awtUnlock();
}
......
......@@ -1473,6 +1473,10 @@ static void OpenXIMCallback(Display *display, XPointer client_data, XPointer cal
static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
/* mark that XIM server was destroyed */
X11im = NULL;
JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
/* free the old pX11IMData and set it to null. this also avoids crashing
* the jvm if the XIM server reappears */
X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
}
/*
......
......@@ -556,24 +556,26 @@ public abstract class WComponentPeer extends WObjectPeer
Component target = (Component)getTarget();
Window window = SunToolkit.getContainingWindow(target);
if (window != null && !window.isOpaque()) {
// Non-opaque windows do not support heavyweight children.
// Redirect all painting to the Window's Graphics instead.
// The caller is responsible for calling the
// WindowPeer.updateWindow() after painting has finished.
int x = 0, y = 0;
for (Component c = target; c != window; c = c.getParent()) {
x += c.getX();
y += c.getY();
}
if (window != null) {
Graphics g =
((WWindowPeer)window.getPeer()).getTranslucentGraphics();
// getTranslucentGraphics() returns non-null value for non-opaque windows only
if (g != null) {
// Non-opaque windows do not support heavyweight children.
// Redirect all painting to the Window's Graphics instead.
// The caller is responsible for calling the
// WindowPeer.updateWindow() after painting has finished.
int x = 0, y = 0;
for (Component c = target; c != window; c = c.getParent()) {
x += c.getX();
y += c.getY();
}
g.translate(x, y);
g.clipRect(0, 0, target.getWidth(), target.getHeight());
g.translate(x, y);
g.clipRect(0, 0, target.getWidth(), target.getHeight());
return g;
return g;
}
}
SurfaceData surfaceData = this.surfaceData;
......
......@@ -191,9 +191,20 @@ public class WEmbeddedFrame extends EmbeddedFrame {
public void activateEmbeddingTopLevel() {
}
public void synthesizeWindowActivation(boolean doActivate) {
((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
public void synthesizeWindowActivation(final boolean doActivate) {
if (!doActivate || EventQueue.isDispatchThread()) {
((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
} else {
// To avoid focus concurrence b/w IE and EmbeddedFrame
// activation is postponed by means of posting it to EDT.
EventQueue.invokeLater(new Runnable() {
public void run() {
((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
}
});
}
}
public void registerAccelerator(AWTKeyStroke stroke) {}
public void unregisterAccelerator(AWTKeyStroke stroke) {}
......
......@@ -594,16 +594,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
}
}
@Override
public Graphics getGraphics() {
synchronized (getStateLock()) {
if (!isOpaque) {
return getTranslucentGraphics();
}
}
return super.getGraphics();
}
@Override
public void setBackground(Color c) {
super.setBackground(c);
......
#
#
# This file describes mapping information between Windows and Java
# time zones.
# Format: Each line should include a colon separated fields of Windows
......@@ -11,7 +10,7 @@
# NOTE
# This table format is not a public interface of any Java
# platforms. No applications should depend on this file in any form.
#
#
# This table has been generated by a program and should not be edited
# manually.
#
......@@ -84,8 +83,8 @@ Ekaterinburg:10,11::Asia/Yekaterinburg:
Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg:
West Asia:10,11:UZ:Asia/Tashkent:
West Asia Standard Time:10,11:UZ:Asia/Tashkent:
Central Asia:12,13::Asia/Dhaka:
Central Asia Standard Time:12,13::Asia/Dhaka:
Central Asia:12,13::Asia/Almaty:
Central Asia Standard Time:12,13::Asia/Almaty:
N. Central Asia Standard Time:12,13::Asia/Novosibirsk:
Bangkok:14,15::Asia/Bangkok:
Bangkok Standard Time:14,15::Asia/Bangkok:
......@@ -167,22 +166,27 @@ Greenwich:88,89::GMT:
Greenwich Standard Time:88,89::GMT:
Argentina Standard Time:900,900::America/Buenos_Aires:
Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
Central Brazilian Standard Time:902,902:BR:America/Manaus:
Central Standard Time (Mexico):903,903::America/Mexico_City:
Georgian Standard Time:904,904:GE:Asia/Tbilisi:
Jordan Standard Time:905,905:JO:Asia/Amman:
Mauritius Standard Time:906,906:MU:Indian/Mauritius:
Middle East Standard Time:907,907:LB:Asia/Beirut:
Montevideo Standard Time:908,908:UY:America/Montevideo:
Morocco Standard Time:909,909:MA:Africa/Casablanca:
Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua:
Namibia Standard Time:911,911:NA:Africa/Windhoek:
Pacific Standard Time (Mexico):912,912:MX:America/Tijuana:
Pakistan Standard Time:913,913::Asia/Karachi:
UTC:914,914::UTC:
Venezuela Standard Time:915,915::America/Caracas:
Kamchatka Standard Time:916,916:RU:Asia/Kamchatka:
Paraguay Standard Time:917,917:PY:America/Asuncion:
Western Brazilian Standard Time:918,918:BR:America/Rio_Branco:
Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar:
Armenian Standard Time:920,920:AM:Asia/Yerevan:
Bangladesh Standard Time:902,902::Asia/Dhaka:
Central Brazilian Standard Time:903,903:BR:America/Manaus:
Central Standard Time (Mexico):904,904::America/Mexico_City:
Georgian Standard Time:905,905:GE:Asia/Tbilisi:
Jordan Standard Time:906,906:JO:Asia/Amman:
Kamchatka Standard Time:907,907:RU:Asia/Kamchatka:
Mauritius Standard Time:908,908:MU:Indian/Mauritius:
Middle East Standard Time:909,909:LB:Asia/Beirut:
Montevideo Standard Time:910,910:UY:America/Montevideo:
Morocco Standard Time:911,911:MA:Africa/Casablanca:
Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua:
Namibia Standard Time:913,913:NA:Africa/Windhoek:
Pacific Standard Time (Mexico):914,914:MX:America/Tijuana:
Pakistan Standard Time:915,915::Asia/Karachi:
Paraguay Standard Time:916,916:PY:America/Asuncion:
Syria Standard Time:917,917:SY:Asia/Damascus:
UTC:918,918::UTC:
UTC+12:919,919::GMT+1200:
UTC-02:920,920::GMT-0200:
UTC-11:921,921::GMT-1100:
Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
Venezuela Standard Time:923,923::America/Caracas:
Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
Armenian Standard Time:925,925:AM:Asia/Yerevan:
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册