Imported GNU Classpath 0.20
Imported GNU Classpath 0.20
* Makefile.am (AM_CPPFLAGS): Add classpath/include.
* java/nio/charset/spi/CharsetProvider.java: New override file.
* java/security/Security.java: Likewise.
* sources.am: Regenerated.
* Makefile.in: Likewise.
From-SVN: r109831
This commit is contained in:
@@ -415,7 +415,7 @@ public class BorderLayout implements LayoutManager2, java.io.Serializable
|
||||
*/
|
||||
public Dimension maximumLayoutSize(Container target)
|
||||
{
|
||||
return calcSize(target, MAX);
|
||||
return new Dimension (Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1038,14 +1038,10 @@ public abstract class Component
|
||||
if ((c != null) && c.equals(background))
|
||||
return;
|
||||
|
||||
// If c is null, inherit from closest ancestor whose bg is set.
|
||||
if (c == null && parent != null)
|
||||
c = parent.getBackground();
|
||||
if (peer != null && c != null)
|
||||
peer.setBackground(c);
|
||||
|
||||
Color previous = background;
|
||||
background = c;
|
||||
if (peer != null && c != null)
|
||||
peer.setBackground(c);
|
||||
firePropertyChange("background", previous, c);
|
||||
}
|
||||
|
||||
@@ -2642,7 +2638,7 @@ public abstract class Component
|
||||
{
|
||||
mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
|
||||
if (mouseMotionListener != null)
|
||||
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
|
||||
enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2775,10 +2771,19 @@ public abstract class Component
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered EventListers of the given listenerType.
|
||||
* Returns all registered {@link EventListener}s of the given
|
||||
* <code>listenerType</code>.
|
||||
*
|
||||
* @param listenerType the class of listeners to filter
|
||||
* @return an array of registered listeners
|
||||
* @param listenerType the class of listeners to filter (<code>null</code>
|
||||
* not permitted).
|
||||
*
|
||||
* @return An array of registered listeners.
|
||||
*
|
||||
* @throws ClassCastException if <code>listenerType</code> does not implement
|
||||
* the {@link EventListener} interface.
|
||||
* @throws NullPointerException if <code>listenerType</code> is
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getComponentListeners()
|
||||
* @see #getFocusListeners()
|
||||
* @see #getHierarchyListeners()
|
||||
@@ -4786,7 +4791,12 @@ p * <li>the set of backward traversal keys
|
||||
void dispatchEventImpl(AWTEvent e)
|
||||
{
|
||||
Event oldEvent = translateEvent (e);
|
||||
|
||||
// This boolean tells us not to process focus events when the focus
|
||||
// opposite component is the same as the focus component.
|
||||
boolean ignoreFocus =
|
||||
(e instanceof FocusEvent &&
|
||||
((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent());
|
||||
|
||||
if (oldEvent != null)
|
||||
postEvent (oldEvent);
|
||||
|
||||
@@ -4817,7 +4827,8 @@ p * <li>the set of backward traversal keys
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE)
|
||||
if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE
|
||||
&& !ignoreFocus)
|
||||
processEvent(e);
|
||||
}
|
||||
|
||||
@@ -4853,11 +4864,12 @@ p * <li>the set of backward traversal keys
|
||||
case MouseEvent.MOUSE_EXITED:
|
||||
case MouseEvent.MOUSE_PRESSED:
|
||||
case MouseEvent.MOUSE_RELEASED:
|
||||
return (mouseListener != null
|
||||
|| (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
|
||||
case MouseEvent.MOUSE_MOVED:
|
||||
case MouseEvent.MOUSE_DRAGGED:
|
||||
return (mouseListener != null
|
||||
|| mouseMotionListener != null
|
||||
|| (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
|
||||
return (mouseMotionListener != null
|
||||
|| (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0);
|
||||
|
||||
case FocusEvent.FOCUS_GAINED:
|
||||
case FocusEvent.FOCUS_LOST:
|
||||
|
||||
@@ -449,9 +449,6 @@ public class Container extends Component
|
||||
ContainerEvent.COMPONENT_REMOVED,
|
||||
r);
|
||||
getToolkit().getSystemEventQueue().postEvent(ce);
|
||||
|
||||
// Repaint this container.
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -896,13 +893,21 @@ public class Container extends Component
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the objects currently registered as FooListeners
|
||||
* upon this Container. FooListeners are registered using the addFooListener
|
||||
* method.
|
||||
*
|
||||
* @exception ClassCastException If listenerType doesn't specify a class or
|
||||
* interface that implements @see java.util.EventListener.
|
||||
* Returns all registered {@link EventListener}s of the given
|
||||
* <code>listenerType</code>.
|
||||
*
|
||||
* @param listenerType the class of listeners to filter (<code>null</code>
|
||||
* not permitted).
|
||||
*
|
||||
* @return An array of registered listeners.
|
||||
*
|
||||
* @throws ClassCastException if <code>listenerType</code> does not implement
|
||||
* the {@link EventListener} interface.
|
||||
* @throws NullPointerException if <code>listenerType</code> is
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getContainerListeners()
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public EventListener[] getListeners(Class listenerType)
|
||||
@@ -1094,7 +1099,7 @@ public class Container extends Component
|
||||
{
|
||||
if (!contains(x, y))
|
||||
return null;
|
||||
|
||||
|
||||
for (int i = 0; i < ncomponents; ++i)
|
||||
{
|
||||
// Ignore invisible children...
|
||||
@@ -1117,7 +1122,8 @@ public class Container extends Component
|
||||
}
|
||||
|
||||
//don't return transparent components with no MouseListeners
|
||||
if (this.getMouseListeners().length == 0)
|
||||
if (getMouseListeners().length == 0
|
||||
&& getMouseMotionListeners().length == 0)
|
||||
return null;
|
||||
return this;
|
||||
}
|
||||
@@ -1625,30 +1631,19 @@ public class Container extends Component
|
||||
Component comp)
|
||||
{
|
||||
Rectangle bounds = comp.getBounds();
|
||||
Rectangle oldClip = gfx.getClipBounds();
|
||||
if (oldClip == null)
|
||||
oldClip = bounds;
|
||||
|
||||
Rectangle clip = oldClip.intersection(bounds);
|
||||
if(!gfx.hitClip(bounds.x,bounds.y, bounds.width, bounds.height))
|
||||
return;
|
||||
|
||||
if (clip.isEmpty()) return;
|
||||
|
||||
boolean clipped = false;
|
||||
boolean translated = false;
|
||||
Graphics g2 = gfx.create(bounds.x, bounds.y, bounds.width,
|
||||
bounds.height);
|
||||
try
|
||||
{
|
||||
gfx.setClip(clip.x, clip.y, clip.width, clip.height);
|
||||
clipped = true;
|
||||
gfx.translate(bounds.x, bounds.y);
|
||||
translated = true;
|
||||
visitor.visit(comp, gfx);
|
||||
visitor.visit(comp, g2);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (translated)
|
||||
gfx.translate (-bounds.x, -bounds.y);
|
||||
if (clipped)
|
||||
gfx.setClip (oldClip.x, oldClip.y, oldClip.width, oldClip.height);
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2148,12 +2143,18 @@ class LightweightDispatcher implements Serializable
|
||||
break;
|
||||
}
|
||||
|
||||
if (me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0
|
||||
if (me.getID() == MouseEvent.MOUSE_RELEASED
|
||||
|| me.getID() == MouseEvent.MOUSE_PRESSED && modifiers > 0
|
||||
|| me.getID() == MouseEvent.MOUSE_DRAGGED)
|
||||
{
|
||||
// If any of the following events occur while a button is held down,
|
||||
// they should be dispatched to the same component to which the
|
||||
// original MOUSE_PRESSED event was dispatched:
|
||||
// - MOUSE_RELEASED: This is important for correct dragging
|
||||
// behaviour, otherwise the release goes to an arbitrary component
|
||||
// outside of the dragged component. OTOH, if there is no mouse
|
||||
// drag while the mouse is pressed, the component under the mouse
|
||||
// is the same as the previously pressed component anyway.
|
||||
// - MOUSE_PRESSED: another button pressed while the first is held
|
||||
// down
|
||||
// - MOUSE_DRAGGED
|
||||
|
||||
@@ -341,11 +341,14 @@ public class GridBagLayout
|
||||
GridBagLayoutInfo info = getLayoutInfo (parent, PREFERREDSIZE);
|
||||
if (info.cols == 0 && info.rows == 0)
|
||||
return;
|
||||
layoutInfo = info;
|
||||
|
||||
// DEBUG
|
||||
//dumpLayoutInfo (layoutInfo);
|
||||
|
||||
//dumpLayoutInfo (info);
|
||||
|
||||
// Calling setBounds on these components causes this layout to
|
||||
// be invalidated, clearing the layout information cache,
|
||||
// layoutInfo. So we wait until after this for loop to set
|
||||
// layoutInfo.
|
||||
for(int i = 0; i < components.length; i++)
|
||||
{
|
||||
Component component = components [i];
|
||||
@@ -357,11 +360,11 @@ public class GridBagLayout
|
||||
GridBagConstraints constraints =
|
||||
lookupInternalConstraints(component);
|
||||
|
||||
int cellx = sumIntArray(layoutInfo.colWidths, constraints.gridx);
|
||||
int celly = sumIntArray(layoutInfo.rowHeights, constraints.gridy);
|
||||
int cellw = sumIntArray(layoutInfo.colWidths,
|
||||
int cellx = sumIntArray(info.colWidths, constraints.gridx);
|
||||
int celly = sumIntArray(info.rowHeights, constraints.gridy);
|
||||
int cellw = sumIntArray(info.colWidths,
|
||||
constraints.gridx + constraints.gridwidth) - cellx;
|
||||
int cellh = sumIntArray(layoutInfo.rowHeights,
|
||||
int cellh = sumIntArray(info.rowHeights,
|
||||
constraints.gridy + constraints.gridheight) - celly;
|
||||
|
||||
Insets insets = constraints.insets;
|
||||
@@ -438,11 +441,14 @@ public class GridBagLayout
|
||||
break;
|
||||
}
|
||||
|
||||
component.setBounds(layoutInfo.pos_x + x, layoutInfo.pos_y + y, dim.width, dim.height);
|
||||
component.setBounds(info.pos_x + x, info.pos_y + y, dim.width, dim.height);
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
//dumpLayoutInfo (layoutInfo);
|
||||
//dumpLayoutInfo (info);
|
||||
|
||||
// Cache layout information.
|
||||
layoutInfo = getLayoutInfo (parent, PREFERREDSIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,9 +38,11 @@ exception statement from your version. */
|
||||
|
||||
package java.awt.datatransfer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* This class maps between native platform type names and DataFlavors.
|
||||
@@ -54,10 +56,28 @@ import java.util.Map;
|
||||
public final class SystemFlavorMap implements FlavorMap, FlavorTable
|
||||
{
|
||||
/**
|
||||
* The default (instance) flavor map.
|
||||
* The map which maps the thread's <code>ClassLoaders</code> to
|
||||
* <code>SystemFlavorMaps</code>.
|
||||
*/
|
||||
private static FlavorMap defaultFlavorMap;
|
||||
|
||||
private static final Map systemFlavorMaps = new WeakHashMap();
|
||||
|
||||
/**
|
||||
* Constant which is used to prefix encode Java MIME types.
|
||||
*/
|
||||
private static final String GNU_JAVA_MIME_PREFIX = "gnu.java:";
|
||||
|
||||
/**
|
||||
* This map maps native <code>String</code>s to lists of
|
||||
* <code>DataFlavor</code>s
|
||||
*/
|
||||
private HashMap nativeToFlavorMap = new HashMap();
|
||||
|
||||
/**
|
||||
* This map maps <code>DataFlavor</code>s to lists of native
|
||||
* <code>String</code>s
|
||||
*/
|
||||
private HashMap flavorToNativeMap = new HashMap();
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*/
|
||||
@@ -98,47 +118,118 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (instance) (System)FlavorMap.
|
||||
* Returns the (System)FlavorMap for the current thread's
|
||||
* ClassLoader.
|
||||
*/
|
||||
public static FlavorMap getDefaultFlavorMap ()
|
||||
{
|
||||
if (defaultFlavorMap == null)
|
||||
defaultFlavorMap = new SystemFlavorMap ();
|
||||
|
||||
return defaultFlavorMap;
|
||||
ClassLoader classLoader = Thread.currentThread()
|
||||
.getContextClassLoader();
|
||||
|
||||
//if ContextClassLoader not set, use system default
|
||||
if (classLoader == null)
|
||||
{
|
||||
classLoader = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
synchronized(systemFlavorMaps)
|
||||
{
|
||||
FlavorMap map = (FlavorMap)
|
||||
systemFlavorMaps.get(classLoader);
|
||||
if (map == null)
|
||||
{
|
||||
map = new SystemFlavorMap();
|
||||
systemFlavorMaps.put(classLoader, map);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the native type name for the given java mime type.
|
||||
* Encodes a MIME type for use as a <code>String</code> native. The format
|
||||
* of an encoded representation of a MIME type is implementation-dependent.
|
||||
* The only restrictions are:
|
||||
* <ul>
|
||||
* <li>The encoded representation is <code>null</code> if and only if the
|
||||
* MIME type <code>String</code> is <code>null</code>.</li>
|
||||
* <li>The encoded representations for two non-<code>null</code> MIME type
|
||||
* <code>String</code>s are equal if and only if these <code>String</code>s
|
||||
* are equal according to <code>String.equals(Object)</code>.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The present implementation of this method returns the specified MIME
|
||||
* type <code>String</code> prefixed with <code>gnu.java:</code>.
|
||||
*
|
||||
* @param mime the MIME type to encode
|
||||
* @return the encoded <code>String</code>, or <code>null</code> if
|
||||
* mimeType is <code>null</code>
|
||||
*/
|
||||
public static String encodeJavaMIMEType (String mime)
|
||||
{
|
||||
return null;
|
||||
if (mime != null)
|
||||
return GNU_JAVA_MIME_PREFIX + mime;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the native type name for the given data flavor.
|
||||
* Encodes a <code>DataFlavor</code> for use as a <code>String</code>
|
||||
* native. The format of an encoded <code>DataFlavor</code> is
|
||||
* implementation-dependent. The only restrictions are:
|
||||
* <ul>
|
||||
* <li>The encoded representation is <code>null</code> if and only if the
|
||||
* specified <code>DataFlavor</code> is <code>null</code> or its MIME type
|
||||
* <code>String</code> is <code>null</code>.</li>
|
||||
* <li>The encoded representations for two non-<code>null</code>
|
||||
* <code>DataFlavor</code>s with non-<code>null</code> MIME type
|
||||
* <code>String</code>s are equal if and only if the MIME type
|
||||
* <code>String</code>s of these <code>DataFlavor</code>s are equal
|
||||
* according to <code>String.equals(Object)</code>.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The present implementation of this method returns the MIME type
|
||||
* <code>String</code> of the specified <code>DataFlavor</code> prefixed
|
||||
* with <code>gnu.java:</code>.
|
||||
*
|
||||
* @param df the <code>DataFlavor</code> to encode
|
||||
* @return the encoded <code>String</code>, or <code>null</code> if
|
||||
* flav is <code>null</code> or has a <code>null</code> MIME type
|
||||
*/
|
||||
public static String encodeDataFlavor (DataFlavor df)
|
||||
{
|
||||
return null;
|
||||
if (df != null)
|
||||
{
|
||||
return encodeJavaMIMEType(df.getMimeType());
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the native type name can be represented as
|
||||
* a java mime type.
|
||||
* a java mime type. Returns <code>false</code> if parameter is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public static boolean isJavaMIMEType (String name)
|
||||
{
|
||||
return false;
|
||||
return (name != null && name.startsWith(GNU_JAVA_MIME_PREFIX));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the java mime type for the given the native type name.
|
||||
* Decodes a <code>String</code> native for use as a Java MIME type.
|
||||
*
|
||||
* @param name the <code>String</code> to decode
|
||||
* @return the decoded Java MIME type, or <code>null</code> if nat
|
||||
* is not an encoded <code>String</code> native
|
||||
*/
|
||||
public static String decodeJavaMIMEType (String name)
|
||||
{
|
||||
return null;
|
||||
if (isJavaMIMEType(name))
|
||||
{
|
||||
return name.substring(GNU_JAVA_MIME_PREFIX.length());
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +247,20 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List of <code>DataFlavors</code> to which the specified
|
||||
* <code>String</code> native can be translated by the data transfer
|
||||
* subsystem. The <code>List</code> will be sorted from best
|
||||
* <code>DataFlavor</code> to worst. That is, the first <code>DataFlavor
|
||||
* </code> will best reflect data in the specified native to a Java
|
||||
* application.
|
||||
* <p>
|
||||
* If the specified native is previously unknown to the data transfer
|
||||
* subsystem, and that native has been properly encoded, then invoking
|
||||
* this method will establish a mapping in both directions between the
|
||||
* specified native and a DataFlavor whose MIME type is a decoded
|
||||
* version of the native.
|
||||
*/
|
||||
public List getFlavorsForNative (String nat)
|
||||
{
|
||||
throw new Error ("Not implemented");
|
||||
@@ -165,5 +270,160 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable
|
||||
{
|
||||
throw new Error ("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from a single <code>String</code> native to a single
|
||||
* <code>DataFlavor</code>. Unlike <code>getFlavorsForNative</code>, the
|
||||
* mapping will only be established in one direction, and the native will
|
||||
* not be encoded. To establish a two-way mapping, call
|
||||
* <code>addUnencodedNativeForFlavor</code> as well. The new mapping will
|
||||
* be of lower priority than any existing mapping.
|
||||
* This method has no effect if a mapping from the specified
|
||||
* <code>String</code> native to the specified or equal
|
||||
* <code>DataFlavor</code> already exists.
|
||||
*
|
||||
* @param nativeStr the <code>String</code> native key for the mapping
|
||||
* @param flavor the <code>DataFlavor</code> value for the mapping
|
||||
* @throws NullPointerException if nat or flav is <code>null</code>
|
||||
*
|
||||
* @see #addUnencodedNativeForFlavor
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized void addFlavorForUnencodedNative(String nativeStr,
|
||||
DataFlavor flavor)
|
||||
{
|
||||
if ((nativeStr == null) || (flavor == null))
|
||||
throw new NullPointerException();
|
||||
List flavors = (List) nativeToFlavorMap.get(nativeStr);
|
||||
if (flavors == null)
|
||||
{
|
||||
flavors = new ArrayList();
|
||||
nativeToFlavorMap.put(nativeStr, flavors);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! flavors.contains(flavor))
|
||||
flavors.add(flavor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mapping from the specified <code>DataFlavor</code> (and all
|
||||
* <code>DataFlavor</code>s equal to the specified <code>DataFlavor</code>)
|
||||
* to the specified <code>String</code> native.
|
||||
* Unlike <code>getNativesForFlavor</code>, the mapping will only be
|
||||
* established in one direction, and the native will not be encoded. To
|
||||
* establish a two-way mapping, call
|
||||
* <code>addFlavorForUnencodedNative</code> as well. The new mapping will
|
||||
* be of lower priority than any existing mapping.
|
||||
* This method has no effect if a mapping from the specified or equal
|
||||
* <code>DataFlavor</code> to the specified <code>String</code> native
|
||||
* already exists.
|
||||
*
|
||||
* @param flavor the <code>DataFlavor</code> key for the mapping
|
||||
* @param nativeStr the <code>String</code> native value for the mapping
|
||||
* @throws NullPointerException if flav or nat is <code>null</code>
|
||||
*
|
||||
* @see #addFlavorForUnencodedNative
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized void addUnencodedNativeForFlavor(DataFlavor flavor,
|
||||
String nativeStr)
|
||||
{
|
||||
if ((nativeStr == null) || (flavor == null))
|
||||
throw new NullPointerException();
|
||||
List natives = (List) flavorToNativeMap.get(flavor);
|
||||
if (natives == null)
|
||||
{
|
||||
natives = new ArrayList();
|
||||
flavorToNativeMap.put(flavor, natives);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! natives.contains(nativeStr))
|
||||
natives.add(nativeStr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the current mappings for the specified <code>DataFlavor</code>
|
||||
* and all <code>DataFlavor</code>s equal to the specified
|
||||
* <code>DataFlavor</code>, and creates new mappings to the
|
||||
* specified <code>String</code> natives.
|
||||
* Unlike <code>getNativesForFlavor</code>, the mappings will only be
|
||||
* established in one direction, and the natives will not be encoded. To
|
||||
* establish two-way mappings, call <code>setFlavorsForNative</code>
|
||||
* as well. The first native in the array will represent the highest
|
||||
* priority mapping. Subsequent natives will represent mappings of
|
||||
* decreasing priority.
|
||||
* <p>
|
||||
* If the array contains several elements that reference equal
|
||||
* <code>String</code> natives, this method will establish new mappings
|
||||
* for the first of those elements and ignore the rest of them.
|
||||
* <p>
|
||||
* It is recommended that client code not reset mappings established by the
|
||||
* data transfer subsystem. This method should only be used for
|
||||
* application-level mappings.
|
||||
*
|
||||
* @param flavor the <code>DataFlavor</code> key for the mappings
|
||||
* @param natives the <code>String</code> native values for the mappings
|
||||
* @throws NullPointerException if flav or natives is <code>null</code>
|
||||
* or if natives contains <code>null</code> elements
|
||||
*
|
||||
* @see #setFlavorsForNative
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized void setNativesForFlavor(DataFlavor flavor,
|
||||
String[] natives)
|
||||
{
|
||||
if ((natives == null) || (flavor == null))
|
||||
throw new NullPointerException();
|
||||
|
||||
flavorToNativeMap.remove(flavor);
|
||||
for (int i = 0; i < natives.length; i++)
|
||||
{
|
||||
addUnencodedNativeForFlavor(flavor, natives[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards the current mappings for the specified <code>String</code>
|
||||
* native, and creates new mappings to the specified
|
||||
* <code>DataFlavor</code>s. Unlike <code>getFlavorsForNative</code>, the
|
||||
* mappings will only be established in one direction, and the natives need
|
||||
* not be encoded. To establish two-way mappings, call
|
||||
* <code>setNativesForFlavor</code> as well. The first
|
||||
* <code>DataFlavor</code> in the array will represent the highest priority
|
||||
* mapping. Subsequent <code>DataFlavor</code>s will represent mappings of
|
||||
* decreasing priority.
|
||||
* <p>
|
||||
* If the array contains several elements that reference equal
|
||||
* <code>DataFlavor</code>s, this method will establish new mappings
|
||||
* for the first of those elements and ignore the rest of them.
|
||||
* <p>
|
||||
* It is recommended that client code not reset mappings established by the
|
||||
* data transfer subsystem. This method should only be used for
|
||||
* application-level mappings.
|
||||
*
|
||||
* @param nativeStr the <code>String</code> native key for the mappings
|
||||
* @param flavors the <code>DataFlavor</code> values for the mappings
|
||||
* @throws NullPointerException if nat or flavors is <code>null</code>
|
||||
* or if flavors contains <code>null</code> elements
|
||||
*
|
||||
* @see #setNativesForFlavor
|
||||
* @since 1.4
|
||||
*/
|
||||
public synchronized void setFlavorsForNative(String nativeStr,
|
||||
DataFlavor[] flavors)
|
||||
{
|
||||
if ((nativeStr == null) || (flavors == null))
|
||||
throw new NullPointerException();
|
||||
|
||||
nativeToFlavorMap.remove(nativeStr);
|
||||
for (int i = 0; i < flavors.length; i++)
|
||||
{
|
||||
addFlavorForUnencodedNative(nativeStr, flavors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // class SystemFlavorMap
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/* DefaultPersistenceDelegate.java
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/** <p><code>DefaultPersistenceDelegate</code> is a {@link PersistenceDelegate}
|
||||
* implementation that can be used to serialize objects which adhere to the
|
||||
* Java Beans naming convention.</p>
|
||||
*
|
||||
* @author Robert Schuster (robertschuster@fsfe.org)
|
||||
* @since 1.4
|
||||
*/
|
||||
public class DefaultPersistenceDelegate extends PersistenceDelegate
|
||||
{
|
||||
|
||||
private String[] constructorPropertyNames;
|
||||
|
||||
/** Using this constructor the object to be serialized will be instantiated
|
||||
* with the default non-argument constructor.
|
||||
*/
|
||||
public DefaultPersistenceDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
/** This constructor allows to specify which Bean properties appear
|
||||
* in the constructor.
|
||||
*
|
||||
* <p>The implementation reads the mentioned properties from the Bean
|
||||
* instance and applies it in the given order to a corresponding
|
||||
* constructor.</p>
|
||||
*
|
||||
* @param constructorPropertyNames The properties the Bean's constructor
|
||||
* should be given to.
|
||||
*/
|
||||
public DefaultPersistenceDelegate(String[] constructorPropertyNames)
|
||||
{
|
||||
this.constructorPropertyNames = constructorPropertyNames;
|
||||
}
|
||||
|
||||
protected boolean mutatesTo(Object oldInstance, Object newInstance)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
return (constructorPropertyNames != null
|
||||
&& constructorPropertyNames.length > 0
|
||||
&& oldInstance.getClass()
|
||||
.getDeclaredMethod("equals",
|
||||
new Class[] { Object.class }) != null)
|
||||
? oldInstance.equals(newInstance)
|
||||
: super.mutatesTo(oldInstance, newInstance);
|
||||
}
|
||||
catch (NoSuchMethodException nsme)
|
||||
{
|
||||
return super.mutatesTo(oldInstance, newInstance);
|
||||
}
|
||||
}
|
||||
|
||||
protected Expression instantiate(Object oldInstance, Encoder out)
|
||||
{
|
||||
Object[] args = null;
|
||||
|
||||
try
|
||||
{
|
||||
// If there are property names in the array, then we create
|
||||
// a corresponding argument array and store every
|
||||
// argument in it. To retrieve an argument object we have
|
||||
// dig up the right property in the bean class' BeanInfo
|
||||
// object.
|
||||
// This is so costly in terms of execution time I better
|
||||
// not think twice about it ...
|
||||
if (constructorPropertyNames != null)
|
||||
{
|
||||
args = new Object[constructorPropertyNames.length];
|
||||
|
||||
// Look up the properties of oldInstance's class to find matches for
|
||||
// the
|
||||
// names given in the constructor.
|
||||
PropertyDescriptor[] propertyDescs = Introspector.getBeanInfo(
|
||||
oldInstance.getClass()).getPropertyDescriptors();
|
||||
|
||||
for (int i = 0; i < constructorPropertyNames.length; i++)
|
||||
{
|
||||
// Scan the property descriptions for a matching name.
|
||||
for (int j = 0; j < propertyDescs.length; j++)
|
||||
{
|
||||
if (propertyDescs[i].getName().equals(
|
||||
constructorPropertyNames[i]))
|
||||
{
|
||||
Method readMethod = propertyDescs[i].getReadMethod();
|
||||
|
||||
args[i] = readMethod.invoke(oldInstance, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (IllegalAccessException iae)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(iae);
|
||||
}
|
||||
catch (IllegalArgumentException iarge)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(iarge);
|
||||
}
|
||||
catch (InvocationTargetException ite)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(ite);
|
||||
}
|
||||
catch (IntrospectionException ie)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(ie);
|
||||
}
|
||||
|
||||
return new Expression(oldInstance, oldInstance.getClass(), "new", args);
|
||||
}
|
||||
|
||||
protected void initialize(Class type, Object oldInstance, Object newInstance,
|
||||
Encoder out)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyDescriptor[] propertyDescs = Introspector.getBeanInfo(
|
||||
oldInstance.getClass()).getPropertyDescriptors();
|
||||
|
||||
for (int i = 0; i < propertyDescs.length; i++)
|
||||
{
|
||||
Method readMethod = propertyDescs[i].getReadMethod();
|
||||
Method writeMethod = propertyDescs[i].getWriteMethod();
|
||||
|
||||
if (readMethod != null && writeMethod != null)
|
||||
{
|
||||
Object oldValue = readMethod.invoke(oldInstance, null);
|
||||
|
||||
if (oldValue != null)
|
||||
out.writeStatement(new Statement(oldInstance,
|
||||
writeMethod.getName(),
|
||||
new Object[] { oldValue }));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IntrospectionException ie)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(ie);
|
||||
}
|
||||
catch (IllegalAccessException iae)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(iae);
|
||||
}
|
||||
catch (InvocationTargetException ite)
|
||||
{
|
||||
out.getExceptionListener().exceptionThrown(ite);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
/* Encoder.java
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import gnu.java.beans.encoder.ArrayPersistenceDelegate;
|
||||
import gnu.java.beans.encoder.ClassPersistenceDelegate;
|
||||
import gnu.java.beans.encoder.CollectionPersistenceDelegate;
|
||||
import gnu.java.beans.encoder.MapPersistenceDelegate;
|
||||
import gnu.java.beans.encoder.PrimitivePersistenceDelegate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* @author Robert Schuster (robertschuster@fsfe.org)
|
||||
* @since 1.4
|
||||
*/
|
||||
public class Encoder
|
||||
{
|
||||
|
||||
/**
|
||||
* An internal DefaultPersistenceDelegate instance that is used for every
|
||||
* class that does not a have a special special PersistenceDelegate.
|
||||
*/
|
||||
private static PersistenceDelegate defaultPersistenceDelegate;
|
||||
|
||||
private static PersistenceDelegate fakePersistenceDelegate;
|
||||
|
||||
/**
|
||||
* Stores the relation Class->PersistenceDelegate.
|
||||
*/
|
||||
private static HashMap delegates = new HashMap();
|
||||
|
||||
/**
|
||||
* Stores the relation oldInstance->newInstance
|
||||
*/
|
||||
private IdentityHashMap candidates = new IdentityHashMap();
|
||||
|
||||
private ExceptionListener exceptionListener;
|
||||
|
||||
/**
|
||||
* A simple number that is used to restrict the access to writeExpression and
|
||||
* writeStatement. The rule is that both methods should only be used when an
|
||||
* object is written to the stream (= writeObject). Therefore accessCounter is
|
||||
* incremented just before the call to writeObject and decremented afterwards.
|
||||
* Then writeStatement and writeExpression allow execution only if
|
||||
* accessCounter is bigger than zero.
|
||||
*/
|
||||
private int accessCounter = 0;
|
||||
|
||||
public Encoder()
|
||||
{
|
||||
setupDefaultPersistenceDelegates();
|
||||
|
||||
setExceptionListener(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a bunch of {@link PersistenceDelegate} instances which are needed
|
||||
* for the basic working of a {@link Encoder}s.
|
||||
*/
|
||||
private static void setupDefaultPersistenceDelegates()
|
||||
{
|
||||
synchronized (delegates)
|
||||
{
|
||||
if (defaultPersistenceDelegate != null)
|
||||
return;
|
||||
|
||||
delegates.put(Class.class, new ClassPersistenceDelegate());
|
||||
|
||||
PersistenceDelegate pd = new PrimitivePersistenceDelegate();
|
||||
delegates.put(Boolean.class, pd);
|
||||
delegates.put(Byte.class, pd);
|
||||
delegates.put(Short.class, pd);
|
||||
delegates.put(Integer.class, pd);
|
||||
delegates.put(Long.class, pd);
|
||||
delegates.put(Float.class, pd);
|
||||
delegates.put(Double.class, pd);
|
||||
|
||||
delegates.put(Object[].class, new ArrayPersistenceDelegate());
|
||||
|
||||
pd = new CollectionPersistenceDelegate();
|
||||
delegates.put(ArrayList.class, pd);
|
||||
delegates.put(LinkedList.class, pd);
|
||||
delegates.put(Vector.class, pd);
|
||||
delegates.put(HashSet.class, pd);
|
||||
delegates.put(LinkedHashSet.class, pd);
|
||||
delegates.put(TreeSet.class, pd);
|
||||
|
||||
pd = new MapPersistenceDelegate();
|
||||
delegates.put(HashMap.class, pd);
|
||||
delegates.put(TreeMap.class, pd);
|
||||
delegates.put(java.util.Hashtable.class, pd);
|
||||
delegates.put(java.util.IdentityHashMap.class, pd);
|
||||
|
||||
delegates.put(java.util.LinkedHashMap.class, pd);
|
||||
delegates.put(java.util.Properties.class, pd);
|
||||
|
||||
delegates.put(java.awt.RenderingHints.class, pd);
|
||||
delegates.put(java.util.WeakHashMap.class, pd);
|
||||
delegates.put(javax.swing.UIDefaults.class, pd);
|
||||
|
||||
// TODO: These classes need to be implemented first
|
||||
//delegates.put(java.security.AuthProvider.class, pd);
|
||||
//delegates.put(java.util.concurrent.ConcurrentHashMap.class, pd);
|
||||
//delegates.put(java.util.EnumMap.class, pd);
|
||||
//delegates.put(javax.management.openmbean.TabularDataSupport.class, pd);
|
||||
|
||||
defaultPersistenceDelegate = new DefaultPersistenceDelegate();
|
||||
delegates.put(Object.class, defaultPersistenceDelegate);
|
||||
|
||||
// Creates a PersistenceDelegate implementation which is
|
||||
// returned for 'null'. In practice this instance is
|
||||
// not used in any way and is just here to be compatible
|
||||
// with the reference implementation which returns a
|
||||
// similar instance when calling getPersistenceDelegate(null) .
|
||||
fakePersistenceDelegate = new PersistenceDelegate()
|
||||
{
|
||||
protected Expression instantiate(Object o, Encoder e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeObject(Object o)
|
||||
{
|
||||
// 'null' has no PersistenceDelegate and will not
|
||||
// create an Expression which has to be cloned.
|
||||
// However subclasses should be aware that writeObject
|
||||
// may be called with a 'null' argument and should
|
||||
// write the proper representation of it.
|
||||
if (o == null)
|
||||
return;
|
||||
|
||||
PersistenceDelegate pd = getPersistenceDelegate(o.getClass());
|
||||
|
||||
accessCounter++;
|
||||
pd.writeObject(o, this);
|
||||
accessCounter--;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link ExceptionListener} instance to be used for reporting
|
||||
* recorable exceptions in the instantiation and initialization sequence. If
|
||||
* the argument is <code>null</code> a default instance will be used that
|
||||
* prints the thrown exception to <code>System.err</code>.
|
||||
*/
|
||||
public void setExceptionListener(ExceptionListener listener)
|
||||
{
|
||||
exceptionListener = (listener != null) ? listener : new ExceptionListener()
|
||||
{
|
||||
public void exceptionThrown(Exception e)
|
||||
{
|
||||
System.err.println("exception thrown: " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently active {@link ExceptionListener} instance.
|
||||
*/
|
||||
public ExceptionListener getExceptionListener()
|
||||
{
|
||||
return exceptionListener;
|
||||
}
|
||||
|
||||
public PersistenceDelegate getPersistenceDelegate(Class type)
|
||||
{
|
||||
// This is not specified but the JDK behaves like this.
|
||||
if (type == null)
|
||||
return fakePersistenceDelegate;
|
||||
|
||||
// Treats all array classes in the same way and assigns
|
||||
// them a shared PersistenceDelegate implementation tailored
|
||||
// for array instantation and initialization.
|
||||
if (type.isArray())
|
||||
return (PersistenceDelegate) delegates.get(Object[].class);
|
||||
|
||||
PersistenceDelegate pd = (PersistenceDelegate) delegates.get(type);
|
||||
|
||||
return (pd != null) ? pd : (PersistenceDelegate) defaultPersistenceDelegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PersistenceDelegate} instance for the given class.
|
||||
* <p>
|
||||
* Note: Throws a <code>NullPointerException</code> if the argument is
|
||||
* <code>null</code>.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note: Silently ignores PersistenceDelegates for Array types and primitive
|
||||
* wrapper classes.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note: Although this method is not declared <code>static</code> changes to
|
||||
* the {@link PersistenceDelegate}s affect <strong>all</strong>
|
||||
* {@link Encoder} instances. <strong>In this implementation</strong> the
|
||||
* access is thread safe.
|
||||
* </p>
|
||||
*/
|
||||
public void setPersistenceDelegate(Class type, PersistenceDelegate delegate)
|
||||
{
|
||||
// If the argument is null this will cause a NullPointerException
|
||||
// which is expected behavior.
|
||||
|
||||
// This makes custom PDs for array, primitive types and their wrappers
|
||||
// impossible but this is how the JDK behaves.
|
||||
if (type.isArray() || type.isPrimitive() || type == Boolean.class
|
||||
|| type == Byte.class || type == Short.class || type == Integer.class
|
||||
|| type == Long.class || type == Float.class || type == Double.class)
|
||||
return;
|
||||
|
||||
synchronized (delegates)
|
||||
{
|
||||
delegates.put(type, delegate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Object remove(Object oldInstance)
|
||||
{
|
||||
return candidates.remove(oldInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the replacement object which has been created by the encoder during
|
||||
* the instantiation sequence or <code>null</code> if the object has not
|
||||
* been processed yet.
|
||||
* <p>
|
||||
* Note: The <code>String</code> class acts as an endpoint for the
|
||||
* inherently recursive algorithm of the {@link Encoder}. Therefore instances
|
||||
* of <code>String</code> will always be returned by this method. In other
|
||||
* words the assertion: <code>
|
||||
* assert (anyEncoder.get(anyString) == anyString)
|
||||
* </code<
|
||||
* will always hold.</p>
|
||||
*
|
||||
* <p>Note: If <code>null</code> is requested, the result will
|
||||
* always be <code>null</code>.</p>
|
||||
*/
|
||||
public Object get(Object oldInstance)
|
||||
{
|
||||
// String instances are handled in a special way.
|
||||
// No one knows why this is not officially specified
|
||||
// because this is a rather important design decision.
|
||||
return (oldInstance == null) ? null :
|
||||
(oldInstance.getClass() == String.class) ?
|
||||
oldInstance : candidates.get(oldInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Note: If you call this method not from within an object instantiation and
|
||||
* initialization sequence it will be silently ignored.
|
||||
* </p>
|
||||
*/
|
||||
public void writeStatement(Statement stmt)
|
||||
{
|
||||
// Silently ignore out of bounds calls.
|
||||
if (accessCounter <= 0)
|
||||
return;
|
||||
|
||||
Object target = stmt.getTarget();
|
||||
|
||||
Object newTarget = get(target);
|
||||
if (newTarget == null)
|
||||
{
|
||||
writeObject(target);
|
||||
newTarget = get(target);
|
||||
}
|
||||
|
||||
Object[] args = stmt.getArguments();
|
||||
Object[] newArgs = new Object[args.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
newArgs[i] = get(args[i]);
|
||||
if (newArgs[i] == null || isImmutableType(args[i].getClass()))
|
||||
{
|
||||
writeObject(args[i]);
|
||||
newArgs[i] = get(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Statement newStmt = new Statement(newTarget, stmt.getMethodName(), newArgs);
|
||||
|
||||
try
|
||||
{
|
||||
newStmt.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionListener.exceptionThrown(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Note: If you call this method not from within an object instantiation and
|
||||
* initialization sequence it will be silently ignored.
|
||||
* </p>
|
||||
*/
|
||||
public void writeExpression(Expression expr)
|
||||
{
|
||||
// Silently ignore out of bounds calls.
|
||||
if (accessCounter <= 0)
|
||||
return;
|
||||
|
||||
Object target = expr.getTarget();
|
||||
Object value = null;
|
||||
Object newValue = null;
|
||||
|
||||
try
|
||||
{
|
||||
value = expr.getValue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionListener.exceptionThrown(e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
newValue = get(value);
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
Object newTarget = get(target);
|
||||
if (newTarget == null)
|
||||
{
|
||||
writeObject(target);
|
||||
newTarget = get(target);
|
||||
|
||||
// May happen if exception was thrown.
|
||||
if (newTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Object[] args = expr.getArguments();
|
||||
Object[] newArgs = new Object[args.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
newArgs[i] = get(args[i]);
|
||||
if (newArgs[i] == null || isImmutableType(args[i].getClass()))
|
||||
{
|
||||
writeObject(args[i]);
|
||||
newArgs[i] = get(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Expression newExpr = new Expression(newTarget, expr.getMethodName(),
|
||||
newArgs);
|
||||
|
||||
// Fakes the result of Class.forName(<primitiveType>) to make it possible
|
||||
// to hand such a type to the encoding process.
|
||||
if (value instanceof Class && ((Class) value).isPrimitive())
|
||||
newExpr.setValue(value);
|
||||
|
||||
// Instantiates the new object.
|
||||
try
|
||||
{
|
||||
newValue = newExpr.getValue();
|
||||
|
||||
candidates.put(value, newValue);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exceptionListener.exceptionThrown(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
writeObject(value);
|
||||
|
||||
}
|
||||
else if(value.getClass() == String.class || value.getClass() == Class.class)
|
||||
{
|
||||
writeObject(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Returns whether the given class is an immutable
|
||||
* type which has to be handled differently when serializing it.
|
||||
*
|
||||
* <p>Immutable objects always have to be instantiated instead of
|
||||
* modifying an existing instance.</p>
|
||||
*
|
||||
* @param type The class to test.
|
||||
* @return Whether the first argument is an immutable type.
|
||||
*/
|
||||
boolean isImmutableType(Class type)
|
||||
{
|
||||
return type == String.class || type == Class.class
|
||||
|| type == Integer.class || type == Boolean.class
|
||||
|| type == Byte.class || type == Short.class
|
||||
|| type == Long.class || type == Float.class
|
||||
|| type == Double.class;
|
||||
}
|
||||
|
||||
/** Sets the stream candidate for a given object.
|
||||
*
|
||||
* @param oldObject The object given to the encoder.
|
||||
* @param newObject The object the encoder generated.
|
||||
*/
|
||||
void putCandidate(Object oldObject, Object newObject)
|
||||
{
|
||||
candidates.put(oldObject, newObject);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,16 +35,19 @@ this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
* class Expression
|
||||
*
|
||||
* An Expression captures the execution of an object method that
|
||||
* returns a value. It stores an object, the method to call, and the
|
||||
* arguments to pass to the method.
|
||||
*
|
||||
* <p>An Expression captures the execution of an object method
|
||||
* that returns a value.</p>
|
||||
*
|
||||
* <p>It stores an object, the method to call, and the arguments to pass to
|
||||
* the method.</p>
|
||||
*
|
||||
* <p>While this class can generally be used to describe method calls it is
|
||||
* part of the XML serialization API.</p>
|
||||
*
|
||||
* @author Robert Schuster (robertschuster@fsfe.org)
|
||||
* @since 1.4
|
||||
*/
|
||||
public class Expression extends Statement
|
||||
@@ -53,38 +56,40 @@ public class Expression extends Statement
|
||||
// yet;
|
||||
private static final Object UNSET = new Object();
|
||||
|
||||
// The value to return. This is equal to unset until getValue is called.
|
||||
// The value to return. This is equal to unset until getValue is called.
|
||||
private Object value;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Constructs an Expression representing the invocation of
|
||||
* object.methodName(arg[0], arg[1], ...); However, it will never
|
||||
* be executed. Instead, value will always be returned.
|
||||
*
|
||||
* @param value The value to return.
|
||||
* @param target The object to invoke the method on.
|
||||
* @param methodName The object method to invoke.
|
||||
* @param arguments An array of arguments to pass to the method.
|
||||
* Constructor Constructs an Expression representing the invocation of
|
||||
* object.methodName(arg[0], arg[1], ...); However, it will never be executed.
|
||||
* Instead, value will always be returned.
|
||||
*
|
||||
* @param value
|
||||
* The value to return.
|
||||
* @param target
|
||||
* The object to invoke the method on.
|
||||
* @param methodName
|
||||
* The object method to invoke.
|
||||
* @param arguments
|
||||
* An array of arguments to pass to the method.
|
||||
*/
|
||||
public Expression(Object value, Object target, String methodName,
|
||||
Object[] arguments)
|
||||
Object[] arguments)
|
||||
{
|
||||
super(target, methodName, arguments);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Constructs an Expression representing the invocation of
|
||||
* Constructor Constructs an Expression representing the invocation of
|
||||
* object.methodName(arg[0], arg[1], ...);
|
||||
*
|
||||
* @param target The object to invoke the method on.
|
||||
* @param methodName The object method to invoke.
|
||||
* @param arguments An array of arguments to pass to the method.
|
||||
*
|
||||
* @param target
|
||||
* The object to invoke the method on.
|
||||
* @param methodName
|
||||
* The object method to invoke.
|
||||
* @param arguments
|
||||
* An array of arguments to pass to the method.
|
||||
*/
|
||||
public Expression(Object target, String methodName, Object[] arguments)
|
||||
{
|
||||
@@ -93,15 +98,14 @@ public class Expression extends Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result of executing the method.
|
||||
*
|
||||
* If the cached value has not yet been set, the method is
|
||||
* executed in the same way as Statement.execute(), except that
|
||||
* the value is cached, and then returned. If the value has been
|
||||
* Return the result of executing the method. If the cached value has not yet
|
||||
* been set, the method is executed in the same way as Statement.execute(),
|
||||
* except that the value is cached, and then returned. If the value has been
|
||||
* set, it is returned without executing the method again.
|
||||
*
|
||||
*
|
||||
* @return the result of executing the method.
|
||||
* @exception Exception if an error occurs
|
||||
* @exception Exception
|
||||
* if an error occurs
|
||||
*/
|
||||
public Object getValue() throws Exception
|
||||
{
|
||||
@@ -112,14 +116,15 @@ public class Expression extends Statement
|
||||
|
||||
/**
|
||||
* Set the cached value to be returned by getValue()
|
||||
*
|
||||
* @param value the value to cache and return.
|
||||
*
|
||||
* @param value
|
||||
* the value to cache and return.
|
||||
*/
|
||||
public void setValue(Object value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a string representation of this expression.
|
||||
*/
|
||||
@@ -127,7 +132,7 @@ public class Expression extends Statement
|
||||
{
|
||||
String result = super.toString();
|
||||
if (value != UNSET)
|
||||
return value.getClass().getName() + " " + result;
|
||||
return value.getClass().getName() + "=" + result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* Indexed property change event
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
/**
|
||||
* This is like a PropertyChangeEvent, but also carries with it the
|
||||
* index of the property which changed.
|
||||
* @author Tom Tromey (tromey@redhat.com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class IndexedPropertyChangeEvent extends PropertyChangeEvent
|
||||
{
|
||||
private static final long serialVersionUID = -320227448495806870L;
|
||||
|
||||
/**
|
||||
* Index of the item that was changed.
|
||||
*/
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* Create a new IndexedPropertyChangeEvent.
|
||||
* @param source the Bean containing the property
|
||||
* @param name the property's name
|
||||
* @param oldValue the old value of the property
|
||||
* @param newValue the new value of the property
|
||||
* @param index the index of the element in the property which changed
|
||||
* @throws IllegalArgumentException if source is null
|
||||
*/
|
||||
public IndexedPropertyChangeEvent(Object source, String name,
|
||||
Object oldValue, Object newValue,
|
||||
int index)
|
||||
{
|
||||
super(source, name, oldValue, newValue);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index of the changed property.
|
||||
* @return the index
|
||||
*/
|
||||
public int getIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@@ -211,6 +211,82 @@ public class Introspector {
|
||||
return cachedInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@BeanInfo} instance for the given Bean class where a flag
|
||||
* controls the usage of explicit BeanInfo class to retrieve that
|
||||
* information.
|
||||
*
|
||||
* <p>You have three options:</p>
|
||||
* <p>With {@link #USE_ALL_BEANINFO} the result is the same as
|
||||
* {@link #getBeanInfo(Class)}.</p>
|
||||
*
|
||||
* <p>Calling the method with <code>flag</code> set to
|
||||
* {@link #IGNORE_IMMEDIATE_BEANINFO} will let it use all
|
||||
* explicit BeanInfo classes for the beans superclasses
|
||||
* but not for the bean class itself. Furthermore eventset,
|
||||
* property and method information is retrieved by introspection
|
||||
* if the explicit <code>BeanInfos</code> did not provide such data
|
||||
* (ie. return <code>null</code> on {@link BeanInfo.getMethodDescriptors},
|
||||
* {@link BeanInfo.getEventSetDescriptors} and
|
||||
* {@link BeanInfo.getPropertyDescriptors}.)
|
||||
* </p>
|
||||
*
|
||||
* <p>When the method is called with <code>flag</code< set to
|
||||
* {@link #IGNORE_ALL_BEANINFO} all the bean data is retrieved
|
||||
* by inspecting the class.</p>
|
||||
*
|
||||
* <p>Note: Any unknown value for <code>flag</code> is interpreted
|
||||
* as {@link #IGNORE_ALL_BEANINFO}</p>.
|
||||
*
|
||||
* @param beanClass The class whose BeanInfo should be returned.
|
||||
* @param flag Controls the usage of explicit <code>BeanInfo</code> classes.
|
||||
* @return A BeanInfo object describing the class.
|
||||
* @throws IntrospectionException If something goes wrong while retrieving
|
||||
* the bean data.
|
||||
*/
|
||||
public static BeanInfo getBeanInfo(Class beanClass, int flag)
|
||||
throws IntrospectionException
|
||||
{
|
||||
IntrospectionIncubator ii;
|
||||
BeanInfoEmbryo infoEmbryo;
|
||||
|
||||
switch(flag)
|
||||
{
|
||||
case USE_ALL_BEANINFO:
|
||||
return getBeanInfo(beanClass);
|
||||
case IGNORE_IMMEDIATE_BEANINFO:
|
||||
Class superclass = beanClass.getSuperclass();
|
||||
ExplicitInfo explicit = new ExplicitInfo(superclass, null);
|
||||
|
||||
ii = new IntrospectionIncubator();
|
||||
if (explicit.explicitEventSetDescriptors != null)
|
||||
ii.setEventStopClass(superclass);
|
||||
|
||||
if (explicit.explicitMethodDescriptors != null)
|
||||
ii.setMethodStopClass(superclass);
|
||||
|
||||
if (explicit.explicitPropertyDescriptors != null)
|
||||
ii.setPropertyStopClass(superclass);
|
||||
|
||||
ii.addMethods(beanClass.getMethods());
|
||||
|
||||
infoEmbryo = ii.getBeanInfoEmbryo();
|
||||
merge(infoEmbryo, explicit);
|
||||
|
||||
infoEmbryo.setBeanDescriptor(new BeanDescriptor(beanClass, null));
|
||||
|
||||
return infoEmbryo.getBeanInfo();
|
||||
case IGNORE_ALL_BEANINFO:
|
||||
default:
|
||||
ii = new IntrospectionIncubator();
|
||||
ii.addMethods(beanClass.getMethods());
|
||||
infoEmbryo = ii.getBeanInfoEmbryo();
|
||||
infoEmbryo.setBeanDescriptor(new BeanDescriptor(beanClass, null));
|
||||
|
||||
return infoEmbryo.getBeanInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush all of the Introspector's internal caches.
|
||||
@@ -244,6 +320,69 @@ public class Introspector {
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds all explicity given bean info data to the introspected
|
||||
* data.
|
||||
*
|
||||
* @param infoEmbryo Bean info data retrieved by introspection.
|
||||
* @param explicit Bean info data retrieved by BeanInfo classes.
|
||||
*/
|
||||
private static void merge(BeanInfoEmbryo infoEmbryo, ExplicitInfo explicit)
|
||||
{
|
||||
PropertyDescriptor[] p = explicit.explicitPropertyDescriptors;
|
||||
if(p!=null)
|
||||
{
|
||||
for(int i=0;i<p.length;i++)
|
||||
{
|
||||
if(!infoEmbryo.hasProperty(p[i]))
|
||||
{
|
||||
infoEmbryo.addProperty(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// -1 should be used to denote a missing default property but
|
||||
// for robustness reasons any value below zero is discarded.
|
||||
// Not doing so would let Classpath fail where the JDK succeeds.
|
||||
if(explicit.defaultProperty > -1)
|
||||
{
|
||||
infoEmbryo.setDefaultPropertyName(p[explicit.defaultProperty].getName());
|
||||
}
|
||||
}
|
||||
EventSetDescriptor[] e = explicit.explicitEventSetDescriptors;
|
||||
if(e!=null)
|
||||
{
|
||||
for(int i=0;i<e.length;i++)
|
||||
{
|
||||
if(!infoEmbryo.hasEvent(e[i]))
|
||||
{
|
||||
infoEmbryo.addEvent(e[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// -1 should be used to denote a missing default event but
|
||||
// for robustness reasons any value below zero is discarded.
|
||||
// Not doing so would let Classpath fail where the JDK succeeds.
|
||||
if(explicit.defaultEvent > -1)
|
||||
{
|
||||
infoEmbryo.setDefaultEventName(e[explicit.defaultEvent].getName());
|
||||
}
|
||||
}
|
||||
MethodDescriptor[] m = explicit.explicitMethodDescriptors;
|
||||
if(m!=null)
|
||||
{
|
||||
for(int i=0;i<m.length;i++)
|
||||
{
|
||||
if(!infoEmbryo.hasMethod(m[i]))
|
||||
{
|
||||
infoEmbryo.addMethod(m[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
infoEmbryo.setAdditionalBeanInfo(explicit.explicitBeanInfo);
|
||||
infoEmbryo.setIcons(explicit.im);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BeanInfo for class <CODE>beanClass</CODE>,
|
||||
* first by looking for explicit information, next by
|
||||
@@ -267,62 +406,19 @@ public class Introspector {
|
||||
ii.addMethods(beanClass.getMethods());
|
||||
|
||||
BeanInfoEmbryo currentInfo = ii.getBeanInfoEmbryo();
|
||||
PropertyDescriptor[] p = explicit.explicitPropertyDescriptors;
|
||||
if(p!=null)
|
||||
{
|
||||
for(int i=0;i<p.length;i++)
|
||||
{
|
||||
if(!currentInfo.hasProperty(p[i]))
|
||||
{
|
||||
currentInfo.addProperty(p[i]);
|
||||
}
|
||||
}
|
||||
if(explicit.defaultProperty != -1)
|
||||
{
|
||||
currentInfo.setDefaultPropertyName(p[explicit.defaultProperty].getName());
|
||||
}
|
||||
}
|
||||
EventSetDescriptor[] e = explicit.explicitEventSetDescriptors;
|
||||
if(e!=null)
|
||||
{
|
||||
for(int i=0;i<e.length;i++)
|
||||
{
|
||||
if(!currentInfo.hasEvent(e[i]))
|
||||
{
|
||||
currentInfo.addEvent(e[i]);
|
||||
}
|
||||
}
|
||||
if(explicit.defaultEvent != -1)
|
||||
{
|
||||
currentInfo.setDefaultEventName(e[explicit.defaultEvent].getName());
|
||||
}
|
||||
}
|
||||
MethodDescriptor[] m = explicit.explicitMethodDescriptors;
|
||||
if(m!=null)
|
||||
{
|
||||
for(int i=0;i<m.length;i++)
|
||||
{
|
||||
if(!currentInfo.hasMethod(m[i]))
|
||||
{
|
||||
currentInfo.addMethod(m[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the info's BeanDescriptor to the one we extracted from the
|
||||
// explicit BeanInfo instance(s) if they contained one. Otherwise we
|
||||
// create the BeanDescriptor from scratch.
|
||||
// Note: We do not create a copy the retrieved BeanDescriptor which will allow
|
||||
// the user to modify the instance while it is cached. However this is how
|
||||
// the RI does it.
|
||||
currentInfo.setBeanDescriptor(
|
||||
(explicit.explicitBeanDescriptor == null ?
|
||||
new BeanDescriptor(beanClass, null) :
|
||||
explicit.explicitBeanDescriptor));
|
||||
|
||||
currentInfo.setAdditionalBeanInfo(explicit.explicitBeanInfo);
|
||||
currentInfo.setIcons(explicit.im);
|
||||
merge(currentInfo, explicit);
|
||||
|
||||
// Sets the info's BeanDescriptor to the one we extracted from the
|
||||
// explicit BeanInfo instance(s) if they contained one. Otherwise we
|
||||
// create the BeanDescriptor from scratch.
|
||||
// Note: We do not create a copy the retrieved BeanDescriptor which will allow
|
||||
// the user to modify the instance while it is cached. However this is how
|
||||
// the RI does it.
|
||||
currentInfo.setBeanDescriptor(
|
||||
(explicit.explicitBeanDescriptor == null ?
|
||||
new BeanDescriptor(beanClass, null) :
|
||||
explicit.explicitBeanDescriptor));
|
||||
return currentInfo.getBeanInfo();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/* java.beans.PersistenceDelegate
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.beans;
|
||||
|
||||
/** <p>A <code>PersistenceDelegate</code> describes how a another object
|
||||
* has to constructed and transformed in order to create a complete
|
||||
* replicate.</p>
|
||||
*
|
||||
* <p>For custom classes you will need to implement
|
||||
* <code>PersistenceDelegate</code> in a way that is suitable for them.
|
||||
* To make use of the implementation you have to register it with an
|
||||
* {@link Encoder} using the {Encoder#setPersistenceDelegate} method.</p>
|
||||
*
|
||||
* @author Robert Schuster (robertschuster@fsfe.org)
|
||||
* @since 1.4
|
||||
*/
|
||||
public abstract class PersistenceDelegate
|
||||
{
|
||||
|
||||
protected void initialize(Class type, Object oldInstance, Object newInstance,
|
||||
Encoder out)
|
||||
{
|
||||
if (type != Object.class)
|
||||
{
|
||||
type = type.getSuperclass();
|
||||
|
||||
PersistenceDelegate pd = out.getPersistenceDelegate(
|
||||
oldInstance.getClass().getSuperclass());
|
||||
|
||||
pd.initialize(type, oldInstance, newInstance, out);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeObject(Object oldInstance, Encoder out)
|
||||
{
|
||||
Object streamCandidate = out.get(oldInstance);
|
||||
|
||||
if (mutatesTo(oldInstance, streamCandidate))
|
||||
{
|
||||
initialize(oldInstance.getClass(), oldInstance, streamCandidate, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.remove(oldInstance);
|
||||
out.writeExpression(instantiate(oldInstance, out));
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean mutatesTo(Object oldInstance, Object newInstance)
|
||||
{
|
||||
return (newInstance != null)
|
||||
&& oldInstance.getClass() == newInstance.getClass();
|
||||
}
|
||||
|
||||
protected abstract Expression instantiate(Object oldInstance, Encoder out);
|
||||
}
|
||||
@@ -396,6 +396,58 @@ public class PropertyChangeSupport implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an indexed property change event. This will only fire
|
||||
* an event if the old and new values are not equal and not null.
|
||||
* @param name the name of the property which changed
|
||||
* @param index the index of the property which changed
|
||||
* @param oldValue the old value of the property
|
||||
* @param newValue the new value of the property
|
||||
* @since 1.5
|
||||
*/
|
||||
public void fireIndexedPropertyChange(String name, int index,
|
||||
Object oldValue, Object newValue)
|
||||
{
|
||||
// Argument checking is done in firePropertyChange(PropertyChangeEvent) .
|
||||
firePropertyChange(new IndexedPropertyChangeEvent(source, name,
|
||||
oldValue, newValue,
|
||||
index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an indexed property change event. This will only fire
|
||||
* an event if the old and new values are not equal.
|
||||
* @param name the name of the property which changed
|
||||
* @param index the index of the property which changed
|
||||
* @param oldValue the old value of the property
|
||||
* @param newValue the new value of the property
|
||||
* @since 1.5
|
||||
*/
|
||||
public void fireIndexedPropertyChange(String name, int index,
|
||||
int oldValue, int newValue)
|
||||
{
|
||||
if (oldValue != newValue)
|
||||
fireIndexedPropertyChange(name, index, Integer.valueOf(oldValue),
|
||||
Integer.valueOf(newValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an indexed property change event. This will only fire
|
||||
* an event if the old and new values are not equal.
|
||||
* @param name the name of the property which changed
|
||||
* @param index the index of the property which changed
|
||||
* @param oldValue the old value of the property
|
||||
* @param newValue the new value of the property
|
||||
* @since 1.5
|
||||
*/
|
||||
public void fireIndexedPropertyChange(String name, int index,
|
||||
boolean oldValue, boolean newValue)
|
||||
{
|
||||
if (oldValue != newValue)
|
||||
fireIndexedPropertyChange(name, index, Boolean.valueOf(oldValue),
|
||||
Boolean.valueOf(newValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the specified property is being listened on or not. This
|
||||
* will only return <code>true</code> if there are listeners on all
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* java.beans.Statement
|
||||
/* Statement.java
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
@@ -42,32 +42,26 @@ import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* class Statement
|
||||
*
|
||||
* A Statement captures the execution of an object method. It stores
|
||||
* <p>A Statement captures the execution of an object method. It stores
|
||||
* the object, the method to call, and the arguments to the method and
|
||||
* provides the ability to execute the method on the object, using the
|
||||
* provided arguments.
|
||||
* provided arguments.</p>
|
||||
*
|
||||
* @author Jerry Quinn (jlquinn@optonline.net)
|
||||
* @author Robert Schuster (robertschuster@fsfe.org)
|
||||
* @since 1.4
|
||||
*/
|
||||
public class Statement
|
||||
{
|
||||
/** Nested map for the relation between a class, its instances and their
|
||||
* names.
|
||||
*/
|
||||
private static HashMap classMaps = new HashMap();
|
||||
|
||||
private Object target;
|
||||
private String methodName;
|
||||
private Object[] arguments;
|
||||
|
||||
// One or the other of these will get a value after execute is
|
||||
// called once, but not both.
|
||||
/**
|
||||
* One or the other of these will get a value after execute is
|
||||
* called once, but not both.
|
||||
*/
|
||||
private transient Method method;
|
||||
private transient Constructor ctor;
|
||||
|
||||
@@ -87,76 +81,44 @@ public class Statement
|
||||
this.target = target;
|
||||
this.methodName = methodName;
|
||||
this.arguments = (arguments != null) ? arguments : new Object[0];
|
||||
storeTargetName(target);
|
||||
}
|
||||
|
||||
/** Creates a name for the target instance or does nothing if the object's
|
||||
* name is already known. This makes sure that there *is* a name for every
|
||||
* target instance.
|
||||
*/
|
||||
private static synchronized void storeTargetName(Object obj)
|
||||
{
|
||||
Class klass = obj.getClass();
|
||||
WeakHashMap names = (WeakHashMap) classMaps.get(klass);
|
||||
|
||||
if ( names == null )
|
||||
{
|
||||
names = new WeakHashMap();
|
||||
|
||||
names.put(obj,
|
||||
( klass == String.class ? ("\"" + obj + "\"") :
|
||||
(klass.getName() + names.size()) ));
|
||||
|
||||
classMaps.put(klass, names);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
String targetName = (String) names.get(obj);
|
||||
if ( targetName == null )
|
||||
{
|
||||
names.put(obj,
|
||||
( klass == String.class ? ("\"" + obj + "\"") :
|
||||
(klass.getName() + names.size()) ));
|
||||
}
|
||||
|
||||
// Nothing to do. The given object was already stored.
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the statement.
|
||||
*
|
||||
* Finds the specified method in the target object and calls it with
|
||||
* the arguments given in the constructor.
|
||||
* <p>Finds the specified method in the target object and calls it with
|
||||
* the arguments given in the constructor.</p>
|
||||
*
|
||||
* The most specific method according to the JLS(15.11) is used when
|
||||
* there are multiple methods with the same name.
|
||||
* <p>The most specific method according to the JLS(15.11) is used when
|
||||
* there are multiple methods with the same name.</p>
|
||||
*
|
||||
* Execute performs some special handling for methods and
|
||||
* <p>Execute performs some special handling for methods and
|
||||
* parameters:
|
||||
* <ul>
|
||||
* <li>Static methods can be executed by providing the class as a
|
||||
* target.</li>
|
||||
*
|
||||
* Static methods can be executed by providing the class as a
|
||||
* target.
|
||||
*
|
||||
* The method name new is reserved to call the constructor
|
||||
* <li>The method name new is reserved to call the constructor
|
||||
* new() will construct an object and return it. Not useful unless
|
||||
* an expression :-)
|
||||
* an expression :-)</li>
|
||||
*
|
||||
* If the target is an array, get and set as defined in
|
||||
* <li>If the target is an array, get and set as defined in
|
||||
* java.util.List are recognized as valid methods and mapped to the
|
||||
* methods of the same name in java.lang.reflect.Array.
|
||||
* methods of the same name in java.lang.reflect.Array.</li>
|
||||
*
|
||||
* The native datatype wrappers Boolean, Byte, Character, Double,
|
||||
* <li>The native datatype wrappers Boolean, Byte, Character, Double,
|
||||
* Float, Integer, Long, and Short will map to methods that have
|
||||
* native datatypes as parameters, in the same way as Method.invoke.
|
||||
* However, these wrappers also select methods that actually take
|
||||
* the wrapper type as an argument.
|
||||
* the wrapper type as an argument.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* The Sun spec doesn't deal with overloading between int and
|
||||
* <p>The Sun spec doesn't deal with overloading between int and
|
||||
* Integer carefully. If there are two methods, one that takes an
|
||||
* Integer and the other taking an int, the method chosen is not
|
||||
* specified, and can depend on the order in which the methods are
|
||||
* declared in the source file.
|
||||
* declared in the source file.</p>
|
||||
*
|
||||
* @throws Exception if an exception occurs while locating or
|
||||
* invoking the method.
|
||||
@@ -178,8 +140,10 @@ public class Statement
|
||||
Integer.TYPE, Long.TYPE, Short.TYPE
|
||||
};
|
||||
|
||||
// Given a wrapper class, return the native class for it. For
|
||||
// example, if c is Integer, Integer.TYPE is returned.
|
||||
/** Given a wrapper class, return the native class for it.
|
||||
* <p>For example, if <code>c</code> is <code>Integer</code>,
|
||||
* <code>Integer.TYPE</code> is returned.</p>
|
||||
*/
|
||||
private Class unwrap(Class c)
|
||||
{
|
||||
for (int i = 0; i < wrappers.length; i++)
|
||||
@@ -188,13 +152,22 @@ public class Statement
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return true if all args can be assigned to params, false
|
||||
// otherwise. Arrays are guaranteed to be the same length.
|
||||
/** Returns <code>true</code> if all args can be assigned to
|
||||
* <code>params</code>, <code>false</code> otherwise.
|
||||
*
|
||||
* <p>Arrays are guaranteed to be the same length.</p>
|
||||
*/
|
||||
private boolean compatible(Class[] params, Class[] args)
|
||||
{
|
||||
for (int i = 0; i < params.length; i++)
|
||||
{
|
||||
// Treat Integer like int if appropriate
|
||||
// Argument types are derived from argument values. If one of them was
|
||||
// null then we cannot deduce its type. However null can be assigned to
|
||||
// any type.
|
||||
if (args[i] == null)
|
||||
continue;
|
||||
|
||||
// Treat Integer like int if appropriate
|
||||
Class nativeType = unwrap(args[i]);
|
||||
if (nativeType != null && params[i].isPrimitive()
|
||||
&& params[i].isAssignableFrom(nativeType))
|
||||
@@ -208,14 +181,15 @@ public class Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the method arguments in first are more specific
|
||||
* than the method arguments in second, i.e. all args in first can
|
||||
* be assigned to those in second.
|
||||
* Returns <code>true</code> if the method arguments in first are
|
||||
* more specific than the method arguments in second, i.e. all
|
||||
* arguments in <code>first</code> can be assigned to those in
|
||||
* <code>second</code>.
|
||||
*
|
||||
* A method is more specific if all parameters can also be fed to
|
||||
* <p>A method is more specific if all parameters can also be fed to
|
||||
* the less specific method, because, e.g. the less specific method
|
||||
* accepts a base class of the equivalent argument for the more
|
||||
* specific one.
|
||||
* specific one.</p>
|
||||
*
|
||||
* @param first a <code>Class[]</code> value
|
||||
* @param second a <code>Class[]</code> value
|
||||
@@ -238,8 +212,11 @@ public class Statement
|
||||
? (Class) target : target.getClass();
|
||||
Object args[] = (arguments == null) ? new Object[0] : arguments;
|
||||
Class argTypes[] = new Class[args.length];
|
||||
|
||||
// Retrieve type or use null if the argument is null. The null argument
|
||||
// type is later used in compatible().
|
||||
for (int i = 0; i < args.length; i++)
|
||||
argTypes[i] = args[i].getClass();
|
||||
argTypes[i] = (args[i] != null) ? args[i].getClass() : null;
|
||||
|
||||
if (target.getClass().isArray())
|
||||
{
|
||||
@@ -333,7 +310,29 @@ public class Statement
|
||||
}
|
||||
if (method == null)
|
||||
throw new NoSuchMethodException("No matching method for statement " + toString());
|
||||
|
||||
// If we were calling Class.forName(String) we intercept and call the
|
||||
// forName-variant that allows a ClassLoader argument. We take the
|
||||
// system classloader (aka application classloader) here to make sure
|
||||
// that application defined classes can be resolved. If we would not
|
||||
// do that the Class.forName implementation would use the class loader
|
||||
// of java.beans.Statement which is <null> and cannot resolve application
|
||||
// defined classes.
|
||||
if (method.equals(
|
||||
Class.class.getMethod("forName", new Class[] { String.class })))
|
||||
return Class.forName(
|
||||
(String) args[0], true, ClassLoader.getSystemClassLoader());
|
||||
|
||||
try {
|
||||
return method.invoke(target, args);
|
||||
} catch(IllegalArgumentException iae){
|
||||
System.err.println("method: " + method);
|
||||
|
||||
for(int i=0;i<args.length;i++){
|
||||
System.err.println("args[" + i + "]: " + args[i]);
|
||||
}
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,9 +351,13 @@ public class Statement
|
||||
{
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
Class klass = target.getClass();
|
||||
String targetName = target.getClass().getName();
|
||||
if ( targetName.startsWith("java"))
|
||||
{
|
||||
targetName = targetName.substring(targetName.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
result.append( ((WeakHashMap) classMaps.get(klass)).get(target));
|
||||
result.append(targetName);
|
||||
result.append(".");
|
||||
result.append(methodName);
|
||||
result.append("(");
|
||||
@@ -363,11 +366,15 @@ public class Statement
|
||||
for (int i = 0; i < arguments.length; i++)
|
||||
{
|
||||
result.append(sep);
|
||||
result.append(arguments[i].getClass().getName());
|
||||
result.append(
|
||||
( arguments[i] == null ) ? "null" :
|
||||
( arguments[i] instanceof String ) ? "\"" + arguments[i] + "\"" :
|
||||
arguments[i].getClass().getName());
|
||||
sep = ", ";
|
||||
}
|
||||
result.append(")");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
/* XMLEncoder.java
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.beans;
|
||||
|
||||
import gnu.java.beans.encoder.ScanEngine;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* This class uses the {@link PersistenceDelegate} and {@link Encoder}
|
||||
* infrastructure to generate an XML representation of the objects it
|
||||
* serializes.
|
||||
*
|
||||
* @author Robert Schuster (robertschuster@fsfe.org)
|
||||
* @since 1.4
|
||||
*/
|
||||
public class XMLEncoder extends Encoder
|
||||
{
|
||||
Object owner;
|
||||
|
||||
Exception exception;
|
||||
|
||||
ScanEngine scanEngine;
|
||||
|
||||
private int accessCounter = 0;
|
||||
|
||||
public XMLEncoder(OutputStream os)
|
||||
{
|
||||
scanEngine = new ScanEngine(os);
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
if (scanEngine != null)
|
||||
{
|
||||
scanEngine.close();
|
||||
scanEngine = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void flush()
|
||||
{
|
||||
scanEngine.flush();
|
||||
}
|
||||
|
||||
public void writeExpression(Expression expr)
|
||||
{
|
||||
// Implementation note: Why is this method overwritten and nearly exactly
|
||||
// reimplemented as in Encoder?
|
||||
// The Encoder class can (and should be) subclassed by users outside of the
|
||||
// java.beans package. While I have doubts that this is possible from an
|
||||
// API design point of view I tried to replicate the Encoder's behavior
|
||||
// in the JDK as exactly as possible. This strictness however made it
|
||||
// extremely complicated to implement the XMLEncoder's backend. Therefore
|
||||
// I decided to copy the Encoder's implementation and make all changes
|
||||
// I needed for a succesfull operation of XMLEncoder.
|
||||
//
|
||||
// The same is true for the writeStatement method.
|
||||
|
||||
// Silently ignore out of bounds calls.
|
||||
if (accessCounter <= 0)
|
||||
return;
|
||||
|
||||
scanEngine.writeExpression(expr);
|
||||
|
||||
|
||||
Object target = expr.getTarget();
|
||||
Object value = null;
|
||||
Object newValue = null;
|
||||
|
||||
try
|
||||
{
|
||||
value = expr.getValue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
getExceptionListener().exceptionThrown(e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
newValue = get(value);
|
||||
|
||||
if (newValue == null)
|
||||
{
|
||||
Object newTarget = get(target);
|
||||
if (newTarget == null)
|
||||
{
|
||||
writeObject(target);
|
||||
newTarget = get(target);
|
||||
|
||||
// May happen if exception was thrown.
|
||||
if (newTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Object[] args = expr.getArguments();
|
||||
Object[] newArgs = new Object[args.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
newArgs[i] = get(args[i]);
|
||||
if (newArgs[i] == null || isImmutableType(args[i].getClass()))
|
||||
{
|
||||
writeObject(args[i]);
|
||||
newArgs[i] = get(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Expression newExpr = new Expression(newTarget, expr.getMethodName(),
|
||||
newArgs);
|
||||
|
||||
// Fakes the result of Class.forName(<primitiveType>) to make it possible
|
||||
// to hand such a type to the encoding process.
|
||||
if (value instanceof Class && ((Class) value).isPrimitive())
|
||||
newExpr.setValue(value);
|
||||
|
||||
// Instantiates the new object.
|
||||
try
|
||||
{
|
||||
newValue = newExpr.getValue();
|
||||
|
||||
putCandidate(value, newValue);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
getExceptionListener().exceptionThrown(e);
|
||||
|
||||
// In Statement.writeExpression we had no possibility to flags
|
||||
// an erroneous state to the ScanEngine without behaving different
|
||||
// to the JDK.
|
||||
scanEngine.revoke();
|
||||
}
|
||||
|
||||
writeObject(value);
|
||||
|
||||
}
|
||||
else if(value.getClass() == String.class || value.getClass() == Class.class)
|
||||
{
|
||||
writeObject(value);
|
||||
}
|
||||
|
||||
scanEngine.end();
|
||||
}
|
||||
|
||||
public void writeStatement(Statement stmt)
|
||||
{
|
||||
// In case of questions have a at the implementation note in
|
||||
// writeExpression.
|
||||
|
||||
scanEngine.writeStatement(stmt);
|
||||
|
||||
// Silently ignore out of bounds calls.
|
||||
if (accessCounter <= 0)
|
||||
return;
|
||||
|
||||
Object target = stmt.getTarget();
|
||||
|
||||
Object newTarget = get(target);
|
||||
if (newTarget == null)
|
||||
{
|
||||
writeObject(target);
|
||||
newTarget = get(target);
|
||||
}
|
||||
|
||||
Object[] args = stmt.getArguments();
|
||||
Object[] newArgs = new Object[args.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
// Here is the difference to the original writeStatement
|
||||
// method in Encoder. In case that the object is known or
|
||||
// not an immutable we put it directly into the ScanEngine
|
||||
// which will then generate an object reference for it.
|
||||
newArgs[i] = get(args[i]);
|
||||
if (newArgs[i] == null || isImmutableType(args[i].getClass()))
|
||||
{
|
||||
writeObject(args[i]);
|
||||
newArgs[i] = get(args[i]);
|
||||
}
|
||||
else
|
||||
scanEngine.writeObject(args[i]);
|
||||
}
|
||||
|
||||
Statement newStmt = new Statement(newTarget, stmt.getMethodName(), newArgs);
|
||||
|
||||
try
|
||||
{
|
||||
newStmt.execute();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
getExceptionListener().exceptionThrown(e);
|
||||
|
||||
// In Statement.writeStatement we had no possibility to flags
|
||||
// an erroneous state to the ScanEngine without behaving different
|
||||
// to the JDK.
|
||||
scanEngine.revoke();
|
||||
return;
|
||||
}
|
||||
|
||||
scanEngine.end();
|
||||
}
|
||||
|
||||
public void writeObject(Object o)
|
||||
{
|
||||
accessCounter++;
|
||||
|
||||
scanEngine.writeObject(o);
|
||||
|
||||
if (get(o) == null);
|
||||
super.writeObject(o);
|
||||
|
||||
accessCounter--;
|
||||
}
|
||||
|
||||
public void setOwner(Object o)
|
||||
{
|
||||
owner = o;
|
||||
}
|
||||
|
||||
public Object getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -396,7 +396,8 @@ public class File implements Serializable, Comparable
|
||||
* This method initializes a new <code>File</code> object to represent
|
||||
* a file corresponding to the specified <code>file:</code> protocol URI.
|
||||
*
|
||||
* @param uri The uri.
|
||||
* @param uri The URI
|
||||
* @throws IllegalArgumentException if the URI is not hierarchical
|
||||
*/
|
||||
public File(URI uri)
|
||||
{
|
||||
@@ -406,7 +407,11 @@ public class File implements Serializable, Comparable
|
||||
if (!uri.getScheme().equals("file"))
|
||||
throw new IllegalArgumentException("invalid uri protocol");
|
||||
|
||||
path = normalizePath(uri.getPath());
|
||||
String name = uri.getPath();
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException("URI \"" + uri
|
||||
+ "\" is not hierarchical");
|
||||
path = normalizePath(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -230,6 +230,8 @@ public class InputStreamReader extends Reader
|
||||
* Creates an InputStreamReader that uses a decoder of the given
|
||||
* charset to decode the bytes in the InputStream into
|
||||
* characters.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public InputStreamReader(InputStream in, Charset charset) {
|
||||
this.in = in;
|
||||
@@ -244,6 +246,8 @@ public class InputStreamReader extends Reader
|
||||
/**
|
||||
* Creates an InputStreamReader that uses the given charset decoder
|
||||
* to decode the bytes in the InputStream into characters.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public InputStreamReader(InputStream in, CharsetDecoder decoder) {
|
||||
this.in = in;
|
||||
|
||||
@@ -50,7 +50,6 @@ import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@@ -442,6 +442,11 @@ public class ObjectOutputStream extends OutputStream
|
||||
realOutput.writeByte(flags);
|
||||
|
||||
ObjectStreamField[] fields = osc.fields;
|
||||
|
||||
if (fields == ObjectStreamClass.INVALID_FIELDS)
|
||||
throw new InvalidClassException
|
||||
(osc.getName(), "serialPersistentFields is invalid");
|
||||
|
||||
realOutput.writeShort(fields.length);
|
||||
|
||||
ObjectStreamField field;
|
||||
|
||||
@@ -63,6 +63,8 @@ import java.util.Vector;
|
||||
|
||||
public class ObjectStreamClass implements Serializable
|
||||
{
|
||||
static final ObjectStreamField[] INVALID_FIELDS = new ObjectStreamField[0];
|
||||
|
||||
/**
|
||||
* Returns the <code>ObjectStreamClass</code> for <code>cl</code>.
|
||||
* If <code>cl</code> is null, or is not <code>Serializable</code>,
|
||||
@@ -71,6 +73,11 @@ public class ObjectStreamClass implements Serializable
|
||||
* same <code>ObjectStreamClass</code> object and no recalculation
|
||||
* will be done.
|
||||
*
|
||||
* Warning: If this class contains an invalid serialPersistentField arrays
|
||||
* lookup will not throw anything. However {@link #getFields()} will return
|
||||
* an empty array and {@link java.io.ObjectOutputStream#writeObject} will throw an
|
||||
* {@link java.io.InvalidClassException}.
|
||||
*
|
||||
* @see java.io.Serializable
|
||||
*/
|
||||
public static ObjectStreamClass lookup(Class cl)
|
||||
@@ -148,6 +155,8 @@ public class ObjectStreamClass implements Serializable
|
||||
* Returns the serializable (non-static and non-transient) Fields
|
||||
* of the class represented by this ObjectStreamClass. The Fields
|
||||
* are sorted by name.
|
||||
* If fields were obtained using serialPersistentFields and this array
|
||||
* is faulty then the returned array of this method will be empty.
|
||||
*
|
||||
* @return the fields.
|
||||
*/
|
||||
@@ -608,6 +617,28 @@ outer:
|
||||
fields = getSerialPersistentFields(cl);
|
||||
if (fields != null)
|
||||
{
|
||||
ObjectStreamField[] fieldsName = new ObjectStreamField[fields.length];
|
||||
System.arraycopy(fields, 0, fieldsName, 0, fields.length);
|
||||
|
||||
Arrays.sort (fieldsName, new Comparator() {
|
||||
public int compare(Object o1, Object o2)
|
||||
{
|
||||
ObjectStreamField f1 = (ObjectStreamField)o1;
|
||||
ObjectStreamField f2 = (ObjectStreamField)o2;
|
||||
|
||||
return f1.getName().compareTo(f2.getName());
|
||||
}
|
||||
});
|
||||
|
||||
for (int i=1; i < fields.length; i++)
|
||||
{
|
||||
if (fieldsName[i-1].getName().equals(fieldsName[i].getName()))
|
||||
{
|
||||
fields = INVALID_FIELDS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Arrays.sort (fields);
|
||||
// Retrieve field reference.
|
||||
for (int i=0; i < fields.length; i++)
|
||||
|
||||
@@ -213,6 +213,8 @@ public class OutputStreamWriter extends Writer
|
||||
*
|
||||
* @param out The <code>OutputStream</code> to write to
|
||||
* @param cs The <code>Charset</code> of the encoding to use
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public OutputStreamWriter(OutputStream out, Charset cs)
|
||||
{
|
||||
@@ -230,6 +232,8 @@ public class OutputStreamWriter extends Writer
|
||||
*
|
||||
* @param out The <code>OutputStream</code> to write to
|
||||
* @param enc The <code>CharsetEncoder</code> to encode the output with
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public OutputStreamWriter(OutputStream out, CharsetEncoder enc)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* PrintStream.java -- OutputStream for printing output
|
||||
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -38,6 +39,8 @@ exception statement from your version. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import gnu.classpath.SystemProperties;
|
||||
|
||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
||||
* "The Java Language Specification", ISBN 0-201-63451-1
|
||||
* Status: Believed complete and correct to 1.3
|
||||
@@ -64,7 +67,7 @@ public class PrintStream extends FilterOutputStream
|
||||
|
||||
// Line separator string.
|
||||
private static final char[] line_separator
|
||||
= System.getProperty("line.separator").toCharArray();
|
||||
= SystemProperties.getProperty("line.separator").toCharArray();
|
||||
|
||||
/**
|
||||
* Encoding name
|
||||
@@ -112,7 +115,7 @@ public class PrintStream extends FilterOutputStream
|
||||
super (out);
|
||||
|
||||
try {
|
||||
this.encoding = System.getProperty("file.encoding");
|
||||
this.encoding = SystemProperties.getProperty("file.encoding");
|
||||
} catch (SecurityException e){
|
||||
this.encoding = "ISO8859_1";
|
||||
} catch (IllegalArgumentException e){
|
||||
|
||||
@@ -124,7 +124,10 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
|
||||
ch = FileChannelImpl.create(file, fdmode);
|
||||
fd = new FileDescriptor(ch);
|
||||
out = new DataOutputStream (new FileOutputStream (fd));
|
||||
if ((fdmode & FileChannelImpl.WRITE) != 0)
|
||||
out = new DataOutputStream (new FileOutputStream (fd));
|
||||
else
|
||||
out = null;
|
||||
in = new DataInputStream (new FileInputStream (fd));
|
||||
}
|
||||
|
||||
@@ -766,6 +769,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public void write (int oneByte) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.write(oneByte);
|
||||
}
|
||||
|
||||
@@ -777,6 +783,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public void write (byte[] buffer) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.write(buffer);
|
||||
}
|
||||
|
||||
@@ -792,6 +801,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public void write (byte[] buffer, int offset, int len) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.write (buffer, offset, len);
|
||||
}
|
||||
|
||||
@@ -806,6 +818,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeBoolean (boolean val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeBoolean(val);
|
||||
}
|
||||
|
||||
@@ -820,6 +835,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeByte (int val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeByte(val);
|
||||
}
|
||||
|
||||
@@ -834,6 +852,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeShort (int val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeShort(val);
|
||||
}
|
||||
|
||||
@@ -848,6 +869,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeChar (int val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeChar(val);
|
||||
}
|
||||
|
||||
@@ -861,6 +885,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeInt (int val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeInt(val);
|
||||
}
|
||||
|
||||
@@ -874,6 +901,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeLong (long val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeLong(val);
|
||||
}
|
||||
|
||||
@@ -893,6 +923,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeFloat (float val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeFloat(val);
|
||||
}
|
||||
|
||||
@@ -913,6 +946,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeDouble (double val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeDouble(val);
|
||||
}
|
||||
|
||||
@@ -927,6 +963,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeBytes (String val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeBytes(val);
|
||||
}
|
||||
|
||||
@@ -941,6 +980,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeChars (String val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeChars(val);
|
||||
}
|
||||
|
||||
@@ -975,6 +1017,9 @@ public class RandomAccessFile implements DataOutput, DataInput
|
||||
*/
|
||||
public final void writeUTF (String val) throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
throw new IOException("Bad file descriptor");
|
||||
|
||||
out.writeUTF(val);
|
||||
}
|
||||
|
||||
|
||||
@@ -550,6 +550,12 @@ public class StreamTokenizer
|
||||
/**
|
||||
* This method sets the numeric attribute on the characters '0' - '9' and
|
||||
* the characters '.' and '-'.
|
||||
* When this method is used, the result of giving other attributes
|
||||
* (whitespace, quote, or comment) to the numeric characters may
|
||||
* vary depending on the implementation. For example, if
|
||||
* parseNumbers() and then whitespaceChars('1', '1') are called,
|
||||
* this implementation reads "121" as 2, while some other implementation
|
||||
* will read it as 21.
|
||||
*/
|
||||
public void parseNumbers()
|
||||
{
|
||||
|
||||
@@ -2410,11 +2410,11 @@ public final class Character implements Serializable, Comparable
|
||||
{
|
||||
// Write second char first to cause IndexOutOfBoundsException
|
||||
// immediately.
|
||||
dst[dstIndex + 1] = (char) ((codePoint & 0x3ff)
|
||||
+ (int) MIN_LOW_SURROGATE );
|
||||
dst[dstIndex] = (char) ((codePoint >> 10) + (int) MIN_HIGH_SURROGATE);
|
||||
final int cp2 = codePoint - 0x10000;
|
||||
dst[dstIndex + 1] = (char) ((cp2 % 0x400) + (int) MIN_LOW_SURROGATE);
|
||||
dst[dstIndex] = (char) ((cp2 / 0x400) + (int) MIN_HIGH_SURROGATE);
|
||||
result = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[dstIndex] = (char) codePoint;
|
||||
@@ -2523,7 +2523,8 @@ public final class Character implements Serializable, Comparable
|
||||
*/
|
||||
public static int toCodePoint(char high, char low)
|
||||
{
|
||||
return ((high - MIN_HIGH_SURROGATE) << 10) + (low - MIN_LOW_SURROGATE);
|
||||
return ((high - MIN_HIGH_SURROGATE) * 0x400) +
|
||||
(low - MIN_LOW_SURROGATE) + 0x10000;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -583,8 +583,7 @@ public final class Class implements Serializable
|
||||
/**
|
||||
* Returns the <code>Package</code> in which this class is defined
|
||||
* Returns null when this information is not available from the
|
||||
* classloader of this class or when the classloader of this class
|
||||
* is null.
|
||||
* classloader of this class.
|
||||
*
|
||||
* @return the package for this class, if it is available
|
||||
* @since 1.2
|
||||
@@ -837,7 +836,10 @@ public final class Class implements Serializable
|
||||
*/
|
||||
public int getModifiers()
|
||||
{
|
||||
return VMClass.getModifiers (this, false);
|
||||
int mod = VMClass.getModifiers (this, false);
|
||||
return (mod & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
|
||||
Modifier.FINAL | Modifier.STATIC | Modifier.ABSTRACT |
|
||||
Modifier.INTERFACE));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -172,6 +172,81 @@ public final class Double extends Number implements Comparable
|
||||
return VMDouble.toString(d, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a double value to a hexadecimal string. This converts as
|
||||
* follows:
|
||||
* <ul>
|
||||
* <li> A NaN value is converted to the string "NaN".
|
||||
* <li> Positive infinity is converted to the string "Infinity".
|
||||
* <li> Negative infinity is converted to the string "-Infinity".
|
||||
* <li> For all other values, the first character of the result is '-'
|
||||
* if the value is negative. This is followed by '0x1.' if the
|
||||
* value is normal, and '0x0.' if the value is denormal. This is
|
||||
* then followed by a (lower-case) hexadecimal representation of the
|
||||
* mantissa, with leading zeros as required for denormal values.
|
||||
* The next character is a 'p', and this is followed by a decimal
|
||||
* representation of the unbiased exponent.
|
||||
* </ul>
|
||||
* @param d the double value
|
||||
* @return the hexadecimal string representation
|
||||
* @since 1.5
|
||||
*/
|
||||
public static String toHexString(double d)
|
||||
{
|
||||
if (isNaN(d))
|
||||
return "NaN";
|
||||
if (isInfinite(d))
|
||||
return d < 0 ? "-Infinity" : "Infinity";
|
||||
|
||||
long bits = doubleToLongBits(d);
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
if (bits < 0)
|
||||
result.append('-');
|
||||
result.append("0x");
|
||||
|
||||
final int mantissaBits = 52;
|
||||
final int exponentBits = 11;
|
||||
long mantMask = (1L << mantissaBits) - 1;
|
||||
long mantissa = bits & mantMask;
|
||||
long expMask = (1L << exponentBits) - 1;
|
||||
long exponent = (bits >>> mantissaBits) & expMask;
|
||||
|
||||
result.append(exponent == 0 ? '0' : '1');
|
||||
result.append('.');
|
||||
result.append(Long.toHexString(mantissa));
|
||||
if (exponent == 0 && mantissa != 0)
|
||||
{
|
||||
// Treat denormal specially by inserting '0's to make
|
||||
// the length come out right. The constants here are
|
||||
// to account for things like the '0x'.
|
||||
int offset = 4 + ((bits < 0) ? 1 : 0);
|
||||
// The silly +3 is here to keep the code the same between
|
||||
// the Float and Double cases. In Float the value is
|
||||
// not a multiple of 4.
|
||||
int desiredLength = offset + (mantissaBits + 3) / 4;
|
||||
while (result.length() < desiredLength)
|
||||
result.insert(offset, '0');
|
||||
}
|
||||
result.append('p');
|
||||
if (exponent == 0 && mantissa == 0)
|
||||
{
|
||||
// Zero, so do nothing special.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply bias.
|
||||
boolean denormal = exponent == 0;
|
||||
exponent -= (1 << (exponentBits - 1)) - 1;
|
||||
// Handle denormal.
|
||||
if (denormal)
|
||||
++exponent;
|
||||
}
|
||||
|
||||
result.append(Long.toString(exponent));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Double</code> object wrapping the value.
|
||||
* In contrast to the <code>Double</code> constructor, this method
|
||||
|
||||
@@ -182,6 +182,83 @@ public final class Float extends Number implements Comparable
|
||||
return VMDouble.toString(f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a float value to a hexadecimal string. This converts as
|
||||
* follows:
|
||||
* <ul>
|
||||
* <li> A NaN value is converted to the string "NaN".
|
||||
* <li> Positive infinity is converted to the string "Infinity".
|
||||
* <li> Negative infinity is converted to the string "-Infinity".
|
||||
* <li> For all other values, the first character of the result is '-'
|
||||
* if the value is negative. This is followed by '0x1.' if the
|
||||
* value is normal, and '0x0.' if the value is denormal. This is
|
||||
* then followed by a (lower-case) hexadecimal representation of the
|
||||
* mantissa, with leading zeros as required for denormal values.
|
||||
* The next character is a 'p', and this is followed by a decimal
|
||||
* representation of the unbiased exponent.
|
||||
* </ul>
|
||||
* @param f the float value
|
||||
* @return the hexadecimal string representation
|
||||
* @since 1.5
|
||||
*/
|
||||
public static String toHexString(float f)
|
||||
{
|
||||
if (isNaN(f))
|
||||
return "NaN";
|
||||
if (isInfinite(f))
|
||||
return f < 0 ? "-Infinity" : "Infinity";
|
||||
|
||||
int bits = floatToIntBits(f);
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
if (bits < 0)
|
||||
result.append('-');
|
||||
result.append("0x");
|
||||
|
||||
final int mantissaBits = 23;
|
||||
final int exponentBits = 8;
|
||||
int mantMask = (1 << mantissaBits) - 1;
|
||||
int mantissa = bits & mantMask;
|
||||
int expMask = (1 << exponentBits) - 1;
|
||||
int exponent = (bits >>> mantissaBits) & expMask;
|
||||
|
||||
result.append(exponent == 0 ? '0' : '1');
|
||||
result.append('.');
|
||||
// For Float only, we have to adjust the mantissa.
|
||||
mantissa <<= 1;
|
||||
result.append(Integer.toHexString(mantissa));
|
||||
if (exponent == 0 && mantissa != 0)
|
||||
{
|
||||
// Treat denormal specially by inserting '0's to make
|
||||
// the length come out right. The constants here are
|
||||
// to account for things like the '0x'.
|
||||
int offset = 4 + ((bits < 0) ? 1 : 0);
|
||||
// The silly +3 is here to keep the code the same between
|
||||
// the Float and Double cases. In Float the value is
|
||||
// not a multiple of 4.
|
||||
int desiredLength = offset + (mantissaBits + 3) / 4;
|
||||
while (result.length() < desiredLength)
|
||||
result.insert(offset, '0');
|
||||
}
|
||||
result.append('p');
|
||||
if (exponent == 0 && mantissa == 0)
|
||||
{
|
||||
// Zero, so do nothing special.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply bias.
|
||||
boolean denormal = exponent == 0;
|
||||
exponent -= (1 << (exponentBits - 1)) - 1;
|
||||
// Handle denormal.
|
||||
if (denormal)
|
||||
++exponent;
|
||||
}
|
||||
|
||||
result.append(Integer.toString(exponent));
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Float</code> object using the <code>String</code>.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* InheritableThreadLocal -- a ThreadLocal which inherits values across threads
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -37,8 +37,9 @@ exception statement from your version. */
|
||||
|
||||
package java.lang;
|
||||
|
||||
import gnu.java.util.WeakIdentityHashMap;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* A ThreadLocal whose value is inherited by child Threads. The value of the
|
||||
@@ -98,15 +99,15 @@ public class InheritableThreadLocal extends ThreadLocal
|
||||
Iterator keys = parentThread.locals.keySet().iterator();
|
||||
while (keys.hasNext())
|
||||
{
|
||||
Key key = (Key)keys.next();
|
||||
if (key.get() instanceof InheritableThreadLocal)
|
||||
Object key = keys.next();
|
||||
if (key instanceof InheritableThreadLocal)
|
||||
{
|
||||
InheritableThreadLocal local = (InheritableThreadLocal)key.get();
|
||||
InheritableThreadLocal local = (InheritableThreadLocal)key;
|
||||
Object parentValue = parentThread.locals.get(key);
|
||||
Object childValue = local.childValue(parentValue == NULL
|
||||
? null : parentValue);
|
||||
if (childThread.locals == null)
|
||||
childThread.locals = new WeakHashMap();
|
||||
childThread.locals = new WeakIdentityHashMap();
|
||||
childThread.locals.put(key, (childValue == null
|
||||
? NULL : childValue));
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@ package java.lang;
|
||||
import gnu.classpath.VMStackWalker;
|
||||
|
||||
import java.awt.AWTPermission;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
@@ -424,7 +421,7 @@ public class SecurityManager
|
||||
public void checkAccess(Thread thread)
|
||||
{
|
||||
if (thread.getThreadGroup() != null
|
||||
&& thread.getThreadGroup().getParent() != null)
|
||||
&& thread.getThreadGroup().getParent() == null)
|
||||
checkPermission(new RuntimePermission("modifyThread"));
|
||||
}
|
||||
|
||||
@@ -457,7 +454,7 @@ public class SecurityManager
|
||||
*/
|
||||
public void checkAccess(ThreadGroup g)
|
||||
{
|
||||
if (g.getParent() != null)
|
||||
if (g.getParent() == null)
|
||||
checkPermission(new RuntimePermission("modifyThreadGroup"));
|
||||
}
|
||||
|
||||
@@ -837,7 +834,7 @@ public class SecurityManager
|
||||
* @param window the window to create
|
||||
* @return true if there is permission to show the window without warning
|
||||
* @throws NullPointerException if window is null
|
||||
* @see Window#Window(Frame)
|
||||
* @see java.awt.Window#Window(java.awt.Frame)
|
||||
*/
|
||||
public boolean checkTopLevelWindow(Object window)
|
||||
{
|
||||
@@ -862,7 +859,7 @@ public class SecurityManager
|
||||
* an exception.
|
||||
*
|
||||
* @throws SecurityException if permission is denied
|
||||
* @see Toolkit#getPrintJob(Frame, String, Properties)
|
||||
* @see java.awt.Toolkit#getPrintJob(java.awt.Frame, String, Properties)
|
||||
* @since 1.1
|
||||
*/
|
||||
public void checkPrintJobAccess()
|
||||
@@ -878,7 +875,7 @@ public class SecurityManager
|
||||
* rather than throwing an exception.
|
||||
*
|
||||
* @throws SecurityException if permission is denied
|
||||
* @see Toolkit#getSystemClipboard()
|
||||
* @see java.awt.Toolkit#getSystemClipboard()
|
||||
* @since 1.1
|
||||
*/
|
||||
public void checkSystemClipboardAccess()
|
||||
@@ -894,7 +891,7 @@ public class SecurityManager
|
||||
* rather than throwing an exception.
|
||||
*
|
||||
* @throws SecurityException if permission is denied
|
||||
* @see Toolkit#getSystemEventQueue()
|
||||
* @see java.awt.Toolkit#getSystemEventQueue()
|
||||
* @since 1.1
|
||||
*/
|
||||
public void checkAwtEventQueueAccess()
|
||||
|
||||
@@ -49,7 +49,7 @@ import java.io.Serializable;
|
||||
* @author Mark Wielaard (mark@klomp.org)
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @since 1.4
|
||||
* @status updated to 1.4
|
||||
* @status updated to 1.5
|
||||
*/
|
||||
public final class StackTraceElement implements Serializable
|
||||
{
|
||||
@@ -111,6 +111,26 @@ public final class StackTraceElement implements Serializable
|
||||
this.isNative = isNative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new StackTraceElement representing a given source location.
|
||||
*
|
||||
* @param className the fully qualified name of the class
|
||||
* @param methodName the name of the method
|
||||
* @param fileName the name of the file, null if unknown
|
||||
* @param lineNumber the line in the file, negative if unknown, or -2
|
||||
* if this method is native
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public StackTraceElement(String className, String methodName, String fileName,
|
||||
int lineNumber)
|
||||
{
|
||||
this(fileName, lineNumber, className, methodName, lineNumber == -2);
|
||||
// The public constructor doesn't allow certain values to be null.
|
||||
if (className == null || methodName == null)
|
||||
throw new NullPointerException("invalid argument to constructor");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the file, or null if unknown. This is usually
|
||||
* obtained from the <code>SourceFile</code> attribute of the class file
|
||||
|
||||
@@ -273,7 +273,8 @@ public final class String implements Serializable, Comparable, CharSequence
|
||||
throw new StringIndexOutOfBoundsException("offset: " + offset);
|
||||
if (count < 0)
|
||||
throw new StringIndexOutOfBoundsException("count: " + count);
|
||||
if (offset + count < 0 || offset + count > ascii.length)
|
||||
// equivalent to: offset + count < 0 || offset + count > ascii.length
|
||||
if (ascii.length - offset < count)
|
||||
throw new StringIndexOutOfBoundsException("offset + count: "
|
||||
+ (offset + count));
|
||||
value = new char[count];
|
||||
@@ -338,7 +339,8 @@ public final class String implements Serializable, Comparable, CharSequence
|
||||
throw new StringIndexOutOfBoundsException("offset: " + offset);
|
||||
if (count < 0)
|
||||
throw new StringIndexOutOfBoundsException("count: " + count);
|
||||
if (offset + count < 0 || offset + count > data.length)
|
||||
// equivalent to: offset + count < 0 || offset + count > data.length
|
||||
if (data.length - offset < count)
|
||||
throw new StringIndexOutOfBoundsException("offset + count: "
|
||||
+ (offset + count));
|
||||
try
|
||||
@@ -418,7 +420,8 @@ public final class String implements Serializable, Comparable, CharSequence
|
||||
throw new StringIndexOutOfBoundsException("offset: " + offset);
|
||||
if (count < 0)
|
||||
throw new StringIndexOutOfBoundsException("count: " + count);
|
||||
if (offset + count < 0 || offset + count > data.length)
|
||||
// equivalent to: offset + count < 0 || offset + count > data.length
|
||||
if (data.length - offset < count)
|
||||
throw new StringIndexOutOfBoundsException("offset + count: "
|
||||
+ (offset + count));
|
||||
int o, c;
|
||||
@@ -533,7 +536,8 @@ public final class String implements Serializable, Comparable, CharSequence
|
||||
throw new StringIndexOutOfBoundsException("offset: " + offset);
|
||||
if (count < 0)
|
||||
throw new StringIndexOutOfBoundsException("count: " + count);
|
||||
if (offset + count < 0 || offset + count > data.length)
|
||||
// equivalent to: offset + count < 0 || offset + count > data.length
|
||||
if (data.length - offset < count)
|
||||
throw new StringIndexOutOfBoundsException("offset + count: "
|
||||
+ (offset + count));
|
||||
if (dont_copy)
|
||||
@@ -1761,7 +1765,7 @@ public final class String implements Serializable, Comparable, CharSequence
|
||||
|
||||
/**
|
||||
* Return the number of code points between two indices in the
|
||||
* <code>StringBuffer</code>. An unpaired surrogate counts as a
|
||||
* <code>String</code>. An unpaired surrogate counts as a
|
||||
* code point for this purpose. Characters outside the indicated
|
||||
* range are not examined, even if the range ends in the middle of a
|
||||
* surrogate pair.
|
||||
@@ -1879,6 +1883,8 @@ public final class String implements Serializable, Comparable, CharSequence
|
||||
* described in s.
|
||||
* @param s the CharSequence
|
||||
* @return true iff this String contains s
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean contains (CharSequence s)
|
||||
{
|
||||
|
||||
@@ -38,9 +38,9 @@ exception statement from your version. */
|
||||
|
||||
package java.lang;
|
||||
|
||||
import gnu.java.util.WeakIdentityHashMap;
|
||||
import java.security.Permission;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
||||
* "The Java Language Specification", ISBN 0-201-63451-1
|
||||
@@ -137,7 +137,7 @@ public class Thread implements Runnable
|
||||
/** Thread local storage. Package accessible for use by
|
||||
* InheritableThreadLocal.
|
||||
*/
|
||||
WeakHashMap locals;
|
||||
WeakIdentityHashMap locals;
|
||||
|
||||
/**
|
||||
* Allocates a new <code>Thread</code> object. This constructor has
|
||||
@@ -996,7 +996,7 @@ public class Thread implements Runnable
|
||||
Map locals = thread.locals;
|
||||
if (locals == null)
|
||||
{
|
||||
locals = thread.locals = new WeakHashMap();
|
||||
locals = thread.locals = new WeakIdentityHashMap();
|
||||
}
|
||||
return locals;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ThreadLocal -- a variable with a unique value per thread
|
||||
Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2002, 2003, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -95,21 +95,6 @@ public class ThreadLocal
|
||||
*/
|
||||
static final Object NULL = new Object();
|
||||
|
||||
/**
|
||||
* Serves as a key for the Thread.locals WeakHashMap.
|
||||
* We can't use "this", because a subclass may override equals/hashCode
|
||||
* and we need to use object identity for the map.
|
||||
*/
|
||||
final Key key = new Key();
|
||||
|
||||
class Key
|
||||
{
|
||||
ThreadLocal get()
|
||||
{
|
||||
return ThreadLocal.this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ThreadLocal object without associating any value to it yet.
|
||||
*/
|
||||
@@ -143,11 +128,11 @@ public class ThreadLocal
|
||||
Map map = Thread.getThreadLocals();
|
||||
// Note that we don't have to synchronize, as only this thread will
|
||||
// ever modify the map.
|
||||
Object value = map.get(key);
|
||||
Object value = map.get(this);
|
||||
if (value == null)
|
||||
{
|
||||
value = initialValue();
|
||||
map.put(key, value == null ? NULL : value);
|
||||
map.put(this, value == null ? NULL : value);
|
||||
}
|
||||
return value == NULL ? null : value;
|
||||
}
|
||||
@@ -165,6 +150,6 @@ public class ThreadLocal
|
||||
Map map = Thread.getThreadLocals();
|
||||
// Note that we don't have to synchronize, as only this thread will
|
||||
// ever modify the map.
|
||||
map.put(key, value == null ? NULL : value);
|
||||
map.put(this, value == null ? NULL : value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,12 @@ public class DatagramSocket
|
||||
{
|
||||
String propVal = SystemProperties.getProperty("impl.prefix");
|
||||
if (propVal == null || propVal.equals(""))
|
||||
impl = new PlainDatagramSocketImpl();
|
||||
{
|
||||
if (factory != null)
|
||||
impl = factory.createDatagramSocketImpl();
|
||||
else
|
||||
impl = new PlainDatagramSocketImpl();
|
||||
}
|
||||
else
|
||||
try
|
||||
{
|
||||
|
||||
@@ -43,7 +43,6 @@ import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
@@ -65,22 +64,6 @@ public class InetAddress implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 3286316764910316507L;
|
||||
|
||||
/**
|
||||
* The default DNS hash table size,
|
||||
* Use a prime number happy with hash table.
|
||||
*/
|
||||
private static final int DEFAULT_CACHE_SIZE = 89;
|
||||
|
||||
/**
|
||||
* The default caching period in minutes.
|
||||
*/
|
||||
private static final int DEFAULT_CACHE_PERIOD = 4 * 60;
|
||||
|
||||
/**
|
||||
* Percentage of cache entries to purge when the table gets full.
|
||||
*/
|
||||
private static final int DEFAULT_CACHE_PURGE_PCT = 30;
|
||||
|
||||
/**
|
||||
* The special IP address INADDR_ANY.
|
||||
*/
|
||||
@@ -96,50 +79,8 @@ public class InetAddress implements Serializable
|
||||
*/
|
||||
static InetAddress LOCALHOST;
|
||||
|
||||
/**
|
||||
* The size of the cache.
|
||||
*/
|
||||
private static int cache_size = 0;
|
||||
|
||||
/**
|
||||
* The length of time we will continue to read the address from cache
|
||||
* before forcing another lookup.
|
||||
*/
|
||||
private static int cache_period = 0;
|
||||
|
||||
/**
|
||||
* What percentage of the cache we will purge if it gets full.
|
||||
*/
|
||||
private static int cache_purge_pct = 0;
|
||||
|
||||
/**
|
||||
* HashMap to use as DNS lookup cache.
|
||||
* Use HashMap because all accesses to cache are already synchronized.
|
||||
*/
|
||||
private static HashMap cache;
|
||||
|
||||
static
|
||||
{
|
||||
// Look for properties that override default caching behavior
|
||||
cache_size =
|
||||
Integer.getInteger("gnu.java.net.dns_cache_size", DEFAULT_CACHE_SIZE)
|
||||
.intValue();
|
||||
cache_period =
|
||||
Integer.getInteger("gnu.java.net.dns_cache_period",
|
||||
DEFAULT_CACHE_PERIOD * 60 * 1000).intValue();
|
||||
|
||||
cache_purge_pct =
|
||||
Integer.getInteger("gnu.java.net.dns_cache_purge_pct",
|
||||
DEFAULT_CACHE_PURGE_PCT).intValue();
|
||||
|
||||
// Fallback to defaults if necessary
|
||||
if ((cache_purge_pct < 1) || (cache_purge_pct > 100))
|
||||
cache_purge_pct = DEFAULT_CACHE_PURGE_PCT;
|
||||
|
||||
// Create the cache
|
||||
if (cache_size != 0)
|
||||
cache = new HashMap(cache_size);
|
||||
|
||||
// precompute the ANY_IF address
|
||||
try
|
||||
{
|
||||
@@ -173,11 +114,6 @@ public class InetAddress implements Serializable
|
||||
*/
|
||||
String hostName;
|
||||
|
||||
/**
|
||||
* The time this address was looked up.
|
||||
*/
|
||||
transient long lookup_time;
|
||||
|
||||
/**
|
||||
* The field 'family' seems to be the AF_ value.
|
||||
* FIXME: Much of the code in the other java.net classes does not make
|
||||
@@ -200,8 +136,6 @@ public class InetAddress implements Serializable
|
||||
addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
|
||||
hostName = hostname;
|
||||
|
||||
lookup_time = System.currentTimeMillis();
|
||||
|
||||
family = 2; /* AF_INET */
|
||||
}
|
||||
|
||||
@@ -649,20 +583,17 @@ public class InetAddress implements Serializable
|
||||
|
||||
InetAddress[] addresses;
|
||||
|
||||
if (hostname != null)
|
||||
hostname = hostname.trim();
|
||||
|
||||
// Default to current host if necessary
|
||||
if (hostname == null)
|
||||
if (hostname == null || hostname.equals(""))
|
||||
{
|
||||
addresses = new InetAddress[1];
|
||||
addresses[0] = LOCALHOST;
|
||||
return addresses;
|
||||
}
|
||||
|
||||
// Check the cache for this host before doing a lookup
|
||||
addresses = checkCacheFor(hostname);
|
||||
|
||||
if (addresses != null)
|
||||
return addresses;
|
||||
|
||||
// Not in cache, try the lookup
|
||||
byte[][] iplist = VMInetAddress.getHostByName(hostname);
|
||||
|
||||
@@ -679,70 +610,9 @@ public class InetAddress implements Serializable
|
||||
addresses[i] = new Inet4Address(iplist[i], hostname);
|
||||
}
|
||||
|
||||
addToCache(hostname, addresses);
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the DNS cache to see if we have looked this hostname
|
||||
* up before. If so, we return the cached addresses unless it has been in the
|
||||
* cache too long.
|
||||
*
|
||||
* @param hostname The hostname to check for
|
||||
*
|
||||
* @return The InetAddress for this hostname or null if not available
|
||||
*/
|
||||
private static synchronized InetAddress[] checkCacheFor(String hostname)
|
||||
{
|
||||
InetAddress[] addresses = null;
|
||||
|
||||
if (cache_size == 0)
|
||||
return null;
|
||||
|
||||
Object obj = cache.get(hostname);
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if (obj instanceof InetAddress[])
|
||||
addresses = (InetAddress[]) obj;
|
||||
|
||||
if (addresses == null)
|
||||
return null;
|
||||
|
||||
if (cache_period != -1)
|
||||
if ((System.currentTimeMillis() - addresses[0].lookup_time) > cache_period)
|
||||
{
|
||||
cache.remove(hostname);
|
||||
return null;
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds an InetAddress object to our DNS cache. Note that
|
||||
* if the cache is full, then we run a purge to get rid of old entries.
|
||||
* This will cause a performance hit, thus applications using lots of
|
||||
* lookups should set the cache size to be very large.
|
||||
*
|
||||
* @param hostname The hostname to cache this address under
|
||||
* @param obj The InetAddress or InetAddress array to store
|
||||
*/
|
||||
private static synchronized void addToCache(String hostname, Object obj)
|
||||
{
|
||||
if (cache_size == 0)
|
||||
return;
|
||||
|
||||
// Check to see if hash table is full
|
||||
if (cache_size != -1)
|
||||
if (cache.size() == cache_size)
|
||||
{
|
||||
// FIXME Add code to purge later.
|
||||
}
|
||||
|
||||
cache.put(hostname, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the special address INADDR_ANY used for binding to a local
|
||||
* port on all IP addresses hosted by a the local host.
|
||||
@@ -757,6 +627,7 @@ public class InetAddress implements Serializable
|
||||
{
|
||||
byte[] tmp = VMInetAddress.lookupInaddrAny();
|
||||
inaddr_any = new Inet4Address(tmp, null);
|
||||
inaddr_any.hostName = inaddr_any.getHostName();
|
||||
}
|
||||
|
||||
return inaddr_any;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* URL.java -- Uniform Resource Locator Class
|
||||
Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005
|
||||
Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
@@ -38,6 +38,7 @@ exception statement from your version. */
|
||||
|
||||
package java.net;
|
||||
|
||||
import gnu.classpath.SystemProperties;
|
||||
import gnu.java.net.URLParseError;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -198,7 +199,7 @@ public final class URL implements Serializable
|
||||
|
||||
static
|
||||
{
|
||||
String s = System.getProperty("gnu.java.net.nocache_protocol_handlers");
|
||||
String s = SystemProperties.getProperty("gnu.java.net.nocache_protocol_handlers");
|
||||
|
||||
if (s == null)
|
||||
cache_handlers = true;
|
||||
@@ -342,7 +343,7 @@ public final class URL implements Serializable
|
||||
*/
|
||||
public URL(URL context, String spec) throws MalformedURLException
|
||||
{
|
||||
this(context, spec, (URLStreamHandler) null);
|
||||
this(context, spec, (context == null) ? (URLStreamHandler)null : context.ph);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -867,7 +868,7 @@ public final class URL implements Serializable
|
||||
// Except in very unusual environments the JDK specified one shouldn't
|
||||
// ever be needed (or available).
|
||||
String ph_search_path =
|
||||
System.getProperty("java.protocol.handler.pkgs");
|
||||
SystemProperties.getProperty("java.protocol.handler.pkgs");
|
||||
|
||||
// Tack our default package on at the ends.
|
||||
if (ph_search_path != null)
|
||||
|
||||
@@ -121,6 +121,8 @@ public abstract class Charset implements Comparable
|
||||
*
|
||||
* This may be set by the user or VM with the file.encoding
|
||||
* property.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public static Charset defaultCharset()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* CharsetProvider.java -- charset service provider interface
|
||||
Copyright (C) 2002 Free Software Foundation
|
||||
Copyright (C) 2002, 2006 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -67,8 +67,12 @@ public abstract class CharsetProvider
|
||||
*/
|
||||
protected CharsetProvider()
|
||||
{
|
||||
// We only do the security check for custom providers, not for the
|
||||
// built in ones.
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
if (s != null)
|
||||
if (s != null &&
|
||||
! (this instanceof gnu.java.nio.charset.Provider
|
||||
|| this instanceof gnu.java.nio.charset.iconv.IconvProvider))
|
||||
s.checkPermission(new RuntimePermission("charsetProvider"));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* MessageDigest.java --- The message digest interface.
|
||||
Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2002, 2003, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -167,6 +167,9 @@ public abstract class MessageDigest extends MessageDigestSpi
|
||||
public static MessageDigest getInstance(String algorithm, String provider)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException
|
||||
{
|
||||
if (provider != null)
|
||||
provider = provider.trim();
|
||||
|
||||
if (provider == null || provider.length() == 0)
|
||||
throw new IllegalArgumentException("Illegal provider");
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* Security.java --- Java base security class implementation
|
||||
Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -41,6 +42,7 @@ package java.security;
|
||||
import gnu.classpath.SystemProperties;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
import gnu.classpath.VMStackWalker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -354,6 +356,14 @@ public final class Security
|
||||
*/
|
||||
public static Provider getProvider(String name)
|
||||
{
|
||||
if (name == null)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
name = name.trim();
|
||||
if (name.length() == 0)
|
||||
return null;
|
||||
}
|
||||
Provider p;
|
||||
int max = providers.size ();
|
||||
for (int i = 0; i < max; i++)
|
||||
@@ -383,8 +393,11 @@ public final class Security
|
||||
*/
|
||||
public static String getProperty(String key)
|
||||
{
|
||||
// XXX To prevent infinite recursion when the SecurityManager calls us,
|
||||
// don't do a security check if the caller is trusted (by virtue of having
|
||||
// been loaded by the bootstrap class loader).
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
if (sm != null && VMStackWalker.getCallingClassLoader() != null)
|
||||
sm.checkSecurityAccess("getProperty." + key);
|
||||
|
||||
return secprops.getProperty(key);
|
||||
@@ -399,20 +412,23 @@ public final class Security
|
||||
* </p>
|
||||
*
|
||||
* @param key the name of the property to be set.
|
||||
* @param datnum the value of the property to be set.
|
||||
* @param datum the value of the property to be set.
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* {@link SecurityManager#checkPermission(Permission)} method denies access
|
||||
* to set the specified security property value.
|
||||
* @see #getProperty(String)
|
||||
* @see SecurityPermission
|
||||
*/
|
||||
public static void setProperty(String key, String datnum)
|
||||
public static void setProperty(String key, String datum)
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkSecurityAccess("setProperty." + key);
|
||||
|
||||
secprops.put(key, datnum);
|
||||
if (datum == null)
|
||||
secprops.remove(key);
|
||||
else
|
||||
secprops.put(key, datum);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/* Bidi.java -- Bidirectional Algorithm implementation
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.text;
|
||||
|
||||
/**
|
||||
* Bidirectional Algorithm implementation.
|
||||
*
|
||||
* TODO/FIXME Only one method <code>requiresBidi</code> is implemented
|
||||
* for now by using <code>Character</code>. The full algorithm is <a
|
||||
* href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard
|
||||
* Annex #9: The Bidirectional Algorithm</a>. A full implementation is
|
||||
* <a href="http://fribidi.org/">GNU FriBidi</a>.
|
||||
*/
|
||||
public class Bidi
|
||||
{
|
||||
/**
|
||||
* Returns false if all characters in the text between start and end
|
||||
* are all left-to-right text. This implementation is just calls
|
||||
* <code>Character.getDirectionality(char)</code> on all characters
|
||||
* and makes sure all characters are either explicitly left-to-right
|
||||
* or neutral in directionality (character types L, EN, ES, ET, AN,
|
||||
* CS, S and WS).
|
||||
*/
|
||||
public static boolean requiresBidi(char[] text, int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
byte dir = Character.getDirectionality(text[i]);
|
||||
if (dir != Character.DIRECTIONALITY_LEFT_TO_RIGHT
|
||||
&& dir != Character.DIRECTIONALITY_EUROPEAN_NUMBER
|
||||
&& dir != Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
|
||||
&& dir != Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
|
||||
&& dir != Character.DIRECTIONALITY_ARABIC_NUMBER
|
||||
&& dir != Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
|
||||
&& dir != Character.DIRECTIONALITY_SEGMENT_SEPARATOR
|
||||
&& dir != Character.DIRECTIONALITY_WHITESPACE)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,9 @@ public class DecimalFormat extends NumberFormat
|
||||
{
|
||||
groupingUsed = saw_group;
|
||||
groupingSize = (byte) countSinceGroup;
|
||||
minimumIntegerDigits = zeroCount;
|
||||
// Checking "zeroCount > 0" avoids 0 being formatted into "" with "#".
|
||||
if (zeroCount > 0)
|
||||
minimumIntegerDigits = zeroCount;
|
||||
}
|
||||
|
||||
// Early termination.
|
||||
|
||||
@@ -594,13 +594,13 @@ public abstract class AbstractMap implements Map
|
||||
*
|
||||
* @param o1 the first object
|
||||
* @param o2 the second object
|
||||
* @return o1 == null ? o2 == null : o1.equals(o2)
|
||||
* @return o1 == o2 || (o1 != null && o1.equals(o2))
|
||||
*/
|
||||
// Package visible for use throughout java.util.
|
||||
// It may be inlined since it is final.
|
||||
static final boolean equals(Object o1, Object o2)
|
||||
{
|
||||
return o1 == null ? o2 == null : o1.equals(o2);
|
||||
return o1 == o2 || (o1 != null && o1.equals(o2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -92,7 +92,7 @@ public class ArrayList extends AbstractList
|
||||
/**
|
||||
* The default capacity for new ArrayLists.
|
||||
*/
|
||||
private static final int DEFAULT_CAPACITY = 16;
|
||||
private static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
/**
|
||||
* The number of elements in this list.
|
||||
|
||||
@@ -670,10 +670,10 @@ public class Collections
|
||||
for ( ; i != pos; i--, o = itr.previous());
|
||||
forward = false;
|
||||
}
|
||||
final int d = compare(key, o, c);
|
||||
final int d = compare(o, key, c);
|
||||
if (d == 0)
|
||||
return pos;
|
||||
else if (d < 0)
|
||||
else if (d > 0)
|
||||
hi = pos - 1;
|
||||
else
|
||||
// This gets the insertion point right on the last loop
|
||||
@@ -685,10 +685,10 @@ public class Collections
|
||||
while (low <= hi)
|
||||
{
|
||||
pos = (low + hi) >> 1;
|
||||
final int d = compare(key, l.get(pos), c);
|
||||
final int d = compare(l.get(pos), key, c);
|
||||
if (d == 0)
|
||||
return pos;
|
||||
else if (d < 0)
|
||||
else if (d > 0)
|
||||
hi = pos - 1;
|
||||
else
|
||||
// This gets the insertion point right on the last loop
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Hashtable.java -- a class providing a basic hashtable data structure,
|
||||
mapping Object --> Object
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@@ -110,12 +111,6 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
private static final int DEFAULT_CAPACITY = 11;
|
||||
|
||||
/** An "enum" of iterator types. */
|
||||
// Package visible for use by nested classes.
|
||||
static final int KEYS = 0,
|
||||
VALUES = 1,
|
||||
ENTRIES = 2;
|
||||
|
||||
/**
|
||||
* The default load factor; this is explicitly specified by the spec.
|
||||
*/
|
||||
@@ -302,7 +297,7 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
public Enumeration keys()
|
||||
{
|
||||
return new Enumerator(KEYS);
|
||||
return new KeyEnumerator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -316,7 +311,7 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
public Enumeration elements()
|
||||
{
|
||||
return new Enumerator(VALUES);
|
||||
return new ValueEnumerator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,20 +328,19 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
public synchronized boolean contains(Object value)
|
||||
{
|
||||
if (value == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
for (int i = buckets.length - 1; i >= 0; i--)
|
||||
{
|
||||
HashEntry e = buckets[i];
|
||||
while (e != null)
|
||||
{
|
||||
if (value.equals(e.value))
|
||||
if (e.value.equals(value))
|
||||
return true;
|
||||
e = e.next;
|
||||
}
|
||||
}
|
||||
|
||||
// Must throw on null argument even if the table is empty
|
||||
if (value == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -385,7 +379,7 @@ public class Hashtable extends Dictionary
|
||||
HashEntry e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (key.equals(e.key))
|
||||
if (e.key.equals(key))
|
||||
return true;
|
||||
e = e.next;
|
||||
}
|
||||
@@ -408,7 +402,7 @@ public class Hashtable extends Dictionary
|
||||
HashEntry e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (key.equals(e.key))
|
||||
if (e.key.equals(key))
|
||||
return e.value;
|
||||
e = e.next;
|
||||
}
|
||||
@@ -438,7 +432,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
while (e != null)
|
||||
{
|
||||
if (key.equals(e.key))
|
||||
if (e.key.equals(key))
|
||||
{
|
||||
// Bypass e.setValue, since we already know value is non-null.
|
||||
Object r = e.value;
|
||||
@@ -484,7 +478,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
while (e != null)
|
||||
{
|
||||
if (key.equals(e.key))
|
||||
if (e.key.equals(key))
|
||||
{
|
||||
modCount++;
|
||||
if (last == null)
|
||||
@@ -581,8 +575,8 @@ public class Hashtable extends Dictionary
|
||||
{
|
||||
// Since we are already synchronized, and entrySet().iterator()
|
||||
// would repeatedly re-lock/release the monitor, we directly use the
|
||||
// unsynchronized HashIterator instead.
|
||||
Iterator entries = new HashIterator(ENTRIES);
|
||||
// unsynchronized EntryIterator instead.
|
||||
Iterator entries = new EntryIterator();
|
||||
StringBuffer r = new StringBuffer("{");
|
||||
for (int pos = size; pos > 0; pos--)
|
||||
{
|
||||
@@ -624,7 +618,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return new HashIterator(KEYS);
|
||||
return new KeyIterator();
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -682,7 +676,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return new HashIterator(VALUES);
|
||||
return new ValueIterator();
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -734,7 +728,7 @@ public class Hashtable extends Dictionary
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return new HashIterator(ENTRIES);
|
||||
return new EntryIterator();
|
||||
}
|
||||
|
||||
public void clear()
|
||||
@@ -798,8 +792,8 @@ public class Hashtable extends Dictionary
|
||||
{
|
||||
// Since we are already synchronized, and entrySet().iterator()
|
||||
// would repeatedly re-lock/release the monitor, we directly use the
|
||||
// unsynchronized HashIterator instead.
|
||||
Iterator itr = new HashIterator(ENTRIES);
|
||||
// unsynchronized EntryIterator instead.
|
||||
Iterator itr = new EntryIterator();
|
||||
int hashcode = 0;
|
||||
for (int pos = size; pos > 0; pos--)
|
||||
hashcode += itr.next().hashCode();
|
||||
@@ -844,7 +838,7 @@ public class Hashtable extends Dictionary
|
||||
HashEntry e = buckets[idx];
|
||||
while (e != null)
|
||||
{
|
||||
if (o.equals(e))
|
||||
if (e.equals(o))
|
||||
return e;
|
||||
e = e.next;
|
||||
}
|
||||
@@ -904,8 +898,12 @@ public class Hashtable extends Dictionary
|
||||
|
||||
if (dest != null)
|
||||
{
|
||||
while (dest.next != null)
|
||||
dest = dest.next;
|
||||
HashEntry next = dest.next;
|
||||
while (next != null)
|
||||
{
|
||||
dest = next;
|
||||
next = dest.next;
|
||||
}
|
||||
dest.next = e;
|
||||
}
|
||||
else
|
||||
@@ -940,8 +938,8 @@ public class Hashtable extends Dictionary
|
||||
s.writeInt(size);
|
||||
// Since we are already synchronized, and entrySet().iterator()
|
||||
// would repeatedly re-lock/release the monitor, we directly use the
|
||||
// unsynchronized HashIterator instead.
|
||||
Iterator it = new HashIterator(ENTRIES);
|
||||
// unsynchronized EntryIterator instead.
|
||||
Iterator it = new EntryIterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
HashEntry entry = (HashEntry) it.next();
|
||||
@@ -980,21 +978,17 @@ public class Hashtable extends Dictionary
|
||||
/**
|
||||
* A class which implements the Iterator interface and is used for
|
||||
* iterating over Hashtables.
|
||||
* This implementation is parameterized to give a sequential view of
|
||||
* keys, values, or entries; it also allows the removal of elements,
|
||||
* as per the Javasoft spec. Note that it is not synchronized; this is
|
||||
* a performance enhancer since it is never exposed externally and is
|
||||
* only used within synchronized blocks above.
|
||||
* This implementation iterates entries. Subclasses are used to
|
||||
* iterate key and values. It also allows the removal of elements,
|
||||
* as per the Javasoft spec. Note that it is not synchronized; this
|
||||
* is a performance enhancer since it is never exposed externally
|
||||
* and is only used within synchronized blocks above.
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
*/
|
||||
private final class HashIterator implements Iterator
|
||||
private class EntryIterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* The type of this Iterator: {@link #KEYS}, {@link #VALUES},
|
||||
* or {@link #ENTRIES}.
|
||||
*/
|
||||
final int type;
|
||||
/**
|
||||
* The number of modifications to the backing Hashtable that we know about.
|
||||
*/
|
||||
@@ -1013,14 +1007,13 @@ public class Hashtable extends Dictionary
|
||||
HashEntry next;
|
||||
|
||||
/**
|
||||
* Construct a new HashIterator with the supplied type.
|
||||
* @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
|
||||
* Construct a new EtryIterator
|
||||
*/
|
||||
HashIterator(int type)
|
||||
EntryIterator()
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the Iterator has more elements.
|
||||
* @return true if there are more elements
|
||||
@@ -1049,14 +1042,13 @@ public class Hashtable extends Dictionary
|
||||
HashEntry e = next;
|
||||
|
||||
while (e == null)
|
||||
e = buckets[--idx];
|
||||
if (idx <= 0)
|
||||
return null;
|
||||
else
|
||||
e = buckets[--idx];
|
||||
|
||||
next = e.next;
|
||||
last = e;
|
||||
if (type == VALUES)
|
||||
return e.value;
|
||||
if (type == KEYS)
|
||||
return e.key;
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -1077,29 +1069,70 @@ public class Hashtable extends Dictionary
|
||||
last = null;
|
||||
knownMod++;
|
||||
}
|
||||
} // class HashIterator
|
||||
} // class EntryIterator
|
||||
|
||||
/**
|
||||
* A class which implements the Iterator interface and is used for
|
||||
* iterating over keys in Hashtables.
|
||||
*
|
||||
* @author Fridtjof Siebert
|
||||
*/
|
||||
private class KeyIterator extends EntryIterator
|
||||
{
|
||||
/**
|
||||
* Returns the next element in the Iterator's sequential view.
|
||||
*
|
||||
* @return the next element
|
||||
*
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
{
|
||||
return ((HashEntry)super.next()).key;
|
||||
}
|
||||
} // class KeyIterator
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration view of this Hashtable, providing sequential access to its
|
||||
* elements; this implementation is parameterized to provide access either
|
||||
* to the keys or to the values in the Hashtable.
|
||||
* A class which implements the Iterator interface and is used for
|
||||
* iterating over values in Hashtables.
|
||||
*
|
||||
* @author Fridtjof Siebert
|
||||
*/
|
||||
private class ValueIterator extends EntryIterator
|
||||
{
|
||||
/**
|
||||
* Returns the next element in the Iterator's sequential view.
|
||||
*
|
||||
* @return the next element
|
||||
*
|
||||
* @throws ConcurrentModificationException if the hashtable was modified
|
||||
* @throws NoSuchElementException if there is none
|
||||
*/
|
||||
public Object next()
|
||||
{
|
||||
return ((HashEntry)super.next()).value;
|
||||
}
|
||||
} // class ValueIterator
|
||||
|
||||
/**
|
||||
* Enumeration view of the entries in this Hashtable, providing
|
||||
* sequential access to its elements.
|
||||
*
|
||||
* <b>NOTE</b>: Enumeration is not safe if new elements are put in the table
|
||||
* as this could cause a rehash and we'd completely lose our place. Even
|
||||
* without a rehash, it is undetermined if a new element added would
|
||||
* appear in the enumeration. The spec says nothing about this, but
|
||||
* the "Java Class Libraries" book infers that modifications to the
|
||||
* the "Java Class Libraries" book implies that modifications to the
|
||||
* hashtable during enumeration causes indeterminate results. Don't do it!
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
*/
|
||||
private final class Enumerator implements Enumeration
|
||||
private class EntryEnumerator implements Enumeration
|
||||
{
|
||||
/**
|
||||
* The type of this Iterator: {@link #KEYS} or {@link #VALUES}.
|
||||
*/
|
||||
final int type;
|
||||
/** The number of elements remaining to be returned by next(). */
|
||||
int count = size;
|
||||
/** Current index in the physical hash table. */
|
||||
@@ -1113,11 +1146,10 @@ public class Hashtable extends Dictionary
|
||||
|
||||
/**
|
||||
* Construct the enumeration.
|
||||
* @param type either {@link #KEYS} or {@link #VALUES}.
|
||||
*/
|
||||
Enumerator(int type)
|
||||
EntryEnumerator()
|
||||
{
|
||||
this.type = type;
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,10 +1174,78 @@ public class Hashtable extends Dictionary
|
||||
HashEntry e = next;
|
||||
|
||||
while (e == null)
|
||||
e = buckets[--idx];
|
||||
if (idx <= 0)
|
||||
return null;
|
||||
else
|
||||
e = buckets[--idx];
|
||||
|
||||
next = e.next;
|
||||
return type == VALUES ? e.value : e.key;
|
||||
return e;
|
||||
}
|
||||
} // class Enumerator
|
||||
} // class EntryEnumerator
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration view of this Hashtable, providing sequential access to its
|
||||
* elements.
|
||||
*
|
||||
* <b>NOTE</b>: Enumeration is not safe if new elements are put in the table
|
||||
* as this could cause a rehash and we'd completely lose our place. Even
|
||||
* without a rehash, it is undetermined if a new element added would
|
||||
* appear in the enumeration. The spec says nothing about this, but
|
||||
* the "Java Class Libraries" book implies that modifications to the
|
||||
* hashtable during enumeration causes indeterminate results. Don't do it!
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
*/
|
||||
private final class KeyEnumerator extends EntryEnumerator
|
||||
{
|
||||
/**
|
||||
* Returns the next element.
|
||||
* @return the next element
|
||||
* @throws NoSuchElementException if there is none.
|
||||
*/
|
||||
public Object nextElement()
|
||||
{
|
||||
HashEntry entry = (HashEntry) super.nextElement();
|
||||
Object retVal = null;
|
||||
if (entry != null)
|
||||
retVal = entry.key;
|
||||
return retVal;
|
||||
}
|
||||
} // class KeyEnumerator
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration view of this Hashtable, providing sequential access to its
|
||||
* values.
|
||||
*
|
||||
* <b>NOTE</b>: Enumeration is not safe if new elements are put in the table
|
||||
* as this could cause a rehash and we'd completely lose our place. Even
|
||||
* without a rehash, it is undetermined if a new element added would
|
||||
* appear in the enumeration. The spec says nothing about this, but
|
||||
* the "Java Class Libraries" book implies that modifications to the
|
||||
* hashtable during enumeration causes indeterminate results. Don't do it!
|
||||
*
|
||||
* @author Jon Zeppieri
|
||||
* @author Fridjof Siebert
|
||||
*/
|
||||
private final class ValueEnumerator extends EntryEnumerator
|
||||
{
|
||||
/**
|
||||
* Returns the next element.
|
||||
* @return the next element
|
||||
* @throws NoSuchElementException if there is none.
|
||||
*/
|
||||
public Object nextElement()
|
||||
{
|
||||
HashEntry entry = (HashEntry) super.nextElement();
|
||||
Object retVal = null;
|
||||
if (entry != null)
|
||||
retVal = entry.value;
|
||||
return retVal;
|
||||
}
|
||||
} // class ValueEnumerator
|
||||
|
||||
} // class Hashtable
|
||||
|
||||
@@ -47,15 +47,10 @@ import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.ext.DefaultHandler2;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.DocumentType;
|
||||
@@ -743,173 +738,64 @@ label = Name:\\u0020</pre>
|
||||
throw new NullPointerException("Null input stream supplied.");
|
||||
try
|
||||
{
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
factory.setValidating(false); /* Don't use the URI */
|
||||
XMLReader parser = factory.newSAXParser().getXMLReader();
|
||||
PropertiesHandler handler = new PropertiesHandler();
|
||||
parser.setContentHandler(handler);
|
||||
parser.setProperty("http://xml.org/sax/properties/lexical-handler",
|
||||
handler);
|
||||
parser.parse(new InputSource(in));
|
||||
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||
// Don't resolve external entity references
|
||||
factory.setProperty("javax.xml.stream.isSupportingExternalEntities",
|
||||
Boolean.FALSE);
|
||||
XMLStreamReader reader = factory.createXMLStreamReader(in);
|
||||
String name, key = null;
|
||||
StringBuffer buf = null;
|
||||
while (reader.hasNext())
|
||||
{
|
||||
switch (reader.next())
|
||||
{
|
||||
case XMLStreamConstants.START_ELEMENT:
|
||||
name = reader.getLocalName();
|
||||
if (buf == null && "entry".equals(name))
|
||||
{
|
||||
key = reader.getAttributeValue(null, "key");
|
||||
if (key == null)
|
||||
{
|
||||
String msg = "missing 'key' attribute";
|
||||
throw new InvalidPropertiesFormatException(msg);
|
||||
}
|
||||
buf = new StringBuffer();
|
||||
}
|
||||
else if (!"properties".equals(name) && !"comment".equals(name))
|
||||
{
|
||||
String msg = "unexpected element name '" + name + "'";
|
||||
throw new InvalidPropertiesFormatException(msg);
|
||||
}
|
||||
break;
|
||||
case XMLStreamConstants.END_ELEMENT:
|
||||
name = reader.getLocalName();
|
||||
if (buf != null && "entry".equals(name))
|
||||
{
|
||||
put(key, buf.toString());
|
||||
buf = null;
|
||||
}
|
||||
else if (!"properties".equals(name) && !"comment".equals(name))
|
||||
{
|
||||
String msg = "unexpected element name '" + name + "'";
|
||||
throw new InvalidPropertiesFormatException(msg);
|
||||
}
|
||||
break;
|
||||
case XMLStreamConstants.CHARACTERS:
|
||||
case XMLStreamConstants.SPACE:
|
||||
case XMLStreamConstants.CDATA:
|
||||
if (buf != null)
|
||||
buf.append(reader.getText());
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
catch (SAXException e)
|
||||
catch (XMLStreamException e)
|
||||
{
|
||||
throw (InvalidPropertiesFormatException)
|
||||
new InvalidPropertiesFormatException("Error in parsing XML.").
|
||||
initCause(e);
|
||||
}
|
||||
catch (ParserConfigurationException e)
|
||||
{
|
||||
throw (IOException)
|
||||
new IOException("An XML parser could not be found.").
|
||||
initCause(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class deals with the parsing of XML using
|
||||
* <a href="http://java.sun.com/dtd/properties.dtd">
|
||||
* http://java.sun.com/dtd/properties.dtd</a>.
|
||||
*
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.5
|
||||
*/
|
||||
private class PropertiesHandler
|
||||
extends DefaultHandler2
|
||||
{
|
||||
|
||||
/**
|
||||
* The current key.
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* The current value.
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* A flag to check whether a valid DTD declaration has been seen.
|
||||
*/
|
||||
private boolean dtdDeclSeen;
|
||||
|
||||
/**
|
||||
* Constructs a new Properties handler.
|
||||
*/
|
||||
public PropertiesHandler()
|
||||
{
|
||||
key = null;
|
||||
value = null;
|
||||
dtdDeclSeen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Captures the start of the DTD declarations, if they exist.
|
||||
* A valid properties file must declare the following doctype:
|
||||
* </p>
|
||||
* <p>
|
||||
* <code>!DOCTYPE properties SYSTEM
|
||||
* "http://java.sun.com/dtd/properties.dtd"</code>
|
||||
* </p>
|
||||
*
|
||||
* @param name the name of the document type.
|
||||
* @param publicId the public identifier that was declared, or
|
||||
* null if there wasn't one.
|
||||
* @param systemId the system identifier that was declared, or
|
||||
* null if there wasn't one.
|
||||
* @throws SAXException if some error occurs in parsing.
|
||||
*/
|
||||
public void startDTD(String name, String publicId, String systemId)
|
||||
throws SAXException
|
||||
{
|
||||
if (name.equals("properties") &&
|
||||
publicId == null &&
|
||||
systemId.equals("http://java.sun.com/dtd/properties.dtd"))
|
||||
{
|
||||
dtdDeclSeen = true;
|
||||
}
|
||||
else
|
||||
throw new SAXException("Invalid DTD declaration: " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the start of an XML element.
|
||||
*
|
||||
* @param uri the namespace URI.
|
||||
* @param localName the local name of the element inside the namespace.
|
||||
* @param qName the local name qualified with the namespace URI.
|
||||
* @param attributes the attributes of this element.
|
||||
* @throws SAXException if some error occurs in parsing.
|
||||
*/
|
||||
public void startElement(String uri, String localName,
|
||||
String qName, Attributes attributes)
|
||||
throws SAXException
|
||||
{
|
||||
if (qName.equals("entry"))
|
||||
{
|
||||
int index = attributes.getIndex("key");
|
||||
if (index != -1)
|
||||
key = attributes.getValue(index);
|
||||
}
|
||||
else if (qName.equals("comment") || qName.equals("properties"))
|
||||
{
|
||||
/* Ignore it */
|
||||
}
|
||||
else
|
||||
throw new SAXException("Invalid tag: " + qName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures characters within an XML element.
|
||||
*
|
||||
* @param ch the array of characters.
|
||||
* @param start the start index of the characters to use.
|
||||
* @param length the number of characters to use from the start index on.
|
||||
* @throws SAXException if some error occurs in parsing.
|
||||
*/
|
||||
public void characters(char[] ch, int start, int length)
|
||||
throws SAXException
|
||||
{
|
||||
if (key != null)
|
||||
value = new String(ch,start,length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the end of an XML element.
|
||||
*
|
||||
* @param uri the namespace URI.
|
||||
* @param localName the local name of the element inside the namespace.
|
||||
* @param qName the local name qualified with the namespace URI.
|
||||
* @throws SAXException if some error occurs in parsing.
|
||||
*/
|
||||
public void endElement(String uri, String localName,
|
||||
String qName)
|
||||
throws SAXException
|
||||
{
|
||||
if (qName.equals("entry"))
|
||||
{
|
||||
if (value == null)
|
||||
value = "";
|
||||
setProperty(key, value);
|
||||
key = null;
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the end of the XML document. If a DTD declaration has
|
||||
* not been seen, the document is erroneous and an exception is thrown.
|
||||
*
|
||||
* @throws SAXException if the correct DTD declaration didn't appear.
|
||||
*/
|
||||
public void endDocument()
|
||||
throws SAXException
|
||||
{
|
||||
if (!dtdDeclSeen)
|
||||
throw new SAXException("No appropriate DTD declaration was seen.");
|
||||
}
|
||||
|
||||
} // class PropertiesHandler
|
||||
|
||||
} // class Properties
|
||||
|
||||
@@ -132,8 +132,7 @@ public class StringTokenizer implements Enumeration
|
||||
{
|
||||
len = str.length();
|
||||
this.str = str;
|
||||
// The toString() hack causes the NullPointerException.
|
||||
this.delim = delim.toString();
|
||||
this.delim = delim;
|
||||
this.retDelims = returnDelims;
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
if (o instanceof Map.Entry)
|
||||
{
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
return key.equals(e.getKey())
|
||||
return WeakHashMap.equals(getKey(), e.getKey())
|
||||
&& WeakHashMap.equals(value, e.getValue());
|
||||
}
|
||||
return false;
|
||||
@@ -483,7 +483,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return key + "=" + value;
|
||||
return getKey() + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
while (bucket != null)
|
||||
{
|
||||
WeakBucket.WeakEntry entry = bucket.getEntry();
|
||||
if (entry != null && key.equals(entry.key))
|
||||
if (entry != null && equals(key, entry.key))
|
||||
return entry;
|
||||
|
||||
bucket = bucket.next;
|
||||
|
||||
@@ -194,7 +194,7 @@ public class XMLFormatter
|
||||
|
||||
|
||||
appendTag(buf, 1, "date", iso8601.format(new Date(millis)));
|
||||
appendTag(buf, 1, "millis", record.getMillis());
|
||||
appendTag(buf, 1, "millis", millis);
|
||||
appendTag(buf, 1, "sequence", record.getSequenceNumber());
|
||||
appendTag(buf, 1, "logger", record.getLoggerName());
|
||||
|
||||
|
||||
@@ -103,8 +103,11 @@ public final class Pattern implements Serializable
|
||||
}
|
||||
catch (REException e)
|
||||
{
|
||||
throw new PatternSyntaxException(e.getMessage(),
|
||||
PatternSyntaxException pse;
|
||||
pse = new PatternSyntaxException(e.getMessage(),
|
||||
regex, e.getPosition());
|
||||
pse.initCause(e);
|
||||
throw pse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user