You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(97) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(127) |
Feb
(34) |
Mar
(16) |
Apr
(26) |
May
(55) |
Jun
(107) |
Jul
(36) |
Aug
(72) |
Sep
(90) |
Oct
(41) |
Nov
(27) |
Dec
(13) |
| 2008 |
Jan
(37) |
Feb
(39) |
Mar
(98) |
Apr
(115) |
May
(134) |
Jun
(120) |
Jul
(86) |
Aug
(149) |
Sep
(68) |
Oct
(66) |
Nov
(104) |
Dec
(49) |
| 2009 |
Jan
(131) |
Feb
(132) |
Mar
(125) |
Apr
(172) |
May
(161) |
Jun
(43) |
Jul
(47) |
Aug
(38) |
Sep
(18) |
Oct
(6) |
Nov
(1) |
Dec
(15) |
| 2010 |
Jan
(21) |
Feb
(8) |
Mar
(10) |
Apr
(4) |
May
(9) |
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(4) |
| 2011 |
Jan
(23) |
Feb
(10) |
Mar
(13) |
Apr
(3) |
May
|
Jun
(19) |
Jul
(11) |
Aug
(22) |
Sep
|
Oct
(4) |
Nov
(2) |
Dec
(12) |
| 2012 |
Jan
(3) |
Feb
(4) |
Mar
(7) |
Apr
(3) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(30) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(8) |
| 2013 |
Jan
(3) |
Feb
(40) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
|
| 2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
|
From: <ls...@us...> - 2007-01-07 18:42:16
|
Revision: 3044
http://jnode.svn.sourceforge.net/jnode/?rev=3044&view=rev
Author: lsantha
Date: 2007-01-07 10:42:15 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/security/sasl/Sasl.java
trunk/core/src/classpath/javax/javax/security/sasl/SaslClientFactory.java
trunk/core/src/classpath/javax/javax/security/sasl/SaslServerFactory.java
trunk/core/src/classpath/javax/javax/swing/undo/CompoundEdit.java
trunk/core/src/classpath/javax/javax/swing/undo/StateEdit.java
trunk/core/src/classpath/javax/javax/swing/undo/StateEditable.java
trunk/core/src/classpath/javax/javax/swing/undo/UndoableEditSupport.java
Modified: trunk/core/src/classpath/javax/javax/security/sasl/Sasl.java
===================================================================
--- trunk/core/src/classpath/javax/javax/security/sasl/Sasl.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/security/sasl/Sasl.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -356,7 +356,8 @@
public static SaslClient createSaslClient(String[] mechanisms,
String authorizationID,
String protocol,
- String serverName, Map props,
+ String serverName,
+ Map<String, ?> props,
CallbackHandler cbh)
throws SaslException
{
@@ -444,7 +445,7 @@
* {@link SaslClient} instance.
* @see #createSaslClient(String[],String,String,String,Map,CallbackHandler)
*/
- public static Enumeration getSaslClientFactories()
+ public static Enumeration<SaslClientFactory> getSaslClientFactories()
{
Vector result = new Vector();
HashSet names = new HashSet();
@@ -559,7 +560,8 @@
*/
public static SaslServer createSaslServer(String mechanism, String protocol,
String serverName,
- Map props, CallbackHandler cbh)
+ Map<String, ?> props,
+ CallbackHandler cbh)
throws SaslException
{
if (mechanism == null)
@@ -636,7 +638,7 @@
* {@link SaslServer} instance.
* @see #createSaslServer(String,String,String,Map,CallbackHandler)
*/
- public static Enumeration getSaslServerFactories()
+ public static Enumeration<SaslServerFactory> getSaslServerFactories()
{
Vector result = new Vector();
HashSet names = new HashSet();
Modified: trunk/core/src/classpath/javax/javax/security/sasl/SaslClientFactory.java
===================================================================
--- trunk/core/src/classpath/javax/javax/security/sasl/SaslClientFactory.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/security/sasl/SaslClientFactory.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -97,8 +97,8 @@
* because of an error.
*/
SaslClient createSaslClient(String[] mechanisms, String authorizationID,
- String protocol, String serverName, Map props,
- CallbackHandler cbh)
+ String protocol, String serverName,
+ Map<String, ?> props, CallbackHandler cbh)
throws SaslException;
/**
@@ -114,5 +114,5 @@
* properties, if present in props, are ignored.
* @return a non-null array containing IANA-registered SASL mechanism names.
*/
- String[] getMechanismNames(Map props);
+ String[] getMechanismNames(Map<String, ?> props);
}
Modified: trunk/core/src/classpath/javax/javax/security/sasl/SaslServerFactory.java
===================================================================
--- trunk/core/src/classpath/javax/javax/security/sasl/SaslServerFactory.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/security/sasl/SaslServerFactory.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -95,7 +95,8 @@
* of an error.
*/
SaslServer createSaslServer(String mechanism, String protocol,
- String serverName, Map props, CallbackHandler cbh)
+ String serverName, Map<String, ?> props,
+ CallbackHandler cbh)
throws SaslException;
/**
@@ -111,5 +112,5 @@
* properties, if present in props, are ignored.
* @return a non-null array containing IANA-registered SASL mechanism names.
*/
- String[] getMechanismNames(Map props);
+ String[] getMechanismNames(Map<String, ?> props);
}
Modified: trunk/core/src/classpath/javax/javax/swing/undo/CompoundEdit.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/undo/CompoundEdit.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/swing/undo/CompoundEdit.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -1,5 +1,5 @@
/* CompoundEdit.java -- Combines multiple UndoableEdits.
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -75,7 +75,7 @@
* The <code>UndoableEdit</code>s being combined into a compound
* editing action.
*/
- protected Vector edits;
+ protected Vector<UndoableEdit> edits;
/**
@@ -92,7 +92,7 @@
*/
public CompoundEdit()
{
- edits = new Vector();
+ edits = new Vector<UndoableEdit>();
inProgress = true;
}
@@ -118,7 +118,7 @@
super.undo();
for (int i = edits.size() - 1; i >= 0; i--)
- ((UndoableEdit) edits.elementAt(i)).undo();
+ edits.elementAt(i).undo();
}
@@ -143,7 +143,7 @@
super.redo();
for (int i = 0; i < edits.size(); i++)
- ((UndoableEdit) edits.elementAt(i)).redo();
+ edits.elementAt(i).redo();
}
@@ -156,7 +156,7 @@
if (edits.size() == 0)
return null;
else
- return (UndoableEdit) edits.elementAt(edits.size() - 1);
+ return edits.elementAt(edits.size() - 1);
}
@@ -172,7 +172,7 @@
public void die()
{
for (int i = edits.size() - 1; i >= 0; i--)
- ((UndoableEdit) edits.elementAt(i)).die();
+ edits.elementAt(i).die();
super.die();
}
@@ -316,7 +316,7 @@
public boolean isSignificant()
{
for (int i = edits.size() - 1; i >= 0; i--)
- if (((UndoableEdit) edits.elementAt(i)).isSignificant())
+ if (edits.elementAt(i).isSignificant())
return true;
return false;
Modified: trunk/core/src/classpath/javax/javax/swing/undo/StateEdit.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/undo/StateEdit.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/swing/undo/StateEdit.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -121,14 +121,14 @@
* The state of <code>object</code> at the time of constructing
* this <code>StateEdit</code>.
*/
- protected Hashtable preState;
+ protected Hashtable<Object, Object> preState;
/**
* The state of <code>object</code> at the time when {@link #end()}
* was called.
*/
- protected Hashtable postState;
+ protected Hashtable<Object, Object> postState;
/**
Modified: trunk/core/src/classpath/javax/javax/swing/undo/StateEditable.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/undo/StateEditable.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/swing/undo/StateEditable.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -100,7 +100,7 @@
* @param state a hash table containing the relevant state
* information.
*/
- void restoreState(Hashtable state);
+ void restoreState(Hashtable<?, ?> state);
/**
@@ -110,5 +110,5 @@
* @param state a hash table for storing relevant state
* information.
*/
- void storeState(Hashtable state);
+ void storeState(Hashtable<Object, Object> state);
}
Modified: trunk/core/src/classpath/javax/javax/swing/undo/UndoableEditSupport.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/undo/UndoableEditSupport.java 2007-01-07 18:41:27 UTC (rev 3043)
+++ trunk/core/src/classpath/javax/javax/swing/undo/UndoableEditSupport.java 2007-01-07 18:42:15 UTC (rev 3044)
@@ -69,7 +69,8 @@
/**
* The currently registered listeners.
*/
- protected Vector listeners = new Vector();
+ protected Vector<UndoableEditListener> listeners =
+ new Vector<UndoableEditListener>();
/**
@@ -148,7 +149,7 @@
public synchronized UndoableEditListener[] getUndoableEditListeners()
{
UndoableEditListener[] result = new UndoableEditListener[listeners.size()];
- return (UndoableEditListener[]) listeners.toArray(result);
+ return listeners.toArray(result);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 18:41:28
|
Revision: 3043
http://jnode.svn.sourceforge.net/jnode/?rev=3043&view=rev
Author: lsantha
Date: 2007-01-07 10:41:27 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/AWTEvent.java
trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java
trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java
trunk/core/src/classpath/java/java/awt/BasicStroke.java
trunk/core/src/classpath/java/java/awt/CardLayout.java
trunk/core/src/classpath/java/java/awt/FileDialog.java
trunk/core/src/classpath/java/java/awt/FlowLayout.java
trunk/core/src/classpath/java/java/awt/GridBagLayout.java
trunk/core/src/classpath/java/java/awt/GridLayout.java
trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java
trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java
trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java
trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java
trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java
trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java
trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java
trunk/core/src/classpath/java/java/awt/font/TextLayout.java
trunk/core/src/classpath/java/java/awt/font/TextMeasurer.java
trunk/core/src/classpath/java/java/awt/geom/Arc2D.java
trunk/core/src/classpath/java/java/awt/geom/GeneralPath.java
trunk/core/src/classpath/java/java/awt/geom/RectangularShape.java
trunk/core/src/classpath/java/java/awt/geom/RoundRectangle2D.java
trunk/core/src/classpath/java/java/awt/print/PrinterJob.java
trunk/core/src/classpath/java/java/lang/Package.java
trunk/core/src/classpath/java/java/lang/Void.java
trunk/core/src/classpath/java/java/math/BigDecimal.java
trunk/core/src/classpath/java/java/math/BigInteger.java
trunk/core/src/classpath/java/java/math/MathContext.java
trunk/core/src/classpath/java/java/net/MimeTypeMapper.java
trunk/core/src/classpath/java/java/nio/channels/Channel.java
trunk/core/src/classpath/java/java/nio/channels/Selector.java
trunk/core/src/classpath/java/java/nio/channels/spi/AbstractSelectableChannel.java
trunk/core/src/classpath/java/java/nio/channels/spi/AbstractSelector.java
trunk/core/src/classpath/java/java/nio/charset/Charset.java
trunk/core/src/classpath/java/java/nio/charset/spi/CharsetProvider.java
trunk/core/src/classpath/java/java/security/AlgorithmParametersSpi.java
trunk/core/src/classpath/java/java/security/BasicPermission.java
trunk/core/src/classpath/java/java/security/IdentityScope.java
trunk/core/src/classpath/java/java/security/KeyFactorySpi.java
trunk/core/src/classpath/java/java/security/KeyStoreSpi.java
trunk/core/src/classpath/java/java/security/PermissionCollection.java
trunk/core/src/classpath/java/java/security/Permissions.java
trunk/core/src/classpath/java/java/security/Security.java
trunk/core/src/classpath/java/java/util/jar/Attributes.java
trunk/core/src/classpath/java/java/util/jar/JarEntry.java
trunk/core/src/classpath/java/java/util/jar/JarFile.java
trunk/core/src/classpath/java/java/util/jar/Manifest.java
trunk/core/src/classpath/java/java/util/regex/Matcher.java
trunk/core/src/classpath/java/java/util/regex/Pattern.java
trunk/core/src/classpath/java/java/util/zip/DeflaterEngine.java
trunk/core/src/classpath/java/java/util/zip/Inflater.java
trunk/core/src/classpath/java/java/util/zip/ZipFile.java
trunk/core/src/classpath/java/java/util/zip/ZipInputStream.java
Modified: trunk/core/src/classpath/java/java/awt/AWTEvent.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/AWTEvent.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/AWTEvent.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -262,9 +262,17 @@
*/
public String toString ()
{
+ String src;
+ if (source instanceof Component)
+ src = ((Component) source).getName();
+ else if (source instanceof MenuComponent)
+ src = ((MenuComponent) source).getName();
+ else if (source != null)
+ src = source.toString();
+ else
+ src = "null";
String string = getClass ().getName () + "[" + paramString () + "] on "
- + source;
-
+ + src;
return string;
}
Modified: trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/AWTEventMulticaster.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1175,16 +1175,17 @@
* @throws IllegalArgumentException if type is Void.TYPE
* @since 1.4
*/
- public static EventListener[] getListeners(EventListener l, Class type)
+ public static <T extends EventListener> T[] getListeners(EventListener l,
+ Class<T> type)
{
- ArrayList list = new ArrayList();
+ ArrayList<EventListener> list = new ArrayList<EventListener>();
if (l instanceof AWTEventMulticaster)
((AWTEventMulticaster) l).getListeners(list, type);
else if (type.isInstance(l))
list.add(l);
EventListener[] r = (EventListener[]) Array.newInstance(type, list.size());
list.toArray(r);
- return r;
+ return (T[]) r;
}
/**
Modified: trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/AWTKeyStroke.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* AWTKeyStroke.java -- an immutable key stroke
- Copyright (C) 2002, 2004, 2005 Free Software Foundation
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -65,6 +65,7 @@
* no-arg constructor (of any accessibility).
*
* @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
* @see #getAWTKeyStroke(char)
* @since 1.4
* @status updated to 1.4
@@ -85,14 +86,16 @@
* under the assumption that garbage collection of a new keystroke is
* easy when we find the old one that it matches in the cache.
*/
- private static final LinkedHashMap cache = new LinkedHashMap(11, 0.75f, true)
+ private static final LinkedHashMap<AWTKeyStroke,AWTKeyStroke> cache =
+ new LinkedHashMap<AWTKeyStroke,AWTKeyStroke>(11, 0.75f, true)
{
/** The largest the keystroke cache can grow. */
private static final int MAX_CACHE_SIZE = 2048;
/** Prune stale entries. */
- protected boolean removeEldestEntry(Map.Entry eldest)
- { // XXX - FIXME Use Map.Entry, not just Entry as gcj 3.1 workaround.
+ protected boolean removeEldestEntry(Entry<AWTKeyStroke,AWTKeyStroke>
+ eldest)
+ {
return size() > MAX_CACHE_SIZE;
}
};
@@ -114,7 +117,7 @@
*
* @see #getAWTKeyStroke(String)
*/
- static final HashMap vktable = new HashMap();
+ static final HashMap<String,Object> vktable = new HashMap<String,Object>();
static
{
// Using reflection saves the hassle of keeping this in sync with KeyEvent,
@@ -229,7 +232,7 @@
* @throws IllegalArgumentException subclass doesn't have no-arg constructor
* @throws ClassCastException subclass doesn't extend AWTKeyStroke
*/
- protected static void registerSubclass(final Class subclass)
+ protected static void registerSubclass(final Class<?> subclass)
{
if (subclass == null)
throw new IllegalArgumentException();
@@ -252,7 +255,8 @@
throws NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException
{
- Constructor c = subclass.getDeclaredConstructor(null);
+ Constructor<?> c =
+ subclass.getDeclaredConstructor((Class<?>[])null);
c.setAccessible(true);
// Create a new instance, to make sure that we can, and
// to cause any ClassCastException.
@@ -595,7 +599,7 @@
*/
protected Object readResolve() throws ObjectStreamException
{
- AWTKeyStroke s = (AWTKeyStroke) cache.get(this);
+ AWTKeyStroke s = cache.get(this);
if (s != null)
return s;
cache.put(this, this);
Modified: trunk/core/src/classpath/java/java/awt/BasicStroke.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/BasicStroke.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/BasicStroke.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -761,9 +761,13 @@
p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
dx = p1[0] - p0[0];
dy = p1[1] - p0[1];
+ if (dx != 0 && dy != 0)
+ {
l = Math.sqrt(dx * dx + dy * dy);
dx = (2.0/3.0)*width*dx/l;
dy = (2.0/3.0)*width*dy/l;
+ }
+
c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
c2 = new Point2D.Double(b.P1.getX() + dx, b.P1.getY() + dy);
a.add(new CubicSegment(a.last.P2, c1, c2, b.P1));
Modified: trunk/core/src/classpath/java/java/awt/CardLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/CardLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/CardLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -225,6 +225,8 @@
*/
public Dimension maximumLayoutSize (Container target)
{
+ if (target == null || target.ncomponents == 0)
+ return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
// The JCL says that this returns Integer.MAX_VALUE for both
// dimensions. But that just seems wrong to me.
return getSize (target, MAX);
@@ -350,6 +352,7 @@
}
}
((Component) target).setVisible (true);
+ parent.validate();
}
}
@@ -360,7 +363,7 @@
*/
public String toString ()
{
- return getClass ().getName () + "[" + hgap + "," + vgap + "]";
+ return getClass ().getName () + "[hgap=" + hgap + ",vgap=" + vgap + "]";
}
/**
@@ -400,11 +403,11 @@
{
if (comps[i].isVisible ())
{
- if (what == NEXT)
+ if (choice == i)
{
- choice = i + 1;
- if (choice == num)
- choice = 0;
+ // Do nothing if we're already looking at the right
+ // component.
+ return;
}
else if (what == PREV)
{
@@ -412,16 +415,19 @@
if (choice < 0)
choice = num - 1;
}
- else if (choice == i)
+ else if (what == NEXT)
{
- // Do nothing if we're already looking at the right
- // component.
- return;
+ choice = i + 1;
+ if (choice == num)
+ choice = 0;
}
comps[i].setVisible (false);
if (choice >= 0)
break;
+ } else
+ {
+ comps[i].setVisible(true);
}
}
Modified: trunk/core/src/classpath/java/java/awt/FileDialog.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/FileDialog.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/FileDialog.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -95,6 +95,11 @@
*/
private int mode;
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_file_dialog_number;
+
/*************************************************************************/
/*
@@ -300,7 +305,11 @@
public synchronized void
setFile(String file)
{
+ if ("".equals(file))
+ this.file = null;
+ else
this.file = file;
+
if (peer != null)
{
FileDialogPeer f = (FileDialogPeer) peer;
@@ -366,5 +375,22 @@
",mode=" + mode + "," + super.paramString());
}
+/**
+ * Generate a unique name for this <code>FileDialog</code>.
+ *
+ * @return A unique name for this <code>FileDialog</code>.
+ */
+String
+generateName()
+{
+ return "filedlg" + getUniqueLong();
+}
+
+private static synchronized long
+getUniqueLong()
+{
+ return next_file_dialog_number++;
+}
+
} // class FileDialog
Modified: trunk/core/src/classpath/java/java/awt/FlowLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/FlowLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/FlowLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -337,6 +337,9 @@
Insets ins = parent.getInsets ();
+ if (num == 0)
+ w += 2 * hgap + ins.left + ins.right;
+ else
w += (num + 1) * hgap + ins.left + ins.right;
h += 2 * vgap + ins.top + ins.bottom;
Modified: trunk/core/src/classpath/java/java/awt/GridBagLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/GridBagLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/GridBagLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* GridBagLayout - Layout manager for components according to GridBagConstraints
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@
package java.awt;
-import gnu.classpath.NotImplementedException;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
@@ -48,6 +46,7 @@
/**
* @author Michael Koch (kon...@gm...)
* @author Jeroen Frijters (je...@fr...)
+ * @author Andrew John Hughes (gnu...@me...)
*/
public class GridBagLayout
implements Serializable, LayoutManager2
@@ -64,8 +63,8 @@
// REMAINDER constraints.
// Constraints kept in comptable are never modified, and constraints
// kept in internalcomptable can be modified internally only.
- protected Hashtable comptable;
- private Hashtable internalcomptable;
+ protected Hashtable<Component,GridBagConstraints> comptable;
+ private Hashtable<Component,GridBagConstraints> internalcomptable;
protected GridBagLayoutInfo layoutInfo;
protected GridBagConstraints defaultConstraints;
@@ -76,8 +75,8 @@
public GridBagLayout ()
{
- this.comptable = new Hashtable();
- this.internalcomptable = new Hashtable();
+ this.comptable = new Hashtable<Component,GridBagConstraints>();
+ this.internalcomptable = new Hashtable<Component,GridBagConstraints>();
this.defaultConstraints= new GridBagConstraints();
}
@@ -322,14 +321,35 @@
}
/**
- * Obsolete.
+ * Return a string representation of this GridBagLayout.
+ *
+ * @return a string representation
*/
- protected void AdjustForGravity (GridBagConstraints gbc, Rectangle rect)
- throws NotImplementedException
+ public String toString()
{
- // FIXME
- throw new Error ("Not implemented");
+ return getClass().getName();
}
+
+ /**
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
+ */
+ protected void AdjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
+ {
+ Insets insets = constraints.insets;
+ if (insets != null)
+ {
+ r.x += insets.left;
+ r.y += insets.top;
+ r.width -= insets.left + insets.right;
+ r.height -= insets.top + insets.bottom;
+ }
+ }
/**
* Obsolete.
@@ -353,10 +373,9 @@
// layoutInfo. So we wait until after this for loop to set
// layoutInfo.
Component lastComp = null;
- int cellx = 0;
- int celly = 0;
- int cellw = 0;
- int cellh = 0;
+
+ Rectangle cell = new Rectangle();
+
for (int i = 0; i < components.length; i++)
{
Component component = components[i];
@@ -370,29 +389,23 @@
if (lastComp != null
&& constraints.gridheight == GridBagConstraints.REMAINDER)
- celly += cellh;
+ cell.y += cell.height;
else
- celly = sumIntArray(info.rowHeights, constraints.gridy);
+ cell.y = sumIntArray(info.rowHeights, constraints.gridy);
if (lastComp != null
&& constraints.gridwidth == GridBagConstraints.REMAINDER)
- cellx += cellw;
+ cell.x += cell.width;
else
- cellx = sumIntArray(info.colWidths, constraints.gridx);
+ cell.x = sumIntArray(info.colWidths, constraints.gridx);
- cellw = sumIntArray(info.colWidths, constraints.gridx
- + constraints.gridwidth) - cellx;
- cellh = sumIntArray(info.rowHeights, constraints.gridy
- + constraints.gridheight) - celly;
+ cell.width = sumIntArray(info.colWidths, constraints.gridx
+ + constraints.gridwidth) - cell.x;
+ cell.height = sumIntArray(info.rowHeights, constraints.gridy
+ + constraints.gridheight) - cell.y;
- Insets insets = constraints.insets;
- if (insets != null)
- {
- cellx += insets.left;
- celly += insets.top;
- cellw -= insets.left + insets.right;
- cellh -= insets.top + insets.bottom;
- }
+ // Adjust for insets.
+ AdjustForGravity( constraints, cell );
// Note: Documentation says that padding is added on both sides, but
// visual inspection shows that the Sun implementation only adds it
@@ -403,14 +416,14 @@
switch (constraints.fill)
{
case GridBagConstraints.HORIZONTAL:
- dim.width = cellw;
+ dim.width = cell.width;
break;
case GridBagConstraints.VERTICAL:
- dim.height = cellh;
+ dim.height = cell.height;
break;
case GridBagConstraints.BOTH:
- dim.width = cellw;
- dim.height = cellh;
+ dim.width = cell.width;
+ dim.height = cell.height;
break;
}
@@ -420,40 +433,40 @@
switch (constraints.anchor)
{
case GridBagConstraints.NORTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y;
break;
case GridBagConstraints.SOUTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + cellh - dim.height;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.WEST:
- x = cellx;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.EAST:
- x = cellx + cellw - dim.width;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.NORTHEAST:
- x = cellx + cellw - dim.width;
- y = celly;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y;
break;
case GridBagConstraints.NORTHWEST:
- x = cellx;
- y = celly;
+ x = cell.x;
+ y = cell.y;
break;
case GridBagConstraints.SOUTHEAST:
- x = cellx + cellw - dim.width;
- y = celly + cellh - dim.height;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.SOUTHWEST:
- x = cellx;
- y = celly + cellh - dim.height;
+ x = cell.x;
+ y = cell.y + cell.height - dim.height;
break;
default:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
}
component.setBounds(info.pos_x + x, info.pos_y + y, dim.width,
@@ -487,16 +500,18 @@
// Guaranteed to contain the last component added to the given row
// or column, whose gridwidth/height is not REMAINDER.
- HashMap lastInRow = new HashMap();
- HashMap lastInCol = new HashMap();
+ HashMap<Integer,Component> lastInRow = new HashMap<Integer,Component>();
+ HashMap<Integer,Component> lastInCol = new HashMap<Integer,Component>();
Component[] components = parent.getComponents();
// Components sorted by gridwidths/heights,
// smallest to largest, with REMAINDER and RELATIVE at the end.
// These are useful when determining sizes and weights.
- ArrayList sortedByWidth = new ArrayList(components.length);
- ArrayList sortedByHeight = new ArrayList(components.length);
+ ArrayList<Component> sortedByWidth =
+ new ArrayList<Component>(components.length);
+ ArrayList<Component> sortedByHeight =
+ new ArrayList<Component>(components.length);
// STEP 1: first we figure out how many rows/columns
for (int i = 0; i < components.length; i++)
@@ -761,7 +776,7 @@
// STEP 3: Determine sizes and weights for columns.
for (int i = 0; i < sortedByWidth.size(); i++)
{
- Component component = (Component) sortedByWidth.get(i);
+ Component component = sortedByWidth.get(i);
// If component is not visible we dont have to care about it.
if (!component.isVisible())
@@ -875,7 +890,8 @@
* width. Otherwise, sort by height.
* FIXME: Use a better sorting algorithm.
*/
- private void sortBySpan (Component component, int span, ArrayList list, boolean sortByWidth)
+ private void sortBySpan (Component component, int span,
+ ArrayList<Component> list, boolean sortByWidth)
{
if (span == GridBagConstraints.REMAINDER
|| span == GridBagConstraints.RELATIVE)
@@ -1082,10 +1098,18 @@
}
/**
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
+ *
* @since 1.4
*/
- protected void adjustForGravity (GridBagConstraints gbc, Rectangle rect)
+ protected void adjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
{
- AdjustForGravity (gbc, rect);
+ AdjustForGravity (constraints, r);
}
}
Modified: trunk/core/src/classpath/java/java/awt/GridLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/GridLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/GridLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -289,7 +289,7 @@
public String toString ()
{
return (getClass ().getName () + "["
- + ",hgap=" + hgap + ",vgap=" + vgap
+ + "hgap=" + hgap + ",vgap=" + vgap
+ ",rows=" + rows + ",cols=" + cols
+ "]");
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/DataFlavor.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -38,14 +38,13 @@
package java.awt.datatransfer;
-import gnu.classpath.NotImplementedException;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.OptionalDataException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
@@ -76,8 +75,7 @@
* deals with bytes not chars. Use <code>getRederForText()</code>.
*/
public static final DataFlavor plainTextFlavor =
- new DataFlavor(java.io.InputStream.class,
- "text/plain; charset=unicode",
+ new DataFlavor("text/plain; charset=unicode; class=java.io.InputStream",
"plain unicode text");
/**
@@ -94,8 +92,7 @@
* element of the list being a <code>java.io.File</code>.
*/
public static final DataFlavor javaFileListFlavor =
- new DataFlavor(java.util.List.class,
- "application/x-java-file-list; class=java.util.List",
+ new DataFlavor("application/x-java-file-list; class=java.util.List",
"Java File List");
/**
@@ -132,10 +129,10 @@
*/
// The MIME type for this flavor
- private final String mimeType;
+ private MimeType mimeType;
// The representation class for this flavor
- private final Class representationClass;
+ private Class<?> representationClass;
// The human readable name of this flavor
private String humanPresentableName;
@@ -156,7 +153,7 @@
*
* @exception ClassNotFoundException If the class cannot be loaded.
*/
- protected static final Class tryToLoadClass(String className,
+ protected static final Class<?> tryToLoadClass(String className,
ClassLoader classLoader)
throws ClassNotFoundException
{
@@ -198,63 +195,7 @@
throw new ClassNotFoundException(className);
}
- private static Class getRepresentationClassFromMimeThrows(String mimeString,
- ClassLoader classLoader)
- throws ClassNotFoundException
- {
- String classname = getParameter("class", mimeString);
- if (classname != null)
- return tryToLoadClass(classname, classLoader);
- else
- return java.io.InputStream.class;
- }
-
- // Same as above, but wraps any ClassNotFoundExceptions
- private static Class getRepresentationClassFromMime(String mimeString,
- ClassLoader classLoader)
- {
- try
- {
- return getRepresentationClassFromMimeThrows(mimeString, classLoader);
- }
- catch(ClassNotFoundException cnfe)
- {
- IllegalArgumentException iae;
- iae = new IllegalArgumentException("mimeString: "
- + mimeString
- + " classLoader: "
- + classLoader);
- iae.initCause(cnfe);
- throw iae;
- }
- }
-
/**
- * Returns the value of the named MIME type parameter, or <code>null</code>
- * if the parameter does not exist. Given the parameter name and the mime
- * string.
- *
- * @param paramName The name of the parameter.
- * @param mimeString The mime string from where the name should be found.
- *
- * @return The value of the parameter or null.
- */
- private static String getParameter(String paramName, String mimeString)
- {
- int idx = mimeString.indexOf(paramName + "=");
- if (idx == -1)
- return(null);
-
- String value = mimeString.substring(idx + paramName.length() + 1);
-
- idx = value.indexOf(";");
- if (idx == -1)
- return(value);
- else
- return(value.substring(0, idx));
- }
-
- /**
* XXX - Currently returns <code>plainTextFlavor</code>.
*/
public static final DataFlavor getTextPlainUnicodeFlavor()
@@ -321,35 +262,10 @@
*/
public DataFlavor()
{
- mimeType = null;
- representationClass = null;
- humanPresentableName = null;
+ // Used for deserialization only, nothing to do here.
}
/**
- * Private constructor.
- */
- private DataFlavor(Class representationClass,
- String mimeType,
- String humanPresentableName)
- {
- this.representationClass = representationClass;
- this.mimeType = mimeType;
-
- // Do some simple validity checks
- String type = getPrimaryType() + "/" + getSubType();
- if (type.indexOf(' ') != -1
- || type.indexOf('=') != -1
- || type.indexOf(';') != -1)
- throw new IllegalArgumentException(mimeType);
-
- if (humanPresentableName != null)
- this.humanPresentableName = humanPresentableName;
- else
- this.humanPresentableName = mimeType;
- }
-
- /**
* Initializes a new instance of <code>DataFlavor</code>. The class
* and human readable name are specified, the MIME type will be
* "application/x-java-serialized-object". If the human readable name
@@ -359,13 +275,23 @@
* @param representationClass The representation class for this object.
* @param humanPresentableName The display name of the object.
*/
- public DataFlavor(Class representationClass, String humanPresentableName)
+ public DataFlavor(Class<?> representationClass, String humanPresentableName)
{
- this(representationClass,
- "application/x-java-serialized-object"
- + "; class="
- + representationClass.getName(),
- humanPresentableName);
+ if (representationClass == null)
+ throw new NullPointerException("representationClass must not be null");
+ try
+ {
+ mimeType = new MimeType(javaSerializedObjectMimeType);
+ }
+ catch (MimeTypeParseException ex)
+ {
+ // Must not happen as we use a constant string.
+ assert false;
+ }
+ if (humanPresentableName == null)
+ humanPresentableName = javaSerializedObjectMimeType;
+ this.humanPresentableName = humanPresentableName;
+ this.representationClass = representationClass;
}
/**
@@ -390,8 +316,7 @@
ClassLoader classLoader)
throws ClassNotFoundException
{
- this(getRepresentationClassFromMimeThrows(mimeType, classLoader),
- mimeType, humanPresentableName);
+ init(mimeType, humanPresentableName, classLoader);
}
/**
@@ -412,8 +337,17 @@
*/
public DataFlavor(String mimeType, String humanPresentableName)
{
- this(getRepresentationClassFromMime (mimeType, null),
- mimeType, humanPresentableName);
+ try
+ {
+ init(mimeType, humanPresentableName, getClass().getClassLoader());
+ }
+ catch (ClassNotFoundException ex)
+ {
+ IllegalArgumentException iae =
+ new IllegalArgumentException("Class not found: " + ex.getMessage());
+ iae.initCause(ex);
+ throw iae;
+ }
}
/**
@@ -432,18 +366,64 @@
*/
public DataFlavor(String mimeType) throws ClassNotFoundException
{
- this(getRepresentationClassFromMimeThrows(mimeType, null),
- mimeType, null);
+ init(mimeType, null, getClass().getClassLoader());
}
/**
+ * Called by various constructors to initialize this object.
+ *
+ * @param mime the mime string
+ * @param humanPresentableName the human presentable name
+ * @param loader the class loader to use for loading the representation
+ * class
+ */
+ private void init(String mime, String humanPresentableName,
+ ClassLoader loader)
+ throws ClassNotFoundException
+ {
+ if (mime == null)
+ throw new NullPointerException("The mime type must not be null");
+ try
+ {
+ mimeType = new MimeType(mime);
+ }
+ catch (MimeTypeParseException ex)
+ {
+ IllegalArgumentException iae =
+ new IllegalArgumentException("Invalid mime type");
+ iae.initCause(ex);
+ throw iae;
+ }
+ String className = mimeType.getParameter("class");
+ if (className == null)
+ {
+ if (mimeType.getBaseType().equals(javaSerializedObjectMimeType))
+ throw new IllegalArgumentException("Serialized object type must have"
+ + " a representation class parameter");
+ else
+ representationClass = java.io.InputStream.class;
+ }
+ else
+ representationClass = tryToLoadClass(className, loader);
+ mimeType.addParameter("class", representationClass.getName());
+
+ if (humanPresentableName == null)
+ {
+ humanPresentableName = mimeType.getParameter("humanPresentableName");
+ if (humanPresentableName == null)
+ humanPresentableName = mimeType.getBaseType();
+ }
+ this.humanPresentableName = humanPresentableName;
+ }
+
+ /**
* Returns the MIME type of this flavor.
*
* @return The MIME type for this flavor.
*/
public String getMimeType()
{
- return(mimeType);
+ return(mimeType.toString());
}
/**
@@ -451,7 +431,7 @@
*
* @return The representation class for this flavor.
*/
- public Class getRepresentationClass()
+ public Class<?> getRepresentationClass()
{
return(representationClass);
}
@@ -473,11 +453,7 @@
*/
public String getPrimaryType()
{
- int idx = mimeType.indexOf("/");
- if (idx == -1)
- return(mimeType);
-
- return(mimeType.substring(0, idx));
+ return(mimeType.getPrimaryType());
}
/**
@@ -487,15 +463,7 @@
*/
public String getSubType()
{
- int start = mimeType.indexOf("/");
- if (start == -1)
- return "";
-
- int end = mimeType.indexOf(";", start + 1);
- if (end == -1)
- return mimeType.substring(start + 1);
- else
- return mimeType.substring(start + 1, end);
+ return mimeType.getSubType();
}
/**
@@ -511,7 +479,7 @@
if ("humanPresentableName".equals(paramName))
return getHumanPresentableName();
- return getParameter(paramName, mimeType);
+ return mimeType.getParameter(paramName);
}
/**
@@ -537,16 +505,22 @@
*/
public boolean isMimeTypeEqual(String mimeType)
{
- String mime = getMimeType();
- int i = mime.indexOf(";");
- if (i != -1)
- mime = mime.substring(0, i);
-
- i = mimeType.indexOf(";");
- if (i != -1)
- mimeType = mimeType.substring(0, i);
-
- return mime.equals(mimeType);
+ if (mimeType == null)
+ throw new NullPointerException("mimeType must not be null");
+ boolean equal = false;
+ try
+ {
+ if (this.mimeType != null)
+ {
+ MimeType other = new MimeType(mimeType);
+ equal = this.mimeType.matches(other);
+ }
+ }
+ catch (MimeTypeParseException ex)
+ {
+ // Return false in this case.
+ }
+ return equal;
}
/**
@@ -571,7 +545,7 @@
*/
public boolean isMimeTypeSerializedObject()
{
- return mimeType.startsWith(javaSerializedObjectMimeType);
+ return isMimeTypeEqual(javaSerializedObjectMimeType);
}
/**
@@ -617,8 +591,8 @@
*/
public boolean isFlavorSerializedObjectType()
{
- // FIXME: What is the diff between this and isMimeTypeSerializedObject?
- return(mimeType.startsWith(javaSerializedObjectMimeType));
+ return isRepresentationClassSerializable()
+ && isMimeTypeEqual(javaSerializedObjectMimeType);
}
/**
@@ -629,7 +603,9 @@
*/
public boolean isFlavorRemoteObjectType()
{
- return(mimeType.startsWith(javaRemoteObjectMimeType));
+ return isRepresentationClassRemote()
+ && isRepresentationClassSerializable()
+ && isMimeTypeEqual(javaRemoteObjectMimeType);
}
/**
@@ -770,7 +746,7 @@
*/
public int hashCode()
{
- return mimeType.toLowerCase().hashCode() ^ representationClass.hashCode();
+ return mimeType.toString().hashCode() ^ representationClass.hashCode();
}
/**
@@ -822,9 +798,17 @@
* @exception IOException If an error occurs.
*/
public void writeExternal(ObjectOutput stream)
- throws IOException, NotImplementedException
+ throws IOException
{
- // FIXME: Implement me
+ if (mimeType != null)
+ {
+ mimeType.addParameter("humanPresentableName", humanPresentableName);
+ stream.writeObject(mimeType);
+ mimeType.removeParameter("humanPresentableName");
+ }
+ else
+ stream.writeObject(null);
+ stream.writeObject(representationClass);
}
@@ -838,9 +822,34 @@
* cannot be found.
*/
public void readExternal(ObjectInput stream)
- throws IOException, ClassNotFoundException, NotImplementedException
+ throws IOException, ClassNotFoundException
{
- // FIXME: Implement me
+ mimeType = (MimeType) stream.readObject();
+ String className = null;
+ if (mimeType != null)
+ {
+ humanPresentableName =
+ mimeType.getParameter("humanPresentableName");
+ mimeType.removeParameter("humanPresentableName");
+ className = mimeType.getParameter("class");
+ if (className == null)
+ throw new IOException("No class in mime type");
+ }
+ try
+ {
+ representationClass = (Class) stream.readObject();
+ }
+ catch (OptionalDataException ex)
+ {
+ if (ex.eof && ex.length == 0)
+ {
+ if (className != null)
+ representationClass = tryToLoadClass(className,
+ getClass().getClassLoader());
+ }
+ else
+ throw ex;
+ }
}
/**
@@ -861,7 +870,7 @@
*
* @since 1.3
*/
- public final Class getDefaultRepresentationClass()
+ public final Class<?> getDefaultRepresentationClass()
{
return java.io.InputStream.class;
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/FlavorMap.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -58,7 +58,7 @@
*
* @return A <code>Map</code> of native data types.
*/
- Map getNativesForFlavors (DataFlavor[] flavors);
+ Map<DataFlavor, String> getNativesForFlavors (DataFlavor[] flavors);
/**
* Maps the specified native type names to <code>DataFlavor</code>'s.
@@ -71,5 +71,5 @@
*
* @return A <code>Map</code> of data flavors.
*/
- Map getFlavorsForNatives (String[] natives);
+ Map<String, DataFlavor> getFlavorsForNatives (String[] natives);
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/FlavorTable.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -59,7 +59,7 @@
* @param flavor the flavor to look up, or null to return all natives
* @return the sorted list of natives
*/
- List getNativesForFlavor(DataFlavor flavor);
+ List<String> getNativesForFlavor(DataFlavor flavor);
/**
* Returns a list of flavors corresponding to the given String native. The
@@ -69,5 +69,5 @@
* @param name the native name to look up, or null to return all flavors
* @return the sorted list of flavors
*/
- List getFlavorsForNative(String name);
+ List<DataFlavor> getFlavorsForNative(String name);
}
Modified: trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/SystemFlavorMap.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -38,12 +38,21 @@
package java.awt.datatransfer;
-import gnu.classpath.NotImplementedException;
-
+import java.awt.Toolkit;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.WeakHashMap;
/**
@@ -72,22 +81,105 @@
* This map maps native <code>String</code>s to lists of
* <code>DataFlavor</code>s
*/
- private HashMap nativeToFlavorMap = new HashMap();
+ private HashMap<String,List<DataFlavor>> nativeToFlavorMap =
+ new HashMap<String,List<DataFlavor>>();
/**
* This map maps <code>DataFlavor</code>s to lists of native
* <code>String</code>s
*/
- private HashMap flavorToNativeMap = new HashMap();
+ private HashMap<DataFlavor, List<String>> flavorToNativeMap =
+ new HashMap<DataFlavor, List<String>>();
/**
* Private constructor.
*/
private SystemFlavorMap ()
{
+ AccessController.doPrivileged
+ (new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ try
+ {
+ // Load installed flavormap.properties first.
+ String sep = File.separator;
+ File propsFile =
+ new File(System.getProperty("gnu.classpath.home.url")
+ + sep + "accessibility.properties");
+ InputStream in = new FileInputStream(propsFile);
+ Properties props = new Properties();
+ props.load(in);
+ in.close();
+
+ String augmented = Toolkit.getProperty("AWT.DnD.flavorMapFileURL",
+ null);
+ if (augmented != null)
+ {
+ URL url = new URL(augmented);
+ in = url.openStream();
+ props.load(in);
+ }
+ setupMapping(props);
+ }
+ catch (IOException ex)
+ {
+ // Can't do anything about it.
+ }
+ return null;
+ }
+ });
}
/**
+ * Sets up the mapping from native to mime types and vice versa as specified
+ * in the flavormap.properties file.
+ *
+ * This is package private to avoid an accessor method.
+ *
+ * @param props the properties file
+ */
+ void setupMapping(Properties props)
+ {
+ Enumeration propNames = props.propertyNames();
+ while (propNames.hasMoreElements())
+ {
+ try
+ {
+ String nat = (String) propNames.nextElement();
+ String mime = (String) props.getProperty(nat);
+ // Check valid mime type.
+ MimeType type = new MimeType(mime);
+ DataFlavor flav = new DataFlavor(mime);
+
+ List<DataFlavor> flavs = nativeToFlavorMap.get(nat);
+ if (flavs == null)
+ {
+ flavs = new ArrayList<DataFlavor>();
+ nativeToFlavorMap.put(nat, flavs);
+ }
+ List<String> nats = flavorToNativeMap.get(flav);
+ if (nats == null)
+ {
+ nats = new ArrayList<String>();
+ flavorToNativeMap.put(flav, nats);
+ }
+ flavs.add(flav);
+ nats.add(nat);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ // Skip.
+ }
+ catch (MimeTypeParseException ex)
+ {
+ // Skip.
+ }
+ }
+ }
+
+ /**
* Maps the specified <code>DataFlavor</code> objects to the native
* data type name. The returned <code>Map</code> has keys that are
* the data flavors and values that are strings. The returned map
@@ -98,9 +190,9 @@
*
* @return A <code>Map</code> of native data types to data flavors.
*/
- public Map getNativesForFlavors (DataFlavor[] flavors)
+ public Map<DataFlavor, String> getNativesForFlavors (DataFlavor[] flavors)
{
- return new HashMap();
+ return new HashMap<DataFlavor, String>();
}
/**
@@ -114,9 +206,9 @@
*
* @return A <code>Map</code> of data flavors to native type names.
*/
- public Map getFlavorsForNatives (String[] natives)
+ public Map<String, DataFlavor> getFlavorsForNatives (String[] natives)
{
- return new HashMap();
+ return new HashMap<String, DataFlavor>();
}
/**
@@ -263,16 +355,52 @@
* specified native and a DataFlavor whose MIME type is a decoded
* version of the native.
*/
- public List getFlavorsForNative (String nat)
- throws NotImplementedException
+ public List<DataFlavor> getFlavorsForNative(String nat)
{
- throw new Error ("Not implemented");
+ List<DataFlavor> ret = new ArrayList<DataFlavor>();
+ if (nat == null)
+ {
+ Collection<List<DataFlavor>> all = nativeToFlavorMap.values();
+ for (List<DataFlavor> list : all)
+ {
+ for (DataFlavor flav : list)
+ {
+ if (! ret.contains(flav))
+ ret.add(flav);
+ }
+ }
+ }
+ else
+ {
+ List<DataFlavor> list = nativeToFlavorMap.get(nat);
+ if (list != null)
+ ret.addAll(list);
+ }
+ return ret;
}
- public List getNativesForFlavor (DataFlavor flav)
- throws NotImplementedException
+ public List<String> getNativesForFlavor (DataFlavor flav)
{
- throw new Error ("Not implemented");
+ List<String> ret = new ArrayList<String>();
+ if (flav == null)
+ {
+ Collection<List<String>> all = flavorToNativeMap.values();
+ for (List<String> list : all)
+ {
+ for (String nat : list)
+ {
+ if (! ret.contains(nat))
+ ret.add(nat);
+ }
+ }
+ }
+ else
+ {
+ List<String> list = flavorToNativeMap.get(flav);
+ if (list != null)
+ ret.addAll(list);
+ }
+ return ret;
}
/**
@@ -298,10 +426,10 @@
{
if ((nativeStr == null) || (flavor == null))
throw new NullPointerException();
- List flavors = (List) nativeToFlavorMap.get(nativeStr);
+ List<DataFlavor> flavors = nativeToFlavorMap.get(nativeStr);
if (flavors == null)
{
- flavors = new ArrayList();
+ flavors = new ArrayList<DataFlavor>();
nativeToFlavorMap.put(nativeStr, flavors);
}
else
@@ -336,10 +464,10 @@
{
if ((nativeStr == null) || (flavor == null))
throw new NullPointerException();
- List natives = (List) flavorToNativeMap.get(flavor);
+ List<String> natives = flavorToNativeMap.get(flavor);
if (natives == null)
{
- natives = new ArrayList();
+ natives = new ArrayList<String>();
flavorToNativeMap.put(flavor, natives);
}
else
Modified: trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/event/ComponentEvent.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* ComponentEvent.java -- notification of events for components
- Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -114,24 +114,27 @@
*/
public String paramString()
{
+ StringBuffer s = new StringBuffer();
+
// Unlike Sun, we don't throw NullPointerException or ClassCastException
// when source was illegally changed.
- switch (id)
- {
- case COMPONENT_MOVED:
- return "COMPONENT_MOVED "
- + (source instanceof Component
- ? ((Component) source).getBounds() : (Object) "");
- case COMPONENT_RESIZED:
- return "COMPONENT_RESIZED "
- + (source instanceof Component
- ? ((Component) source).getBounds() : (Object) "");
- case COMPONENT_SHOWN:
- return "COMPONENT_SHOWN";
- case COMPONENT_HIDDEN:
- return "COMPONENT_HIDDEN";
- default:
+ if (id == COMPONENT_MOVED)
+ s.append("COMPONENT_MOVED ");
+ else if (id == COMPONENT_RESIZED)
+ s.append("COMPONENT_RESIZED ");
+ else if (id == COMPONENT_SHOWN)
+ s.append("COMPONENT_SHOWN ");
+ else if (id == COMPONENT_HIDDEN)
+ s.append("COMPONENT_HIDDEN ");
+ else
return "unknown type";
+
+ s.append("(").append(getComponent().getX()).append(",")
+ .append(getComponent().getY()).append(" ")
+ .append(getComponent().getWidth()).append("x")
+ .append(getComponent().getHeight()).append(")");
+
+ return s.toString();
}
- }
+
} // class ComponentEvent
Modified: trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/font/LineBreakMeasurer.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -1,5 +1,5 @@
/* LineBreakMeasurer.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,84 +38,114 @@
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
import java.text.BreakIterator;
+import java.awt.Shape;
public final class LineBreakMeasurer
{
- private AttributedCharacterIterator ci;
- private FontRenderContext frc;
- private BreakIterator bi;
+ private AttributedCharacterIterator text;
+ private int position;
+ private TextMeasurer tm;
+ private int numChars;
- /**
- * Constructs a <code>LineBreakMeasurer</code> object.
- */
- public LineBreakMeasurer (AttributedCharacterIterator text,
- FontRenderContext frc)
- {
- this (text, null, frc);
- }
-
- /**
- * Constructs a <code>LineBreakMeasurer</code> object.
- */
- public LineBreakMeasurer (AttributedCharacterIterator text,
+ public LineBreakMeasurer(AttributedCharacterIterator text,
BreakIterator breakIter, FontRenderContext frc)
{
- this.ci = text;
- this.bi = breakIter;
- this.frc = frc;
+ this( text, frc );
}
- public void deleteChar (AttributedCharacterIterator newParagraph,
- int deletePos)
- throws NotImplementedException
+ public LineBreakMeasurer(AttributedCharacterIterator text,
+ FontRenderContext frc)
{
- throw new Error ("not implemented");
+ this.text = text;
+ position = 0;
+ numChars = text.getEndIndex();
+ tm = new TextMeasurer( text, frc );
}
- public int getPosition ()
+ public void deleteChar(AttributedCharacterIterator newParagraph,
+ int deletePos)
{
- return ci.getIndex ();
+ tm.deleteChar( newParagraph, deletePos );
+ position = 0;
}
- public void insertChar (AttributedCharacterIterator newParagraph,
+ public void insertChar(AttributedCharacterIterator newParagraph,
int insertPos)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ tm.insertChar( newParagraph, insertPos );
+ position = 0;
}
- public TextLayout nextLayout (float wrappingWidth)
- throws NotImplementedException
+ public TextLayout nextLayout(float wrappingWidth)
{
- throw new Error ("not implemented");
+ return nextLayout( wrappingWidth, numChars, false );
}
- public TextLayout nextLayout (float wrappingWidth, int offsetLimit,
+ public TextLayout nextLayout(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord );
+ TextLayout tl = tm.getLayout( position, next );
+ position = next;
+ return tl;
}
- public int nextOffset (float wrappingWidth)
- throws NotImplementedException
+ public int nextOffset(float wrappingWidth)
{
- throw new Error ("not implemented");
+ return nextOffset( wrappingWidth, numChars, false );
}
- public int nextOffset (float wrappingWidth, int offsetLimit,
+ public int nextOffset(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ int guessOffset = tm.getLineBreakIndex(position, wrappingWidth);
+ if( offsetLimit > numChars )
+ offsetLimit = numChars;
+
+ if( guessOffset > offsetLimit )
+ {
+ text.setIndex( offsetLimit );
+ return offsetLimit;
+ }
+
+ text.setIndex( guessOffset );
+
+ // If we're on a breaking character, return directly
+ if( Character.isWhitespace( text.current() ) )
+ return guessOffset;
+
+ // Otherwise jump forward or backward to the last such char.
+ if( !requireNextWord )
+ while( !Character.isWhitespace( text.previous() ) &&
+ guessOffset > position )
+ guessOffset--;
+ else
+ while( !Character.isWhitespace( text.next() ) &&
+ guessOffset < offsetLimit )
+ guessOffset++;
+
+ if( guessOffset > offsetLimit )
+ {
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
- public void setPosition (int newPosition)
+ text.setIndex( guessOffset );
+
+ return guessOffset;
+ }
+
+ public void setPosition(int newPosition)
{
- ci.setIndex (newPosition);
+ position = newPosition;
}
+
+ public int getPosition()
+ {
+ return position;
+ }
}
+
Modified: trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/font/TextHitInfo.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -81,6 +81,9 @@
public boolean equals(TextHitInfo hitInfo)
{
+ if (hitInfo == null)
+ return false;
+
return (charIndex == hitInfo.getCharIndex ())
&& (leadingEdge == hitInfo.isLeadingEdge ());
}
@@ -97,7 +100,7 @@
public static TextHitInfo beforeOffset(int offset)
{
- return new TextHitInfo (offset, false);
+ return new TextHitInfo ((offset - 1), false);
}
public static TextHitInfo afterOffset(int offset)
Modified: trunk/core/src/classpath/java/java/awt/font/TextLayout.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/font/TextLayout.java 2007-01-07 18:39:36 UTC (rev 3042)
+++ trunk/core/src/classpath/java/java/awt/font/TextLayout.java 2007-01-07 18:41:27 UTC (rev 3043)
@@ -38,19 +38,18 @@
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
-import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
+import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
import java.text.Bidi;
+import java.util.ArrayList;
import java.util.Map;
/**
@@ -58,21 +57,94 @@
*/
public final class TextLayout implements Cloneable
{
- private GlyphVector[] runs;
- private Font font;
+ /**
+ * Holds the layout data that belongs to one run of characters.
+ */
+ private class Run
+ {
+ /**
+ * The actual glyph vector.
+ */
+ GlyphVector glyphVector;
+
+ /**
+ * The font for this text run.
+ */
+ Font font;
+
+ /**
+ * The start of the run.
+ */
+ int runStart;
+
+ /**
+ * The end of the run.
+ */
+ int runEnd;
+
+ /**
+ * The layout location of the beginning of the run.
+ */
+ float location;
+
+ /**
+ * Initializes the Run instance.
+ *
+ * @param gv the glyph vector
+ * @param start the start index of the run
+ * @param end the end index of the run
+ */
+ Run(GlyphVector gv, Font f, int start, int end)
+ {
+ glyphVector = gv;
+ font = f;
+ runStart = start;
+ runEnd = end;
+ }
+
+ /**
+ * Returns <code>true</code> when this run is left to right,
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> when this run is left to right,
+ * <code>false</code> otherwise
+ */
+ boolean isLeftToRight()
+ {
+ return (glyphVector.getLayoutFlags() & GlyphVector.FLAG_RUN_RTL) == 0;
+ }
+ }
+
+ /**
+ * The laid out character runs.
+ */
+ private Run[] runs;
+
private FontRenderContext frc;
- private String string;
+ private char[] string;
+ private int offset;
+ private int length;
private Rectangle2D boundsCache;
private LineMetrics lm;
/**
- * Start and end character indices of the runs.
- * First index is the run number, second is 0 or 1 for the starting
- * and ending character index of the run, respectively.
+ * The total advance of this text layout. This is cache for maximum
+ * performance.
*/
- private int[][] runIndices;
+ private float totalAdvance = -1F;
+
+ /**
+ * The cached natural bounds.
+ */
+ private Rectangle2D naturalBounds;
/**
+ * Character indices.
+ * Fixt index is the glyphvector, second index is the (first) glyph.
+ */
+ private int[][] charIndices;
+
+ /**
* Base directionality, determined from the first char.
*/
private boolean leftToRight;
@@ -83,87 +155,249 @@
private boolean hasWhitespace = false;
/**
+ * The {@link Bidi} object that is used for reordering and by
+ * {@link #getCharacterLevel(int)}.
+ */
+ private Bidi bidi;
+
+ /**
+ * Mpas the logical position of each individual character in the original
+ * string to its visual position.
+ */
+ private int[] logicalToVisual;
+
+ /**
+ * Maps visual positions of a character to its logical position
+ * in the original string.
+ */
+ private int[] visualToLogical;
+
+ /**
+ * The cached hashCode.
+ */
+ private int hash;
+
+ /**
* The default caret policy.
*/
- static TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+ public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY =
+ new CaretPolicy();
/**
* Constructs a TextLayout.
*/
- public TextLayout (String string, Font font, FontRenderContext frc)
+ public TextLayout (String str, Font font, FontRenderContext frc)
{
- this.font = font;
this.frc = frc;
- this.string = string;
- lm = font.getLineMetrics(string, frc);
+ string = str.toCharArray();
+ offset = 0;
+ length = this.string.length;
+ lm = font.getLineMetrics(this.string, offset, length, frc);
// Get base direction and whitespace info
getStringProperties();
- if( Bidi.requiresBidi( string.toCharArray(), 0, string.length() ) )
+ if (Bidi.requiresBidi(string, offset, offset + length))
{
- Bidi bidi = new Bidi( string, leftToRight ?
- Bidi.DIRECTION_LEFT_TO_RIGHT :
- Bidi.DIRECTION_RIGHT_TO_LEFT );
+ bidi = new Bidi(str, leftToRight ? Bidi.DIRECTION_LEFT_TO_RIGHT
+ : Bidi.DIRECTION_RIGHT_TO_LEFT );
int rc = bidi.getRunCount();
byte[] table = new byte[ rc ];
for(int i = 0; i < table.length; i++)
table[i] = (byte)bidi.getRunLevel(i);
- runs = new GlyphVector[ rc ];
- runIndices = new int[rc][2];
- for(int i = 0; i < runs.length; i++)
+ runs = new Run[rc];
+ for(int i = 0; i < rc; i...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 18:39:40
|
Revision: 3042
http://jnode.svn.sourceforge.net/jnode/?rev=3042&view=rev
Author: lsantha
Date: 2007-01-07 10:39:36 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/gnu/gnu/java/io/Base64InputStream.java
trunk/core/src/classpath/gnu/gnu/java/lang/InstrumentationImpl.java
trunk/core/src/classpath/gnu/gnu/java/lang/management/BeanImpl.java
trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryMXBeanImpl.java
trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryPoolMXBeanImpl.java
trunk/core/src/classpath/gnu/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
trunk/core/src/classpath/gnu/gnu/java/lang/management/ThreadMXBeanImpl.java
trunk/core/src/classpath/gnu/gnu/java/lang/reflect/ClassSignatureParser.java
trunk/core/src/classpath/gnu/gnu/java/lang/reflect/GenericSignatureParser.java
trunk/core/src/classpath/gnu/gnu/java/lang/reflect/MethodSignatureParser.java
trunk/core/src/classpath/gnu/gnu/java/nio/charset/ByteCharset.java
trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java
trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java
trunk/core/src/classpath/gnu/gnu/java/rmi/server/ActivatableRef.java
trunk/core/src/classpath/gnu/gnu/java/rmi/server/RMIObjectInputStream.java
trunk/core/src/classpath/gnu/gnu/java/security/Engine.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/X509Certificate.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/CertificatePolicies.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/ExtendedKeyUsage.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/Extension.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/GeneralNames.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/IssuerAlternativeNames.java
trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/SubjectAlternativeNames.java
trunk/core/src/classpath/gnu/gnu/java/util/regex/RESyntax.java
trunk/core/src/classpath/gnu/gnu/java/util/regex/RETokenNamedProperty.java
trunk/core/src/classpath/gnu/gnu/java/util/regex/RETokenRepeated.java
trunk/core/src/classpath/gnu/gnu/javax/crypto/RSACipherImpl.java
trunk/core/src/classpath/gnu/gnu/javax/crypto/jce/cipher/CipherAdapter.java
trunk/core/src/classpath/gnu/gnu/javax/crypto/pad/PKCS7.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/InputSecurityParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SimpleSessionContext.java
Modified: trunk/core/src/classpath/gnu/gnu/java/io/Base64InputStream.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/io/Base64InputStream.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/io/Base64InputStream.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -139,7 +139,9 @@
while (count < len)
{
int i;
- while (Character.isWhitespace((char) (i = in.read())));
+ while (Character.isWhitespace((char) (i = in.read())))
+ ;
+
int pos = BASE_64.indexOf((char) i);
if (pos >= 0)
{
@@ -173,11 +175,13 @@
case 1:
throw new IOException("malformed Base-64 input");
case 2:
- while (Character.isWhitespace((char) (i = in.read())));
+ while (Character.isWhitespace((char) (i = in.read())))
+ ;
if (i != BASE_64_PAD)
throw new IOException("malformed Base-64 input");
case 3:
- while (Character.isWhitespace((char) (i = in.read())));
+ while (Character.isWhitespace((char) (i = in.read())))
+ ;
}
eof = true;
break;
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/InstrumentationImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/InstrumentationImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/InstrumentationImpl.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -1,6 +1,6 @@
/* InstrumentationImpl.java -- GNU implementation of
java.lang.instrument.Instrumentation
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -63,11 +63,11 @@
{
/* List of transformers */
- /* FIXME[GENERICS]: Should be ClassFileTransformer list */
- private ArrayList transformers = new ArrayList();
+ private ArrayList<ClassFileTransformer> transformers =
+ new ArrayList<ClassFileTransformer>();
- private InstrumentationImpl()
+ InstrumentationImpl()
{
}
@@ -210,9 +210,8 @@
*
* @return the new class file
*/
- /* FIXME[GENERICS]: Should be Class<?> */
public byte[] callTransformers(ClassLoader loader, String className,
- Class classBeingRedefined, ProtectionDomain protectionDomain,
+ Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer)
{
byte[] newBuffer = null;
@@ -220,11 +219,10 @@
ClassFileTransformer current;
synchronized (transformers)
{
- Iterator i = transformers.iterator();
+ Iterator<ClassFileTransformer> i = transformers.iterator();
while (i.hasNext())
{
- /* FIXME[GENERICS]: Remove cast */
- current = (ClassFileTransformer) i.next();
+ current = i.next();
try
{
newBuffer = current.transform(loader, className,
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/management/BeanImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/management/BeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/management/BeanImpl.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -201,32 +201,36 @@
return ((Enum) value).name();
Class vClass = value.getClass();
if (vClass.isArray())
- return value;
+ vClass = vClass.getComponentType();
String cName = vClass.getName();
String[] allowedTypes = OpenType.ALLOWED_CLASSNAMES;
for (int a = 0; a < allowedTypes.length; ++a)
if (cName.equals(allowedTypes[a]))
return value;
+ OpenMBeanInfo info = (OpenMBeanInfo) getMBeanInfo();
+ MBeanAttributeInfo[] attribs =
+ (MBeanAttributeInfo[]) info.getAttributes();
+ OpenType type = null;
+ for (int a = 0; a < attribs.length; ++a)
+ if (attribs[a].getName().equals(attribute))
+ type = ((OpenMBeanAttributeInfo) attribs[a]).getOpenType();
if (value instanceof List)
{
+ try
+ {
+ Class e =
+ Class.forName(((ArrayType) type).getElementOpenType().getClassName());
List l = (List) value;
- Class e = null;
- TypeVariable[] vars = vClass.getTypeParameters();
- for (int a = 0; a < vars.length; ++a)
- if (vars[a].getName().equals("E"))
- e = (Class) vars[a].getGenericDeclaration();
- if (e == null)
- e = Object.class;
Object[] array = (Object[]) Array.newInstance(e, l.size());
return l.toArray(array);
}
- OpenMBeanInfo info = (OpenMBeanInfo) getMBeanInfo();
- OpenMBeanAttributeInfo[] attribs =
- (OpenMBeanAttributeInfo[]) info.getAttributes();
- OpenType type = null;
- for (int a = 0; a < attribs.length; ++a)
- if (attribs[a].getName().equals("attribute"))
- type = attribs[a].getOpenType();
+ catch (ClassNotFoundException e)
+ {
+ throw (InternalError) (new InternalError("The class of the list " +
+ "element type could not " +
+ "be created").initCause(e));
+ }
+ }
if (value instanceof Map)
{
TabularType ttype = (TabularType) type;
@@ -425,6 +429,34 @@
return new OpenMBeanParameterInfoSupport("TransParam",
"Translated parameter",
SimpleType.VOID);
+ if (type.startsWith("java.util.Map"))
+ {
+ int lparam = type.indexOf("<");
+ int comma = type.indexOf(",", lparam);
+ int rparam = type.indexOf(">", comma);
+ String key = type.substring(lparam + 1, comma).trim();
+ OpenType k = translate(key).getOpenType();
+ OpenType v = translate(type.substring(comma + 1, rparam).trim()).getOpenType();
+ CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
+ new String[] { "key", "value" },
+ new String[] { "Map key", "Map value"},
+ new OpenType[] { k, v});
+ TabularType ttype = new TabularType(key, key, ctype,
+ new String[] { "key" });
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ ttype);
+ }
+ if (type.startsWith("java.util.List"))
+ {
+ int lparam = type.indexOf("<");
+ int rparam = type.indexOf(">");
+ OpenType e = translate(type.substring(lparam + 1, rparam).trim()).getOpenType();
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ new ArrayType(1, e)
+ );
+ }
Class c;
try
{
@@ -432,8 +464,9 @@
}
catch (ClassNotFoundException e)
{
- throw new InternalError("The class for a type used in a management bean " +
- "could not be loaded.");
+ throw (InternalError)
+ (new InternalError("The class for a type used in a management bean " +
+ "could not be loaded.").initCause(e));
}
if (c.isEnum())
{
@@ -450,9 +483,9 @@
try
{
c.getMethod("from", new Class[] { CompositeData.class });
- Method[] methods = c.getMethods();
- List names = new ArrayList();
- List types = new ArrayList();
+ Method[] methods = c.getDeclaredMethods();
+ List<String> names = new ArrayList<String>();
+ List<OpenType> types = new ArrayList<OpenType>();
for (int a = 0; a < methods.length; ++a)
{
String name = methods[a].getName();
@@ -462,10 +495,10 @@
types.add(getTypeFromClass(methods[a].getReturnType()));
}
}
- String[] fields = (String[]) names.toArray();
+ String[] fields = names.toArray(new String[names.size()]);
CompositeType ctype = new CompositeType(c.getName(), c.getName(),
fields, fields,
- (OpenType[]) types.toArray());
+ types.toArray(new OpenType[types.size()]));
return new OpenMBeanParameterInfoSupport("TransParam",
"Translated parameter",
ctype);
@@ -474,46 +507,11 @@
{
/* Ignored; we expect this if this isn't a from(CompositeData) class */
}
- if (Map.class.isAssignableFrom(c))
- {
- OpenType k = SimpleType.VOID;
- OpenType v = SimpleType.VOID;
- TypeVariable[] vars = c.getTypeParameters();
- for (int a = 0; a < vars.length; ++a)
- {
- if (vars[a].getName().equals("K"))
- k = getTypeFromClass((Class) vars[a].getGenericDeclaration());
- if (vars[a].getName().equals("V"))
- v = getTypeFromClass((Class) vars[a].getGenericDeclaration());
- }
- CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
- new String[] { "key", "value" },
- new String[] { "Map key", "Map value"},
- new OpenType[] { k, v});
- TabularType ttype = new TabularType(c.getName(), c.getName(), ctype,
- new String[] { "key" });
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- ttype);
- }
- if (List.class.isAssignableFrom(c))
- {
- OpenType e = SimpleType.VOID;
- TypeVariable[] vars = c.getTypeParameters();
- for (int a = 0; a < vars.length; ++a)
- {
- if (vars[a].getName().equals("E"))
- e = getTypeFromClass((Class) vars[a].getGenericDeclaration());
- }
- return new OpenMBeanParameterInfoSupport("TransParam",
- "Translated parameter",
- new ArrayType(1, e)
- );
- }
if (c.isArray())
{
int depth;
- for (depth = 0; c.getName().charAt(depth) == '['; ++depth);
+ for (depth = 0; c.getName().charAt(depth) == '['; ++depth)
+ ;
OpenType ot = getTypeFromClass(c.getComponentType());
return new OpenMBeanParameterInfoSupport("TransParam",
"Translated parameter",
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryMXBeanImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryMXBeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryMXBeanImpl.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -37,6 +37,8 @@
package gnu.java.lang.management;
+import gnu.classpath.ListenerData;
+
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryNotificationInfo;
import java.lang.management.MemoryUsage;
@@ -168,49 +170,6 @@
VMMemoryMXBeanImpl.setVerbose(verbose);
}
- private class ListenerData
- {
- private NotificationListener listener;
- private NotificationFilter filter;
- private Object passback;
-
- public ListenerData(NotificationListener listener,
- NotificationFilter filter, Object passback)
- {
- this.listener = listener;
- this.filter = filter;
- this.passback = passback;
- }
-
- public NotificationListener getListener()
- {
- return listener;
- }
-
- public NotificationFilter getFilter()
- {
- return filter;
- }
-
- public Object getPassback()
- {
- return passback;
- }
-
- public boolean equals(Object obj)
- {
- if (obj instanceof ListenerData)
- {
- ListenerData data = (ListenerData) obj;
- return (data.getListener() == listener &&
- data.getFilter() == filter &&
- data.getPassback() == passback);
- }
- return false;
- }
-
- }
-
public void addNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object passback)
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryPoolMXBeanImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryPoolMXBeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/management/MemoryPoolMXBeanImpl.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -40,8 +40,8 @@
import gnu.classpath.SystemProperties;
import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
-import java.lang.management.MemoryType;
import javax.management.NotCompliantMBeanException;
@@ -136,7 +136,8 @@
public MemoryType getType()
{
- return null;
+ return
+ MemoryType.valueOf(VMMemoryPoolMXBeanImpl.getType(name));
}
public MemoryUsage getUsage()
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/management/OperatingSystemMXBeanImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/management/OperatingSystemMXBeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/management/OperatingSystemMXBeanImpl.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -82,14 +82,14 @@
return System.getProperty("os.name");
}
+ public double getSystemLoadAverage()
+ {
+ return VMOperatingSystemMXBeanImpl.getSystemLoadAverage();
+ }
+
public String getVersion()
{
return System.getProperty("os.version");
}
-
- public double getSystemLoadAverage() {
- //todo implement
- throw new UnsupportedOperationException();
- }
}
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/management/ThreadMXBeanImpl.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/management/ThreadMXBeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/management/ThreadMXBeanImpl.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -85,6 +85,18 @@
"gnu.java.lang.management.ThreadTimeInitallyEnabled";
/**
+ * Constant for monitor usage monitoring support.
+ */
+ private static final String MONITOR_SUPPORT =
+ "gnu.java.lang.management.MonitorUsageMonitoringSupport";
+
+ /**
+ * Constant for ownable synchronizer usage monitoring support.
+ */
+ private static final String SYNCHRONIZER_SUPPORT =
+ "gnu.java.lang.management.OwnableSynchronizerUsageMonitoringSupport";
+
+ /**
* Flag to indicate whether time monitoring is enabled or not.
*/
private boolean timeEnabled;
@@ -112,6 +124,23 @@
contentionEnabled = false;
}
+ public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
+ boolean lockedSynchronizers)
+ {
+ return getThreadInfo(getAllThreadIds(), lockedMonitors,
+ lockedSynchronizers);
+ }
+
+ public long[] findDeadlockedThreads()
+ {
+ checkMonitorPermissions();
+ if (!isSynchronizerUsageSupported())
+ throw new UnsupportedOperationException("Ownable synchronizer usage " +
+ "monitoring is not provided " +
+ "by this VM.");
+ return VMThreadMXBeanImpl.findDeadlockedThreads();
+ }
+
public long[] findMonitorDeadlockedThreads()
{
checkMonitorPermissions();
@@ -207,6 +236,27 @@
return infos;
}
+ public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors,
+ boolean lockedSynchronizers)
+ {
+ checkMonitorPermissions();
+ if (lockedMonitors && !isObjectMonitorUsageSupported())
+ throw new UnsupportedOperationException("Monitor usage monitoring is " +
+ "not provided by this VM.");
+ if (lockedSynchronizers && !isSynchronizerUsageSupported())
+ throw new UnsupportedOperationException("Ownable synchronizer usage " +
+ "monitoring is not provided " +
+ "by this VM.");
+ ThreadInfo[] infos = getThreadInfo(ids, Integer.MAX_VALUE);
+ if (lockedMonitors)
+ for (ThreadInfo info : infos)
+ VMThreadMXBeanImpl.getMonitorInfo(info);
+ if (lockedSynchronizers)
+ for (ThreadInfo info : infos)
+ VMThreadMXBeanImpl.getLockInfo(info);
+ return infos;
+ }
+
public long getThreadUserTime(long id)
{
if (!isThreadCpuTimeSupported())
@@ -231,6 +281,16 @@
return SystemProperties.getProperty(CURRENT_THREAD_TIME_SUPPORT) != null;
}
+ public boolean isObjectMonitorUsageSupported()
+ {
+ return SystemProperties.getProperty(MONITOR_SUPPORT) != null;
+ }
+
+ public boolean isSynchronizerUsageSupported()
+ {
+ return SystemProperties.getProperty(SYNCHRONIZER_SUPPORT) != null;
+ }
+
public boolean isThreadContentionMonitoringEnabled()
{
if (isThreadContentionMonitoringSupported())
@@ -287,30 +347,5 @@
"supported.");
}
-
- public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers) {
- //todo implement
- throw new UnsupportedOperationException();
- }
-
- public long[] findDeadlockedThreads() {
- //todo implement
- throw new UnsupportedOperationException();
- }
-
- public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers) {
- //todo implement
- throw new UnsupportedOperationException();
- }
-
- public boolean isObjectMonitorUsageSupported() {
- //todo implement
- throw new UnsupportedOperationException();
- }
-
- public boolean isSynchronizerUsageSupported() {
- //todo implement
- throw new UnsupportedOperationException();
- }
}
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/reflect/ClassSignatureParser.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/reflect/ClassSignatureParser.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/reflect/ClassSignatureParser.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -61,7 +61,7 @@
}
// SuperclassSignature
superclassType = readClassTypeSignature();
- ArrayList interfaces = new ArrayList();
+ ArrayList<Type> interfaces = new ArrayList<Type>();
while (peekChar() == 'L')
{
// SuperinterfaceSignature
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/reflect/GenericSignatureParser.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/reflect/GenericSignatureParser.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/reflect/GenericSignatureParser.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -60,11 +60,10 @@
return this;
}
- /* FIXME[GENERICS]: Remove cast */
public Type[] getBounds()
{
resolve(bounds);
- return (Type[]) bounds.clone();
+ return bounds.clone();
}
public GenericDeclaration getGenericDeclaration()
@@ -141,10 +140,9 @@
return this;
}
- /* FIXME[GENERICS]: Remove cast */
public Type[] getActualTypeArguments()
{
- return (Type[]) typeArgs.clone();
+ return typeArgs.clone();
}
public Type getRawType()
@@ -276,12 +274,11 @@
GenericDeclaration d = decl;
while (d != null)
{
- TypeVariable[] vars = d.getTypeParameters();
- for (int a = 0; a < vars.length ; ++a)
+ for (TypeVariable t : d.getTypeParameters())
{
- if (vars[a].getName().equals(name))
+ if (t.getName().equals(name))
{
- return vars[a];
+ return t;
}
}
d = getParent(d);
@@ -414,7 +411,7 @@
TypeVariable[] readFormalTypeParameters()
{
consume('<');
- ArrayList params = new ArrayList();
+ ArrayList<TypeVariable> params = new ArrayList<TypeVariable>();
do
{
// TODO should we handle name clashes?
@@ -430,7 +427,7 @@
{
String identifier = readIdentifier();
consume(':');
- ArrayList bounds = new ArrayList();
+ ArrayList<Type> bounds = new ArrayList<Type>();
if (peekChar() != ':')
{
bounds.add(readFieldTypeSignature());
@@ -501,7 +498,7 @@
private Type[] readTypeArguments()
{
consume('<');
- ArrayList list = new ArrayList();
+ ArrayList<Type> list = new ArrayList<Type>();
do
{
list.add(readTypeArgument());
Modified: trunk/core/src/classpath/gnu/gnu/java/lang/reflect/MethodSignatureParser.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/lang/reflect/MethodSignatureParser.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/lang/reflect/MethodSignatureParser.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -72,7 +72,7 @@
typeParameters = new TypeVariable[0];
}
consume('(');
- ArrayList args = new ArrayList();
+ ArrayList<Type> args = new ArrayList<Type>();
while (peekChar() != ')')
{
args.add(readTypeSignature());
@@ -81,7 +81,7 @@
args.toArray(argTypes);
consume(')');
retType = readTypeSignature();
- ArrayList throwsSigs = new ArrayList();
+ ArrayList<Type> throwsSigs = new ArrayList<Type>();
while (peekChar() == '^')
{
consume('^');
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/charset/ByteCharset.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/charset/ByteCharset.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/charset/ByteCharset.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -115,8 +115,8 @@
return CoderResult.OVERFLOW;
}
- if((c = lookup[(int) (b & 0xFF)]) == NONE);
- // return CoderResult.unmappableForLength (1);
+ if((c = lookup[(int) (b & 0xFF)]) == NONE)
+ return CoderResult.unmappableForLength (1);
out.put (c);
}
@@ -156,6 +156,22 @@
}
}
+ public boolean canEncode(char c)
+ {
+ byte b = (c < lookup.length) ? lookup[c] : 0;
+ return b != 0 || c == 0;
+ }
+
+ public boolean canEncode(CharSequence cs)
+ {
+ for (int i = 0; i < cs.length(); ++i)
+ {
+ if (! canEncode(cs.charAt(i)))
+ return false;
+ }
+ return true;
+ }
+
protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out)
{
// TODO: Optimize this in the case in.hasArray() / out.hasArray()
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/charset/ISO_8859_1.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -128,6 +128,19 @@
super (cs, 1.0f, 1.0f);
}
+ public boolean canEncode(char c)
+ {
+ return c <= 0xff;
+ }
+
+ public boolean canEncode(CharSequence cs)
+ {
+ for (int i = 0; i < cs.length(); ++i)
+ if (! canEncode(cs.charAt(i)))
+ return false;
+ return true;
+ }
+
protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out)
{
// TODO: Optimize this in the case in.hasArray() / out.hasArray()
Modified: trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/nio/charset/US_ASCII.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -134,6 +134,19 @@
super (cs, 1.0f, 1.0f);
}
+ public boolean canEncode(char c)
+ {
+ return c <= 0x7f;
+ }
+
+ public boolean canEncode(CharSequence cs)
+ {
+ for (int i = 0; i < cs.length(); ++i)
+ if (! canEncode(cs.charAt(i)))
+ return false;
+ return true;
+ }
+
protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out)
{
// TODO: Optimize this in the case in.hasArray() / out.hasArray()
@@ -141,7 +154,7 @@
{
char c = in.get ();
- if (c > Byte.MAX_VALUE)
+ if (c > 0x7f)
{
in.position (in.position () - 1);
return CoderResult.unmappableForLength (1);
Modified: trunk/core/src/classpath/gnu/gnu/java/rmi/server/ActivatableRef.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/rmi/server/ActivatableRef.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/rmi/server/ActivatableRef.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -112,8 +112,10 @@
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException
{
+ actId = (ActivationID) in.readObject();
+ String type = in.readUTF();
+ // XXX handle type.equals("") (null reference)
super.readExternal(in);
- actId = (ActivationID) in.readObject();
}
/**
@@ -121,8 +123,10 @@
*/
public void writeExternal(ObjectOutput out) throws IOException
{
+ out.writeObject(actId);
+ // XXX write a "" if the "nested" reference is a null reference
+ out.writeUTF("UnicastRef2");
super.writeExternal(out);
- out.writeObject(actId);
}
/**
Modified: trunk/core/src/classpath/gnu/gnu/java/rmi/server/RMIObjectInputStream.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/rmi/server/RMIObjectInputStream.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/rmi/server/RMIObjectInputStream.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -1,5 +1,5 @@
/* RMIObjectInputStream.java --
- Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,11 +39,11 @@
package gnu.java.rmi.server;
+import gnu.classpath.VMStackWalker;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
-import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.rmi.server.RMIClassLoader;
import java.util.ArrayList;
@@ -57,16 +57,14 @@
}
protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
- String annotation = (String)getAnnotation();
-
try {
- if(annotation == null)
- return (RMIClassLoader.loadClass(desc.getName()));
- else
- return (RMIClassLoader.loadClass(annotation, desc.getName()));
+ return RMIClassLoader.loadClass(
+ (String)getAnnotation(),
+ desc.getName(),
+ VMStackWalker.firstNonNullClassLoader());
}
- catch (MalformedURLException _) {
- throw new ClassNotFoundException(desc.getName());
+ catch (MalformedURLException x) {
+ throw new ClassNotFoundException(desc.getName(), x);
}
}
@@ -81,45 +79,16 @@
protected Class resolveProxyClass(String intfs[]) throws IOException,
ClassNotFoundException
{
- String annotation = (String) getAnnotation();
-
- Class clss[] = new Class[intfs.length];
-
- for (int i = 0; i < intfs.length; i++)
- {
- if (annotation == null)
- clss[i] = RMIClassLoader.loadClass(intfs[i]);
- else
- clss[i] = RMIClassLoader.loadClass(annotation, intfs[i]);
- }
-
- ClassLoader loader;
-
- if (clss.length > 0)
- {
- // Chain all class loaders (they may differ).
- ArrayList loaders = new ArrayList(intfs.length);
- ClassLoader cx;
- for (int i = 0; i < clss.length; i++)
- {
- cx = clss[i].getClassLoader();
- if (!loaders.contains(cx))
- {
- loaders.add(0, cx);
- }
- }
- loader = new CombinedClassLoader(loaders);
- }
- else
- loader = ClassLoader.getSystemClassLoader();
-
try
{
- return Proxy.getProxyClass(loader, clss);
+ return RMIClassLoader.loadProxyClass(
+ (String)getAnnotation(),
+ intfs,
+ VMStackWalker.firstNonNullClassLoader());
}
- catch (IllegalArgumentException e)
+ catch (MalformedURLException x)
{
- throw new ClassNotFoundException(null, e);
+ throw new ClassNotFoundException(null, x);
}
}
Modified: trunk/core/src/classpath/gnu/gnu/java/security/Engine.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/security/Engine.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/security/Engine.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -42,6 +42,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import java.util.Enumeration;
/**
* Generic implementation of the getInstance methods in the various
@@ -78,25 +79,22 @@
/** This class cannot be instantiated. */
private Engine() { }
- // Class method.
- // ------------------------------------------------------------------------
-
/**
- * Get the implementation for <i>algorithm</i> for service
- * <i>service</i> from <i>provider</i>. The service is e.g.
- * "Signature", and the algorithm "DSA".
+ * Return the implementation for <i>algorithm</i> for service <i>service</i>
+ * from <i>provider</i>. The service is e.g. "Signature", and the algorithm
+ * "DSA".
*
* @param service The service name.
* @param algorithm The name of the algorithm to get.
* @param provider The provider to get the implementation from.
- * @return The engine class for the specified algorithm; the object
- * returned is typically a subclass of the SPI class for that
- * service, but callers should check that this is so.
- * @throws NoSuchAlgorithmException If the implementation cannot be
- * found or cannot be instantiated.
- * @throws InvocationTargetException If the SPI class's constructor
- * throws an exception.
- * @throws IllegalArgumentException If any of the three arguments are null.
+ * @return The engine class for the specified algorithm; the object returned
+ * is typically a subclass of the SPI class for that service, but
+ * callers should check that this is so.
+ * @throws NoSuchAlgorithmException If the implementation cannot be found or
+ * cannot be instantiated.
+ * @throws InvocationTargetException If the SPI class's constructor throws an
+ * exception.
+ * @throws IllegalArgumentException If any of the three arguments is null.
*/
public static Object getInstance(String service, String algorithm,
Provider provider)
@@ -106,107 +104,145 @@
}
/**
- * Get the implementation for <i>algorithm</i> for service
- * <i>service</i> from <i>provider</i>, passing <i>initArgs</i> to the
- * SPI class's constructor (which cannot be null; pass a zero-length
- * array if the SPI takes no arguments). The service is e.g.
- * "Signature", and the algorithm "DSA".
+ * Return the implementation for <i>algorithm</i> for service <i>service</i>
+ * from <i>provider</i>, passing <i>initArgs</i> to the SPI class's
+ * constructor (which cannot be null; pass a zero-length array if the SPI
+ * takes no arguments). The service is e.g. "Signature", and the algorithm
+ * "DSA".
*
* @param service The service name.
* @param algorithm The name of the algorithm to get.
* @param provider The provider to get the implementation from.
- * @param initArgs The arguments to pass to the SPI class's
- * constructor (cannot be null).
- * @return The engine class for the specified algorithm; the object
- * returned is typically a subclass of the SPI class for that
- * service, but callers should check that this is so.
- * @throws NoSuchAlgorithmException If the implementation cannot be
- * found or cannot be instantiated.
- * @throws InvocationTargetException If the SPI class's constructor
- * throws an exception.
- * @throws IllegalArgumentException If any of the four arguments are null.
+ * @param initArgs The arguments to pass to the SPI class's constructor
+ * (cannot be null).
+ * @return The engine class for the specified algorithm; the object returned
+ * is typically a subclass of the SPI class for that service, but
+ * callers should check that this is so.
+ * @throws NoSuchAlgorithmException If the implementation cannot be found or
+ * cannot be instantiated.
+ * @throws InvocationTargetException If the SPI class's constructor throws an
+ * exception.
+ * @throws IllegalArgumentException If any of the four arguments is
+ * <code>null</code> or if either <code>service</code>, or
+ * <code>algorithm</code> is an empty string.
*/
public static Object getInstance(String service, String algorithm,
Provider provider, Object[] initArgs)
throws InvocationTargetException, NoSuchAlgorithmException
{
- if (service != null)
+ if (service == null)
+ throw new IllegalArgumentException("service MUST NOT be null");
service = service.trim();
-
- if (algorithm != null)
+ if (service.length() == 0)
+ throw new IllegalArgumentException("service MUST NOT be empty");
+ if (algorithm == null)
+ throw new IllegalArgumentException("algorithm MUST NOT be null");
algorithm = algorithm.trim();
+ if (algorithm.length() == 0)
+ throw new IllegalArgumentException("algorithm MUST NOT be empty");
+ if (provider == null)
+ throw new IllegalArgumentException("provider MUST NOT be null");
+ if (initArgs == null)
+ throw new IllegalArgumentException("Constructor's parameters MUST NOT be null");
- if (service == null || service.length() == 0
- || algorithm == null || algorithm.length() == 0
- || provider == null || initArgs == null)
- throw new IllegalArgumentException();
-
- // If there is no property "service.algorithm"
- if (provider.getProperty(service + "." + algorithm) == null)
+ Enumeration enumer = provider.propertyNames();
+ String key;
+ String alias;
+ int count = 0;
+ boolean algorithmFound = false;
+ StringBuilder sb = new StringBuilder();
+ while (enumer.hasMoreElements())
{
- // Iterate through aliases, until we find the class name or resolve
- // too many aliases.
- String alias = null;
- int count = 0;
- while ((alias = provider.getProperty(
- ALG_ALIAS + service + "." + algorithm)) != null)
+ key = (String) enumer.nextElement();
+ if (key.equalsIgnoreCase(service + "." + algorithm))
{
- if (algorithm.equals(alias)) // Refers to itself!
+ // remove the service portion from the key
+ algorithm = key.substring(service.length() + 1);
+ algorithmFound = true;
break;
+ }
+ else if (key.equalsIgnoreCase(ALG_ALIAS + service + "." + algorithm))
+ {
+ alias = (String) provider.getProperty(key);
+ if (! algorithm.equalsIgnoreCase(alias)) // does not refer to itself
+ {
algorithm = alias;
if (count++ > MAX_ALIASES)
- throw new NoSuchAlgorithmException("too many aliases");
+ {
+ sb.append("Algorithm [").append(algorithm)
+ .append("] of type [").append(service)
+ .append("] from provider [").append(provider)
+ .append("] has too many aliases");
+ throw new NoSuchAlgorithmException(sb.toString());
}
- if (provider.getProperty(service + "." + algorithm) == null)
- throw new NoSuchAlgorithmException(algorithm);
+ // need to reset enumeration to now look for the alias
+ enumer = provider.propertyNames();
+ }
+ }
}
- // Find and instantiate the implementation.
+ if (! algorithmFound)
+ {
+ sb.append("Algorithm [").append(algorithm).append("] of type [")
+ .append(service).append("] from provider [")
+ .append(provider).append("] is not found");
+ throw new NoSuchAlgorithmException(sb.toString());
+ }
+
+ // Find and instantiate the implementation
Class clazz = null;
ClassLoader loader = provider.getClass().getClassLoader();
Constructor constructor = null;
- String error = algorithm;
-
+ String className = provider.getProperty(service + "." + algorithm);
+ sb.append("Class [").append(className).append("] for algorithm [")
+ .append(algorithm).append("] of type [").append(service)
+ .append("] from provider [").append(provider).append("] ");
+ Throwable cause = null;
try
{
if (loader != null)
- clazz = loader.loadClass(provider.getProperty(service+"."+algorithm));
+ clazz = loader.loadClass(className);
else
- clazz = Class.forName(provider.getProperty(service+"."+algorithm));
+ clazz = Class.forName(className);
constructor = getCompatibleConstructor(clazz, initArgs);
return constructor.newInstance(initArgs);
}
- catch (ClassNotFoundException cnfe)
+ catch (ClassNotFoundException x)
{
- error = "class not found: " + algorithm;
+ sb.append("cannot not be found");
+ cause = x;
}
- catch (IllegalAccessException iae)
+ catch (IllegalAccessException x)
{
- error = "illegal access: " + iae.getMessage();
+ sb.append("cannot be accessed");
+ cause = x;
}
- catch (InstantiationException ie)
+ catch (InstantiationException x)
{
- error = "instantiation exception: " + ie.getMessage();
+ sb.append("cannot be instantiated");
+ cause = x;
}
- catch (ExceptionInInitializerError eiie)
+ catch (ExceptionInInitializerError x)
{
- error = "exception in initializer: " + eiie.getMessage();
+ sb.append("cannot be initialized");
+ cause = x;
}
- catch (SecurityException se)
+ catch (SecurityException x)
{
- error = "security exception: " + se.getMessage();
+ sb.append("caused a security violation");
+ cause = x;
}
- catch (NoSuchMethodException nsme)
+ catch (NoSuchMethodException x)
{
- error = "no appropriate constructor found";
+ sb.append("does not have/expose an appropriate constructor");
+ cause = x;
}
- throw new NoSuchAlgorithmException(error);
+ NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
+ x.initCause(cause);
+ throw x;
}
- // Own methods.
- // ------------------------------------------------------------------------
-
/**
* Find a constructor in the given class that can take the specified
* argument list, allowing any of which to be null.
Modified: trunk/core/src/classpath/gnu/gnu/java/security/x509/X509Certificate.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/security/x509/X509Certificate.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/security/x509/X509Certificate.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -1,5 +1,5 @@
/* X509Certificate.java -- X.509 certificate.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,6 +48,7 @@
import gnu.java.security.x509.ext.BasicConstraints;
import gnu.java.security.x509.ext.ExtendedKeyUsage;
import gnu.java.security.x509.ext.Extension;
+import gnu.java.security.x509.ext.GeneralName;
import gnu.java.security.x509.ext.IssuerAlternativeNames;
import gnu.java.security.x509.ext.KeyUsage;
import gnu.java.security.x509.ext.SubjectAlternativeNames;
@@ -103,6 +104,7 @@
// Constants and fields.
// ------------------------------------------------------------------------
+ private static final long serialVersionUID = -2491127588187038216L;
private static final Logger logger = SystemLogger.SYSTEM;
protected static final OID ID_DSA = new OID ("1.2.840.10040.4.1");
@@ -133,7 +135,7 @@
protected transient PublicKey subjectKey;
protected transient BitString issuerUniqueId;
protected transient BitString subjectUniqueId;
- protected transient Map extensions;
+ protected transient Map<OID, Extension> extensions;
// Signature.
protected transient OID sigAlgId;
@@ -157,7 +159,7 @@
throws CertificateException, IOException
{
super();
- extensions = new HashMap();
+ extensions = new HashMap<OID, Extension>();
try
{
parse(encoded);
@@ -178,7 +180,7 @@
protected X509Certificate()
{
- extensions = new HashMap();
+ extensions = new HashMap<OID, Extension>();
}
// X509Certificate methods.
@@ -316,17 +318,15 @@
return null;
}
- public List getExtendedKeyUsage() throws CertificateParsingException
+ public List<String> getExtendedKeyUsage() throws CertificateParsingException
{
Extension e = getExtension(ExtendedKeyUsage.ID);
if (e != null)
{
- List a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
- List b = new ArrayList(a.size());
- for (Iterator it = a.iterator(); it.hasNext(); )
- {
- b.add(it.next().toString());
- }
+ List<OID> a = ((ExtendedKeyUsage) e.getValue()).getPurposeIds();
+ List<String> b = new ArrayList<String>(a.size());
+ for (OID oid : a)
+ b.add(oid.toString());
return Collections.unmodifiableList(b);
}
return null;
@@ -342,24 +342,44 @@
return -1;
}
- public Collection getSubjectAlternativeNames()
+ public Collection<List<?>> getSubjectAlternativeNames()
throws CertificateParsingException
{
Extension e = getExtension(SubjectAlternativeNames.ID);
if (e != null)
{
- return ((SubjectAlternativeNames) e.getValue()).getNames();
+ List<GeneralName> names
+ = ((SubjectAlternativeNames) e.getValue()).getNames();
+ List<List<?>> list = new ArrayList<List<?>>(names.size());
+ for (GeneralName name : names)
+ {
+ List<Object> n = new ArrayList<Object>(2);
+ n.add(name.kind().tag());
+ n.add(name.name());
+ list.add(n);
+ }
+ return list;
}
return null;
}
- public Collection getIssuerAlternativeNames()
+ public Collection<List<?>> getIssuerAlternativeNames()
throws CertificateParsingException
{
Extension e = getExtension(IssuerAlternativeNames.ID);
if (e != null)
{
- return ((IssuerAlternativeNames) e.getValue()).getNames();
+ List<GeneralName> names
+ = ((IssuerAlternativeNames) e.getValue()).getNames();
+ List<List<?>> list = new ArrayList<List<?>>(names.size());
+ for (GeneralName name : names)
+ {
+ List<Object> n = new ArrayList<Object>(2);
+ n.add(name.kind().tag());
+ n.add(name.name());
+ list.add(n);
+ }
+ return list;
}
return null;
}
@@ -378,24 +398,22 @@
return false;
}
- public Set getCriticalExtensionOIDs()
+ public Set<String> getCriticalExtensionOIDs()
{
- HashSet s = new HashSet();
- for (Iterator it = extensions.values().iterator(); it.hasNext(); )
+ HashSet<String> s = new HashSet<String>();
+ for (Extension e : extensions.values())
{
- Extension e = (Extension) it.next();
if (e.isCritical())
s.add(e.getOid().toString());
}
return Collections.unmodifiableSet(s);
}
- public Set getNonCriticalExtensionOIDs()
+ public Set<String> getNonCriticalExtensionOIDs()
{
- HashSet s = new HashSet();
- for (Iterator it = extensions.values().iterator(); it.hasNext(); )
+ HashSet<String> s = new HashSet<String>();
+ for (Extension e : extensions.values())
{
- Extension e = (Extension) it.next();
if (!e.isCritical())
s.add(e.getOid().toString());
}
Modified: trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/CertificatePolicies.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/CertificatePolicies.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/CertificatePolicies.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -1,5 +1,5 @@
/* CertificatePolicies.java -- certificate policy extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -61,8 +61,8 @@
public static final OID ID = new OID("2.5.29.32");
- private final List policies;
- private final Map policyQualifierInfos;
+ private final List<OID> policies;
+ private final Map<OID, List<PolicyQualifierInfo>> policyQualifierInfos;
// Constructor.
// -------------------------------------------------------------------------
@@ -76,8 +76,9 @@
throw new IOException("malformed CertificatePolicies");
int len = 0;
- LinkedList policyList = new LinkedList();
- HashMap qualifierMap = new HashMap();
+ LinkedList<OID> policyList = new LinkedList<OID>();
+ HashMap<OID, List<PolicyQualifierInfo>> qualifierMap
+ = new HashMap<OID, List<PolicyQualifierInfo>>();
while (len < pol.getLength())
{
DERValue policyInfo = der.read();
@@ -92,7 +93,7 @@
{
DERValue qual = der.read();
int len2 = 0;
- LinkedList quals = new LinkedList();
+ LinkedList<PolicyQualifierInfo> quals = new LinkedList<PolicyQualifierInfo>();
while (len2 < qual.getLength())
{
val = der.read();
@@ -109,8 +110,8 @@
policyQualifierInfos = Collections.unmodifiableMap(qualifierMap);
}
- public CertificatePolicies (final List policies,
- final Map policyQualifierInfos)
+ public CertificatePolicies (final List<OID> policies,
+ final Map<OID, List<PolicyQualifierInfo>> policyQualifierInfos)
{
for (Iterator it = policies.iterator(); it.hasNext(); )
if (!(it.next() instanceof OID))
@@ -129,54 +130,69 @@
throw new IllegalArgumentException
("policyQualifierInfos values must be Lists of PolicyQualifierInfos");
}
- this.policies = Collections.unmodifiableList (new ArrayList (policies));
+ this.policies = Collections.unmodifiableList (new ArrayList<OID>(policies));
this.policyQualifierInfos = Collections.unmodifiableMap
- (new HashMap (policyQualifierInfos));
+ (new HashMap<OID, List<PolicyQualifierInfo>>(policyQualifierInfos));
}
// Instance methods.
// -------------------------------------------------------------------------
- public List getPolicies()
+ public List<OID> getPolicies()
{
return policies;
}
- public List getPolicyQualifierInfos(OID oid)
+ /**
+ * Returns the list of policy OIDs, formatted as dotted-decimal strings.
+ *
+ * @return
+ */
+ public List<String> getPolicyStrings()
{
- return (List) policyQualifierInfos.get(oid);
+ List<String> l = new ArrayList<String>(policies.size());
+ for (OID oid : policies)
+ {
+ l.add(oid.toString());
+ }
+ return l;
}
+ public List<PolicyQualifierInfo> getPolicyQualifierInfos(OID oid)
+ {
+ return policyQualifierInfos.get(oid);
+ }
+
public byte[] getEncoded()
{
if (encoded == null)
{
- List pol = new ArrayList (policies.size());
- for (Iterator it = policies.iterator(); it.hasNext(); )
+ List<DERValue> pol = new ArrayList<DERValue>(policies.size());
+ for (Iterator<OID> it = policies.iterator(); it.hasNext(); )
{
- OID policy = (OID) it.next();
- List qualifiers = getPolicyQualifierInfos (policy);
- List l = new ArrayList (qualifiers == null ? 1 : 2);
- l.add (new DERValue (DER.OBJECT_IDENTIFIER, policy));
+ OID policy = it.next();
+ List<PolicyQualifierInfo> qualifiers = getPolicyQualifierInfos(policy);
+ List<DERValue> l = new ArrayList<DERValue>(qualifiers == null ? 1 : 2);
+ l.add(new DERValue(DER.OBJECT_IDENTIFIER, policy));
if (qualifiers != null)
{
- List ll = new ArrayList (qualifiers.size());
- for (Iterator it2 = qualifiers.iterator(); it.hasNext(); )
+ List<DERValue> ll = new ArrayList<DERValue>(qualifiers.size());
+ for (Iterator<PolicyQualifierInfo> it2 = qualifiers.iterator(); it.hasNext(); )
{
- PolicyQualifierInfo info = (PolicyQualifierInfo) it2.next();
+ PolicyQualifierInfo info = it2.next();
try
{
- ll.add (DERReader.read (info.getEncoded()));
+ ll.add(DERReader.read(info.getEncoded()));
}
catch (IOException ioe)
{
}
}
- l.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ll));
+ l.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, ll));
}
- pol.add (new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, l));
+ pol.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, l));
}
- encoded = new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded();
+ encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pol).getEncoded();
}
return (byte[]) encoded.clone();
}
Modified: trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/ExtendedKeyUsage.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/ExtendedKeyUsage.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/ExtendedKeyUsage.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -1,5 +1,5 @@
/* ExtendedKeyUsage.java -- the extended key usage extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -56,7 +56,7 @@
public static final OID ID = new OID("2.5.29.37");
- private final List purposeIds;
+ private final List<OID> purposeIds;
// Constructor.
// -------------------------------------------------------------------------
@@ -69,13 +69,13 @@
if (!usageList.isConstructed())
throw new IOException("malformed ExtKeyUsageSyntax");
int len = 0;
- purposeIds = new LinkedList();
+ purposeIds = new LinkedList<OID>();
while (len < usageList.getLength())
{
DERValue val = der.read();
if (val.getTag() != DER.OBJECT_IDENTIFIER)
throw new IOException("malformed KeyPurposeId");
- purposeIds.add(val.getValue());
+ purposeIds.add((OID) val.getValue());
len += val.getEncodedLength();
}
}
@@ -83,7 +83,7 @@
// Instance method.
// -------------------------------------------------------------------------
- public List getPurposeIds()
+ public List<OID> getPurposeIds()
{
return Collections.unmodifiableList(purposeIds);
}
Modified: trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/Extension.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/Extension.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/Extension.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -1,5 +1,5 @@
/* Extension.java -- an X.509 certificate or CRL extension.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -171,6 +171,10 @@
{
value = new ReasonCode(encval);
}
+ else if (oid.equals(NameConstraints.ID))
+ {
+ value = new NameConstraints(encval);
+ }
else
{
value = new Value(encval);
@@ -226,11 +230,11 @@
public DERValue getDerValue()
{
- List ext = new ArrayList (3);
- ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid));
- ext.add (new DERValue (DER.BOOLEAN, Boolean.valueOf (critical)));
- ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded()));
- return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext);
+ List<DERValue> ext = new ArrayList<DERValue>(3);
+ ext.add(new DERValue(DER.OBJECT_IDENTIFIER, oid));
+ ext.add(new DERValue(DER.BOOLEAN, Boolean.valueOf(critical)));
+ ext.add(new DERValue(DER.OCTET_STRING, value.getEncoded()));
+ return new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, ext);
}
// Own methods.
Modified: trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/GeneralNames.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/GeneralNames.java 2007-01-07 18:38:08 UTC (rev 3041)
+++ trunk/core/src/classpath/gnu/gnu/java/security/x509/ext/GeneralNames.java 2007-01-07 18:39:36 UTC (rev 3042)
@@ -38,106 +38,38 @@
package gnu.java.security.x509.ext;
-import gnu.java.security.OID;
-import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import java.io.IOException;
-import java.net.InetAddress;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-import javax.security.auth.x500.X500Principal;
-
public class GeneralNames
{
// Instance methods.
// -------------------------------------------------------------------------
- public static final int OTHER_NAME = 0;
- public static final int RFC822_NAME = 1;
- public static final int DNS_NAME = 2;
- public static final int X400_ADDRESS = 3;
- public static final int DIRECTORY_NAME = 4;
- public static final int EDI_PARTY_NAME = 5;
- public static final int URI = 6;
- public static final int IP_ADDRESS = 7;
- public static final int REGISTERED_ID = 8;
+ private List<GeneralName> names;
- private List names;
-
// Constructor.
// -------------------------------------------------------------------------
public GeneralNames(final byte[] encoded) throws IOException
{
- names = new LinkedList();
+ names = new LinkedList<GeneralName>();
DERReader der = new DERReader(encoded);
DERValue nameList = der.read();
if (!nameList.isConstructed())
throw new IOException("malformed GeneralNames");
int len = 0;
- int i = 0;
while (len < nameList.getLength())
{
DERValue name = der.read();
- List namePair = new ArrayList(2);
- int tagClass = name.getTagClass();
- if (tagClass != DER.CONTEXT)
- throw new IOException("malformed GeneralName: Tag class is " + tagClass);
- namePair.add(Integer.valueOf(name.getTag()));
- DERValue val = null;
- switch (name.getTag())
- {
- case RFC822_NAME:
- case DNS_NAME:
- case X400_ADDRESS:
- case URI:
- namePair.add(new String((byte[]) name.getValue()));
- break;
-
- case OTHER_NAME:
- // MUST return the encoded bytes of the OID/OctetString sequence
- byte[] anotherName = name.getEncoded();
- anotherName[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
- namePair.add(anotherName);
- // DERReader goes back on Constructed things so we need to skip over them
- DERValue skip = der.read(); // skip OID
- skip = der.read(); // skip Octet String
- break;
-
- case EDI_PARTY_NAME:
- namePair.add(name.getValue());
- break;
-
- case DIRECTORY_NAME:
- byte[] b = name.getEncoded();
- b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE);
- DERReader r = new DERReader (b);
- r.read ();
- namePair.add(new X500Principal(r.read ().getEncoded ()).toString());
- break;
-
- case IP_ADDRESS:
- namePair.add(InetAddress.getByAddress((byte[]) name.getValue())
- .getHostAddress());
- break;
-
- case REGISTERED_ID:
- byte[] bb = name.getEncoded();
- bb[0] = (byte) DER.OBJECT_IDENTIFIER;
- namePair.add(new OID(bb).toString());
- break;
-
- default:
- throw new IOException("unknown tag " + name.getTag());
- }
- names.add(namePair);
+ GeneralName generalName = new GeneralName(name.getEncoded());
+ names.add(generalName);
len += name.getEncodedLength();
}
}
@@ -145,21 +77,9 @@
// Instance methods.
// -------------------------------------------------------------------------
- public List getNames()
- {
- List l = new ArrayList(names.size());
- for (Iterator it = names.iterator(); it.hasNext(); )
+ public List<GeneralName> getNames()
{
- List ll = (List) it.next();
- List pair = new ArrayList(2);
- ...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 18:38:09
|
Revision: 3041
http://jnode.svn.sourceforge.net/jnode/?rev=3041&view=rev
Author: lsantha
Date: 2007-01-07 10:38:08 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/vm/gnu/java/lang/management/VMThreadMXBeanImpl.java
Added Paths:
-----------
trunk/core/src/classpath/vm/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java
Added: trunk/core/src/classpath/vm/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java
===================================================================
--- trunk/core/src/classpath/vm/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java (rev 0)
+++ trunk/core/src/classpath/vm/gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
@@ -0,0 +1,71 @@
+/* VMOperatingSystemMXBeanImpl.java - VM implementation of an OS bean
+ Copyright (C) 2006 Free Software Foundation
+
+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 gnu.java.lang.management;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Provides access to information about the operating system.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.6
+ */
+final class VMOperatingSystemMXBeanImpl
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangmanagement");
+ }
+ }
+
+ /**
+ * Returns the system load average from the last
+ * minute.
+ *
+ * @return the system load average from the last
+ * minute.
+ */
+ static double getSystemLoadAverage(){
+ //todo implement it
+ throw new UnsupportedOperationException();
+ }
+
+}
Modified: trunk/core/src/classpath/vm/gnu/java/lang/management/VMThreadMXBeanImpl.java
===================================================================
--- trunk/core/src/classpath/vm/gnu/java/lang/management/VMThreadMXBeanImpl.java 2007-01-07 16:10:30 UTC (rev 3040)
+++ trunk/core/src/classpath/vm/gnu/java/lang/management/VMThreadMXBeanImpl.java 2007-01-07 18:38:08 UTC (rev 3041)
@@ -43,7 +43,7 @@
* Provides access to information about the threads
* of the virtual machine. An instance of this bean is
* obtained by calling
- * {@link ManagementFactory#getThreadMXBean()}.
+ * {@link java.lang.management.ManagementFactory#getThreadMXBean()}.
* See {@link java.lang.management.ThreadMXBean} for
* full documentation.
*
@@ -60,6 +60,19 @@
/**
* Returns the ids of cycles of deadlocked threads, occurring
+ * due to monitor ownership or ownable synchronizer ownership.
+ * This will only be called if ownable synchronizer monitoring
+ * is supported.
+ *
+ * @return the ids of the deadlocked threads.
+ */
+ static long[] findDeadlockedThreads(){
+ //todo implement
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the ids of cycles of deadlocked threads, occurring
* due to monitor ownership.
*
* @return the ids of the deadlocked threads.
@@ -144,6 +157,31 @@
}
/**
+ * Fill out the given {@link ThreadInfo} object
+ * with ownable synchronizer usage information.
+ * This is only called if ownable synchronizer
+ * usage monitoring is supported.
+ *
+ * @param info the {@link ThreadInfo} object to modify.
+ */
+ static void getLockInfo(ThreadInfo info){
+ //todo implement
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Fill out the given {@link ThreadInfo} object
+ * with monitor usage information. This is only
+ * called if monitor usage monitoring is supported.
+ *
+ * @param info the {@link ThreadInfo} object to modify.
+ */
+ static void getMonitorInfo(ThreadInfo info){
+ //todo implement
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Returns the current peak number of live threads.
*
* @return the peak number of live threads.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 16:10:34
|
Revision: 3040
http://jnode.svn.sourceforge.net/jnode/?rev=3040&view=rev
Author: lsantha
Date: 2007-01-07 08:10:30 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Added rmic templates.
Modified Paths:
--------------
trunk/core/build.xml
Modified: trunk/core/build.xml
===================================================================
--- trunk/core/build.xml 2007-01-07 16:09:10 UTC (rev 3039)
+++ trunk/core/build.xml 2007-01-07 16:10:30 UTC (rev 3040)
@@ -91,6 +91,7 @@
<fileset dir="${my-src.dir}/classpath/gnu" includes="**/*.properties"/>
<fileset dir="${my-src.dir}/classpath/java" includes="**/*.properties"/>
<fileset dir="${my-src.dir}/classpath/vm" includes="**/*.security"/>
+ <fileset dir="${my-src.dir}/classpath/tools" includes="**/*.jav"/>
</copy>
<ExpandTest classname="PrimitiveIntTest" type="int"/>
<ExpandTest classname="PrimitiveLongTest" type="long"/>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 16:09:12
|
Revision: 3039
http://jnode.svn.sourceforge.net/jnode/?rev=3039&view=rev
Author: lsantha
Date: 2007-01-07 08:09:10 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Added rmic templates.
Modified Paths:
--------------
trunk/core/descriptors/org.classpath.tools.xml
Modified: trunk/core/descriptors/org.classpath.tools.xml
===================================================================
--- trunk/core/descriptors/org.classpath.tools.xml 2007-01-07 14:11:30 UTC (rev 3038)
+++ trunk/core/descriptors/org.classpath.tools.xml 2007-01-07 16:09:10 UTC (rev 3039)
@@ -24,6 +24,7 @@
<export name="gnu.classpath.tools.rmid.*"/>
<export name="gnu.classpath.tools.rmiregistry.*"/>
<export name="gnu.classpath.tools.rmic.*"/>
+ <export name="gnu.classpath.tools.rmic.templates.*"/>
<export name="gnu.classpath.tools.serialver.*"/>
<export name="gnu.classpath.tools.tnameserv.*"/>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 14:11:31
|
Revision: 3038
http://jnode.svn.sourceforge.net/jnode/?rev=3038&view=rev
Author: lsantha
Date: 2007-01-07 06:11:30 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Added rmic.
Modified Paths:
--------------
trunk/core/descriptors/org.classpath.tools.xml
Modified: trunk/core/descriptors/org.classpath.tools.xml
===================================================================
--- trunk/core/descriptors/org.classpath.tools.xml 2007-01-07 13:59:33 UTC (rev 3037)
+++ trunk/core/descriptors/org.classpath.tools.xml 2007-01-07 14:11:30 UTC (rev 3038)
@@ -12,7 +12,6 @@
<runtime>
<library name="jnode-core.jar">
-
<export name="gnu.classpath.tools.*"/>
<export name="gnu.classpath.tools.appletviewer.*"/>
<export name="gnu.classpath.tools.common.*"/>
@@ -24,10 +23,20 @@
<export name="gnu.classpath.tools.orbd.*"/>
<export name="gnu.classpath.tools.rmid.*"/>
<export name="gnu.classpath.tools.rmiregistry.*"/>
- <!--export name="gnu.classpath.tools.rmic.*"/-->
+ <export name="gnu.classpath.tools.rmic.*"/>
<export name="gnu.classpath.tools.serialver.*"/>
<export name="gnu.classpath.tools.tnameserv.*"/>
+ <export name="org.objectweb.asm.*"/>
+ <export name="org.objectweb.asm.attrs.*"/>
+ <export name="org.objectweb.asm.commons.*"/>
+ <export name="org.objectweb.asm.optimizer.*"/>
+ <export name="org.objectweb.asm.signature.*"/>
+ <export name="org.objectweb.asm.tree.*"/>
+ <export name="org.objectweb.asm.tree.analysis.*"/>
+ <export name="org.objectweb.asm.util.*"/>
+ <export name="org.objectweb.asm.util.attrs.*"/>
+ <export name="org.objectweb.asm.xml.*"/>
</library>
</runtime>
@@ -38,7 +47,7 @@
<alias name="keytool" class="gnu.classpath.tools.keytool.Main"/>
<alias name="native2ascii" class="gnu.classpath.tools.native2ascii.Native2ASCII"/>
<alias name="orbd" class="gnu.classpath.tools.orbd.Main"/>
- <!--alias name="rmic" class="gnu.classpath.tools.rmi.RMIC"/-->
+ <alias name="rmic" class="gnu.classpath.tools.rmic.Main"/>
<alias name="rmid" class="gnu.classpath.tools.rmid.Main"/>
<alias name="rmiregistry" class="gnu.classpath.tools.rmiregistry.Main"/>
<alias name="serialver" class="gnu.classpath.tools.serialver.SerialVer"/>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 13:59:34
|
Revision: 3037
http://jnode.svn.sourceforge.net/jnode/?rev=3037&view=rev
Author: lsantha
Date: 2007-01-07 05:59:33 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/all/build.xml
Modified: trunk/all/build.xml
===================================================================
--- trunk/all/build.xml 2007-01-07 13:58:42 UTC (rev 3036)
+++ trunk/all/build.xml 2007-01-07 13:59:33 UTC (rev 3037)
@@ -517,6 +517,10 @@
<patternset refid="cp-includes-pattern"/>
<patternset refid="cp-sources-pattern"/>
</fileset>
+ <fileset dir="${root.dir}/../classpath/tools/external/asm">
+ <patternset refid="cp-includes-pattern"/>
+ <patternset refid="cp-sources-pattern"/>
+ </fileset>
</classpathsources>
</cp-compare>
</target>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 13:58:43
|
Revision: 3036
http://jnode.svn.sourceforge.net/jnode/?rev=3036&view=rev
Author: lsantha
Date: 2007-01-07 05:58:42 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/AnnotationVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/AnnotationWriter.java
trunk/core/src/classpath/org/org/objectweb/asm/Attribute.java
trunk/core/src/classpath/org/org/objectweb/asm/ByteVector.java
trunk/core/src/classpath/org/org/objectweb/asm/ClassAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/ClassReader.java
trunk/core/src/classpath/org/org/objectweb/asm/ClassVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/ClassWriter.java
trunk/core/src/classpath/org/org/objectweb/asm/Edge.java
trunk/core/src/classpath/org/org/objectweb/asm/FieldVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/FieldWriter.java
trunk/core/src/classpath/org/org/objectweb/asm/Handler.java
trunk/core/src/classpath/org/org/objectweb/asm/Item.java
trunk/core/src/classpath/org/org/objectweb/asm/Label.java
trunk/core/src/classpath/org/org/objectweb/asm/MethodAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/MethodVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/MethodWriter.java
trunk/core/src/classpath/org/org/objectweb/asm/Opcodes.java
trunk/core/src/classpath/org/org/objectweb/asm/Type.java
trunk/core/src/classpath/org/org/objectweb/asm/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/AnnotationVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/AnnotationVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/AnnotationVisitor.java 2007-01-07 13:58:42 UTC (rev 3036)
@@ -0,0 +1,88 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java annotation. The methods of this interface must be
+ * called in the following order: (<tt>visit<tt> | <tt>visitEnum<tt> |
+ * <tt>visitAnnotation<tt> | <tt>visitArray<tt>)* <tt>visitEnd<tt>.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public interface AnnotationVisitor {
+
+ /**
+ * Visits a primitive value of the annotation.
+ *
+ * @param name the value name.
+ * @param value the actual value, whose type must be {@link Byte},
+ * {@link Boolean}, {@link Character}, {@link Short},
+ * {@link Integer}, {@link Long}, {@link Float}, {@link Double},
+ * {@link String} or {@link Type}.
+ */
+ void visit(String name, Object value);
+
+ /**
+ * Visits an enumeration value of the annotation.
+ *
+ * @param name the value name.
+ * @param desc the class descriptor of the enumeration class.
+ * @param value the actual enumeration value.
+ */
+ void visitEnum(String name, String desc, String value);
+
+ /**
+ * Visits a nested annotation value of the annotation.
+ *
+ * @param name the value name.
+ * @param desc the class descriptor of the nested annotation class.
+ * @return a non null visitor to visit the actual nested annotation value.
+ * <i>The nested annotation value must be fully visited before
+ * calling other methods on this annotation visitor</i>.
+ */
+ AnnotationVisitor visitAnnotation(String name, String desc);
+
+ /**
+ * Visits an array value of the annotation.
+ *
+ * @param name the value name.
+ * @return a non null visitor to visit the actual array value elements. The
+ * 'name' parameters passed to the methods of this visitor are
+ * ignored. <i>All the array values must be visited before calling
+ * other methods on this annotation visitor</i>.
+ */
+ AnnotationVisitor visitArray(String name);
+
+ /**
+ * Visits the end of the annotation.
+ */
+ void visitEnd();
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/AnnotationWriter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/AnnotationWriter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/AnnotationWriter.java 2007-01-07 13:58:42 UTC (rev 3036)
@@ -0,0 +1,311 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm;
+
+/**
+ * An {@link AnnotationVisitor} that generates annotations in bytecode form.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+final class AnnotationWriter implements AnnotationVisitor {
+
+ /**
+ * The class writer to which this annotation must be added.
+ */
+ private final ClassWriter cw;
+
+ /**
+ * The number of values in this annotation.
+ */
+ private int size;
+
+ /**
+ * <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation
+ * writers used for annotation default and annotation arrays use unnamed
+ * values.
+ */
+ private final boolean named;
+
+ /**
+ * The annotation values in bytecode form. This byte vector only contains
+ * the values themselves, i.e. the number of values must be stored as a
+ * unsigned short just before these bytes.
+ */
+ private final ByteVector bv;
+
+ /**
+ * The byte vector to be used to store the number of values of this
+ * annotation. See {@link #bv}.
+ */
+ private final ByteVector parent;
+
+ /**
+ * Where the number of values of this annotation must be stored in
+ * {@link #parent}.
+ */
+ private final int offset;
+
+ /**
+ * Next annotation writer. This field is used to store annotation lists.
+ */
+ AnnotationWriter next;
+
+ /**
+ * Previous annotation writer. This field is used to store annotation lists.
+ */
+ AnnotationWriter prev;
+
+ // ------------------------------------------------------------------------
+ // Constructor
+ // ------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link AnnotationWriter}.
+ *
+ * @param cw the class writer to which this annotation must be added.
+ * @param named <tt>true<tt> if values are named, <tt>false</tt> otherwise.
+ * @param bv where the annotation values must be stored.
+ * @param parent where the number of annotation values must be stored.
+ * @param offset where in <tt>parent</tt> the number of annotation values must
+ * be stored.
+ */
+ AnnotationWriter(
+ final ClassWriter cw,
+ final boolean named,
+ final ByteVector bv,
+ final ByteVector parent,
+ final int offset)
+ {
+ this.cw = cw;
+ this.named = named;
+ this.bv = bv;
+ this.parent = parent;
+ this.offset = offset;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(final String name, final Object value) {
+ ++size;
+ if (named) {
+ bv.putShort(cw.newUTF8(name));
+ }
+ if (value instanceof String) {
+ bv.put12('s', cw.newUTF8((String) value));
+ } else if (value instanceof Byte) {
+ bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
+ } else if (value instanceof Boolean) {
+ int v = ((Boolean) value).booleanValue() ? 1 : 0;
+ bv.put12('Z', cw.newInteger(v).index);
+ } else if (value instanceof Character) {
+ bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
+ } else if (value instanceof Short) {
+ bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
+ } else if (value instanceof Type) {
+ bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
+ } else if (value instanceof byte[]) {
+ byte[] v = (byte[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('B', cw.newInteger(v[i]).index);
+ }
+ } else if (value instanceof boolean[]) {
+ boolean[] v = (boolean[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
+ }
+ } else if (value instanceof short[]) {
+ short[] v = (short[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('S', cw.newInteger(v[i]).index);
+ }
+ } else if (value instanceof char[]) {
+ char[] v = (char[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('C', cw.newInteger(v[i]).index);
+ }
+ } else if (value instanceof int[]) {
+ int[] v = (int[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('I', cw.newInteger(v[i]).index);
+ }
+ } else if (value instanceof long[]) {
+ long[] v = (long[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('J', cw.newLong(v[i]).index);
+ }
+ } else if (value instanceof float[]) {
+ float[] v = (float[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('F', cw.newFloat(v[i]).index);
+ }
+ } else if (value instanceof double[]) {
+ double[] v = (double[]) value;
+ bv.put12('[', v.length);
+ for (int i = 0; i < v.length; i++) {
+ bv.put12('D', cw.newDouble(v[i]).index);
+ }
+ } else {
+ Item i = cw.newConstItem(value);
+ bv.put12(".s.IFJDCS".charAt(i.type), i.index);
+ }
+ }
+
+ public void visitEnum(
+ final String name,
+ final String desc,
+ final String value)
+ {
+ ++size;
+ if (named) {
+ bv.putShort(cw.newUTF8(name));
+ }
+ bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String name,
+ final String desc)
+ {
+ ++size;
+ if (named) {
+ bv.putShort(cw.newUTF8(name));
+ }
+ // write tag and type, and reserve space for values count
+ bv.put12('@', cw.newUTF8(desc)).putShort(0);
+ return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ ++size;
+ if (named) {
+ bv.putShort(cw.newUTF8(name));
+ }
+ // write tag, and reserve space for array size
+ bv.put12('[', 0);
+ return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
+ }
+
+ public void visitEnd() {
+ if (parent != null) {
+ byte[] data = parent.data;
+ data[offset] = (byte) (size >>> 8);
+ data[offset + 1] = (byte) size;
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the size of this annotation writer list.
+ *
+ * @return the size of this annotation writer list.
+ */
+ int getSize() {
+ int size = 0;
+ AnnotationWriter aw = this;
+ while (aw != null) {
+ size += aw.bv.length;
+ aw = aw.next;
+ }
+ return size;
+ }
+
+ /**
+ * Puts the annotations of this annotation writer list into the given byte
+ * vector.
+ *
+ * @param out where the annotations must be put.
+ */
+ void put(final ByteVector out) {
+ int n = 0;
+ int size = 2;
+ AnnotationWriter aw = this;
+ AnnotationWriter last = null;
+ while (aw != null) {
+ ++n;
+ size += aw.bv.length;
+ aw.visitEnd(); // in case user forgot to call visitEnd
+ aw.prev = last;
+ last = aw;
+ aw = aw.next;
+ }
+ out.putInt(size);
+ out.putShort(n);
+ aw = last;
+ while (aw != null) {
+ out.putByteArray(aw.bv.data, 0, aw.bv.length);
+ aw = aw.prev;
+ }
+ }
+
+ /**
+ * Puts the given annotation lists into the given byte vector.
+ *
+ * @param panns an array of annotation writer lists.
+ * @param out where the annotations must be put.
+ */
+ static void put(final AnnotationWriter[] panns, final ByteVector out) {
+ int size = 1 + 2 * panns.length;
+ for (int i = 0; i < panns.length; ++i) {
+ size += panns[i] == null ? 0 : panns[i].getSize();
+ }
+ out.putInt(size).putByte(panns.length);
+ for (int i = 0; i < panns.length; ++i) {
+ AnnotationWriter aw = panns[i];
+ AnnotationWriter last = null;
+ int n = 0;
+ while (aw != null) {
+ ++n;
+ aw.visitEnd(); // in case user forgot to call visitEnd
+ aw.prev = last;
+ last = aw;
+ aw = aw.next;
+ }
+ out.putShort(n);
+ aw = last;
+ while (aw != null) {
+ out.putByteArray(aw.bv.data, 0, aw.bv.length);
+ aw = aw.prev;
+ }
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/Attribute.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/Attribute.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/Attribute.java 2007-01-07 13:58:42 UTC (rev 3036)
@@ -0,0 +1,254 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm;
+
+/**
+ * A non standard class, field, method or code attribute.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class Attribute {
+
+ /**
+ * The type of this attribute.
+ */
+ public final String type;
+
+ /**
+ * The raw value of this attribute, used only for unknown attributes.
+ */
+ byte[] value;
+
+ /**
+ * The next attribute in this attribute list. May be <tt>null</tt>.
+ */
+ Attribute next;
+
+ /**
+ * Constructs a new empty attribute.
+ *
+ * @param type the type of the attribute.
+ */
+ protected Attribute(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns <tt>true</tt> if this type of attribute is unknown. The default
+ * implementation of this method always returns <tt>true</tt>.
+ *
+ * @return <tt>true</tt> if this type of attribute is unknown.
+ */
+ public boolean isUnknown() {
+ return true;
+ }
+
+ /**
+ * Returns <tt>true</tt> if this type of attribute is a code attribute.
+ *
+ * @return <tt>true</tt> if this type of attribute is a code attribute.
+ */
+ public boolean isCodeAttribute() {
+ return false;
+ }
+
+ /**
+ * Returns the labels corresponding to this attribute.
+ *
+ * @return the labels corresponding to this attribute, or <tt>null</tt> if
+ * this attribute is not a code attribute that contains labels.
+ */
+ protected Label[] getLabels() {
+ return null;
+ }
+
+ /**
+ * Reads a {@link #type type} attribute. This method must return a <i>new</i>
+ * {@link Attribute} object, of type {@link #type type}, corresponding to
+ * the <tt>len</tt> bytes starting at the given offset, in the given class
+ * reader.
+ *
+ * @param cr the class that contains the attribute to be read.
+ * @param off index of the first byte of the attribute's content in {@link
+ * ClassReader#b cr.b}. The 6 attribute header bytes, containing the
+ * type and the length of the attribute, are not taken into account
+ * here.
+ * @param len the length of the attribute's content.
+ * @param buf buffer to be used to call
+ * {@link ClassReader#readUTF8 readUTF8},
+ * {@link ClassReader#readClass(int,char[]) readClass} or
+ * {@link ClassReader#readConst readConst}.
+ * @param codeOff index of the first byte of code's attribute content in
+ * {@link ClassReader#b cr.b}, or -1 if the attribute to be read is
+ * not a code attribute. The 6 attribute header bytes, containing the
+ * type and the length of the attribute, are not taken into account
+ * here.
+ * @param labels the labels of the method's code, or <tt>null</tt> if the
+ * attribute to be read is not a code attribute.
+ * @return a <i>new</i> {@link Attribute} object corresponding to the given
+ * bytes.
+ */
+ protected Attribute read(
+ ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ Attribute attr = new Attribute(type);
+ attr.value = new byte[len];
+ System.arraycopy(cr.b, off, attr.value, 0, len);
+ return attr;
+ }
+
+ /**
+ * Returns the byte array form of this attribute.
+ *
+ * @param cw the class to which this attribute must be added. This parameter
+ * can be used to add to the constant pool of this class the items
+ * that corresponds to this attribute.
+ * @param code the bytecode of the method corresponding to this code
+ * attribute, or <tt>null</tt> if this attribute is not a code
+ * attributes.
+ * @param len the length of the bytecode of the method corresponding to this
+ * code attribute, or <tt>null</tt> if this attribute is not a code
+ * attribute.
+ * @param maxStack the maximum stack size of the method corresponding to
+ * this code attribute, or -1 if this attribute is not a code
+ * attribute.
+ * @param maxLocals the maximum number of local variables of the method
+ * corresponding to this code attribute, or -1 if this attribute is
+ * not a code attribute.
+ * @return the byte array form of this attribute.
+ */
+ protected ByteVector write(
+ ClassWriter cw,
+ byte[] code,
+ int len,
+ int maxStack,
+ int maxLocals)
+ {
+ ByteVector v = new ByteVector();
+ v.data = value;
+ v.length = value.length;
+ return v;
+ }
+
+ /**
+ * Returns the length of the attribute list that begins with this attribute.
+ *
+ * @return the length of the attribute list that begins with this attribute.
+ */
+ final int getCount() {
+ int count = 0;
+ Attribute attr = this;
+ while (attr != null) {
+ count += 1;
+ attr = attr.next;
+ }
+ return count;
+ }
+
+ /**
+ * Returns the size of all the attributes in this attribute list.
+ *
+ * @param cw the class writer to be used to convert the attributes into byte
+ * arrays, with the {@link #write write} method.
+ * @param code the bytecode of the method corresponding to these code
+ * attributes, or <tt>null</tt> if these attributes are not code
+ * attributes.
+ * @param len the length of the bytecode of the method corresponding to
+ * these code attributes, or <tt>null</tt> if these attributes are
+ * not code attributes.
+ * @param maxStack the maximum stack size of the method corresponding to
+ * these code attributes, or -1 if these attributes are not code
+ * attributes.
+ * @param maxLocals the maximum number of local variables of the method
+ * corresponding to these code attributes, or -1 if these attributes
+ * are not code attributes.
+ * @return the size of all the attributes in this attribute list. This size
+ * includes the size of the attribute headers.
+ */
+ final int getSize(
+ final ClassWriter cw,
+ final byte[] code,
+ final int len,
+ final int maxStack,
+ final int maxLocals)
+ {
+ Attribute attr = this;
+ int size = 0;
+ while (attr != null) {
+ cw.newUTF8(attr.type);
+ size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
+ attr = attr.next;
+ }
+ return size;
+ }
+
+ /**
+ * Writes all the attributes of this attribute list in the given byte
+ * vector.
+ *
+ * @param cw the class writer to be used to convert the attributes into byte
+ * arrays, with the {@link #write write} method.
+ * @param code the bytecode of the method corresponding to these code
+ * attributes, or <tt>null</tt> if these attributes are not code
+ * attributes.
+ * @param len the length of the bytecode of the method corresponding to
+ * these code attributes, or <tt>null</tt> if these attributes are
+ * not code attributes.
+ * @param maxStack the maximum stack size of the method corresponding to
+ * these code attributes, or -1 if these attributes are not code
+ * attributes.
+ * @param maxLocals the maximum number of local variables of the method
+ * corresponding to these code attributes, or -1 if these attributes
+ * are not code attributes.
+ * @param out where the attributes must be written.
+ */
+ final void put(
+ final ClassWriter cw,
+ final byte[] code,
+ final int len,
+ final int maxStack,
+ final int maxLocals,
+ final ByteVector out)
+ {
+ Attribute attr = this;
+ while (attr != null) {
+ ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
+ out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
+ out.putByteArray(b.data, 0, b.length);
+ attr = attr.next;
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/ByteVector.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/ByteVector.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/ByteVector.java 2007-01-07 13:58:42 UTC (rev 3036)
@@ -0,0 +1,293 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm;
+
+/**
+ * A dynamically extensible vector of bytes. This class is roughly equivalent to
+ * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
+ *
+ * @author Eric Bruneton
+ */
+public class ByteVector {
+
+ /**
+ * The content of this vector.
+ */
+ byte[] data;
+
+ /**
+ * Actual number of bytes in this vector.
+ */
+ int length;
+
+ /**
+ * Constructs a new {@link ByteVector ByteVector} with a default initial
+ * size.
+ */
+ public ByteVector() {
+ data = new byte[64];
+ }
+
+ /**
+ * Constructs a new {@link ByteVector ByteVector} with the given initial
+ * size.
+ *
+ * @param initialSize the initial size of the byte vector to be constructed.
+ */
+ public ByteVector(final int initialSize) {
+ data = new byte[initialSize];
+ }
+
+ /**
+ * Puts a byte into this byte vector. The byte vector is automatically
+ * enlarged if necessary.
+ *
+ * @param b a byte.
+ * @return this byte vector.
+ */
+ public ByteVector putByte(final int b) {
+ int length = this.length;
+ if (length + 1 > data.length) {
+ enlarge(1);
+ }
+ data[length++] = (byte) b;
+ this.length = length;
+ return this;
+ }
+
+ /**
+ * Puts two bytes into this byte vector. The byte vector is automatically
+ * enlarged if necessary.
+ *
+ * @param b1 a byte.
+ * @param b2 another byte.
+ * @return this byte vector.
+ */
+ ByteVector put11(final int b1, final int b2) {
+ int length = this.length;
+ if (length + 2 > data.length) {
+ enlarge(2);
+ }
+ byte[] data = this.data;
+ data[length++] = (byte) b1;
+ data[length++] = (byte) b2;
+ this.length = length;
+ return this;
+ }
+
+ /**
+ * Puts a short into this byte vector. The byte vector is automatically
+ * enlarged if necessary.
+ *
+ * @param s a short.
+ * @return this byte vector.
+ */
+ public ByteVector putShort(final int s) {
+ int length = this.length;
+ if (length + 2 > data.length) {
+ enlarge(2);
+ }
+ byte[] data = this.data;
+ data[length++] = (byte) (s >>> 8);
+ data[length++] = (byte) s;
+ this.length = length;
+ return this;
+ }
+
+ /**
+ * Puts a byte and a short into this byte vector. The byte vector is
+ * automatically enlarged if necessary.
+ *
+ * @param b a byte.
+ * @param s a short.
+ * @return this byte vector.
+ */
+ ByteVector put12(final int b, final int s) {
+ int length = this.length;
+ if (length + 3 > data.length) {
+ enlarge(3);
+ }
+ byte[] data = this.data;
+ data[length++] = (byte) b;
+ data[length++] = (byte) (s >>> 8);
+ data[length++] = (byte) s;
+ this.length = length;
+ return this;
+ }
+
+ /**
+ * Puts an int into this byte vector. The byte vector is automatically
+ * enlarged if necessary.
+ *
+ * @param i an int.
+ * @return this byte vector.
+ */
+ public ByteVector putInt(final int i) {
+ int length = this.length;
+ if (length + 4 > data.length) {
+ enlarge(4);
+ }
+ byte[] data = this.data;
+ data[length++] = (byte) (i >>> 24);
+ data[length++] = (byte) (i >>> 16);
+ data[length++] = (byte) (i >>> 8);
+ data[length++] = (byte) i;
+ this.length = length;
+ return this;
+ }
+
+ /**
+ * Puts a long into this byte vector. The byte vector is automatically
+ * enlarged if necessary.
+ *
+ * @param l a long.
+ * @return this byte vector.
+ */
+ public ByteVector putLong(final long l) {
+ int length = this.length;
+ if (length + 8 > data.length) {
+ enlarge(8);
+ }
+ byte[] data = this.data;
+ int i = (int) (l >>> 32);
+ data[length++] = (byte) (i >>> 24);
+ data[length++] = (byte) (i >>> 16);
+ data[length++] = (byte) (i >>> 8);
+ data[length++] = (byte) i;
+ i = (int) l;
+ data[length++] = (byte) (i >>> 24);
+ data[length++] = (byte) (i >>> 16);
+ data[length++] = (byte) (i >>> 8);
+ data[length++] = (byte) i;
+ this.length = length;
+ return this;
+ }
+
+ /**
+ * Puts an UTF8 string into this byte vector. The byte vector is
+ * automatically enlarged if necessary.
+ *
+ * @param s a String.
+ * @return this byte vector.
+ */
+ public ByteVector putUTF8(final String s) {
+ int charLength = s.length();
+ if (length + 2 + charLength > data.length) {
+ enlarge(2 + charLength);
+ }
+ int len = length;
+ byte[] data = this.data;
+ // optimistic algorithm: instead of computing the byte length and then
+ // serializing the string (which requires two loops), we assume the byte
+ // length is equal to char length (which is the most frequent case), and
+ // we start serializing the string right away. During the serialization,
+ // if we find that this assumption is wrong, we continue with the
+ // general method.
+ data[len++] = (byte) (charLength >>> 8);
+ data[len++] = (byte) (charLength);
+ for (int i = 0; i < charLength; ++i) {
+ char c = s.charAt(i);
+ if (c >= '\001' && c <= '\177') {
+ data[len++] = (byte) c;
+ } else {
+ int byteLength = i;
+ for (int j = i; j < charLength; ++j) {
+ c = s.charAt(j);
+ if (c >= '\001' && c <= '\177') {
+ byteLength++;
+ } else if (c > '\u07FF') {
+ byteLength += 3;
+ } else {
+ byteLength += 2;
+ }
+ }
+ data[length] = (byte) (byteLength >>> 8);
+ data[length + 1] = (byte) (byteLength);
+ if (length + 2 + byteLength > data.length) {
+ length = len;
+ enlarge(2 + byteLength);
+ data = this.data;
+ }
+ for (int j = i; j < charLength; ++j) {
+ c = s.charAt(j);
+ if (c >= '\001' && c <= '\177') {
+ data[len++] = (byte) c;
+ } else if (c > '\u07FF') {
+ data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
+ data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
+ data[len++] = (byte) (0x80 | c & 0x3F);
+ } else {
+ data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
+ data[len++] = (byte) (0x80 | c & 0x3F);
+ }
+ }
+ break;
+ }
+ }
+ length = len;
+ return this;
+ }
+
+ /**
+ * Puts an array of bytes into this byte vector. The byte vector is
+ * automatically enlarged if necessary.
+ *
+ * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
+ * null bytes into this byte vector.
+ * @param off index of the fist byte of b that must be copied.
+ * @param len number of bytes of b that must be copied.
+ * @return this byte vector.
+ */
+ public ByteVector putByteArray(final byte[] b, final int off, final int len)
+ {
+ if (length + len > data.length) {
+ enlarge(len);
+ }
+ if (b != null) {
+ System.arraycopy(b, off, data, length, len);
+ }
+ length += len;
+ return this;
+ }
+
+ /**
+ * Enlarge this byte vector so that it can receive n more bytes.
+ *
+ * @param size number of additional bytes that this byte vector should be
+ * able to receive.
+ */
+ private void enlarge(final int size) {
+ int length1 = 2 * data.length;
+ int length2 = length + size;
+ byte[] newData = new byte[length1 > length2 ? length1 : length2];
+ System.arraycopy(data, 0, newData, 0, length);
+ data = newData;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/ClassAdapter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/ClassAdapter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/ClassAdapter.java 2007-01-07 13:58:42 UTC (rev 3036)
@@ -0,0 +1,121 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm;
+
+/**
+ * An empty {@link ClassVisitor} that delegates to another {@link ClassVisitor}.
+ * This class can be used as a super class to quickly implement usefull class
+ * adapter classes, just by overriding the necessary methods.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassAdapter implements ClassVisitor {
+
+ /**
+ * The {@link ClassVisitor} to which this adapter delegates calls.
+ */
+ protected ClassVisitor cv;
+
+ /**
+ * Constructs a new {@link ClassAdapter} object.
+ *
+ * @param cv the class visitor to which this adapter must delegate calls.
+ */
+ public ClassAdapter(final ClassVisitor cv) {
+ this.cv = cv;
+ }
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ public void visitSource(final String source, final String debug) {
+ cv.visitSource(source, debug);
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ cv.visitOuterClass(owner, name, desc);
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ return cv.visitAnnotation(desc, visible);
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ cv.visitAttribute(attr);
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ return cv.visitField(access, name, desc, signature, value);
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ return cv.visitMethod(access, name, desc, signature, exceptions);
+ }
+
+ public void visitEnd() {
+ cv.visitEnd();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/ClassReader.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/ClassReader.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/ClassReader.java 2007-01-07 13:58:42 UTC (rev 3036)
@@ -0,0 +1,1606 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * A Java class parser to make a {@link ClassVisitor} visit an existing class.
+ * This class parses a byte array conforming to the Java class file format and
+ * calls the appropriate visit methods of a given class visitor for each field,
+ * method and bytecode instruction encountered.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ClassReader {
+
+ /**
+ * The class to be parsed. <i>The content of this array must not be
+ * modified. This field is intended for {@link Attribute} sub classes, and
+ * is normally not needed by class generators or adapters.</i>
+ */
+ public final byte[] b;
+
+ /**
+ * The start index of each constant pool item in {@link #b b}, plus one.
+ * The one byte offset skips the constant pool item tag that indicates its
+ * type.
+ */
+ private int[] items;
+
+ /**
+ * The String objects corresponding to the CONSTANT_Utf8 items. This cache
+ * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
+ * which GREATLY improves performances (by a factor 2 to 3). This caching
+ * strategy could be extended to all constant pool items, but its benefit
+ * would not be so great for these items (because they are much less
+ * expensive to parse than CONSTANT_Utf8 items).
+ */
+ private String[] strings;
+
+ /**
+ * Maximum length of the strings contained in the constant pool of the
+ * class.
+ */
+ private int maxStringLength;
+
+ /**
+ * Start index of the class header information (access, name...) in
+ * {@link #b b}.
+ */
+ public final int header;
+
+ // ------------------------------------------------------------------------
+ // Constructors
+ // ------------------------------------------------------------------------
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param b the bytecode of the class to be read.
+ */
+ public ClassReader(final byte[] b) {
+ this(b, 0, b.length);
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param b the bytecode of the class to be read.
+ * @param off the start offset of the class data.
+ * @param len the length of the class data.
+ */
+ public ClassReader(final byte[] b, final int off, final int len) {
+ this.b = b;
+ // parses the constant pool
+ items = new int[readUnsignedShort(off + 8)];
+ int ll = items.length;
+ strings = new String[ll];
+ int max = 0;
+ int index = off + 10;
+ for (int i = 1; i < ll; ++i) {
+ items[i] = index + 1;
+ int tag = b[index];
+ int size;
+ switch (tag) {
+ case ClassWriter.FIELD:
+ case ClassWriter.METH:
+ case ClassWriter.IMETH:
+ case ClassWriter.INT:
+ case ClassWriter.FLOAT:
+ case ClassWriter.NAME_TYPE:
+ size = 5;
+ break;
+ case ClassWriter.LONG:
+ case ClassWriter.DOUBLE:
+ size = 9;
+ ++i;
+ break;
+ case ClassWriter.UTF8:
+ size = 3 + readUnsignedShort(index + 1);
+ if (size > max) {
+ max = size;
+ }
+ break;
+ // case ClassWriter.CLASS:
+ // case ClassWriter.STR:
+ default:
+ size = 3;
+ break;
+ }
+ index += size;
+ }
+ maxStringLength = max;
+ // the class header information starts just after the constant pool
+ header = index;
+ }
+
+ /**
+ * Copies the constant pool data into the given {@link ClassWriter}. Should
+ * be called before the {@link #accept(ClassVisitor,boolean)} method.
+ *
+ * @param classWriter the {@link ClassWriter} to copy constant pool into.
+ */
+ void copyPool(final ClassWriter classWriter) {
+ char[] buf = new char[maxStringLength];
+ int ll = items.length;
+ Item[] items2 = new Item[ll];
+ for (int i = 1; i < ll; i++) {
+ int index = items[i];
+ int tag = b[index - 1];
+ Item item = new Item(i);
+ int nameType;
+ switch (tag) {
+ case ClassWriter.FIELD:
+ case ClassWriter.METH:
+ case ClassWriter.IMETH:
+ nameType = items[readUnsignedShort(index + 2)];
+ item.set(tag,
+ readClass(index, buf),
+ readUTF8(nameType, buf),
+ readUTF8(nameType + 2, buf));
+ break;
+
+ case ClassWriter.INT:
+ item.set(readInt(index));
+ break;
+
+ case ClassWriter.FLOAT:
+ item.set(Float.intBitsToFloat(readInt(index)));
+ break;
+
+ case ClassWriter.NAME_TYPE:
+ item.set(tag,
+ readUTF8(index, buf),
+ readUTF8(index + 2, buf),
+ null);
+ break;
+
+ case ClassWriter.LONG:
+ item.set(readLong(index));
+ ++i;
+ break;
+
+ case ClassWriter.DOUBLE:
+ item.set(Double.longBitsToDouble(readLong(index)));
+ ++i;
+ break;
+
+ case ClassWriter.UTF8: {
+ String s = strings[i];
+ if (s == null) {
+ index = items[i];
+ s = strings[i] = readUTF(index + 2,
+ readUnsignedShort(index),
+ buf);
+ }
+ item.set(tag, s, null, null);
+ }
+ break;
+
+ // case ClassWriter.STR:
+ // case ClassWriter.CLASS:
+ default:
+ item.set(tag, readUTF8(index, buf), null, null);
+ break;
+ }
+
+ int index2 = item.hashCode % items2.length;
+ item.next = items2[index2];
+ items2[index2] = item;
+ }
+
+ int off = items[1] - 1;
+ classWriter.pool.putByteArray(b, off, header - off);
+ classWriter.items = items2;
+ classWriter.threshold = (int) (0.75d * ll);
+ classWriter.index = ll;
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param is an input stream from which to read the class.
+ * @throws IOException if a problem occurs during reading.
+ */
+ public ClassReader(final InputStream is) throws IOException {
+ this(readClass(is));
+ }
+
+ /**
+ * Constructs a new {@link ClassReader} object.
+ *
+ * @param name the fully qualified name of the class to be read.
+ * @throws IOException if an exception occurs during reading.
+ */
+ public ClassReader(final String name) throws IOException {
+ this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+ + ".class"));
+ }
+
+ /**
+ * Reads the bytecode of a class.
+ *
+ * @param is an input stream from which to read the class.
+ * @return the bytecode read from the given input stream.
+ * @throws IOException if a problem occurs during reading.
+ */
+ private static byte[] readClass(final InputStream is) throws IOException {
+ if (is == null) {
+ throw new IOException("Class not found");
+ }
+ byte[] b = new byte[is.available()];
+ int len = 0;
+ while (true) {
+ int n = is.read(b, len, b.length - len);
+ if (n == -1) {
+ if (len < b.length) {
+ byte[] c = new byte[len];
+ System.arraycopy(b, 0, c, 0, len);
+ b = c;
+ }
+ return b;
+ }
+ len += n;
+ if (len == b.length) {
+ byte[] c = new byte[b.length + 1000];
+ System.arraycopy(b, 0, c, 0, len);
+ b = c;
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Public methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Makes the given visitor visit the Java class of this {@link ClassReader}.
+ * This class is the one specified in the constructor (see
+ * {@link #ClassReader(byte[]) ClassReader}).
+ *
+ * @param classVisitor the visitor that must visit this class.
+ * @param skipDebug <tt>true</tt> if the debug information of the class
+ * must not be visited. In this case the
+ * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
+ * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will
+ * not be called.
+ */
+ public void accept(final ClassVisitor classVisitor, final boolean skipDebug)
+ {
+ accept(classVisitor, new Attribute[0], skipDebug);
+ }
+
+ /**
+ * Makes the given visitor visit the Java class of this {@link ClassReader}.
+ * This class is the one specified in the constructor (see
+ * {@link #ClassReader(byte[]) ClassReader}).
+ *
+ * @param classVisitor the visitor that must visit this class.
+ * @param attrs prototypes of the attributes that must be parsed during the
+ * visit of the class. Any attribute whose type is not equal to the
+ * type of one the prototypes will be ignored.
+ * @param skipDebug <tt>true</tt> if the debug information of the class
+ * must not be visited. In this case the
+ * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
+ * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will
+ * not be called.
+ */
+ public void accept(
+ final ClassVisitor classVisitor,
+ final Attribute[] attrs,
+ final boolean skipDebug)
+ {
+ byte[] b = this.b; // the bytecode array
+ char[] c = new char[maxStringLength]; // buffer used to read strings
+ int i, j, k; // loop variables
+ int u, v, w; // indexes in b
+ Attribute attr;
+
+ int access;
+ String name;
+ String desc;
+ String attrName;
+ String signature;
+ int anns = 0;
+ int ianns = 0;
+ Attribute cattrs = null;
+
+ // visits the header
+ u = header;
+ access = readUnsignedShort(u);
+ name = readClass(u + 2, c);
+ v = items[readUnsignedShort(u + 4)];
+ String superClassName = v == 0 ? null : readUTF8(v, c);
+ String[] implementedItfs = new String[readUnsignedShort(u + 6)];
+ w = 0;
+ u += 8;
+ for (i = 0; i < implementedItfs.length; ++i) {
+ implementedItfs[i] = readClass(u, c);
+ u += 2;
+ }
+
+ // skips fields and methods
+ v = u;
+ i = readUnsignedShort(v);
+ v += 2;
+ for (; i > 0; --i) {
+ j = readUnsignedShort(v + 6);
+ v += 8;
+ for (; j > 0; --j) {
+ v += 6 + readInt(v + 2);
+ }
+ }
+ i = readUnsignedShort(v);
+ v += 2;
+ for (; i > 0; --i) {
+ j = readUnsignedShort(v + 6);
+ v += 8;
+ for (; j > 0; --j) {
+ v += 6 + readInt(v + 2);
+ }
+ }
+ // reads the class's attributes
+ signature = null;
+ String sourceFile = null;
+ String sourceDebug = null;
+ String enclosingOwner = null;
+ String enclosingName = null;
+ String enclosingDesc = null;
+
+ i = readUnsignedShort(v);
+ v += 2;
+ for (; i > 0; --i) {
+ attrName = readUTF8(v, c);
+ if (attrName.equals("SourceFile")) {
+ sourceFile = readUTF8(v + 6, c);
+ } else if (attrName.equals("Deprecated")) {
+ access |= Opcodes.ACC_DEPRECATED;
+ } else if (attrName.equals("Synthetic")) {
+ access |= Opcodes.ACC_SYNTHETIC;
+ } else if (attrName.equals("Annotation")) {
+ access |= Opcodes.ACC_ANNOTATION;
+ } else if (attrName.equals("Enum")) {
+ access |= Opcodes.ACC_ENUM;
+ } else if (attrName.equals("InnerClasses")) {
+ w = v + 6;
+ } else if (attrName.equals("Signature")) {
+ signature = readUTF8(v + 6, c);
+ } else if (attrName.equals("SourceDebugExtension")) {
+ int len = readInt(v + 2);
+ sourceDebug = readUTF(v + 6, len, new char[len]);
+ } else if (attrName.equals("EnclosingMethod")) {
+ enclosingOwner = readClass(v + 6, c);
+ int item = readUnsignedShort(v + 8);
+ if (item != 0) {
+ enclosingName = readUTF8(items[item], c);
+ enclosingDesc = readUTF8(items[item] + 2, c);
+ }
+ } else if (attrName.equals("RuntimeVisibleAnnotations")) {
+ anns = v + 6;
+ } else if (attrName.equals("RuntimeInvisibleAnnotations")) {
+ ianns = v + 6;
+ } else {
+ attr = readAttribute(attrs,
+ attrName,
+ v + 6,
+ readInt(v + 2),
+ c,
+ -1,
+ null);
+ if (attr != null) {
+ attr.next = cattrs;
+ cattrs = attr;
+ }
+ }
+ v += 6 + readInt(v + 2);
+ }
+ // calls the visit method
+ classVisitor.visit(readInt(4),
+ access,
+ name,
+ signature,
+ superClassName,
+ implementedItfs);
+
+ // calls the visitSource method
+ if (sourceFile != null || sourceDebug != null) {
+ classVisitor.visitSource(sourceFile, sourceDebug);
+ }
+
+ // calls the visitOuterClass method
+ if (enclosingOwner != null) {
+ classVisitor.visitOuterClass(enclosingOwner,
+ enclosingName,
+ enclosingDesc);
+ }
+
+ // visits the class annotations
+ for (i = 1; i >= 0; --i) {
+ v = i == 0 ? ianns : anns;
+ if (v != 0) {
+ j = readUnsignedShort(v);
+ v += 2;
+ for (; j > 0; --j) {
+ desc = readUTF8(v, c);
+ v += 2;
+ v = readAnnotationValues(v,
+ c,
+ classVisitor.visitAnnotation(desc, i != 0));
+ }
+ }
+ }
+
+ // visits the class attributes
+ while (cattrs != null) {
+ attr = cattrs.next;
+ cattrs.next = null;
+ classVisitor.visitAttribute(cattrs);
+ cattrs = attr;
+ }
+
+ // class the visitInnerClass method
+ if (w != 0) {
+ i = readUnsignedShort(w);
+ w += 2;
+ for (; i > 0; --i) {
+ classVisitor.visitInnerClass(readUnsignedShort(w) == 0
+ ? null
+ : readClass(w, c), readUnsignedShort(w +...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:57:34
|
Revision: 3035
http://jnode.svn.sourceforge.net/jnode/?rev=3035&view=rev
Author: lsantha
Date: 2007-01-07 05:57:32 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/xml/
trunk/core/src/classpath/org/org/objectweb/asm/xml/ASMContentHandler.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/Processor.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/SAXAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/SAXAnnotationAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/SAXClassAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/SAXCodeAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/SAXFieldAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/xml/asm-xml.dtd
trunk/core/src/classpath/org/org/objectweb/asm/xml/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/xml/ASMContentHandler.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/xml/ASMContentHandler.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/xml/ASMContentHandler.java 2007-01-07 13:57:32 UTC (rev 3035)
@@ -0,0 +1,1215 @@
+/***
+ * ASM XML Adapter
+ * Copyright (c) 2004, Eugene Kuleshov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.xml;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Type;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * A {@link org.xml.sax.ContentHandler ContentHandler} that transforms XML
+ * document into Java class file. This class can be feeded by any kind of SAX
+ * 2.0 event producers, e.g. XML parser, XSLT or XPath engines, or custom code.
+ *
+ * @see org.objectweb.asm.xml.SAXClassAdapter
+ * @see org.objectweb.asm.xml.Processor
+ *
+ * @author Eugene Kuleshov
+ */
+public class ASMContentHandler extends DefaultHandler implements Opcodes {
+ /**
+ * Stack of the intermediate processing contexts.
+ */
+ private List stack = new ArrayList();
+
+ /**
+ * Complete name of the current element.
+ */
+ private String match = "";
+
+ /**
+ * <tt>true</tt> if the maximum stack size and number of local variables
+ * must be automatically computed.
+ */
+ protected boolean computeMax;
+
+ /**
+ * Output stream to write result bytecode.
+ */
+ protected OutputStream os;
+
+ /**
+ * Current instance of the {@link ClassWriter ClassWriter} used to write
+ * class bytecode.
+ */
+ protected ClassWriter cw;
+
+ /**
+ * Map of the active {@link Label Label} instances for current method.
+ */
+ protected Map labels;
+
+ private static final String BASE = "class";
+
+ private final RuleSet RULES = new RuleSet();
+ {
+ RULES.add(BASE, new ClassRule());
+ RULES.add(BASE + "/interfaces/interface", new InterfaceRule());
+ RULES.add(BASE + "/interfaces", new InterfacesRule());
+ RULES.add(BASE + "/outerclass", new OuterClassRule());
+ RULES.add(BASE + "/innerclass", new InnerClassRule());
+ RULES.add(BASE + "/source", new SourceRule());
+ RULES.add(BASE + "/field", new FieldRule());
+
+ RULES.add(BASE + "/method", new MethodRule());
+ RULES.add(BASE + "/method/exceptions/exception", new ExceptionRule());
+ RULES.add(BASE + "/method/exceptions", new ExceptionsRule());
+
+ RULES.add(BASE + "/method/annotationDefault",
+ new AnnotationDefaultRule());
+
+ RULES.add(BASE + "/method/code/*", new OpcodesRule()); // opcodes
+
+ RULES.add(BASE + "/method/code/TABLESWITCH", new TableSwitchRule());
+ RULES.add(BASE + "/method/code/TABLESWITCH/label",
+ new TableSwitchLabelRule());
+ RULES.add(BASE + "/method/code/LOOKUPSWITCH", new LookupSwitchRule());
+ RULES.add(BASE + "/method/code/LOOKUPSWITCH/label",
+ new LookupSwitchLabelRule());
+
+ RULES.add(BASE + "/method/code/Label", new LabelRule());
+ RULES.add(BASE + "/method/code/TryCatch", new TryCatchRule());
+ RULES.add(BASE + "/method/code/LineNumber", new LineNumberRule());
+ RULES.add(BASE + "/method/code/LocalVar", new LocalVarRule());
+ RULES.add(BASE + "/method/code/Max", new MaxRule());
+
+ RULES.add("*/annotation", new AnnotationRule());
+ RULES.add("*/parameterAnnotation", new AnnotationParameterRule());
+ RULES.add("*/annotationValue", new AnnotationValueRule());
+ RULES.add("*/annotationValueAnnotation",
+ new AnnotationValueAnnotationRule());
+ RULES.add("*/annotationValueEnum", new AnnotationValueEnumRule());
+ RULES.add("*/annotationValueArray", new AnnotationValueArrayRule());
+ }
+
+ private static interface OpcodeGroup {
+ public static final int INSN = 0;
+ public static final int INSN_INT = 1;
+ public static final int INSN_VAR = 2;
+ public static final int INSN_TYPE = 3;
+ public static final int INSN_FIELD = 4;
+ public static final int INSN_METHOD = 5;
+ public static final int INSN_JUMP = 6;
+ public static final int INSN_LDC = 7;
+ public static final int INSN_IINC = 8;
+ public static final int INSN_MULTIANEWARRAY = 9;
+ }
+
+ /**
+ * Map of the opcode names to opcode and opcode group
+ */
+ static final Map OPCODES = new HashMap();
+ static {
+ OPCODES.put("NOP", new Opcode(NOP, OpcodeGroup.INSN));
+ OPCODES.put("ACONST_NULL", new Opcode(ACONST_NULL, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_M1", new Opcode(ICONST_M1, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_0", new Opcode(ICONST_0, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_1", new Opcode(ICONST_1, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_2", new Opcode(ICONST_2, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_3", new Opcode(ICONST_3, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_4", new Opcode(ICONST_4, OpcodeGroup.INSN));
+ OPCODES.put("ICONST_5", new Opcode(ICONST_5, OpcodeGroup.INSN));
+ OPCODES.put("LCONST_0", new Opcode(LCONST_0, OpcodeGroup.INSN));
+ OPCODES.put("LCONST_1", new Opcode(LCONST_1, OpcodeGroup.INSN));
+ OPCODES.put("FCONST_0", new Opcode(FCONST_0, OpcodeGroup.INSN));
+ OPCODES.put("FCONST_1", new Opcode(FCONST_1, OpcodeGroup.INSN));
+ OPCODES.put("FCONST_2", new Opcode(FCONST_2, OpcodeGroup.INSN));
+ OPCODES.put("DCONST_0", new Opcode(DCONST_0, OpcodeGroup.INSN));
+ OPCODES.put("DCONST_1", new Opcode(DCONST_1, OpcodeGroup.INSN));
+ OPCODES.put("BIPUSH", new Opcode(BIPUSH, OpcodeGroup.INSN_INT));
+ OPCODES.put("SIPUSH", new Opcode(SIPUSH, OpcodeGroup.INSN_INT));
+ OPCODES.put("LDC", new Opcode(LDC, OpcodeGroup.INSN_LDC));
+ OPCODES.put("ILOAD", new Opcode(ILOAD, OpcodeGroup.INSN_VAR));
+ OPCODES.put("LLOAD", new Opcode(LLOAD, OpcodeGroup.INSN_VAR));
+ OPCODES.put("FLOAD", new Opcode(FLOAD, OpcodeGroup.INSN_VAR));
+ OPCODES.put("DLOAD", new Opcode(DLOAD, OpcodeGroup.INSN_VAR));
+ OPCODES.put("ALOAD", new Opcode(ALOAD, OpcodeGroup.INSN_VAR));
+ OPCODES.put("IALOAD", new Opcode(IALOAD, OpcodeGroup.INSN));
+ OPCODES.put("LALOAD", new Opcode(LALOAD, OpcodeGroup.INSN));
+ OPCODES.put("FALOAD", new Opcode(FALOAD, OpcodeGroup.INSN));
+ OPCODES.put("DALOAD", new Opcode(DALOAD, OpcodeGroup.INSN));
+ OPCODES.put("AALOAD", new Opcode(AALOAD, OpcodeGroup.INSN));
+ OPCODES.put("BALOAD", new Opcode(BALOAD, OpcodeGroup.INSN));
+ OPCODES.put("CALOAD", new Opcode(CALOAD, OpcodeGroup.INSN));
+ OPCODES.put("SALOAD", new Opcode(SALOAD, OpcodeGroup.INSN));
+ OPCODES.put("ISTORE", new Opcode(ISTORE, OpcodeGroup.INSN_VAR));
+ OPCODES.put("LSTORE", new Opcode(LSTORE, OpcodeGroup.INSN_VAR));
+ OPCODES.put("FSTORE", new Opcode(FSTORE, OpcodeGroup.INSN_VAR));
+ OPCODES.put("DSTORE", new Opcode(DSTORE, OpcodeGroup.INSN_VAR));
+ OPCODES.put("ASTORE", new Opcode(ASTORE, OpcodeGroup.INSN_VAR));
+ OPCODES.put("IASTORE", new Opcode(IASTORE, OpcodeGroup.INSN));
+ OPCODES.put("LASTORE", new Opcode(LASTORE, OpcodeGroup.INSN));
+ OPCODES.put("FASTORE", new Opcode(FASTORE, OpcodeGroup.INSN));
+ OPCODES.put("DASTORE", new Opcode(DASTORE, OpcodeGroup.INSN));
+ OPCODES.put("AASTORE", new Opcode(AASTORE, OpcodeGroup.INSN));
+ OPCODES.put("BASTORE", new Opcode(BASTORE, OpcodeGroup.INSN));
+ OPCODES.put("CASTORE", new Opcode(CASTORE, OpcodeGroup.INSN));
+ OPCODES.put("SASTORE", new Opcode(SASTORE, OpcodeGroup.INSN));
+ OPCODES.put("POP", new Opcode(POP, OpcodeGroup.INSN));
+ OPCODES.put("POP2", new Opcode(POP2, OpcodeGroup.INSN));
+ OPCODES.put("DUP", new Opcode(DUP, OpcodeGroup.INSN));
+ OPCODES.put("DUP_X1", new Opcode(DUP_X1, OpcodeGroup.INSN));
+ OPCODES.put("DUP_X2", new Opcode(DUP_X2, OpcodeGroup.INSN));
+ OPCODES.put("DUP2", new Opcode(DUP2, OpcodeGroup.INSN));
+ OPCODES.put("DUP2_X1", new Opcode(DUP2_X1, OpcodeGroup.INSN));
+ OPCODES.put("DUP2_X2", new Opcode(DUP2_X2, OpcodeGroup.INSN));
+ OPCODES.put("SWAP", new Opcode(SWAP, OpcodeGroup.INSN));
+ OPCODES.put("IADD", new Opcode(IADD, OpcodeGroup.INSN));
+ OPCODES.put("LADD", new Opcode(LADD, OpcodeGroup.INSN));
+ OPCODES.put("FADD", new Opcode(FADD, OpcodeGroup.INSN));
+ OPCODES.put("DADD", new Opcode(DADD, OpcodeGroup.INSN));
+ OPCODES.put("ISUB", new Opcode(ISUB, OpcodeGroup.INSN));
+ OPCODES.put("LSUB", new Opcode(LSUB, OpcodeGroup.INSN));
+ OPCODES.put("FSUB", new Opcode(FSUB, OpcodeGroup.INSN));
+ OPCODES.put("DSUB", new Opcode(DSUB, OpcodeGroup.INSN));
+ OPCODES.put("IMUL", new Opcode(IMUL, OpcodeGroup.INSN));
+ OPCODES.put("LMUL", new Opcode(LMUL, OpcodeGroup.INSN));
+ OPCODES.put("FMUL", new Opcode(FMUL, OpcodeGroup.INSN));
+ OPCODES.put("DMUL", new Opcode(DMUL, OpcodeGroup.INSN));
+ OPCODES.put("IDIV", new Opcode(IDIV, OpcodeGroup.INSN));
+ OPCODES.put("LDIV", new Opcode(LDIV, OpcodeGroup.INSN));
+ OPCODES.put("FDIV", new Opcode(FDIV, OpcodeGroup.INSN));
+ OPCODES.put("DDIV", new Opcode(DDIV, OpcodeGroup.INSN));
+ OPCODES.put("IREM", new Opcode(IREM, OpcodeGroup.INSN));
+ OPCODES.put("LREM", new Opcode(LREM, OpcodeGroup.INSN));
+ OPCODES.put("FREM", new Opcode(FREM, OpcodeGroup.INSN));
+ OPCODES.put("DREM", new Opcode(DREM, OpcodeGroup.INSN));
+ OPCODES.put("INEG", new Opcode(INEG, OpcodeGroup.INSN));
+ OPCODES.put("LNEG", new Opcode(LNEG, OpcodeGroup.INSN));
+ OPCODES.put("FNEG", new Opcode(FNEG, OpcodeGroup.INSN));
+ OPCODES.put("DNEG", new Opcode(DNEG, OpcodeGroup.INSN));
+ OPCODES.put("ISHL", new Opcode(ISHL, OpcodeGroup.INSN));
+ OPCODES.put("LSHL", new Opcode(LSHL, OpcodeGroup.INSN));
+ OPCODES.put("ISHR", new Opcode(ISHR, OpcodeGroup.INSN));
+ OPCODES.put("LSHR", new Opcode(LSHR, OpcodeGroup.INSN));
+ OPCODES.put("IUSHR", new Opcode(IUSHR, OpcodeGroup.INSN));
+ OPCODES.put("LUSHR", new Opcode(LUSHR, OpcodeGroup.INSN));
+ OPCODES.put("IAND", new Opcode(IAND, OpcodeGroup.INSN));
+ OPCODES.put("LAND", new Opcode(LAND, OpcodeGroup.INSN));
+ OPCODES.put("IOR", new Opcode(IOR, OpcodeGroup.INSN));
+ OPCODES.put("LOR", new Opcode(LOR, OpcodeGroup.INSN));
+ OPCODES.put("IXOR", new Opcode(IXOR, OpcodeGroup.INSN));
+ OPCODES.put("LXOR", new Opcode(LXOR, OpcodeGroup.INSN));
+ OPCODES.put("IINC", new Opcode(IINC, OpcodeGroup.INSN_IINC));
+ OPCODES.put("I2L", new Opcode(I2L, OpcodeGroup.INSN));
+ OPCODES.put("I2F", new Opcode(I2F, OpcodeGroup.INSN));
+ OPCODES.put("I2D", new Opcode(I2D, OpcodeGroup.INSN));
+ OPCODES.put("L2I", new Opcode(L2I, OpcodeGroup.INSN));
+ OPCODES.put("L2F", new Opcode(L2F, OpcodeGroup.INSN));
+ OPCODES.put("L2D", new Opcode(L2D, OpcodeGroup.INSN));
+ OPCODES.put("F2I", new Opcode(F2I, OpcodeGroup.INSN));
+ OPCODES.put("F2L", new Opcode(F2L, OpcodeGroup.INSN));
+ OPCODES.put("F2D", new Opcode(F2D, OpcodeGroup.INSN));
+ OPCODES.put("D2I", new Opcode(D2I, OpcodeGroup.INSN));
+ OPCODES.put("D2L", new Opcode(D2L, OpcodeGroup.INSN));
+ OPCODES.put("D2F", new Opcode(D2F, OpcodeGroup.INSN));
+ OPCODES.put("I2B", new Opcode(I2B, OpcodeGroup.INSN));
+ OPCODES.put("I2C", new Opcode(I2C, OpcodeGroup.INSN));
+ OPCODES.put("I2S", new Opcode(I2S, OpcodeGroup.INSN));
+ OPCODES.put("LCMP", new Opcode(LCMP, OpcodeGroup.INSN));
+ OPCODES.put("FCMPL", new Opcode(FCMPL, OpcodeGroup.INSN));
+ OPCODES.put("FCMPG", new Opcode(FCMPG, OpcodeGroup.INSN));
+ OPCODES.put("DCMPL", new Opcode(DCMPL, OpcodeGroup.INSN));
+ OPCODES.put("DCMPG", new Opcode(DCMPG, OpcodeGroup.INSN));
+ OPCODES.put("IFEQ", new Opcode(IFEQ, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IFNE", new Opcode(IFNE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IFLT", new Opcode(IFLT, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IFGE", new Opcode(IFGE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IFGT", new Opcode(IFGT, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IFLE", new Opcode(IFLE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ICMPEQ", new Opcode(IF_ICMPEQ, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ICMPNE", new Opcode(IF_ICMPNE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ICMPLT", new Opcode(IF_ICMPLT, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ICMPGE", new Opcode(IF_ICMPGE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ICMPGT", new Opcode(IF_ICMPGT, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ICMPLE", new Opcode(IF_ICMPLE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ACMPEQ", new Opcode(IF_ACMPEQ, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IF_ACMPNE", new Opcode(IF_ACMPNE, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("GOTO", new Opcode(GOTO, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("JSR", new Opcode(JSR, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("RET", new Opcode(RET, OpcodeGroup.INSN_VAR));
+ // OPCODES.put( "TABLESWITCH", new Opcode( TABLESWITCH,
+ // "visiTableSwitchInsn"));
+ // OPCODES.put( "LOOKUPSWITCH", new Opcode( LOOKUPSWITCH,
+ // "visitLookupSwitch"));
+ OPCODES.put("IRETURN", new Opcode(IRETURN, OpcodeGroup.INSN));
+ OPCODES.put("LRETURN", new Opcode(LRETURN, OpcodeGroup.INSN));
+ OPCODES.put("FRETURN", new Opcode(FRETURN, OpcodeGroup.INSN));
+ OPCODES.put("DRETURN", new Opcode(DRETURN, OpcodeGroup.INSN));
+ OPCODES.put("ARETURN", new Opcode(ARETURN, OpcodeGroup.INSN));
+ OPCODES.put("RETURN", new Opcode(RETURN, OpcodeGroup.INSN));
+ OPCODES.put("GETSTATIC", new Opcode(GETSTATIC, OpcodeGroup.INSN_FIELD));
+ OPCODES.put("PUTSTATIC", new Opcode(PUTSTATIC, OpcodeGroup.INSN_FIELD));
+ OPCODES.put("GETFIELD", new Opcode(GETFIELD, OpcodeGroup.INSN_FIELD));
+ OPCODES.put("PUTFIELD", new Opcode(PUTFIELD, OpcodeGroup.INSN_FIELD));
+ OPCODES.put("INVOKEVIRTUAL", new Opcode(INVOKEVIRTUAL,
+ OpcodeGroup.INSN_METHOD));
+ OPCODES.put("INVOKESPECIAL", new Opcode(INVOKESPECIAL,
+ OpcodeGroup.INSN_METHOD));
+ OPCODES.put("INVOKESTATIC", new Opcode(INVOKESTATIC,
+ OpcodeGroup.INSN_METHOD));
+ OPCODES.put("INVOKEINTERFACE", new Opcode(INVOKEINTERFACE,
+ OpcodeGroup.INSN_METHOD));
+ OPCODES.put("NEW", new Opcode(NEW, OpcodeGroup.INSN_TYPE));
+ OPCODES.put("NEWARRAY", new Opcode(NEWARRAY, OpcodeGroup.INSN_INT));
+ OPCODES.put("ANEWARRAY", new Opcode(ANEWARRAY, OpcodeGroup.INSN_TYPE));
+ OPCODES.put("ARRAYLENGTH", new Opcode(ARRAYLENGTH, OpcodeGroup.INSN));
+ OPCODES.put("ATHROW", new Opcode(ATHROW, OpcodeGroup.INSN));
+ OPCODES.put("CHECKCAST", new Opcode(CHECKCAST, OpcodeGroup.INSN_TYPE));
+ OPCODES.put("INSTANCEOF", new Opcode(INSTANCEOF, OpcodeGroup.INSN_TYPE));
+ OPCODES.put("MONITORENTER", new Opcode(MONITORENTER, OpcodeGroup.INSN));
+ OPCODES.put("MONITOREXIT", new Opcode(MONITOREXIT, OpcodeGroup.INSN));
+ OPCODES.put("MULTIANEWARRAY", new Opcode(MULTIANEWARRAY,
+ OpcodeGroup.INSN_MULTIANEWARRAY));
+ OPCODES.put("IFNULL", new Opcode(IFNULL, OpcodeGroup.INSN_JUMP));
+ OPCODES.put("IFNONNULL", new Opcode(IFNONNULL, OpcodeGroup.INSN_JUMP));
+ }
+
+ /**
+ * Constructs a new {@link ASMContentHandler ASMContentHandler} object.
+ *
+ * @param os output stream to write generated class.
+ * @param computeMax <tt>true</tt> if the maximum stack size and the
+ * maximum number of local variables must be automatically computed.
+ * This value is passed to {@link ClassWriter ClassWriter} instance.
+ */
+ public ASMContentHandler(OutputStream os, boolean computeMax) {
+ this.os = os;
+ this.computeMax = computeMax;
+ }
+
+ /**
+ * Returns the bytecode of the class that was build with underneath class
+ * writer.
+ *
+ * @return the bytecode of the class that was build with underneath class
+ * writer or null if there are no classwriter created.
+ */
+ public byte[] toByteArray() {
+ return cw == null ? null : cw.toByteArray();
+ }
+
+ /**
+ * Process notification of the start of an XML element being reached.
+ *
+ * @param ns - The Namespace URI, or the empty string if the element has no
+ * Namespace URI or if Namespace processing is not being performed.
+ * @param localName - The local name (without prefix), or the empty string
+ * if Namespace processing is not being performed.
+ * @param qName - The qualified name (with prefix), or the empty string if
+ * qualified names are not available.
+ * @param list - The attributes attached to the element. If there are no
+ * attributes, it shall be an empty Attributes object.
+ * @exception SAXException if a parsing error is to be reported
+ */
+ public final void startElement(
+ String ns,
+ String localName,
+ String qName,
+ Attributes list) throws SAXException
+ {
+ // the actual element name is either in localName or qName, depending
+ // on whether the parser is namespace aware
+ String name = localName;
+ if (name == null || name.length() < 1) {
+ name = qName;
+ }
+
+ // Compute the current matching rule
+ StringBuffer sb = new StringBuffer(match);
+ if (match.length() > 0) {
+ sb.append('/');
+ }
+ sb.append(name);
+ match = sb.toString();
+
+ // Fire "begin" events for all relevant rules
+ Rule r = (Rule) RULES.match(match);
+ if (r != null)
+ r.begin(name, list);
+ }
+
+ /**
+ * Process notification of the end of an XML element being reached.
+ *
+ * @param ns - The Namespace URI, or the empty string if the element has no
+ * Namespace URI or if Namespace processing is not being performed.
+ * @param localName - The local name (without prefix), or the empty string
+ * if Namespace processing is not being performed.
+ * @param qName - The qualified XML 1.0 name (with prefix), or the empty
+ * string if qualified names are not available.
+ *
+ * @exception SAXException if a parsing error is to be reported
+ */
+ public final void endElement(String ns, String localName, String qName)
+ throws SAXException
+ {
+ // the actual element name is either in localName or qName, depending
+ // on whether the parser is namespace aware
+ String name = localName;
+ if (name == null || name.length() < 1) {
+ name = qName;
+ }
+
+ // Fire "end" events for all relevant rules in reverse order
+ Rule r = (Rule) RULES.match(match);
+ if (r != null)
+ r.end(name);
+
+ // Recover the previous match expression
+ int slash = match.lastIndexOf('/');
+ if (slash >= 0) {
+ match = match.substring(0, slash);
+ } else {
+ match = "";
+ }
+ }
+
+ /**
+ * Process notification of the end of a document and write generated
+ * bytecode into output stream.
+ *
+ * @exception SAXException if parsing or writing error is to be reported.
+ */
+ public final void endDocument() throws SAXException {
+ try {
+ os.write(cw.toByteArray());
+ } catch (IOException ex) {
+ throw new SAXException(ex.toString(), ex);
+ }
+ }
+
+ /**
+ * Return the top object on the stack without removing it. If there are no
+ * objects on the stack, return <code>null</code>.
+ *
+ * @return the top object on the stack without removing it.
+ */
+ final Object peek() {
+ return stack.size() == 0 ? null : stack.get(stack.size() - 1);
+ }
+
+ /**
+ * Return the n'th object down the stack, where 0 is the top element and
+ * [getCount()-1] is the bottom element. If the specified index is out of
+ * range, return <code>null</code>.
+ *
+ * @param n Index of the desired element, where 0 is the top of the stack, 1
+ * is the next element down, and so on.
+ * @return the n'th object down the stack.
+ */
+ final Object peek(int n) {
+ return stack.size() < (n + 1) ? null : stack.get(n);
+ }
+
+ /**
+ * Pop the top object off of the stack, and return it. If there are no
+ * objects on the stack, return <code>null</code>.
+ *
+ * @return the top object off of the stack.
+ */
+ final Object pop() {
+ return stack.size() == 0 ? null : stack.remove(stack.size() - 1);
+ }
+
+ /**
+ * Push a new object onto the top of the object stack.
+ *
+ * @param object The new object
+ */
+ final void push(Object object) {
+ stack.add(object);
+ }
+
+ private static final class RuleSet {
+ private Map rules = new HashMap();
+
+ private List lpatterns = new ArrayList();
+
+ private List rpatterns = new ArrayList();
+
+ public void add(String path, Object rule) {
+ String pattern = path;
+ if (path.startsWith("*/")) {
+ pattern = path.substring(1);
+ lpatterns.add(pattern);
+ } else if (path.endsWith("/*")) {
+ pattern = path.substring(0, path.length() - 1);
+ rpatterns.add(pattern);
+ }
+ rules.put(pattern, rule);
+ }
+
+ public Object match(String path) {
+ if (rules.containsKey(path)) {
+ return rules.get(path);
+ }
+
+ int n = path.lastIndexOf('/');
+ for (Iterator it = lpatterns.iterator(); it.hasNext();) {
+ String pattern = (String) it.next();
+ if (path.substring(n).endsWith(pattern)) {
+ return rules.get(pattern);
+ }
+ }
+
+ for (Iterator it = rpatterns.iterator(); it.hasNext();) {
+ String pattern = (String) it.next();
+ if (path.startsWith(pattern)) {
+ return rules.get(pattern);
+ }
+ }
+
+ return null;
+ }
+
+ }
+
+ /**
+ * Rule
+ */
+ protected abstract class Rule {
+
+ public void begin(String name, Attributes attrs) {
+ }
+
+ public void end(String name) {
+ }
+
+ protected final Object getValue(String desc, String val) {
+ Object value = null;
+ if (val != null) {
+ if (desc.equals("Ljava/lang/String;")) {
+ value = decode(val);
+ } else if ("Ljava/lang/Integer;".equals(desc)
+ || "I".equals(desc) || "S".equals(desc)
+ || "B".equals(desc) || "C".equals(desc)
+ || desc.equals("Z"))
+ {
+ value = new Integer(val);
+
+ } else if ("Ljava/lang/Short;".equals(desc)) {
+ value = new Short(val);
+
+ } else if ("Ljava/lang/Byte;".equals(desc)) {
+ value = new Byte(val);
+
+ } else if ("Ljava/lang/Character;".equals(desc)) {
+ value = new Character(decode(val).charAt(0));
+
+ } else if ("Ljava/lang/Boolean;".equals(desc)) {
+ value = Boolean.valueOf(val);
+
+ // } else if ("Ljava/lang/Integer;".equals(desc)
+ // || desc.equals("I"))
+ // {
+ // value = new Integer(val);
+ // } else if ("Ljava/lang/Character;".equals(desc)
+ // || desc.equals("C"))
+ // {
+ // value = new Character(decode(val).charAt(0));
+ // } else if ("Ljava/lang/Short;".equals(desc) ||
+ // desc.equals("S"))
+ // {
+ // value = Short.valueOf(val);
+ // } else if ("Ljava/lang/Byte;".equals(desc) ||
+ // desc.equals("B"))
+ // {
+ // value = Byte.valueOf(val);
+
+ } else if ("Ljava/lang/Long;".equals(desc) || desc.equals("J"))
+ {
+ value = new Long(val);
+ } else if ("Ljava/lang/Float;".equals(desc) || desc.equals("F"))
+ {
+ value = new Float(val);
+ } else if ("Ljava/lang/Double;".equals(desc)
+ || desc.equals("D"))
+ {
+ value = new Double(val);
+ } else if (Type.getDescriptor(Type.class).equals(desc)) {
+ value = Type.getType(val);
+
+ // } else if ("[I".equals(desc)) {
+ // value = new int[0]; // TODO
+ // } else if ("[C".equals(desc)) {
+ // value = new char[0]; // TODO
+ // } else if ("[Z".equals(desc)) {
+ // value = new boolean[0]; // TODO
+ // } else if ("[S".equals(desc)) {
+ // value = new short[0]; // TODO
+ // } else if ("[B".equals(desc)) {
+ // value = new byte[0]; // TODO
+ // } else if ("[J".equals(desc)) {
+ // value = new long[0]; // TODO
+ // } else if ("[F".equals(desc)) {
+ // value = new float[0]; // TODO
+ // } else if ("[D".equals(desc)) {
+ // value = new double[0]; // TODO
+
+ } else {
+ throw new RuntimeException("Invalid value:" + val
+ + " desc:" + desc + " ctx:" + this);
+ }
+ }
+ return value;
+ }
+
+ private final String decode(String val) {
+ StringBuffer sb = new StringBuffer(val.length());
+ try {
+ int n = 0;
+ while (n < val.length()) {
+ char c = val.charAt(n);
+ if (c == '\\') {
+ n++;
+ c = val.charAt(n);
+ if (c == '\\') {
+ sb.append('\\');
+ } else {
+ n++; // skip 'u'
+ sb.append((char) Integer.parseInt(val.substring(n,
+ n + 4), 16));
+ n += 3;
+ }
+ } else {
+ sb.append(c);
+ }
+ n++;
+ }
+
+ } catch (RuntimeException ex) {
+ System.err.println(val + "\n" + ex.toString());
+ ex.printStackTrace();
+ throw ex;
+ }
+ return sb.toString();
+ }
+
+ protected final Label getLabel(Object label) {
+ Label lbl = (Label) labels.get(label);
+ if (lbl == null) {
+ lbl = new Label();
+ labels.put(label, lbl);
+ }
+ return lbl;
+ }
+
+ // TODO verify move to stack
+ protected final MethodVisitor getCodeVisitor() {
+ return (MethodVisitor) peek();
+ }
+
+ protected final int getAccess(String s) {
+ int access = 0;
+ if (s.indexOf("public") != -1)
+ access |= Opcodes.ACC_PUBLIC;
+ if (s.indexOf("private") != -1)
+ access |= Opcodes.ACC_PRIVATE;
+ if (s.indexOf("protected") != -1)
+ access |= Opcodes.ACC_PROTECTED;
+ if (s.indexOf("static") != -1)
+ access |= Opcodes.ACC_STATIC;
+ if (s.indexOf("final") != -1)
+ access |= Opcodes.ACC_FINAL;
+ if (s.indexOf("super") != -1)
+ access |= Opcodes.ACC_SUPER;
+ if (s.indexOf("synchronized") != -1)
+ access |= Opcodes.ACC_SYNCHRONIZED;
+ if (s.indexOf("volatile") != -1)
+ access |= Opcodes.ACC_VOLATILE;
+ if (s.indexOf("bridge") != -1)
+ access |= Opcodes.ACC_BRIDGE;
+ if (s.indexOf("varargs") != -1)
+ access |= Opcodes.ACC_VARARGS;
+ if (s.indexOf("transient") != -1)
+ access |= Opcodes.ACC_TRANSIENT;
+ if (s.indexOf("native") != -1)
+ access |= Opcodes.ACC_NATIVE;
+ if (s.indexOf("interface") != -1)
+ access |= Opcodes.ACC_INTERFACE;
+ if (s.indexOf("abstract") != -1)
+ access |= Opcodes.ACC_ABSTRACT;
+ if (s.indexOf("strict") != -1)
+ access |= Opcodes.ACC_STRICT;
+ if (s.indexOf("synthetic") != -1)
+ access |= Opcodes.ACC_SYNTHETIC;
+ if (s.indexOf("annotation") != -1)
+ access |= Opcodes.ACC_ANNOTATION;
+ if (s.indexOf("enum") != -1)
+ access |= Opcodes.ACC_ENUM;
+ if (s.indexOf("deprecated") != -1)
+ access |= Opcodes.ACC_DEPRECATED;
+ return access;
+ }
+
+ }
+
+ /**
+ * ClassRule
+ */
+ private final class ClassRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ int major = Integer.parseInt(attrs.getValue("major"));
+ int minor = Integer.parseInt(attrs.getValue("minor"));
+ cw = new ClassWriter(computeMax);
+ Map vals = new HashMap();
+ vals.put("version", new Integer(minor << 16 | major));
+ vals.put("access", attrs.getValue("access"));
+ vals.put("name", attrs.getValue("name"));
+ vals.put("parent", attrs.getValue("parent"));
+ vals.put("source", attrs.getValue("source"));
+ vals.put("signature", attrs.getValue("signature"));
+ vals.put("interfaces", new ArrayList());
+ push(vals);
+ // values will be extracted in InterfacesRule.end();
+ }
+
+ }
+
+ private final class SourceRule extends Rule {
+
+ public void begin(String name, Attributes attrs) {
+ String file = attrs.getValue("file");
+ String debug = attrs.getValue("debug");
+ cw.visitSource(file, debug);
+ }
+
+ }
+
+ /**
+ * InterfaceRule
+ */
+ private final class InterfaceRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ ((List) ((Map) peek()).get("interfaces")).add(attrs.getValue("name"));
+ }
+
+ }
+
+ /**
+ * InterfacesRule
+ */
+ private final class InterfacesRule extends Rule {
+
+ public final void end(String element) {
+ Map vals = (Map) pop();
+ int version = ((Integer) vals.get("version")).intValue();
+ int access = getAccess((String) vals.get("access"));
+ String name = (String) vals.get("name");
+ String signature = (String) vals.get("signature");
+ String parent = (String) vals.get("parent");
+ List infs = (List) vals.get("interfaces");
+ String[] interfaces = (String[]) infs.toArray(new String[infs.size()]);
+ cw.visit(version, access, name, signature, parent, interfaces);
+ push(cw);
+ }
+
+ }
+
+ /**
+ * OuterClassRule
+ */
+ private final class OuterClassRule extends Rule {
+
+ public final void begin(String element, Attributes attrs) {
+ String owner = attrs.getValue("owner");
+ String name = attrs.getValue("name");
+ String desc = attrs.getValue("desc");
+ cw.visitOuterClass(owner, name, desc);
+ }
+
+ }
+
+ /**
+ * InnerClassRule
+ */
+ private final class InnerClassRule extends Rule {
+
+ public final void begin(String element, Attributes attrs) {
+ int access = getAccess(attrs.getValue("access"));
+ String name = attrs.getValue("name");
+ String outerName = attrs.getValue("outerName");
+ String innerName = attrs.getValue("innerName");
+ cw.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ }
+
+ /**
+ * FieldRule
+ */
+ private final class FieldRule extends Rule {
+
+ public final void begin(String element, Attributes attrs) {
+ int access = getAccess(attrs.getValue("access"));
+ String name = attrs.getValue("name");
+ String signature = attrs.getValue("signature");
+ String desc = attrs.getValue("desc");
+ Object value = getValue(desc, attrs.getValue("value"));
+ push(cw.visitField(access, name, desc, signature, value));
+ }
+
+ public void end(String name) {
+ ((FieldVisitor) pop()).visitEnd();
+ }
+
+ }
+
+ /**
+ * MethodRule
+ */
+ private final class MethodRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ labels = new HashMap();
+ Map vals = new HashMap();
+ vals.put("access", attrs.getValue("access"));
+ vals.put("name", attrs.getValue("name"));
+ vals.put("desc", attrs.getValue("desc"));
+ vals.put("signature", attrs.getValue("signature"));
+ vals.put("exceptions", new ArrayList());
+ push(vals);
+ // values will be extracted in ExceptionsRule.end();
+ }
+
+ public final void end(String name) {
+ ((MethodVisitor) pop()).visitEnd();
+ labels = null;
+ }
+
+ }
+
+ /**
+ * ExceptionRule
+ */
+ private final class ExceptionRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ ((List) ((Map) peek()).get("exceptions")).add(attrs.getValue("name"));
+ }
+
+ }
+
+ /**
+ * ExceptionsRule
+ */
+ private final class ExceptionsRule extends Rule {
+
+ public final void end(String element) {
+ Map vals = (Map) pop();
+ int access = getAccess((String) vals.get("access"));
+ String name = (String) vals.get("name");
+ String desc = (String) vals.get("desc");
+ String signature = (String) vals.get("signature");
+ List excs = (List) vals.get("exceptions");
+ String[] exceptions = (String[]) excs.toArray(new String[excs.size()]);
+
+ push(cw.visitMethod(access, name, desc, signature, exceptions));
+ }
+
+ }
+
+ /**
+ * TableSwitchRule
+ */
+ private class TableSwitchRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ Map vals = new HashMap();
+ vals.put("min", attrs.getValue("min"));
+ vals.put("max", attrs.getValue("max"));
+ vals.put("dflt", attrs.getValue("dflt"));
+ vals.put("labels", new ArrayList());
+ push(vals);
+ }
+
+ public final void end(String name) {
+ Map vals = (Map) pop();
+ int min = Integer.parseInt((String) vals.get("min"));
+ int max = Integer.parseInt((String) vals.get("max"));
+ Label dflt = getLabel(vals.get("dflt"));
+ List lbls = (List) vals.get("labels");
+ Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]);
+ getCodeVisitor().visitTableSwitchInsn(min, max, dflt, labels);
+ }
+
+ }
+
+ /**
+ * TableSwitchLabelRule
+ */
+ private final class TableSwitchLabelRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ ((List) ((Map) peek()).get("labels")).add(getLabel(attrs.getValue("name")));
+ }
+
+ }
+
+ /**
+ * LookupSwitchRule
+ */
+ private final class LookupSwitchRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ Map vals = new HashMap();
+ vals.put("dflt", attrs.getValue("dflt"));
+ vals.put("labels", new ArrayList());
+ vals.put("keys", new ArrayList());
+ push(vals);
+ }
+
+ public final void end(String name) {
+ Map vals = (Map) pop();
+ Label dflt = getLabel(vals.get("dflt"));
+ List keyList = (List) vals.get("keys");
+ List lbls = (List) vals.get("labels");
+ Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]);
+ int[] keys = new int[keyList.size()];
+ for (int i = 0; i < keys.length; i++) {
+ keys[i] = Integer.parseInt((String) keyList.get(i));
+ }
+ getCodeVisitor().visitLookupSwitchInsn(dflt, keys, labels);
+ }
+
+ }
+
+ /**
+ * LookupSwitchLabelRule
+ */
+ private final class LookupSwitchLabelRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ Map vals = (Map) peek();
+ ((List) vals.get("labels")).add(getLabel(attrs.getValue("name")));
+ ((List) vals.get("keys")).add(attrs.getValue("key"));
+ }
+
+ }
+
+ /**
+ * LabelRule
+ */
+ private final class LabelRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ getCodeVisitor().visitLabel(getLabel(attrs.getValue("name")));
+ }
+
+ }
+
+ /**
+ * TryCatchRule
+ */
+ private final class TryCatchRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ Label start = getLabel(attrs.getValue("start"));
+ Label end = getLabel(attrs.getValue("end"));
+ Label handler = getLabel(attrs.getValue("handler"));
+ String type = attrs.getValue("type");
+ getCodeVisitor().visitTryCatchBlock(start, end, handler, type);
+ }
+
+ }
+
+ /**
+ * LineNumberRule
+ */
+ private final class LineNumberRule extends Rule {
+
+ public final void begin(String name, Attributes attrs) {
+ int line = Integer.parseInt(attrs.getValue("line"));
+ Label start = getLabel(attrs.getValue("start"));
+ getCodeVisitor().visitLineNumber(line, start);
+ }
+
+ }
+
+ /**
+ * LocalVarRule
+ */
+ private final class LocalVarRule extends Rule {
+
+ public final void begin(String element, Attributes attrs) {
+ String name = attrs.getValue("name");
+ String desc = attrs.getValue("desc");
+ String signature = attrs.getValue("signature");
+ Label start = getLabel(attrs.getValue("start"));
+ Label end = getLabel(attrs.getValue("end"));
+ int var = Integer.parseInt(attrs.getValue("var"));
+ getCodeVisitor().visitLocalVariable(name,
+ desc,
+ signature,
+ start,
+ end,
+ var);
+ }
+
+ }
+
+ /**
+ * OpcodesRule
+ */
+ private final class OpcodesRule extends Rule {
+
+ // public boolean match( String match, String element) {
+ // return match.startsWith( path) && OPCODES.containsKey( element);
+ // }
+
+ public final void begin(String element, Attributes attrs) {
+ Opcode o = ((Opcode) OPCODES.get(element));
+ if (o == null)
+ return;
+
+ switch (o.type) {
+ case OpcodeGroup.INSN:
+ getCodeVisitor().visitInsn(o.opcode);
+ break;
+
+ case OpcodeGroup.INSN_FIELD:
+ getCodeVisitor().visitFieldInsn(o.opcode,
+ attrs.getValue("owner"),
+ attrs.getValue("name"),
+ attrs.getValue("desc"));
+ break;
+
+ case OpcodeGroup.INSN_INT:
+ getCodeVisitor().visitIntInsn(o.opcode,
+ Integer.parseInt(attrs.getValue("value")));
+ break;
+
+ case OpcodeGroup.INSN_JUMP:
+ getCodeVisitor().visitJumpInsn(o.opcode,
+ getLabel(attrs.getValue("label")));
+ break;
+
+ case OpcodeGroup.INSN_METHOD:
+ getCodeVisitor().visitMethodInsn(o.opcode,
+ attrs.getValue("owner"),
+ attrs.getValue("name"),
+ attrs.getValue("desc"));
+ break;
+
+ case OpcodeGroup.INSN_TYPE:
+ getCodeVisitor().visitTypeInsn(o.opcode,
+ attrs.getValue("desc"));
+ break;
+
+ case OpcodeGroup.INSN_VAR:
+ getCodeVisitor().visitVarInsn(o.opcode,
+ Integer.parseInt(attrs.getValue("var")));
+ break;
+
+ case OpcodeGroup.INSN_IINC:
+ getCodeVisitor().visitIincInsn(Integer.parseInt(attrs.getValue("var")),
+ Integer.parseInt(attrs.getValue("inc")));
+ break;
+
+ case OpcodeGroup.INSN_LDC:
+ getCodeVisitor().visitLdcInsn(getValue(attrs.getValue("desc"),
+ attrs.getValue("cst")));
+ break;
+
+ case OpcodeGroup.INSN_MULTIANEWARRAY:
+ getCodeVisitor().visitMultiANewArrayInsn(attrs.getValue("desc"),
+ Integer.parseInt(attrs.getValue("dims")));
+ break;
+
+ default:
+ throw new RuntimeException("Invalid element: " + element
+ + " at " + match);
+
+ }
+ }
+ }
+
+ /**
+ * MaxRule
+ */
+ private final class MaxRule extends Rule {
+
+ public final void begin(String element, Attributes attrs) {
+ int maxStack = Integer.parseInt(attrs.getValue("maxStack"));
+ int maxLocals = Integer.parseInt(attrs.getValue("maxLocals"));
+ getCodeVisitor().visitMaxs(maxStack, maxLocals);
+ }
+
+ }
+
+ private final class AnnotationRule extends Rule {
+
+ public void begin(String name, Attributes attrs) {
+ String desc = attrs.getValue("desc");
+ boolean visible = Boolean.valueOf(attrs.getValue("visible"))
+ .booleanValue();
+
+ Object v = peek();
+ if (v instanceof ClassVisitor) {
+ push(((ClassVisitor) v).visitAnnotation(desc, visible));
+ } else if (v instanceof FieldVisitor) {
+ push(((FieldVisitor) v).visitAnnotation(desc, visible));
+ } else if (v instanceof MethodVisitor) {
+ push(((MethodVisitor) v).visitAnnotation(desc, visible));
+ }
+ }
+
+ public void end(String name) {
+ ((AnnotationVisitor) pop()).visitEnd();
+ }
+
+ }
+
+ private final class AnnotationParameterRule extends Rule {
+
+ public void begin(String name, Attributes attrs) {
+ int parameter = Integer.parseInt(attrs.getValue("parameter"));
+ String desc = attrs.getValue("desc");
+ boolean visible = Boolean.valueOf(attrs.getValue("visible"))
+ .booleanValue();
+
+ push(((MethodVisitor) peek()).visitParameterAnnotation(parameter,
+ desc,
+ visible));
+ }
+
+ public void end(String name) {
+ ((AnnotationVisitor) pop()).visitEnd();
+ }
+
+ }
+
+ private final class AnnotationValueRule extends Rule {
+
+ public void begin(String nm, Attributes attrs) {
+ String name = attrs.getValue("name");
+ String desc = attrs.getValue("desc");
+ String value = attrs.getValue("value");
+ ((AnnotationVisitor) peek()).visit(name, getValue(desc, value));
+ }
+
+ }
+
+ private final class AnnotationValueEnumRule extends Rule {
+
+ public void begin(String nm, Attributes attrs) {
+ String name = attrs.getValue("name");
+ String desc = attrs.getValue("desc");
+ String value = attrs.getValue("value");
+ ((AnnotationVisitor) peek()).visitEnum(name, desc, value);
+ }
+
+ }
+
+ private final class AnnotationValueAnnotationRule extends Rule {
+
+ public void begin(String nm, Attributes attrs) {
+ String name = attrs.getValue("name");
+ String desc = attrs.getValue("desc");
+ push(((AnnotationVisitor) peek()).visitAnnotation(name, desc));
+ }
+
+ public void end(String name) {
+ ((AnnotationVisitor) pop()).visitEnd();
+ }
+
+ }
+
+ private final class AnnotationValueArrayRule extends Rule {
+
+ public void begin(String nm, Attributes attrs) {
+ String name = attrs.getValue("name");
+ push(((AnnotationVisitor) peek()).visitArray(name));
+ }
+
+ public void end(String name) {
+ ((AnnotationVisitor) pop()).visitEnd();
+ }
+
+ }
+
+ private final class AnnotationDefaultRule extends Rule {
+
+ public void begin(String nm, Attributes attrs) {
+ push(((MethodVisitor) peek()).visitAnnotationDefault());
+ }
+
+ public void end(String name) {
+ ((AnnotationVisitor) pop()).visitEnd();
+ }
+
+ }
+
+ /**
+ * Opcode
+ */
+ private final static class Opcode {
+ public int opcode;
+
+ public int type;
+
+ public Opcode(int opcode, int type) {
+ this.opcode = opcode;
+ this.type = type;
+ }
+
+ }
+
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/xml/Processor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/xml/Processor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/xml/Processor.java 2007-01-07 13:57:32 UTC (rev 3035)
@@ -0,0 +1,1048 @@
+/***
+ * ASM XML Adapter
+ * Copyright (c) 2004, Eugene Kuleshov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.xml;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamSource;
+
+import org.objectweb.asm.ClassReader;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Processor is a command line tool that can be used for bytecode waving
+ * directed by XSL transformation. <p> In order to use a concrete XSLT engine,
+ * system property <tt>javax.xml.transform.TransformerFactory</tt> must be set
+ * to one of the following values.
+ *
+ * <blockquote> <table border="1" cellspacing="0" cellpadding="3"> <tr> <td>jd.xslt</td>
+ * <td>jd.xml.xslt.trax.TransformerFactoryImpl</td> </tr>
+ *
+ * <tr> <td>Saxon</td> <td>net.sf.saxon.TransformerFactoryImpl</td> </tr>
+ *
+ * <tr> <td>Caucho</td> <td>com.caucho.xsl.Xsl</td> </tr>
+ *
+ * <tr> <td>Xalan interpeter</td> <td>org.apache.xalan.processor.TransformerFactory</td>
+ * </tr>
+ *
+ * <tr> <td>Xalan xsltc</td> <td>org.apache.xalan.xsltc.trax.TransformerFactoryImpl</td>
+ * </tr> </table> </blockquote>
+ *
+ * @author Eugene Kuleshov
+ */
+public class Processor {
+
+ public static final int BYTECODE = 1;
+
+ public static final int MULTI_XML = 2;
+
+ public static final int SINGLE_XML = 3;
+
+ private static final String SINGLE_XML_NAME = "classes.xml";
+
+ private int inRepresentation;
+
+ private int outRepresentation;
+
+ private InputStream input = null;
+
+ private OutputStream output = null;
+
+ private Source xslt = null;
+
+ private boolean computeMax;
+
+ private int n = 0;
+
+ public Processor(
+ int inRepresenation,
+ int outRepresentation,
+ InputStream input,
+ OutputStream output,
+ Source xslt)
+ {
+ this.inRepresentation = inRepresenation;
+ this.outRepresentation = outRepresentation;
+ this.input = input;
+ this.output = output;
+ this.xslt = xslt;
+ this.computeMax = true;
+ }
+
+ public int process() throws TransformerException, IOException, SAXException
+ {
+ ZipInputStream zis = new ZipInputStream(input);
+ final ZipOutputStream zos = new ZipOutputStream(output);
+ final OutputStreamWriter osw = new OutputStreamWriter(zos);
+
+ Thread.currentThread()
+ .setContextClassLoader(getClass().getClassLoader());
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ if (!tf.getFeature(SAXSource.FEATURE)
+ || !tf.getFeature(SAXResult.FEATURE))
+ return 0;
+
+ SAXTransformerFactory saxtf = (SAXTransformerFactory) tf;
+ Templates templates = null;
+ if (xslt != null) {
+ templates = saxtf.newTemplates(xslt);
+ }
+
+ // configuring outHandlerFactory
+ // ///////////////////////////////////////////////////////
+
+ EntryElement entryElement = getEntryElement(zos);
+
+ ContentHandler outDocHandler = null;
+ switch (outRepresentation) {
+ case BYTECODE:
+ outDocHandler = new OutputSlicingHandler(new ASMContentHandlerFactory(zos,
+ computeMax),
+ entryElement,
+ false);
+ break;
+
+ case MULTI_XML:
+ outDocHandler = new OutputSlicingHandler(new SAXWriterFactory(osw,
+ true),
+ entryElement,
+ true);
+ break;
+
+ case SINGLE_XML:
+ ZipEntry outputEntry = new ZipEntry(SINGLE_XML_NAME);
+ zos.putNextEntry(outputEntry);
+ outDocHandler = new SAXWriter(osw, false);
+ break;
+
+ }
+
+ // configuring inputDocHandlerFactory
+ // /////////////////////////////////////////////////
+ ContentHandler inDocHandler = null;
+ if (templates == null) {
+ inDocHandler = outDocHandler;
+ } else {
+ inDocHandler = new InputSlicingHandler("class",
+ outDocHandler,
+ new TransformerHandlerFactory(saxtf,
+ templates,
+ outDocHandler));
+ }
+ ContentHandlerFactory inDocHandlerFactory = new SubdocumentHandlerFactory(inDocHandler);
+
+ if (inDocHandler != null && inRepresentation != SINGLE_XML) {
+ inDocHandler.startDocument();
+ inDocHandler.startElement("",
+ "classes",
+ "classes",
+ new AttributesImpl());
+ }
+
+ int i = 0;
+ ZipEntry ze = null;
+ while ((ze = zis.getNextEntry()) != null) {
+ update(ze.getName(), n++);
+ if (isClassEntry(ze)) {
+ processEntry(zis, ze, inDocHandlerFactory);
+ } else {
+ OutputStream os = entryElement.openEntry(getName(ze));
+ copyEntry(zis, os);
+ entryElement.closeEntry();
+ }
+
+ i++;
+ }
+
+ if (inDocHandler != null && inRepresentation != SINGLE_XML) {
+ inDocHandler.endElement("", "classes", "classes");
+ inDocHandler.endDocument();
+ }
+
+ if (outRepresentation == SINGLE_XML) {
+ zos.closeEntry();
+ }
+ zos.flush();
+ zos.close();
+
+ return i;
+ }
+
+ private void copyEntry(InputStream is, OutputStream os) throws IOException {
+ if (outRepresentation == SINGLE_XML)
+ return;
+
+ byte[] buff = new byte[2048];
+ int i;
+ while ((i = is.read(buff)) != -1) {
+ os.write(buff, 0, i);
+ }
+ }
+
+ private boolean isClassEntry(ZipEntry ze) {
+ String name = ze.getName();
+ return inRepresentation == SINGLE_XML && name.equals(SINGLE_XML_NAME)
+ || name.endsWith(".class") || name.endsWith(".class.xml");
+ }
+
+ private void processEntry(
+ final ZipInputStream zis,
+ ZipEntry ze,
+ ContentHandlerFactory handlerFactory)
+ {
+ ContentHandler handler = handlerFactory.createContentHandler();
+ try {
+
+ // if (CODE2ASM.equals(command)) { // read bytecode and process it
+ // // with TraceClassVisitor
+ // ClassReader cr = new ClassReader(readEntry(zis, ze));
+ // cr.accept(new TraceClassVisitor(null, new PrintWriter(os)),
+ // false);
+ // }
+
+ boolean singleInputDocument = inRepresentation == SINGLE_XML;
+ if (inRepresentation == BYTECODE) { // read bytecode and process it
+ // with handler
+ ClassReader cr = new ClassReader(readEntry(zis, ze));
+ cr.accept(new SAXClassAdapter(handler, singleInputDocument),
+ false);
+
+ } else { // read XML and process it with handler
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ reader.setContentHandler(handler);
+ reader.parse(new InputSource(singleInputDocument
+ ? (InputStream) new ProtectedInputStream(zis)
+ : new ByteArrayInputStream(readEntry(zis, ze))));
+
+ }
+ } catch (Exception ex) {
+ update(ze.getName(), 0);
+ update(ex, 0);
+ }
+ }
+
+ private EntryElement getEntryElement(ZipOutputStream zos) {
+ if (outRepresentation == SINGLE_XML) {
+ return new SingleDocElement(zos);
+ }
+ return new ZipEntryElement(zos);
+ }
+
+ // private ...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:55:16
|
Revision: 3034
http://jnode.svn.sourceforge.net/jnode/?rev=3034&view=rev
Author: lsantha
Date: 2007-01-07 05:55:15 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/util/
trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAbstractVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAnnotationVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierClassVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierFieldVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierMethodVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/AbstractVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/CheckAnnotationAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/util/CheckClassAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/util/CheckFieldAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/util/CheckMethodAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/util/TraceAbstractVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/TraceAnnotationVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/TraceClassVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/TraceFieldVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/TraceMethodVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/TraceSignatureVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/util/attrs/
trunk/core/src/classpath/org/org/objectweb/asm/util/attrs/ASMStackMapAttribute.java
trunk/core/src/classpath/org/org/objectweb/asm/util/attrs/ASMStackMapTableAttribute.java
trunk/core/src/classpath/org/org/objectweb/asm/util/attrs/ASMifiable.java
trunk/core/src/classpath/org/org/objectweb/asm/util/attrs/Traceable.java
trunk/core/src/classpath/org/org/objectweb/asm/util/attrs/package.html
trunk/core/src/classpath/org/org/objectweb/asm/util/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAbstractVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAbstractVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAbstractVisitor.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,226 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.util.HashMap;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.util.attrs.ASMifiable;
+
+/**
+ * An abstract ASMifier visitor.
+ *
+ * @author Eric Bruneton
+ */
+public class ASMifierAbstractVisitor extends AbstractVisitor {
+
+ /**
+ * The name of the variable for this visitor in the produced code.
+ */
+ protected String name;
+
+ /**
+ * The label names. This map associates String values to Label keys. It is
+ * used only in ASMifierMethodVisitor.
+ */
+ HashMap labelNames;
+
+ /**
+ * Constructs a new {@link ASMifierAbstractVisitor}.
+ *
+ * @param name the name of the variable for this visitor in the produced
+ * code.
+ */
+ protected ASMifierAbstractVisitor(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Prints the ASM code that generates the given annotation.
+ *
+ * @param desc the class descriptor of the annotation class.
+ * @param visible <tt>true</tt> if the annotation is visible at runtime.
+ * @return a visitor to visit the annotation values.
+ */
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append("{\n")
+ .append("av0 = ")
+ .append(name)
+ .append(".visitAnnotation(");
+ appendConstant(desc);
+ buf.append(", ").append(visible).append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ /**
+ * Prints the ASM code that generates the given attribute.
+ *
+ * @param attr an attribute.
+ */
+ public void visitAttribute(final Attribute attr) {
+ buf.setLength(0);
+ if (attr instanceof ASMifiable) {
+ buf.append("{\n");
+ buf.append("// ATTRIBUTE\n");
+ ((ASMifiable) attr).asmify(buf, "attr", labelNames);
+ buf.append(name).append(".visitAttribute(attr);\n");
+ buf.append("}\n");
+ } else {
+ buf.append("// WARNING! skipped a non standard attribute of type \"");
+ buf.append(attr.type).append("\"\n");
+ }
+ text.add(buf.toString());
+ }
+
+ /**
+ * Prints the ASM code to end the visit.
+ */
+ public void visitEnd() {
+ buf.setLength(0);
+ buf.append(name).append(".visitEnd();\n");
+ text.add(buf.toString());
+ }
+
+ /**
+ * Appends a string representation of the given constant to the given
+ * buffer.
+ *
+ * @param cst an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double} or {@link String} object. May be <tt>null</tt>.
+ */
+ void appendConstant(final Object cst) {
+ appendConstant(buf, cst);
+ }
+
+ /**
+ * Appends a string representation of the given constant to the given
+ * buffer.
+ *
+ * @param buf a string buffer.
+ * @param cst an {@link Integer}, {@link Float}, {@link Long},
+ * {@link Double} or {@link String} object. May be <tt>null</tt>.
+ */
+ static void appendConstant(final StringBuffer buf, final Object cst) {
+ if (cst == null) {
+ buf.append("null");
+ } else if (cst instanceof String) {
+ appendString(buf, (String) cst);
+ } else if (cst instanceof Type) {
+ buf.append("Type.getType(\"");
+ buf.append(((Type) cst).getDescriptor());
+ buf.append("\")");
+ } else if (cst instanceof Byte) {
+ buf.append("new Byte((byte)").append(cst).append(")");
+ } else if (cst instanceof Boolean) {
+ buf.append("new Boolean(").append(cst).append(")");
+ } else if (cst instanceof Short) {
+ buf.append("new Short((short)").append(cst).append(")");
+ } else if (cst instanceof Character) {
+ int c = ((Character) cst).charValue();
+ buf.append("new Character((char)").append(c).append(")");
+ } else if (cst instanceof Integer) {
+ buf.append("new Integer(").append(cst).append(")");
+ } else if (cst instanceof Float) {
+ buf.append("new Float(\"").append(cst).append("\")");
+ } else if (cst instanceof Long) {
+ buf.append("new Long(").append(cst).append("L)");
+ } else if (cst instanceof Double) {
+ buf.append("new Double(\"").append(cst).append("\")");
+ } else if (cst instanceof byte[]) {
+ byte[] v = (byte[]) cst;
+ buf.append("new byte[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof boolean[]) {
+ boolean[] v = (boolean[]) cst;
+ buf.append("new boolean[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof short[]) {
+ short[] v = (short[]) cst;
+ buf.append("new short[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof char[]) {
+ char[] v = (char[]) cst;
+ buf.append("new char[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",")
+ .append("(char)")
+ .append((int) v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof int[]) {
+ int[] v = (int[]) cst;
+ buf.append("new int[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]);
+ }
+ buf.append("}");
+ } else if (cst instanceof long[]) {
+ long[] v = (long[]) cst;
+ buf.append("new long[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]).append("L");
+ }
+ buf.append("}");
+ } else if (cst instanceof float[]) {
+ float[] v = (float[]) cst;
+ buf.append("new float[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]).append("f");
+ }
+ buf.append("}");
+ } else if (cst instanceof double[]) {
+ double[] v = (double[]) cst;
+ buf.append("new double[] {");
+ for (int i = 0; i < v.length; i++) {
+ buf.append(i == 0 ? "" : ",").append(v[i]).append("d");
+ }
+ buf.append("}");
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAnnotationVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAnnotationVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierAnnotationVisitor.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,127 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+ * An {@link AnnotationVisitor} that prints the ASM code that generates the
+ * annotations it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class ASMifierAnnotationVisitor extends AbstractVisitor implements
+ AnnotationVisitor
+{
+
+ /**
+ * Identifier of the annotation visitor variable in the produced code.
+ */
+ protected final int id;
+
+ /**
+ * Constructs a new {@link ASMifierAnnotationVisitor}.
+ *
+ * @param id identifier of the annotation visitor variable in the produced
+ * code.
+ */
+ public ASMifierAnnotationVisitor(final int id) {
+ this.id = id;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(final String name, final Object value) {
+ buf.setLength(0);
+ buf.append("av").append(id).append(".visit(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, value);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitEnum(
+ final String name,
+ final String desc,
+ final String value)
+ {
+ buf.setLength(0);
+ buf.append("av").append(id).append(".visitEnum(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, desc);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, value);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("AnnotationVisitor av").append(id + 1).append(" = av");
+ buf.append(id).append(".visitAnnotation(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(", ");
+ ASMifierAbstractVisitor.appendConstant(buf, desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(id + 1);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("AnnotationVisitor av").append(id + 1).append(" = av");
+ buf.append(id).append(".visitArray(");
+ ASMifierAbstractVisitor.appendConstant(buf, name);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(id + 1);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public void visitEnd() {
+ buf.setLength(0);
+ buf.append("av").append(id).append(".visitEnd();\n");
+ text.add(buf.toString());
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierClassVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierClassVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierClassVisitor.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,607 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link ClassVisitor} that prints the ASM code that generates the classes it
+ * visits. This class visitor can be used to quickly write ASM code to generate
+ * some given bytecode: <ul> <li>write the Java source code equivalent to the
+ * bytecode you want to generate;</li> <li>compile it with <tt>javac</tt>;</li>
+ * <li>make a {@link ASMifierClassVisitor} visit this compiled class (see the
+ * {@link #main main} method);</li> <li>edit the generated source code, if
+ * necessary.</li> </ul> The source code printed when visiting the
+ * <tt>Hello</tt> class is the following: <p> <blockquote>
+ *
+ * <pre>
+ * import org.objectweb.asm.*;
+ *
+ * public class HelloDump implements Opcodes {
+ *
+ * public static byte[] dump() throws Exception {
+ *
+ * ClassWriter cw = new ClassWriter(false);
+ * FieldVisitor fv;
+ * MethodVisitor mv;
+ * AnnotationVisitor av0;
+ *
+ * cw.visit(49,
+ * ACC_PUBLIC + ACC_SUPER,
+ * "Hello",
+ * null,
+ * "java/lang/Object",
+ * null);
+ *
+ * cw.visitSource("Hello.java", null);
+ *
+ * {
+ * mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ * mv.visitVarInsn(ALOAD, 0);
+ * mv.visitMethodInsn(INVOKESPECIAL,
+ * "java/lang/Object",
+ * "<init>",
+ * "()V");
+ * mv.visitInsn(RETURN);
+ * mv.visitMaxs(1, 1);
+ * mv.visitEnd();
+ * }
+ * {
+ * mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
+ * "main",
+ * "([Ljava/lang/String;)V",
+ * null,
+ * null);
+ * mv.visitFieldInsn(GETSTATIC,
+ * "java/lang/System",
+ * "out",
+ * "Ljava/io/PrintStream;");
+ * mv.visitLdcInsn("hello");
+ * mv.visitMethodInsn(INVOKEVIRTUAL,
+ * "java/io/PrintStream",
+ * "println",
+ * "(Ljava/lang/String;)V");
+ * mv.visitInsn(RETURN);
+ * mv.visitMaxs(2, 1);
+ * mv.visitEnd();
+ * }
+ * cw.visitEnd();
+ *
+ * return cw.toByteArray();
+ * }
+ * }
+ *
+ * </pre>
+ *
+ * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
+ *
+ * <pre>
+ * public class Hello {
+ *
+ * public static void main(String[] args) {
+ * System.out.println("hello");
+ * }
+ * }
+ * </pre>
+ *
+ * </blockquote>
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ASMifierClassVisitor extends ASMifierAbstractVisitor implements
+ ClassVisitor
+{
+
+ /**
+ * Pseudo access flag used to distinguish class access flags.
+ */
+ private final static int ACCESS_CLASS = 262144;
+
+ /**
+ * Pseudo access flag used to distinguish field access flags.
+ */
+ private final static int ACCESS_FIELD = 524288;
+
+ /**
+ * Pseudo access flag used to distinguish inner class flags.
+ */
+ private static final int ACCESS_INNER = 1048576;
+
+ /**
+ * The print writer to be used to print the class.
+ */
+ protected final PrintWriter pw;
+
+ /**
+ * Prints the ASM source code to generate the given class to the standard
+ * output. <p> Usage: ASMifierClassVisitor [-debug] <fully qualified
+ * class name or class file name>
+ *
+ * @param args the command line arguments.
+ *
+ * @throws Exception if the class cannot be found, or if an IO exception
+ * occurs.
+ */
+ public static void main(final String[] args) throws Exception {
+ int i = 0;
+ boolean skipDebug = true;
+
+ boolean ok = true;
+ if (args.length < 1 || args.length > 2) {
+ ok = false;
+ }
+ if (ok && args[0].equals("-debug")) {
+ i = 1;
+ skipDebug = false;
+ if (args.length != 2) {
+ ok = false;
+ }
+ }
+ if (!ok) {
+ System.err.println("Prints the ASM code to generate the given class.");
+ System.err.println("Usage: ASMifierClassVisitor [-debug] "
+ + "<fully qualified class name or class file name>");
+ return;
+ }
+ ClassReader cr;
+ if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
+ || args[i].indexOf('/') > -1) {
+ cr = new ClassReader(new FileInputStream(args[i]));
+ } else {
+ cr = new ClassReader(args[i]);
+ }
+ cr.accept(new ASMifierClassVisitor(new PrintWriter(System.out)),
+ getDefaultAttributes(),
+ skipDebug);
+ }
+
+ /**
+ * Constructs a new {@link ASMifierClassVisitor} object.
+ *
+ * @param pw the print writer to be used to print the class.
+ */
+ public ASMifierClassVisitor(final PrintWriter pw) {
+ super("cw");
+ this.pw = pw;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the ClassVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ String simpleName;
+ int n = name.lastIndexOf('/');
+ if (n != -1) {
+ text.add("package asm." + name.substring(0, n).replace('/', '.')
+ + ";\n");
+ simpleName = name.substring(n + 1);
+ } else {
+ simpleName = name;
+ }
+ text.add("import java.util.*;\n");
+ text.add("import org.objectweb.asm.*;\n");
+ text.add("import org.objectweb.asm.attrs.*;\n");
+ text.add("public class " + simpleName + "Dump implements Opcodes {\n\n");
+ text.add("public static byte[] dump () throws Exception {\n\n");
+ text.add("ClassWriter cw = new ClassWriter(false);\n");
+ text.add("FieldVisitor fv;\n");
+ text.add("MethodVisitor mv;\n");
+ text.add("AnnotationVisitor av0;\n\n");
+
+ buf.setLength(0);
+ buf.append("cw.visit(");
+ switch (version) {
+ case Opcodes.V1_1:
+ buf.append("V1_1");
+ break;
+ case Opcodes.V1_2:
+ buf.append("V1_2");
+ break;
+ case Opcodes.V1_3:
+ buf.append("V1_3");
+ break;
+ case Opcodes.V1_4:
+ buf.append("V1_4");
+ break;
+ case Opcodes.V1_5:
+ buf.append("V1_5");
+ break;
+ case Opcodes.V1_6:
+ buf.append("V1_6");
+ break;
+ default:
+ buf.append(version);
+ break;
+ }
+ buf.append(", ");
+ appendAccess(access | ACCESS_CLASS);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ appendConstant(superName);
+ buf.append(", ");
+ if (interfaces != null && interfaces.length > 0) {
+ buf.append("new String[] {");
+ for (int i = 0; i < interfaces.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(interfaces[i]);
+ }
+ buf.append(" }");
+ } else {
+ buf.append("null");
+ }
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public void visitSource(final String file, final String debug) {
+ buf.setLength(0);
+ buf.append("cw.visitSource(");
+ appendConstant(file);
+ buf.append(", ");
+ appendConstant(debug);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("cw.visitOuterClass(");
+ appendConstant(owner);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ buf.setLength(0);
+ buf.append("cw.visitInnerClass(");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(outerName);
+ buf.append(", ");
+ appendConstant(innerName);
+ buf.append(", ");
+ appendAccess(access | ACCESS_INNER);
+ buf.append(");\n\n");
+ text.add(buf.toString());
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("fv = cw.visitField(");
+ appendAccess(access | ACCESS_FIELD);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ appendConstant(value);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierFieldVisitor aav = new ASMifierFieldVisitor();
+ text.add(aav.getText());
+ text.add("}\n");
+ return aav;
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("mv = cw.visitMethod(");
+ appendAccess(access);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ if (exceptions != null && exceptions.length > 0) {
+ buf.append("new String[] {");
+ for (int i = 0; i < exceptions.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendConstant(exceptions[i]);
+ }
+ buf.append(" }");
+ } else {
+ buf.append("null");
+ }
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierMethodVisitor acv = new ASMifierMethodVisitor();
+ text.add(acv.getText());
+ text.add("}\n");
+ return acv;
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append("{\n");
+ buf.append("av0 = cw.visitAnnotation(");
+ appendConstant(desc);
+ buf.append(", ");
+ buf.append(visible);
+ buf.append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public void visitEnd() {
+ text.add("cw.visitEnd();\n\n");
+ text.add("return cw.toByteArray();\n");
+ text.add("}\n");
+ text.add("}\n");
+ printList(pw, text);
+ pw.flush();
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Appends a string representation of the given access modifiers to {@link
+ * #buf buf}.
+ *
+ * @param access some access modifiers.
+ */
+ void appendAccess(final int access) {
+ boolean first = true;
+ if ((access & Opcodes.ACC_PUBLIC) != 0) {
+ buf.append("ACC_PUBLIC");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_PRIVATE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_PRIVATE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_PROTECTED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_PROTECTED");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_FINAL) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_FINAL");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_STATIC) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_STATIC");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ if ((access & ACCESS_CLASS) != 0) {
+ buf.append("ACC_SUPER");
+ } else {
+ buf.append("ACC_SYNCHRONIZED");
+ }
+ first = false;
+ }
+ if ((access & Opcodes.ACC_VOLATILE) != 0
+ && (access & ACCESS_FIELD) != 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_VOLATILE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
+ && (access & ACCESS_FIELD) == 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_BRIDGE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
+ && (access & ACCESS_FIELD) == 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_VARARGS");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_TRANSIENT) != 0
+ && (access & ACCESS_FIELD) != 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_TRANSIENT");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0
+ && (access & ACCESS_FIELD) == 0)
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_NATIVE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_ENUM) != 0
+ && ((access & ACCESS_CLASS) != 0
+ || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0))
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ENUM");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_ANNOTATION) != 0
+ && ((access & ACCESS_CLASS) != 0))
+ {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ANNOTATION");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_ABSTRACT) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_ABSTRACT");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_INTERFACE) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_INTERFACE");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_STRICT) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_STRICT");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_SYNTHETIC");
+ first = false;
+ }
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ if (!first) {
+ buf.append(" + ");
+ }
+ buf.append("ACC_DEPRECATED");
+ first = false;
+ }
+ if (first) {
+ buf.append("0");
+ }
+ }
+
+ /**
+ * Appends a string representation of the given constant to the given
+ * buffer.
+ *
+ * @param buf a string buffer.
+ * @param cst an {@link java.lang.Integer Integer}, {@link java.lang.Float
+ * Float}, {@link java.lang.Long Long},
+ * {@link java.lang.Double Double} or {@link String String} object.
+ * May be <tt>null</tt>.
+ */
+ static void appendConstant(final StringBuffer buf, final Object cst) {
+ if (cst == null) {
+ buf.append("null");
+ } else if (cst instanceof String) {
+ AbstractVisitor.appendString(buf, (String) cst);
+ } else if (cst instanceof Type) {
+ buf.append("Type.getType(\"")
+ .append(((Type) cst).getDescriptor())
+ .append("\")");
+ } else if (cst instanceof Integer) {
+ buf.append("new Integer(").append(cst).append(")");
+ } else if (cst instanceof Float) {
+ buf.append("new Float(\"").append(cst).append("\")");
+ } else if (cst instanceof Long) {
+ buf.append("new Long(").append(cst).append("L)");
+ } else if (cst instanceof Double) {
+ buf.append("new Double(\"").append(cst).append("\")");
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierFieldVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierFieldVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierFieldVisitor.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,50 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.FieldVisitor;
+
+/**
+ * A {@link FieldVisitor} that prints the ASM code that generates the fields it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class ASMifierFieldVisitor extends ASMifierAbstractVisitor implements
+ FieldVisitor
+{
+
+ /**
+ * Constructs a new {@link ASMifierFieldVisitor}.
+ */
+ public ASMifierFieldVisitor() {
+ super("fv");
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierMethodVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierMethodVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/ASMifierMethodVisitor.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,347 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+
+import java.util.HashMap;
+
+/**
+ * A {@link MethodVisitor} that prints the ASM code that generates the methods
+ * it visits.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ASMifierMethodVisitor extends ASMifierAbstractVisitor implements
+ MethodVisitor
+{
+
+ /**
+ * Constructs a new {@link ASMifierMethodVisitor} object.
+ */
+ public ASMifierMethodVisitor() {
+ super("mv");
+ this.labelNames = new HashMap();
+ }
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ buf.setLength(0);
+ buf.append("{\n").append("av0 = mv.visitAnnotationDefault();\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter,
+ final String desc,
+ final boolean visible)
+ {
+ buf.setLength(0);
+ buf.append("{\n")
+ .append("av0 = mv.visitParameterAnnotation(")
+ .append(parameter)
+ .append(", ");
+ appendConstant(desc);
+ buf.append(", ").append(visible).append(");\n");
+ text.add(buf.toString());
+ ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
+ text.add(av.getText());
+ text.add("}\n");
+ return av;
+ }
+
+ public void visitCode() {
+ text.add("mv.visitCode();\n");
+ }
+
+ public void visitInsn(final int opcode) {
+ buf.setLength(0);
+ buf.append("mv.visitInsn(").append(OPCODES[opcode]).append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitIntInsn(final int opcode, final int operand) {
+ buf.setLength(0);
+ buf.append("mv.visitIntInsn(")
+ .append(OPCODES[opcode])
+ .append(", ")
+ .append(opcode == Opcodes.NEWARRAY
+ ? TYPES[operand]
+ : Integer.toString(operand))
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitVarInsn(final int opcode, final int var) {
+ buf.setLength(0);
+ buf.append("mv.visitVarInsn(")
+ .append(OPCODES[opcode])
+ .append(", ")
+ .append(var)
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitTypeInsn(final int opcode, final String desc) {
+ buf.setLength(0);
+ buf.append("mv.visitTypeInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitFieldInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("mv.visitFieldInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(owner);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ buf.setLength(0);
+ buf.append("mv.visitMethodInsn(").append(OPCODES[opcode]).append(", ");
+ appendConstant(owner);
+ buf.append(", ");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitJumpInsn(final int opcode, final Label label) {
+ buf.setLength(0);
+ declareLabel(label);
+ buf.append("mv.visitJumpInsn(").append(OPCODES[opcode]).append(", ");
+ appendLabel(label);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLabel(final Label label) {
+ buf.setLength(0);
+ declareLabel(label);
+ buf.append("mv.visitLabel(");
+ appendLabel(label);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLdcInsn(final Object cst) {
+ buf.setLength(0);
+ buf.append("mv.visitLdcInsn(");
+ appendConstant(cst);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitIincInsn(final int var, final int increment) {
+ buf.setLength(0);
+ buf.append("mv.visitIincInsn(")
+ .append(var)
+ .append(", ")
+ .append(increment)
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitTableSwitchInsn(
+ final int min,
+ final int max,
+ final Label dflt,
+ final Label labels[])
+ {
+ buf.setLength(0);
+ for (int i = 0; i < labels.length; ++i) {
+ declareLabel(labels[i]);
+ }
+ declareLabel(dflt);
+
+ buf.append("mv.visitTableSwitchInsn(")
+ .append(min)
+ .append(", ")
+ .append(max)
+ .append(", ");
+ appendLabel(dflt);
+ buf.append(", new Label[] {");
+ for (int i = 0; i < labels.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendLabel(labels[i]);
+ }
+ buf.append(" });\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLookupSwitchInsn(
+ final Label dflt,
+ final int keys[],
+ final Label labels[])
+ {
+ buf.setLength(0);
+ for (int i = 0; i < labels.length; ++i) {
+ declareLabel(labels[i]);
+ }
+ declareLabel(dflt);
+
+ buf.append("mv.visitLookupSwitchInsn(");
+ appendLabel(dflt);
+ buf.append(", new int[] {");
+ for (int i = 0; i < keys.length; ++i) {
+ buf.append(i == 0 ? " " : ", ").append(keys[i]);
+ }
+ buf.append(" }, new Label[] {");
+ for (int i = 0; i < labels.length; ++i) {
+ buf.append(i == 0 ? " " : ", ");
+ appendLabel(labels[i]);
+ }
+ buf.append(" });\n");
+ text.add(buf.toString());
+ }
+
+ public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ buf.setLength(0);
+ buf.append("mv.visitMultiANewArrayInsn(");
+ appendConstant(desc);
+ buf.append(", ").append(dims).append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitTryCatchBlock(
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ buf.setLength(0);
+ declareLabel(start);
+ declareLabel(end);
+ declareLabel(handler);
+ buf.append("mv.visitTryCatchBlock(");
+ appendLabel(start);
+ buf.append(", ");
+ appendLabel(end);
+ buf.append(", ");
+ appendLabel(handler);
+ buf.append(", ");
+ appendConstant(type);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLocalVariable(
+ final String name,
+ final String desc,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ buf.setLength(0);
+ buf.append("mv.visitLocalVariable(");
+ appendConstant(name);
+ buf.append(", ");
+ appendConstant(desc);
+ buf.append(", ");
+ appendConstant(signature);
+ buf.append(", ");
+ appendLabel(start);
+ buf.append(", ");
+ appendLabel(end);
+ buf.append(", ").append(index).append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitLineNumber(final int line, final Label start) {
+ buf.setLength(0);
+ buf.append("mv.visitLineNumber(").append(line).append(", ");
+ appendLabel(start);
+ buf.append(");\n");
+ text.add(buf.toString());
+ }
+
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ buf.setLength(0);
+ buf.append("mv.visitMaxs(")
+ .append(maxStack)
+ .append(", ")
+ .append(maxLocals)
+ .append(");\n");
+ text.add(buf.toString());
+ }
+
+ /**
+ * Appends a declaration of the given label to {@link #buf buf}. This
+ * declaration is of the form "Label lXXX = new Label();". Does nothing if
+ * the given label has already been declared.
+ *
+ * @param l a label.
+ */
+ private void declareLabel(final Label l) {
+ String name = (String) labelNames.get(l);
+ if (name == null) {
+ name = "l" + labelNames.size();
+ labelNames.put(l, name);
+ buf.append("Label ").append(name).append(" = new Label();\n");
+ }
+ }
+
+ /**
+ * Appends the name of the given label to {@link #buf buf}. The given label
+ * <i>must</i> already have a name. One way to ensure this is to always
+ * call {@link #declareLabel declared} before calling this method.
+ *
+ * @param l a label.
+ */
+ private void appendLabel(final Label l) {
+ buf.append((String) labelNames.get(l));
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/AbstractVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/AbstractVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/AbstractVisitor.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,201 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.util;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.util.attrs.ASMStackMapAttribute;
+import org.objectweb.asm.util.attrs.ASMStackMapTableAttribute;
+
+/**
+ * An abstract visitor.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class AbstractVisitor {
+
+ /**
+ * The names of the Java Virtual Machine opcodes.
+ */
+ public final static String[] OPCODES;
+ /**
+ * Types for <code>operand</code> parameter of the
+ * {@link org.objectweb.asm.MethodVisitor#visitIntInsn} method when
+ * <code>opcode</code> is <code>NEWARRAY</code>.
+ */
+ public final static String[] TYPES;
+
+ static {
+ String s = "NOP,ACONST_NULL,ICONST_M1,ICONST_0,ICONST_1,ICONST_2,"
+ + "ICONST_3,ICONST_4,ICONST_5,LCONST_0,LCONST_1,FCONST_0,"
+ + "FCONST_1,FCONST_2,DCONST_0,DCONST_1,BIPUSH,SIPUSH,LDC,,,"
+ + "ILOAD,LLOAD,FLOAD,DLOAD,ALOAD,,,,,,,,,,,,,,,,,,,,,IALOAD,"
+ + "LALOAD,FALOAD,DALOAD,AALOAD,BALOAD,CALOAD,SALOAD,ISTORE,"
+ + "LSTORE,FSTORE,DSTORE,ASTORE,,,,,,,,,,,,,,,,,,,,,IASTORE,"
+ + "LASTORE,FASTORE,DASTORE,AASTORE,BASTORE,CASTORE,SASTORE,POP,"
+ + "POP2,DUP,DUP_X1,DUP_X2,DUP2,DUP2_X1,DUP2_X2,SWAP,IADD,LADD,"
+ + "FADD,DADD,ISUB,LSUB,FSUB,DSUB,IMUL,LMUL,FMUL,DMUL,IDIV,LDIV,"
+ + "FDIV,DDIV,IREM,LREM,FREM,DREM,INEG,LNEG,FNEG,DNEG,ISHL,LSHL,"
+ + "ISHR,LSHR,IUSHR,LUSHR,IAND,LAND,IOR,LOR,IXOR,LXOR,IINC,I2L,"
+ + "I2F,I2D,L2I,L2F,L2D,F2I,F2L,F2D,D2I,D2L,D2F,I2B,I2C,I2S,LCMP,"
+ + "FCMPL,FCMPG,DCMPL,DCMPG,IFEQ,IFNE,IFLT,IFGE,IFGT,IFLE,"
+ + "IF_ICMPEQ,IF_ICMPNE,IF_ICMPLT,IF_ICMPGE,IF_ICMPGT,IF_ICMPLE,"
+ + "IF_ACMPEQ,IF_ACMPNE,GOTO,JSR,RET,TABLESWITCH,LOOKUPSWITCH,"
+ + "IRETURN,LRETURN,FRETURN,DRETURN,ARETURN,RETURN,GETSTATIC,"
+ + "PUTSTATIC,GETFIELD,PUTFIELD,INVOKEVIRTUAL,INVOKESPECIAL,"
+ + "INVOKESTATIC,INVOKEINTERFACE,,NEW,NEWARRAY,ANEWARRAY,"
+ + "ARRAYLENGTH,ATHROW,CHECKCAST,INSTANCEOF,MONITORENTER,"
+ + "MONITOREXIT,,MULTIANEWARRAY,IFNULL,IFNONNULL,";
+ OPCODES = new String[200];
+ int i = 0;
+ int j = 0;
+ int l;
+ while ((l = s.indexOf(',', j)) > 0) {
+ OPCODES[i++] = j + 1 == l ? null : s.substring(j, l);
+ j = l + 1;
+ }
+
+ s = "T_BOOLEAN,T_CHAR,T_FLOAT,T_DOUBLE,T_BYTE,T_SHORT,T_INT,T_LONG,";
+ TYPES = new String[12];
+ j = 0;
+ i = 4;
+ while ((l = s.indexOf(',', j)) > 0) {
+ TYPES[i++] = s.substring(j, l);
+ j = l + 1;
+ }
+ }
+
+ /**
+ * The text to be printed. Since the code of methods is not necessarily
+ * visited in sequential order, one method after the other, but can be
+ * interlaced (some instructions from method one, then some instructions
+ * from method two, then some instructions from method one again...), it is
+ * not possible to print the visited instructions directly to a sequential
+ * stream. A class is therefore printed in a two steps process: a string
+ * tree is constructed during the visit, and printed to a sequential stream
+ * at the end of the visit. This string tree is stored in this field, as a
+ * string list that can contain other string lists, which can themselves
+ * contain other string lists, and so on.
+ */
+ public final List text;
+
+ /**
+ * A buffer that can be used to create strings.
+ */
+ protected final StringBuffer buf;
+
+ /**
+ * Constructs a new {@link AbstractVisitor}.
+ */
+ protected AbstractVisitor() {
+ this.text = new ArrayList();
+ this.buf = new StringBuffer();
+ }
+
+ /**
+ * Returns the text printed by this visitor.
+ *
+ * @return the text printed by this visitor.
+ */
+ public List getText() {
+ return text;
+ }
+
+ /**
+ * Appends a quoted string to a given buffer.
+ *
+ * @param buf the buffer where the string must be added.
+ * @param s the string to be added.
+ */
+ public static void appendString(final StringBuffer buf, final String s) {
+ buf.append("\"");
+ for (int i = 0; i < s.length(); ++i) {
+ char c = s.charAt(i);
+ if (c == '\n') {
+ buf.append("\\n");
+ } else if (c == '\r') {
+ buf.append("\\r");
+ } else if (c == '\\') {
+ buf.append("\\\\");
+ } else if (c == '"') {
+ buf.append("\\\"");
+ } else if (c < 0x20 || c > 0x7f) {
+ buf.append("\\u");
+ if (c < 0x10) {
+ buf.append("000");
+ } else if (c < 0x100) {
+ buf.append("00");
+ } else if (c < 0x1000) {
+ buf.append("0");
+ }
+ buf.append(Integer.toString(c, 16));
+ } else {
+ buf.append(c);
+ }
+ }
+ buf.append("\"");
+ }
+
+ /**
+ * Prints the given string tree.
+ *
+ * @param pw the writer to be used to print the tree.
+ * @param l a string tree, i.e., a string list that can contain other string
+ * lists, and so on recursively.
+ */
+ void printList(final PrintWriter pw, final List l) {
+ for (int i = 0; i < l.size(); ++i) {
+ Object o = l.get(i);
+ if (o instanceof List) {
+ printList(pw, (List) o);
+ } else {
+ pw.print(o.toString());
+ }
+ }
+ }
+
+ /**
+ * Returns the default {@link ASMifiable} prototypes.
+ *
+ * @return the default {@link ASMifiable} prototypes.
+ */
+ public static Attribute[] getDefaultAttributes() {
+ try {
+ return new Attribute[] {
+ new ASMStackMapAttribute(),
+ new ASMStackMapTableAttribute() };
+ } catch (Exception e) {
+ return new Attribute[0];
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/util/CheckAnnotationAdapter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/util/CheckAnnotationAdapter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/util/CheckAnnotationAdapter.java 2007-01-07 13:55:15 UTC (rev 3034)
@@ -0,0 +1,125 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with o...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:53:12
|
Revision: 3033
http://jnode.svn.sourceforge.net/jnode/?rev=3033&view=rev
Author: lsantha
Date: 2007-01-07 05:53:11 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/tree/AbstractInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/AnnotationNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/ClassNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/IincInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/InnerClassNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/InsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/IntInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/JumpInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/LabelNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/LdcInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/LineNumberNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/LocalVariableNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/LookupSwitchInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/MemberNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/MethodInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/MethodNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/MultiANewArrayInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/TableSwitchInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/TryCatchBlockNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/TypeInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/VarInsnNode.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/AbstractInsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/AbstractInsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/AbstractInsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,143 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a bytecode instruction.
+ *
+ * @author Eric Bruneton
+ */
+public abstract class AbstractInsnNode {
+
+ /**
+ * The type of {@link InsnNode} instructions.
+ */
+ public final static int INSN = 0;
+
+ /**
+ * The type of {@link IntInsnNode} instructions.
+ */
+ public final static int INT_INSN = 1;
+
+ /**
+ * The type of {@link VarInsnNode} instructions.
+ */
+ public final static int VAR_INSN = 2;
+
+ /**
+ * The type of {@link TypeInsnNode} instructions.
+ */
+ public final static int TYPE_INSN = 3;
+
+ /**
+ * The type of {@link FieldInsnNode} instructions.
+ */
+ public final static int FIELD_INSN = 4;
+
+ /**
+ * The type of {@link MethodInsnNode} instructions.
+ */
+ public final static int METHOD_INSN = 5;
+
+ /**
+ * The type of {@link JumpInsnNode} instructions.
+ */
+ public final static int JUMP_INSN = 6;
+
+ /**
+ * The type of {@link LabelNode} "instructions".
+ */
+ public final static int LABEL = 7;
+
+ /**
+ * The type of {@link LdcInsnNode} instructions.
+ */
+ public final static int LDC_INSN = 8;
+
+ /**
+ * The type of {@link IincInsnNode} instructions.
+ */
+ public final static int IINC_INSN = 9;
+
+ /**
+ * The type of {@link TableSwitchInsnNode} instructions.
+ */
+ public final static int TABLESWITCH_INSN = 10;
+
+ /**
+ * The type of {@link LookupSwitchInsnNode} instructions.
+ */
+ public final static int LOOKUPSWITCH_INSN = 11;
+
+ /**
+ * The type of {@link MultiANewArrayInsnNode} instructions.
+ */
+ public final static int MULTIANEWARRAY_INSN = 12;
+
+ /**
+ * The opcode of this instruction.
+ */
+ protected int opcode;
+
+ /**
+ * Constructs a new {@link AbstractInsnNode}.
+ *
+ * @param opcode the opcode of the instruction to be constructed.
+ */
+ protected AbstractInsnNode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ /**
+ * Returns the opcode of this instruction.
+ *
+ * @return the opcode of this instruction.
+ */
+ public int getOpcode() {
+ return opcode;
+ }
+
+ /**
+ * Returns the type of this instruction.
+ *
+ * @return the type of this instruction, i.e. one the constants defined in
+ * this class.
+ */
+ public abstract int getType();
+
+ /**
+ * Makes the given code visitor visit this instruction.
+ *
+ * @param cv a code visitor.
+ */
+ public abstract void accept(final MethodVisitor cv);
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/AnnotationNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/AnnotationNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/AnnotationNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,187 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+ * A node that represents an annotationn.
+ *
+ * @author Eric Bruneton
+ */
+public class AnnotationNode implements AnnotationVisitor {
+
+ /**
+ * The class descriptor of the annotation class.
+ */
+ public String desc;
+
+ /**
+ * The name value pairs of this annotation. Each name value pair is stored
+ * as two consecutive elements in the list. The name is a {@link String},
+ * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
+ * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
+ * {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
+ * two elements String array (for enumeration values), a
+ * {@link AnnotationNode}, or a {@link List} of values of one of the
+ * preceding types. The list may be <tt>null</tt> if there is no name
+ * value pair.
+ */
+ public List values;
+
+ /**
+ * Constructs a new {@link AnnotationNode}.
+ *
+ * @param desc the class descriptor of the annotation class.
+ */
+ public AnnotationNode(final String desc) {
+ this.desc = desc;
+ }
+
+ /**
+ * Constructs a new {@link AnnotationNode} to visit an array value.
+ *
+ * @param values where the visited values must be stored.
+ */
+ AnnotationNode(final List values) {
+ this.values = values;
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the AnnotationVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(final String name, final Object value) {
+ if (values == null) {
+ values = new ArrayList(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ values.add(value);
+ }
+
+ public void visitEnum(
+ final String name,
+ final String desc,
+ final String value)
+ {
+ if (values == null) {
+ values = new ArrayList(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ values.add(new String[] { desc, value });
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String name,
+ final String desc)
+ {
+ if (values == null) {
+ values = new ArrayList(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ AnnotationNode annotation = new AnnotationNode(desc);
+ values.add(annotation);
+ return annotation;
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ if (values == null) {
+ values = new ArrayList(this.desc != null ? 2 : 1);
+ }
+ if (this.desc != null) {
+ values.add(name);
+ }
+ List array = new ArrayList();
+ values.add(array);
+ return new AnnotationNode(array);
+ }
+
+ public void visitEnd() {
+ }
+
+ // ------------------------------------------------------------------------
+ // Accept methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Makes the given visitor visit this annotation.
+ *
+ * @param av an annotation visitor.
+ */
+ public void accept(final AnnotationVisitor av) {
+ if (values != null) {
+ for (int i = 0; i < values.size(); i += 2) {
+ String name = (String) values.get(i);
+ Object value = values.get(i + 1);
+ accept(av, name, value);
+ }
+ }
+ av.visitEnd();
+ }
+
+ /**
+ * Makes the given visitor visit a given annotation value.
+ *
+ * @param av an annotation visitor.
+ * @param name the value name.
+ * @param value the actual value.
+ */
+ static void accept(
+ final AnnotationVisitor av,
+ final String name,
+ final Object value)
+ {
+ if (value instanceof String[]) {
+ String[] typeconst = (String[]) value;
+ av.visitEnum(name, typeconst[0], typeconst[1]);
+ } else if (value instanceof AnnotationNode) {
+ AnnotationNode an = (AnnotationNode) value;
+ an.accept(av.visitAnnotation(name, an.desc));
+ } else if (value instanceof List) {
+ AnnotationVisitor v = av.visitArray(name);
+ List array = (List) value;
+ for (int j = 0; j < array.size(); ++j) {
+ accept(v, null, array.get(j));
+ }
+ v.visitEnd();
+ } else {
+ av.visit(name, value);
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/ClassNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/ClassNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/ClassNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,283 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.FieldVisitor;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * A node that represents a class.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassNode extends MemberNode implements ClassVisitor {
+
+ /**
+ * The class version.
+ */
+ public int version;
+
+ /**
+ * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This
+ * field also indicates if the class is deprecated.
+ */
+ public int access;
+
+ /**
+ * The internal name of the class (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ */
+ public String name;
+
+ /**
+ * The signature of the class. Mayt be <tt>null</tt>.
+ */
+ public String signature;
+
+ /**
+ * The internal of name of the super class (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). For
+ * interfaces, the super class is {@link Object}. May be <tt>null</tt>,
+ * but only for the {@link Object} class.
+ */
+ public String superName;
+
+ /**
+ * The internal names of the class's interfaces (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This
+ * list is a list of {@link String} objects.
+ */
+ public List interfaces;
+
+ /**
+ * The name of the source file from which this class was compiled. May be
+ * <tt>null</tt>.
+ */
+ public String sourceFile;
+
+ /**
+ * Debug information to compute the correspondance between source and
+ * compiled elements of the class. May be <tt>null</tt>.
+ */
+ public String sourceDebug;
+
+ /**
+ * The internal name of the enclosing class of the class. May be
+ * <tt>null</tt>.
+ */
+ public String outerClass;
+
+ /**
+ * The name of the method that contains the class, or <tt>null</tt> if the
+ * class is not enclosed in a method.
+ */
+ public String outerMethod;
+
+ /**
+ * The descriptor of the method that contains the class, or <tt>null</tt>
+ * if the class is not enclosed in a method.
+ */
+ public String outerMethodDesc;
+
+ /**
+ * Informations about the inner classes of this class. This list is a list
+ * of {@link InnerClassNode} objects.
+ *
+ * @associates org.objectweb.asm.tree.InnerClassNode
+ */
+ public List innerClasses;
+
+ /**
+ * The fields of this class. This list is a list of {@link FieldNode}
+ * objects.
+ *
+ * @associates org.objectweb.asm.tree.FieldNode
+ */
+ public List fields;
+
+ /**
+ * The methods of this class. This list is a list of {@link MethodNode}
+ * objects.
+ *
+ * @associates org.objectweb.asm.tree.MethodNode
+ */
+ public List methods;
+
+ /**
+ * Constructs a new {@link ClassNode}.
+ */
+ public ClassNode() {
+ this.interfaces = new ArrayList();
+ this.innerClasses = new ArrayList();
+ this.fields = new ArrayList();
+ this.methods = new ArrayList();
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the ClassVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ this.version = version;
+ this.access = access;
+ this.name = name;
+ this.signature = signature;
+ this.superName = superName;
+ if (interfaces != null) {
+ this.interfaces.addAll(Arrays.asList(interfaces));
+ }
+ }
+
+ public void visitSource(final String file, final String debug) {
+ sourceFile = file;
+ sourceDebug = debug;
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ outerClass = owner;
+ outerMethod = name;
+ outerMethodDesc = desc;
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ InnerClassNode icn = new InnerClassNode(name,
+ outerName,
+ innerName,
+ access);
+ innerClasses.add(icn);
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ FieldNode fn = new FieldNode(access, name, desc, signature, value);
+ fields.add(fn);
+ return fn;
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ MethodNode mn = new MethodNode(access,
+ name,
+ desc,
+ signature,
+ exceptions);
+ methods.add(mn);
+ return mn;
+ }
+
+ public void visitEnd() {
+ }
+
+ // ------------------------------------------------------------------------
+ // Accept method
+ // ------------------------------------------------------------------------
+
+ /**
+ * Makes the given class visitor visit this class.
+ *
+ * @param cv a class visitor.
+ */
+ public void accept(final ClassVisitor cv) {
+ // visits header
+ String[] interfaces = new String[this.interfaces.size()];
+ this.interfaces.toArray(interfaces);
+ cv.visit(version, access, name, signature, superName, interfaces);
+ // visits source
+ if (sourceFile != null || sourceDebug != null) {
+ cv.visitSource(sourceFile, sourceDebug);
+ }
+ // visits outer class
+ if (outerClass != null) {
+ cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
+ }
+ // visits attributes
+ int i, n;
+ n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i);
+ an.accept(cv.visitAnnotation(an.desc, true));
+ }
+ n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i);
+ an.accept(cv.visitAnnotation(an.desc, false));
+ }
+ n = attrs == null ? 0 : attrs.size();
+ for (i = 0; i < n; ++i) {
+ cv.visitAttribute((Attribute) attrs.get(i));
+ }
+ // visits inner classes
+ for (i = 0; i < innerClasses.size(); ++i) {
+ ((InnerClassNode) innerClasses.get(i)).accept(cv);
+ }
+ // visits fields
+ for (i = 0; i < fields.size(); ++i) {
+ ((FieldNode) fields.get(i)).accept(cv);
+ }
+ // visits methods
+ for (i = 0; i < methods.size(); ++i) {
+ ((MethodNode) methods.get(i)).accept(cv);
+ }
+ // visits end
+ cv.visitEnd();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldInsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldInsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldInsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,97 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a field instruction. A field instruction is an
+ * instruction that loads or stores the value of a field of an object.
+ *
+ * @author Eric Bruneton
+ */
+public class FieldInsnNode extends AbstractInsnNode {
+
+ /**
+ * The internal name of the field's owner class (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ */
+ public String owner;
+
+ /**
+ * The field's name.
+ */
+ public String name;
+
+ /**
+ * The field's descriptor (see {@link org.objectweb.asm.Type}).
+ */
+ public String desc;
+
+ /**
+ * Constructs a new {@link FieldInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This
+ * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+ * @param owner the internal name of the field's owner class (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * @param name the field's name.
+ * @param desc the field's descriptor (see {@link org.objectweb.asm.Type}).
+ */
+ public FieldInsnNode(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ super(opcode);
+ this.owner = owner;
+ this.name = name;
+ this.desc = desc;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be GETSTATIC,
+ * PUTSTATIC, GETFIELD or PUTFIELD.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ public void accept(final MethodVisitor cv) {
+ cv.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ public int getType() {
+ return FIELD_INSN;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/FieldNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,123 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+
+/**
+ * A node that represents a field.
+ *
+ * @author Eric Bruneton
+ */
+public class FieldNode extends MemberNode implements FieldVisitor {
+
+ /**
+ * The field's access flags (see {@link org.objectweb.asm.Opcodes}). This
+ * field also indicates if the field is synthetic and/or deprecated.
+ */
+ public int access;
+
+ /**
+ * The field's name.
+ */
+ public String name;
+
+ /**
+ * The field's descriptor (see {@link org.objectweb.asm.Type}).
+ */
+ public String desc;
+
+ /**
+ * The field's signature. May be <tt>null</tt>.
+ */
+ public String signature;
+
+ /**
+ * The field's initial value. This field, which may be <tt>null</tt> if
+ * the field does not have an initial value, must be an {@link Integer}, a
+ * {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
+ */
+ public Object value;
+
+ /**
+ * Constructs a new {@link FieldNode}.
+ *
+ * @param access the field's access flags (see
+ * {@link org.objectweb.asm.Opcodes}). This parameter also indicates
+ * if the field is synthetic and/or deprecated.
+ * @param name the field's name.
+ * @param desc the field's descriptor (see {@link org.objectweb.asm.Type}).
+ * @param signature the field's signature.
+ * @param value the field's initial value. This parameter, which may be
+ * <tt>null</tt> if the field does not have an initial value, must
+ * be an {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String}.
+ */
+ public FieldNode(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ this.access = access;
+ this.name = name;
+ this.desc = desc;
+ this.signature = signature;
+ this.value = value;
+ }
+
+ /**
+ * Makes the given class visitor visit this field.
+ *
+ * @param cv a class visitor.
+ */
+ public void accept(final ClassVisitor cv) {
+ FieldVisitor fv = cv.visitField(access, name, desc, signature, value);
+ int i, n;
+ n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i);
+ an.accept(fv.visitAnnotation(an.desc, true));
+ }
+ n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+ for (i = 0; i < n; ++i) {
+ AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i);
+ an.accept(fv.visitAnnotation(an.desc, false));
+ }
+ n = attrs == null ? 0 : attrs.size();
+ for (i = 0; i < n; ++i) {
+ fv.visitAttribute((Attribute) attrs.get(i));
+ }
+ fv.visitEnd();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/IincInsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/IincInsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/IincInsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,71 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents an IINC instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class IincInsnNode extends AbstractInsnNode {
+
+ /**
+ * Index of the local variable to be incremented.
+ */
+ public int var;
+
+ /**
+ * Amount to increment the local variable by.
+ */
+ public int incr;
+
+ /**
+ * Constructs a new {@link IincInsnNode}.
+ *
+ * @param var index of the local variable to be incremented.
+ * @param incr increment amount to increment the local variable by.
+ */
+ public IincInsnNode(final int var, final int incr) {
+ super(Opcodes.IINC);
+ this.var = var;
+ this.incr = incr;
+ }
+
+ public void accept(final MethodVisitor mv) {
+ mv.visitIincInsn(var, incr);
+ }
+
+ public int getType() {
+ return IINC_INSN;
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/InnerClassNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/InnerClassNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/InnerClassNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,101 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.ClassVisitor;
+
+/**
+ * A node that represents an inner class.
+ *
+ * @author Eric Bruneton
+ */
+public class InnerClassNode {
+
+ /**
+ * The internal name of an inner class (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ */
+ public String name;
+
+ /**
+ * The internal name of the class to which the inner class belongs (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May
+ * be <tt>null</tt>.
+ */
+ public String outerName;
+
+ /**
+ * The (simple) name of the inner class inside its enclosing class. May be
+ * <tt>null</tt> for anonymous inner classes.
+ */
+ public String innerName;
+
+ /**
+ * The access flags of the inner class as originally declared in the
+ * enclosing class.
+ */
+ public int access;
+
+ /**
+ * Constructs a new {@link InnerClassNode}.
+ *
+ * @param name the internal name of an inner class (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * @param outerName the internal name of the class to which the inner class
+ * belongs (see
+ * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
+ * May be <tt>null</tt>.
+ * @param innerName the (simple) name of the inner class inside its
+ * enclosing class. May be <tt>null</tt> for anonymous inner
+ * classes.
+ * @param access the access flags of the inner class as originally declared
+ * in the enclosing class.
+ */
+ public InnerClassNode(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ this.name = name;
+ this.outerName = outerName;
+ this.innerName = innerName;
+ this.access = access;
+ }
+
+ /**
+ * Makes the given class visitor visit this inner class.
+ *
+ * @param cv a class visitor.
+ */
+ public void accept(final ClassVisitor cv) {
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/InsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/InsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/InsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,96 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a zero operand instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class InsnNode extends AbstractInsnNode {
+
+ private final static InsnNode[] INSNS;
+
+ static {
+ INSNS = new InsnNode[255];
+ for (int i = 0; i < INSNS.length; ++i) {
+ INSNS[i] = new InsnNode(i);
+ }
+ }
+
+ /**
+ * Returns the {@link InsnNode} corresponding to the given opcode.
+ *
+ * @deprecated uses the constructor instead.
+ *
+ * @param opcode an instruction opcode.
+ * @return the {@link InsnNode} corresponding to the given opcode.
+ */
+ public final static InsnNode getByOpcode(final int opcode) {
+ return INSNS[opcode];
+ }
+
+ /**
+ * Constructs a new {@link InsnNode}.
+ *
+ * @param opcode the opcode of the instruction to be constructed. This
+ * opcode must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+ * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+ * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
+ * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE,
+ * FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2,
+ * DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD,
+ * FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
+ * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG,
+ * ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR,
+ * LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F,
+ * I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
+ * FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
+ * MONITORENTER, or MONITOREXIT.
+ */
+ public InsnNode(final int opcode) {
+ super(opcode);
+ }
+
+ /**
+ * Makes the given visitor visit this instruction.
+ *
+ * @param mv a method visitor.
+ */
+ public void accept(final MethodVisitor mv) {
+ mv.visitInsn(opcode);
+ }
+
+ public int getType() {
+ return INSN;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/IntInsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/IntInsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/IntInsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,75 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents an instruction with a single int operand.
+ *
+ * @author Eric Bruneton
+ */
+public class IntInsnNode extends AbstractInsnNode {
+
+ /**
+ * The operand of this instruction.
+ */
+ public int operand;
+
+ /**
+ * Constructs a new {@link IntInsnNode}.
+ *
+ * @param opcode the opcode of the instruction to be constructed. This
+ * opcode must be BIPUSH, SIPUSH or NEWARRAY.
+ * @param operand the operand of the instruction to be constructed.
+ */
+ public IntInsnNode(final int opcode, final int operand) {
+ super(opcode);
+ this.operand = operand;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be BIPUSH,
+ * SIPUSH or NEWARRAY.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ public void accept(final MethodVisitor mv) {
+ mv.visitIntInsn(opcode, operand);
+ }
+
+ public int getType() {
+ return INT_INSN;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/JumpInsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/JumpInsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/JumpInsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,84 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a jump instruction. A jump instruction is an
+ * instruction that may jump to another instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class JumpInsnNode extends AbstractInsnNode {
+
+ /**
+ * The operand of this instruction. This operand is a label that designates
+ * the instruction to which this instruction may jump.
+ */
+ public Label label;
+
+ /**
+ * Constructs a new {@link JumpInsnNode}.
+ *
+ * @param opcode the opcode of the type instruction to be constructed. This
+ * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+ * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
+ * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+ * @param label the operand of the instruction to be constructed. This
+ * operand is a label that designates the instruction to which the
+ * jump instruction may jump.
+ */
+ public JumpInsnNode(final int opcode, final Label label) {
+ super(opcode);
+ this.label = label;
+ }
+
+ /**
+ * Sets the opcode of this instruction.
+ *
+ * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE,
+ * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
+ * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR,
+ * IFNULL or IFNONNULL.
+ */
+ public void setOpcode(final int opcode) {
+ this.opcode = opcode;
+ }
+
+ public void accept(final MethodVisitor mv) {
+ mv.visitJumpInsn(opcode, label);
+ }
+
+ public int getType() {
+ return JUMP_INSN;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/LabelNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/LabelNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/LabelNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,54 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * An {@link AbstractInsnNode} that encapsulates a {@link Label}.
+ */
+public class LabelNode extends AbstractInsnNode {
+
+ public Label label;
+
+ public LabelNode(final Label label) {
+ super(-1);
+ this.label = label;
+ }
+
+ public void accept(final MethodVisitor cv) {
+ cv.visitLabel(label);
+ }
+
+ public int getType() {
+ return LABEL;
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/LdcInsnNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/LdcInsnNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/LdcInsnNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,68 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents an LDC instruction.
+ *
+ * @author Eric Bruneton
+ */
+public class LdcInsnNode extends AbstractInsnNode {
+
+ /**
+ * The constant to be loaded on the stack. This parameter must be a non null
+ * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a
+ * {@link String} or a {@link org.objectweb.asm.Type}.
+ */
+ public Object cst;
+
+ /**
+ * Constructs a new {@link LdcInsnNode}.
+ *
+ * @param cst the constant to be loaded on the stack. This parameter must be
+ * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+ * {@link Double} or a {@link String}.
+ */
+ public LdcInsnNode(final Object cst) {
+ super(Opcodes.LDC);
+ this.cst = cst;
+ }
+
+ public void accept(final MethodVisitor mv) {
+ mv.visitLdcInsn(cst);
+ }
+
+ public int getType() {
+ return LDC_INSN;
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/LineNumberNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/LineNumberNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/LineNumberNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,73 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A node that represents a line number declaration.
+ *
+ * @author Eric Bruneton
+ */
+public class LineNumberNode {
+
+ /**
+ * A line number. This number refers to the source file from which the class
+ * was compiled.
+ */
+ public int line;
+
+ /**
+ * The first instruction corresponding to this line number.
+ */
+ public Label start;
+
+ /**
+ * Constructs a new {@link LineNumberNode}.
+ *
+ * @param line a line number. This number refers to the source file from
+ * which the class was compiled.
+ * @param start the first instruction corresponding to this line number.
+ */
+ public LineNumberNode(final int line, final Label start) {
+ this.line = line;
+ this.start = start;
+ }
+
+ /**
+ * Makes the given visitor visit this line number declaration.
+ *
+ * @param mv a method visitor.
+ */
+ public void accept(final MethodVisitor mv) {
+ mv.visitLineNumber(line, start);
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/LocalVariableNode.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/LocalVariableNode.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/LocalVariableNode.java 2007-01-07 13:53:11 UTC (rev 3033)
@@ -0,0 +1,111 @@
+/***
+ * ASM: a very small and fast Java bytecode manip...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:45:47
|
Revision: 3032
http://jnode.svn.sourceforge.net/jnode/?rev=3032&view=rev
Author: lsantha
Date: 2007-01-07 05:45:46 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/tree/
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Analyzer.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/AnalyzerException.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicInterpreter.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicValue.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicVerifier.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowInterpreter.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowValue.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Frame.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/IntMap.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Interpreter.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/SimpleVerifier.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/SmallSet.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Subroutine.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Value.java
trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Analyzer.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Analyzer.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/Analyzer.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,416 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree.analysis;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.IincInsnNode;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LookupSwitchInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TableSwitchInsnNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.VarInsnNode;
+
+/**
+ * A semantic bytecode analyzer.
+ *
+ * @author Eric Bruneton
+ */
+public class Analyzer implements Opcodes {
+
+ private Interpreter interpreter;
+
+ private int n;
+
+ private IntMap indexes;
+
+ private List[] handlers;
+
+ private Frame[] frames;
+
+ private Subroutine[] subroutines;
+
+ private boolean[] queued;
+
+ private int[] queue;
+
+ private int top;
+
+ private boolean jsr;
+
+ /**
+ * Constructs a new {@link Analyzer}.
+ *
+ * @param interpreter the interpreter to be used to symbolically interpret
+ * the bytecode instructions.
+ */
+ public Analyzer(final Interpreter interpreter) {
+ this.interpreter = interpreter;
+ }
+
+ /**
+ * Analyzes the given method.
+ *
+ * @param owner the internal name of the class to which the method belongs.
+ * @param m the method to be analyzed.
+ * @return the symbolic state of the execution stack frame at each bytecode
+ * instruction of the method. The size of the returned array is
+ * equal to the number of instructions (and labels) of the method. A
+ * given frame is <tt>null</tt> if and only if the corresponding
+ * instruction cannot be reached (dead code).
+ * @throws AnalyzerException if a problem occurs during the analysis.
+ */
+ public Frame[] analyze(final String owner, final MethodNode m)
+ throws AnalyzerException
+ {
+ n = m.instructions.size();
+ indexes = new IntMap(2 * n);
+ handlers = new List[n];
+ frames = new Frame[n];
+ subroutines = new Subroutine[n];
+ queued = new boolean[n];
+ queue = new int[n];
+ top = 0;
+
+ // computes instruction indexes
+ for (int i = 0; i < n; ++i) {
+ Object insn = m.instructions.get(i);
+ if (insn instanceof LabelNode) {
+ insn = ((LabelNode) insn).label;
+ }
+ indexes.put(insn, i);
+ }
+
+ // computes exception handlers for each instruction
+ for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
+ TryCatchBlockNode tcb = (TryCatchBlockNode) m.tryCatchBlocks.get(i);
+ int begin = indexes.get(tcb.start);
+ int end = indexes.get(tcb.end);
+ for (int j = begin; j < end; ++j) {
+ List insnHandlers = handlers[j];
+ if (insnHandlers == null) {
+ insnHandlers = new ArrayList();
+ handlers[j] = insnHandlers;
+ }
+ insnHandlers.add(tcb);
+ }
+ }
+
+ // initializes the data structures for the control flow analysis
+ // algorithm
+ Frame current = newFrame(m.maxLocals, m.maxStack);
+ Frame handler = newFrame(m.maxLocals, m.maxStack);
+ Type[] args = Type.getArgumentTypes(m.desc);
+ int local = 0;
+ if ((m.access & ACC_STATIC) == 0) {
+ Type ctype = Type.getType("L" + owner + ";");
+ current.setLocal(local++, interpreter.newValue(ctype));
+ }
+ for (int i = 0; i < args.length; ++i) {
+ current.setLocal(local++, interpreter.newValue(args[i]));
+ if (args[i].getSize() == 2) {
+ current.setLocal(local++, interpreter.newValue(null));
+ }
+ }
+ while (local < m.maxLocals) {
+ current.setLocal(local++, interpreter.newValue(null));
+ }
+ merge(0, current, null);
+
+ // control flow analysis
+ while (top > 0) {
+ int insn = queue[--top];
+ Frame f = frames[insn];
+ Subroutine subroutine = subroutines[insn];
+ queued[insn] = false;
+
+ try {
+ Object o = m.instructions.get(insn);
+ jsr = false;
+
+ if (o instanceof LabelNode) {
+ merge(insn + 1, f, subroutine);
+ } else {
+ AbstractInsnNode insnNode = (AbstractInsnNode) o;
+ int insnOpcode = insnNode.getOpcode();
+
+ current.init(f).execute(insnNode, interpreter);
+ subroutine = subroutine == null ? null : subroutine.copy();
+
+ if (insnNode instanceof JumpInsnNode) {
+ JumpInsnNode j = (JumpInsnNode) insnNode;
+ if (insnOpcode != GOTO && insnOpcode != JSR) {
+ merge(insn + 1, current, subroutine);
+ }
+ if (insnOpcode == JSR) {
+ jsr = true;
+ merge(indexes.get(j.label),
+ current,
+ new Subroutine(j.label, m.maxLocals, j));
+ } else {
+ merge(indexes.get(j.label), current, subroutine);
+ }
+ } else if (insnNode instanceof LookupSwitchInsnNode) {
+ LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
+ merge(indexes.get(lsi.dflt), current, subroutine);
+ for (int j = 0; j < lsi.labels.size(); ++j) {
+ Label label = (Label) lsi.labels.get(j);
+ merge(indexes.get(label), current, subroutine);
+ }
+ } else if (insnNode instanceof TableSwitchInsnNode) {
+ TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
+ merge(indexes.get(tsi.dflt), current, subroutine);
+ for (int j = 0; j < tsi.labels.size(); ++j) {
+ Label label = (Label) tsi.labels.get(j);
+ merge(indexes.get(label), current, subroutine);
+ }
+ } else if (insnOpcode == RET) {
+ if (subroutine == null) {
+ throw new AnalyzerException("RET instruction outside of a sub routine");
+ }
+ for (int i = 0; i < subroutine.callers.size(); ++i) {
+ int caller = indexes.get(subroutine.callers.get(i));
+ merge(caller + 1,
+ frames[caller],
+ current,
+ subroutines[caller],
+ subroutine.access);
+ }
+ } else if (insnOpcode != ATHROW
+ && (insnOpcode < IRETURN || insnOpcode > RETURN))
+ {
+ if (subroutine != null) {
+ if (insnNode instanceof VarInsnNode) {
+ int var = ((VarInsnNode) insnNode).var;
+ subroutine.access[var] = true;
+ if (insnOpcode == LLOAD || insnOpcode == DLOAD
+ || insnOpcode == LSTORE
+ || insnOpcode == DSTORE)
+ {
+ subroutine.access[var + 1] = true;
+ }
+ } else if (insnNode instanceof IincInsnNode) {
+ int var = ((IincInsnNode) insnNode).var;
+ subroutine.access[var] = true;
+ }
+ }
+ merge(insn + 1, current, subroutine);
+ }
+ }
+
+ List insnHandlers = handlers[insn];
+ if (insnHandlers != null) {
+ for (int i = 0; i < insnHandlers.size(); ++i) {
+ TryCatchBlockNode tcb = (TryCatchBlockNode) insnHandlers.get(i);
+ Type type;
+ if (tcb.type == null) {
+ type = Type.getType("Ljava/lang/Throwable;");
+ } else {
+ type = Type.getType("L" + tcb.type + ";");
+ }
+ handler.init(f);
+ handler.clearStack();
+ handler.push(interpreter.newValue(type));
+ merge(indexes.get(tcb.handler), handler, subroutine);
+ }
+ }
+ } catch (AnalyzerException e) {
+ throw new AnalyzerException("Error at instruction " + insn
+ + ": " + e.getMessage(), e);
+ } catch(Exception e) {
+ throw new AnalyzerException("Error at instruction " + insn
+ + ": " + e.getMessage(), e);
+ }
+ }
+
+ return frames;
+ }
+
+ /**
+ * Returns the symbolic stack frame for each instruction of the last
+ * recently analyzed method.
+ *
+ * @return the symbolic state of the execution stack frame at each bytecode
+ * instruction of the method. The size of the returned array is
+ * equal to the number of instructions (and labels) of the method. A
+ * given frame is <tt>null</tt> if the corresponding instruction
+ * cannot be reached, or if an error occured during the analysis of
+ * the method.
+ */
+ public Frame[] getFrames() {
+ return frames;
+ }
+
+ /**
+ * Returns the index of the given instruction.
+ *
+ * @param insn a {@link Label} or {@link AbstractInsnNode} of the last
+ * recently analyzed method.
+ * @return the index of the given instruction of the last recently analyzed
+ * method.
+ */
+ public int getIndex(final Object insn) {
+ return indexes.get(insn);
+ }
+
+ /**
+ * Returns the exception handlers for the given instruction.
+ *
+ * @param insn the index of an instruction of the last recently analyzed
+ * method.
+ * @return a list of {@link TryCatchBlockNode} objects.
+ */
+ public List getHandlers(final int insn) {
+ return handlers[insn];
+ }
+
+ /**
+ * Constructs a new frame with the given size.
+ *
+ * @param nLocals the maximum number of local variables of the frame.
+ * @param nStack the maximum stack size of the frame.
+ * @return the created frame.
+ */
+ protected Frame newFrame(final int nLocals, final int nStack) {
+ return new Frame(nLocals, nStack);
+ }
+
+ /**
+ * Constructs a new frame that is identical to the given frame.
+ *
+ * @param src a frame.
+ * @return the created frame.
+ */
+ protected Frame newFrame(final Frame src) {
+ return new Frame(src);
+ }
+
+ /**
+ * Creates a control flow graph edge. The default implementation of this
+ * method does nothing. It can be overriden in order to construct the
+ * control flow graph of a method (this method is called by the
+ * {@link #analyze analyze} method during its visit of the method's code).
+ *
+ * @param frame the frame corresponding to an instruction.
+ * @param successor the frame corresponding to a successor instruction.
+ */
+ protected void newControlFlowEdge(final Frame frame, final Frame successor)
+ {
+ }
+
+ // -------------------------------------------------------------------------
+
+ private void merge(
+ final int insn,
+ final Frame frame,
+ final Subroutine subroutine) throws AnalyzerException
+ {
+ if (insn > n - 1) {
+ throw new AnalyzerException("Execution can fall off end of the code");
+ }
+
+ Frame oldFrame = frames[insn];
+ Subroutine oldSubroutine = subroutines[insn];
+ boolean changes = false;
+
+ if (oldFrame == null) {
+ frames[insn] = newFrame(frame);
+ changes = true;
+ } else {
+ changes |= oldFrame.merge(frame, interpreter);
+ }
+
+ newControlFlowEdge(frame, oldFrame);
+
+ if (oldSubroutine == null) {
+ if (subroutine != null) {
+ subroutines[insn] = subroutine.copy();
+ changes = true;
+ }
+ } else {
+ if (subroutine != null) {
+ changes |= oldSubroutine.merge(subroutine, !jsr);
+ }
+ }
+ if (changes && !queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+
+ private void merge(
+ final int insn,
+ final Frame beforeJSR,
+ final Frame afterRET,
+ final Subroutine subroutineBeforeJSR,
+ final boolean[] access) throws AnalyzerException
+ {
+ if (insn > n - 1) {
+ throw new AnalyzerException("Execution can fall off end of the code");
+ }
+
+ Frame oldFrame = frames[insn];
+ Subroutine oldSubroutine = subroutines[insn];
+ boolean changes = false;
+
+ afterRET.merge(beforeJSR, access);
+
+ if (oldFrame == null) {
+ frames[insn] = newFrame(afterRET);
+ changes = true;
+ } else {
+ changes |= oldFrame.merge(afterRET, access);
+ }
+
+ newControlFlowEdge(afterRET, oldFrame);
+
+ if (oldSubroutine == null) {
+ if (subroutineBeforeJSR != null) {
+ subroutines[insn] = subroutineBeforeJSR.copy();
+ changes = true;
+ }
+ } else {
+ if (subroutineBeforeJSR != null) {
+ changes |= oldSubroutine.merge(subroutineBeforeJSR, !jsr);
+ }
+ }
+ if (changes && !queued[insn]) {
+ queued[insn] = true;
+ queue[top++] = insn;
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/AnalyzerException.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/AnalyzerException.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/AnalyzerException.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,56 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree.analysis;
+
+/**
+ * Thrown if a problem occurs during the analysis of a method.
+ *
+ * @author Bing Ran
+ * @author Eric Bruneton
+ */
+public class AnalyzerException extends Exception {
+
+ public AnalyzerException(final String msg) {
+ super(msg);
+ }
+
+ public AnalyzerException(final String msg, final Throwable exception) {
+ super(msg, exception);
+ }
+
+ public AnalyzerException(
+ final String msg,
+ final Object expected,
+ final Value encountered)
+ {
+ super((msg == null ? "Expected " : msg + ": expected ") + expected
+ + ", but found " + encountered);
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicInterpreter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicInterpreter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicInterpreter.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,335 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree.analysis;
+
+import java.util.List;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.IntInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MultiANewArrayInsnNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+
+/**
+ * An {@link Interpreter} for {@link BasicValue} values.
+ *
+ * @author Eric Bruneton
+ * @author Bing Ran
+ */
+public class BasicInterpreter implements Opcodes, Interpreter {
+
+ public Value newValue(final Type type) {
+ if (type == null) {
+ return BasicValue.UNINITIALIZED_VALUE;
+ }
+ switch (type.getSort()) {
+ case Type.VOID:
+ return null;
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ return BasicValue.INT_VALUE;
+ case Type.FLOAT:
+ return BasicValue.FLOAT_VALUE;
+ case Type.LONG:
+ return BasicValue.LONG_VALUE;
+ case Type.DOUBLE:
+ return BasicValue.DOUBLE_VALUE;
+ case Type.ARRAY:
+ case Type.OBJECT:
+ return BasicValue.REFERENCE_VALUE;
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ }
+
+ public Value newOperation(final AbstractInsnNode insn) {
+ switch (insn.getOpcode()) {
+ case ACONST_NULL:
+ return newValue(Type.getType("Lnull;"));
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ return BasicValue.INT_VALUE;
+ case LCONST_0:
+ case LCONST_1:
+ return BasicValue.LONG_VALUE;
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ return BasicValue.FLOAT_VALUE;
+ case DCONST_0:
+ case DCONST_1:
+ return BasicValue.DOUBLE_VALUE;
+ case BIPUSH:
+ case SIPUSH:
+ return BasicValue.INT_VALUE;
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ if (cst instanceof Integer) {
+ return BasicValue.INT_VALUE;
+ } else if (cst instanceof Float) {
+ return BasicValue.FLOAT_VALUE;
+ } else if (cst instanceof Long) {
+ return BasicValue.LONG_VALUE;
+ } else if (cst instanceof Double) {
+ return BasicValue.DOUBLE_VALUE;
+ } else if (cst instanceof Type) {
+ return newValue(Type.getType("Ljava/lang/Class;"));
+ } else {
+ return newValue(Type.getType(cst.getClass()));
+ }
+ case JSR:
+ return BasicValue.RETURNADDRESS_VALUE;
+ case GETSTATIC:
+ return newValue(Type.getType(((FieldInsnNode) insn).desc));
+ case NEW:
+ return newValue(Type.getType("L" + ((TypeInsnNode) insn).desc
+ + ";"));
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ }
+
+ public Value copyOperation(final AbstractInsnNode insn, final Value value)
+ throws AnalyzerException
+ {
+ return value;
+ }
+
+ public Value unaryOperation(final AbstractInsnNode insn, final Value value)
+ throws AnalyzerException
+ {
+ switch (insn.getOpcode()) {
+ case INEG:
+ case IINC:
+ case L2I:
+ case F2I:
+ case D2I:
+ case I2B:
+ case I2C:
+ case I2S:
+ return BasicValue.INT_VALUE;
+ case FNEG:
+ case I2F:
+ case L2F:
+ case D2F:
+ return BasicValue.FLOAT_VALUE;
+ case LNEG:
+ case I2L:
+ case F2L:
+ case D2L:
+ return BasicValue.LONG_VALUE;
+ case DNEG:
+ case I2D:
+ case L2D:
+ case F2D:
+ return BasicValue.DOUBLE_VALUE;
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ case PUTSTATIC:
+ return null;
+ case GETFIELD:
+ return newValue(Type.getType(((FieldInsnNode) insn).desc));
+ case NEWARRAY:
+ switch (((IntInsnNode) insn).operand) {
+ case T_BOOLEAN:
+ return newValue(Type.getType("[Z"));
+ case T_CHAR:
+ return newValue(Type.getType("[C"));
+ case T_BYTE:
+ return newValue(Type.getType("[B"));
+ case T_SHORT:
+ return newValue(Type.getType("[S"));
+ case T_INT:
+ return newValue(Type.getType("[I"));
+ case T_FLOAT:
+ return newValue(Type.getType("[F"));
+ case T_DOUBLE:
+ return newValue(Type.getType("[D"));
+ case T_LONG:
+ return newValue(Type.getType("[J"));
+ default:
+ throw new AnalyzerException("Invalid array type");
+ }
+ case ANEWARRAY:
+ String desc = ((TypeInsnNode) insn).desc;
+ if (desc.charAt(0) == '[') {
+ return newValue(Type.getType("[" + desc));
+ } else {
+ return newValue(Type.getType("[L" + desc + ";"));
+ }
+ case ARRAYLENGTH:
+ return BasicValue.INT_VALUE;
+ case ATHROW:
+ return null;
+ case CHECKCAST:
+ desc = ((TypeInsnNode) insn).desc;
+ if (desc.charAt(0) == '[') {
+ return newValue(Type.getType(desc));
+ } else {
+ return newValue(Type.getType("L" + desc + ";"));
+ }
+ case INSTANCEOF:
+ return BasicValue.INT_VALUE;
+ case MONITORENTER:
+ case MONITOREXIT:
+ case IFNULL:
+ case IFNONNULL:
+ return null;
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ }
+
+ public Value binaryOperation(
+ final AbstractInsnNode insn,
+ final Value value1,
+ final Value value2) throws AnalyzerException
+ {
+ switch (insn.getOpcode()) {
+ case IALOAD:
+ case BALOAD:
+ case CALOAD:
+ case SALOAD:
+ case IADD:
+ case ISUB:
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ return BasicValue.INT_VALUE;
+ case FALOAD:
+ case FADD:
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ return BasicValue.FLOAT_VALUE;
+ case LALOAD:
+ case LADD:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ return BasicValue.LONG_VALUE;
+ case DALOAD:
+ case DADD:
+ case DSUB:
+ case DMUL:
+ case DDIV:
+ case DREM:
+ return BasicValue.DOUBLE_VALUE;
+ case AALOAD:
+ Type t = ((BasicValue) value1).getType();
+ if (t != null && t.getSort() == Type.ARRAY) {
+ return newValue(t.getElementType());
+ } else {
+ return BasicValue.REFERENCE_VALUE;
+ }
+ case LCMP:
+ case FCMPL:
+ case FCMPG:
+ case DCMPL:
+ case DCMPG:
+ return BasicValue.INT_VALUE;
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case PUTFIELD:
+ return null;
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ }
+
+ public Value ternaryOperation(
+ final AbstractInsnNode insn,
+ final Value value1,
+ final Value value2,
+ final Value value3) throws AnalyzerException
+ {
+ return null;
+ }
+
+ public Value naryOperation(final AbstractInsnNode insn, final List values)
+ throws AnalyzerException
+ {
+ if (insn.getOpcode() == MULTIANEWARRAY) {
+ return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
+ } else {
+ return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
+ }
+ }
+
+ public Value merge(final Value v, final Value w) {
+ if (!v.equals(w)) {
+ return BasicValue.UNINITIALIZED_VALUE;
+ }
+ return v;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicValue.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicValue.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicValue.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,105 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree.analysis;
+
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link Value} that is represented by its type in a seven types type sytem.
+ * This type system distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE,
+ * REFERENCE and RETURNADDRESS types.
+ *
+ * @author Eric Bruneton
+ */
+public class BasicValue implements Value {
+
+ public final static Value UNINITIALIZED_VALUE = new BasicValue(null);
+
+ public final static Value INT_VALUE = new BasicValue(Type.INT_TYPE);
+
+ public final static Value FLOAT_VALUE = new BasicValue(Type.FLOAT_TYPE);
+
+ public final static Value LONG_VALUE = new BasicValue(Type.LONG_TYPE);
+
+ public final static Value DOUBLE_VALUE = new BasicValue(Type.DOUBLE_TYPE);
+
+ public final static Value REFERENCE_VALUE = new BasicValue(Type.getType("Ljava/lang/Object;"));
+
+ public final static Value RETURNADDRESS_VALUE = new BasicValue(null);
+
+ private Type type;
+
+ public BasicValue(final Type type) {
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public int getSize() {
+ return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
+ }
+
+ public boolean isReference() {
+ return type != null
+ && (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY);
+ }
+
+ public boolean equals(final Object value) {
+ if (value == this) {
+ return true;
+ } else if (value instanceof BasicValue) {
+ if (type == null) {
+ return ((BasicValue) value).type == null;
+ } else {
+ return type.equals(((BasicValue) value).type);
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public int hashCode() {
+ return type == null ? 0 : type.hashCode();
+ }
+
+ public String toString() {
+ if (this == UNINITIALIZED_VALUE) {
+ return ".";
+ } else if (this == RETURNADDRESS_VALUE) {
+ return "A";
+ } else if (this == REFERENCE_VALUE) {
+ return "R";
+ } else {
+ return type.getDescriptor();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicVerifier.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicVerifier.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/BasicVerifier.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,428 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree.analysis;
+
+import java.util.List;
+
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/**
+ * An extended {@link BasicInterpreter} that checks that bytecode instructions
+ * are correctly used.
+ *
+ * @author Eric Bruneton
+ * @author Bing Ran
+ */
+public class BasicVerifier extends BasicInterpreter {
+
+ public Value copyOperation(final AbstractInsnNode insn, final Value value)
+ throws AnalyzerException
+ {
+ Value expected;
+ switch (insn.getOpcode()) {
+ case ILOAD:
+ case ISTORE:
+ expected = BasicValue.INT_VALUE;
+ break;
+ case FLOAD:
+ case FSTORE:
+ expected = BasicValue.FLOAT_VALUE;
+ break;
+ case LLOAD:
+ case LSTORE:
+ expected = BasicValue.LONG_VALUE;
+ break;
+ case DLOAD:
+ case DSTORE:
+ expected = BasicValue.DOUBLE_VALUE;
+ break;
+ case ALOAD:
+ if (!((BasicValue) value).isReference()) {
+ throw new AnalyzerException(null,
+ "an object reference",
+ value);
+ }
+ return value;
+ case ASTORE:
+ if (!((BasicValue) value).isReference()
+ && value != BasicValue.RETURNADDRESS_VALUE)
+ {
+ throw new AnalyzerException(null,
+ "an object reference or a return address",
+ value);
+ }
+ return value;
+ default:
+ return value;
+ }
+ // type is necessarily a primitive type here,
+ // so value must be == to expected value
+ if (value != expected) {
+ throw new AnalyzerException(null, expected, value);
+ }
+ return value;
+ }
+
+ public Value unaryOperation(final AbstractInsnNode insn, Value value)
+ throws AnalyzerException
+ {
+ Value expected;
+ switch (insn.getOpcode()) {
+ case INEG:
+ case IINC:
+ case I2F:
+ case I2L:
+ case I2D:
+ case I2B:
+ case I2C:
+ case I2S:
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ case IRETURN:
+ case NEWARRAY:
+ case ANEWARRAY:
+ expected = BasicValue.INT_VALUE;
+ break;
+ case FNEG:
+ case F2I:
+ case F2L:
+ case F2D:
+ case FRETURN:
+ expected = BasicValue.FLOAT_VALUE;
+ break;
+ case LNEG:
+ case L2I:
+ case L2F:
+ case L2D:
+ case LRETURN:
+ expected = BasicValue.LONG_VALUE;
+ break;
+ case DNEG:
+ case D2I:
+ case D2F:
+ case D2L:
+ case DRETURN:
+ expected = BasicValue.DOUBLE_VALUE;
+ break;
+ case GETFIELD:
+ expected = newValue(Type.getType("L"
+ + ((FieldInsnNode) insn).owner + ";"));
+ break;
+ case CHECKCAST:
+ if (!((BasicValue) value).isReference()) {
+ throw new AnalyzerException(null,
+ "an object reference",
+ value);
+ }
+ return super.unaryOperation(insn, value);
+ case ARRAYLENGTH:
+ if (!isArrayValue(value)) {
+ throw new AnalyzerException(null,
+ "an array reference",
+ value);
+ }
+ return super.unaryOperation(insn, value);
+ case ARETURN:
+ case ATHROW:
+ case INSTANCEOF:
+ case MONITORENTER:
+ case MONITOREXIT:
+ case IFNULL:
+ case IFNONNULL:
+ if (!((BasicValue) value).isReference()) {
+ throw new AnalyzerException(null,
+ "an object reference",
+ value);
+ }
+ return super.unaryOperation(insn, value);
+ case PUTSTATIC:
+ expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
+ break;
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ if (!isSubTypeOf(value, expected)) {
+ throw new AnalyzerException(null, expected, value);
+ }
+ return super.unaryOperation(insn, value);
+ }
+
+ public Value binaryOperation(
+ final AbstractInsnNode insn,
+ final Value value1,
+ final Value value2) throws AnalyzerException
+ {
+ Value expected1;
+ Value expected2;
+ switch (insn.getOpcode()) {
+ case IALOAD:
+ expected1 = newValue(Type.getType("[I"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case BALOAD:
+ if (!isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+ expected1 = newValue(Type.getType("[B"));
+ } else {
+ expected1 = newValue(Type.getType("[Z"));
+ }
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case CALOAD:
+ expected1 = newValue(Type.getType("[C"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case SALOAD:
+ expected1 = newValue(Type.getType("[S"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case LALOAD:
+ expected1 = newValue(Type.getType("[J"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case FALOAD:
+ expected1 = newValue(Type.getType("[F"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case DALOAD:
+ expected1 = newValue(Type.getType("[D"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case AALOAD:
+ expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case IADD:
+ case ISUB:
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ expected1 = BasicValue.INT_VALUE;
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case FADD:
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ case FCMPL:
+ case FCMPG:
+ expected1 = BasicValue.FLOAT_VALUE;
+ expected2 = BasicValue.FLOAT_VALUE;
+ break;
+ case LADD:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LAND:
+ case LOR:
+ case LXOR:
+ case LCMP:
+ expected1 = BasicValue.LONG_VALUE;
+ expected2 = BasicValue.LONG_VALUE;
+ break;
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ expected1 = BasicValue.LONG_VALUE;
+ expected2 = BasicValue.INT_VALUE;
+ break;
+ case DADD:
+ case DSUB:
+ case DMUL:
+ case DDIV:
+ case DREM:
+ case DCMPL:
+ case DCMPG:
+ expected1 = BasicValue.DOUBLE_VALUE;
+ expected2 = BasicValue.DOUBLE_VALUE;
+ break;
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ expected1 = BasicValue.REFERENCE_VALUE;
+ expected2 = BasicValue.REFERENCE_VALUE;
+ break;
+ case PUTFIELD:
+ FieldInsnNode fin = (FieldInsnNode) insn;
+ expected1 = newValue(Type.getType("L" + fin.owner + ";"));
+ expected2 = newValue(Type.getType(fin.desc));
+ break;
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ if (!isSubTypeOf(value1, expected1)) {
+ throw new AnalyzerException("First argument", expected1, value1);
+ } else if (!isSubTypeOf(value2, expected2)) {
+ throw new AnalyzerException("Second argument", expected2, value2);
+ }
+ if (insn.getOpcode() == AALOAD) {
+ return getElementValue(value1);
+ } else {
+ return super.binaryOperation(insn, value1, value2);
+ }
+ }
+
+ public Value ternaryOperation(
+ final AbstractInsnNode insn,
+ final Value value1,
+ final Value value2,
+ final Value value3) throws AnalyzerException
+ {
+ Value expected1;
+ Value expected3;
+ switch (insn.getOpcode()) {
+ case IASTORE:
+ expected1 = newValue(Type.getType("[I"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case BASTORE:
+ if (!isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+ expected1 = newValue(Type.getType("[B"));
+ } else {
+ expected1 = newValue(Type.getType("[Z"));
+ }
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case CASTORE:
+ expected1 = newValue(Type.getType("[C"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case SASTORE:
+ expected1 = newValue(Type.getType("[S"));
+ expected3 = BasicValue.INT_VALUE;
+ break;
+ case LASTORE:
+ expected1 = newValue(Type.getType("[J"));
+ expected3 = BasicValue.LONG_VALUE;
+ break;
+ case FASTORE:
+ expected1 = newValue(Type.getType("[F"));
+ expected3 = BasicValue.FLOAT_VALUE;
+ break;
+ case DASTORE:
+ expected1 = newValue(Type.getType("[D"));
+ expected3 = BasicValue.DOUBLE_VALUE;
+ break;
+ case AASTORE:
+ expected1 = value1;
+ expected3 = BasicValue.REFERENCE_VALUE;
+ break;
+ default:
+ throw new RuntimeException("Internal error.");
+ }
+ if (!isSubTypeOf(value1, expected1)) {
+ throw new AnalyzerException("First argument", "a " + expected1
+ + " array reference", value1);
+ } else if (value2 != BasicValue.INT_VALUE) {
+ throw new AnalyzerException("Second argument",
+ BasicValue.INT_VALUE,
+ value2);
+ } else if (!isSubTypeOf(value3, expected3)) {
+ throw new AnalyzerException("Third argument", expected3, value3);
+ }
+ return null;
+ }
+
+ public Value naryOperation(final AbstractInsnNode insn, final List values)
+ throws AnalyzerException
+ {
+ int opcode = insn.getOpcode();
+ if (opcode == MULTIANEWARRAY) {
+ for (int i = 0; i < values.size(); ++i) {
+ if (values.get(i) != BasicValue.INT_VALUE) {
+ throw new AnalyzerException(null,
+ BasicValue.INT_VALUE,
+ (Value) values.get(i));
+ }
+ }
+ } else {
+ int i = 0;
+ int j = 0;
+ if (opcode != INVOKESTATIC) {
+ String own = ((MethodInsnNode) insn).owner;
+ if (own.charAt(0) != '[') { // can happen with JDK1.5 clone()
+ own = "L" + own + ";";
+ }
+ Type owner = Type.getType(own);
+ if (!isSubTypeOf((Value) values.get(i++), newValue(owner))) {
+ throw new AnalyzerException("Method owner",
+ newValue(owner),
+ (Value) values.get(0));
+ }
+ }
+ Type[] args = Type.getArgumentTypes(((MethodInsnNode) insn).desc);
+ while (i < values.size()) {
+ Value expected = newValue(args[j++]);
+ Value encountered = (Value) values.get(i++);
+ if (!isSubTypeOf(encountered, expected)) {
+ throw new AnalyzerException("Argument " + j,
+ expected,
+ encountered);
+ }
+ }
+ }
+ return super.naryOperation(insn, values);
+ }
+
+ protected boolean isArrayValue(final Value value) {
+ return ((BasicValue) value).isReference();
+ }
+
+ protected Value getElementValue(final Value objectArrayValue)
+ throws AnalyzerException
+ {
+ return BasicValue.REFERENCE_VALUE;
+ }
+
+ protected boolean isSubTypeOf(final Value value, final Value expected) {
+ return value == expected;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowInterpreter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowInterpreter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowInterpreter.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,174 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.tree.analysis;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/**
+ * An {@link Interpreter} for {@link DataflowValue} values.
+ *
+ * @author Eric Bruneton
+ */
+public class DataflowInterpreter implements Opcodes, Interpreter {
+
+ public Value newValue(final Type type) {
+ return new DataflowValue(type == null ? 1 : type.getSize());
+ }
+
+ public Value newOperation(final AbstractInsnNode insn) {
+ int size;
+ switch (insn.getOpcode()) {
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ size = 2;
+ break;
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+ break;
+ case GETSTATIC:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ }
+ return new DataflowValue(size, insn);
+ }
+
+ public Value copyOperation(final AbstractInsnNode insn, final Value value) {
+ return new DataflowValue(value.getSize(), insn);
+ }
+
+ public Value unaryOperation(final AbstractInsnNode insn, final Value value)
+ {
+ int size;
+ switch (insn.getOpcode()) {
+ case LNEG:
+ case DNEG:
+ case I2L:
+ case I2D:
+ case L2D:
+ case F2L:
+ case F2D:
+ case D2L:
+ size = 2;
+ break;
+ case GETFIELD:
+ size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+ break;
+ default:
+ size = 1;
+ }
+ return new DataflowValue(size, insn);
+ }
+
+ public Value binaryOperation(
+ final AbstractInsnNode insn,
+ final Value value1,
+ final Value value2)
+ {
+ int size;
+ switch (insn.getOpcode()) {
+ case LALOAD:
+ case DALOAD:
+ case LADD:
+ case DADD:
+ case LSUB:
+ case DSUB:
+ case LMUL:
+ case DMUL:
+ case LDIV:
+ case DDIV:
+ case LREM:
+ case DREM:
+ case LSHL:
+ case LSHR:
+ case LUSHR:
+ case LAND:
+ case LOR:
+ case LXOR:
+ size = 2;
+ break;
+ default:
+ size = 1;
+ }
+ return new DataflowValue(size, insn);
+ }
+
+ public Value ternaryOperation(
+ final AbstractInsnNode insn,
+ final Value value1,
+ final Value value2,
+ final Value value3)
+ {
+ return new DataflowValue(1, insn);
+ }
+
+ public Value naryOperation(final AbstractInsnNode insn, final List values) {
+ int size;
+ if (insn.getOpcode() == MULTIANEWARRAY) {
+ size = 1;
+ } else {
+ size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize();
+ }
+ return new DataflowValue(size, insn);
+ }
+
+ public Value merge(final Value v, final Value w) {
+ DataflowValue dv = (DataflowValue) v;
+ DataflowValue dw = (DataflowValue) w;
+ if (dv.insns instanceof SmallSet && dw.insns instanceof SmallSet) {
+ Set s = ((SmallSet) dv.insns).union((SmallSet) dw.insns);
+ if (s == dv.insns && dv.size == dw.size) {
+ return v;
+ } else {
+ return new DataflowValue(Math.min(dv.size, dw.size), s);
+ }
+ }
+ if (dv.size != dw.size || !dv.insns.containsAll(dw.insns)) {
+ Set s = new HashSet();
+ s.addAll(dv.insns);
+ s.addAll(dw.insns);
+ return new DataflowValue(Math.min(dv.size, dw.size), s);
+ }
+ return v;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowValue.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowValue.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/tree/analysis/DataflowValue.java 2007-01-07 13:45:46 UTC (rev 3032)
@@ -0,0 +1,92 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * ...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:44:40
|
Revision: 3031
http://jnode.svn.sourceforge.net/jnode/?rev=3031&view=rev
Author: lsantha
Date: 2007-01-07 05:44:38 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/signature/
trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureReader.java
trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureWriter.java
trunk/core/src/classpath/org/org/objectweb/asm/signature/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureReader.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureReader.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureReader.java 2007-01-07 13:44:38 UTC (rev 3031)
@@ -0,0 +1,233 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.signature;
+
+/**
+ * A type signature parser to make a signature visitor visit an existing
+ * signature.
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public class SignatureReader {
+
+ /**
+ * The signature to be read.
+ */
+ private final String signature;
+
+ /**
+ * Constructs a {@link SignatureReader} for the given signature.
+ *
+ * @param signature A <i>ClassSignature</i>, <i>MethodTypeSignature</i>,
+ * or <i>FieldTypeSignature</i>.
+ */
+ public SignatureReader(final String signature) {
+ this.signature = signature;
+ }
+
+ /**
+ * Makes the given visitor visit the signature of this
+ * {@link SignatureReader}. This signature is the one specified in the
+ * constructor (see {@link #SignatureReader(String) SignatureReader}). This
+ * method is intended to be called on a {@link SignatureReader} that was
+ * created using a <i>ClassSignature</i> (such as the
+ * <code>signature</code> parameter of the
+ * {@link org.objectweb.asm.ClassVisitor#visit ClassVisitor.visit} method)
+ * or a <i>MethodTypeSignature</i> (such as the <code>signature</code>
+ * parameter of the
+ * {@link org.objectweb.asm.ClassVisitor#visitMethod ClassVisitor.visitMethod}
+ * method).
+ *
+ * @param v the visitor that must visit this signature.
+ */
+ public void accept(final SignatureVisitor v) {
+ String signature = this.signature;
+ int len = signature.length();
+ int pos;
+ char c;
+
+ if (signature.charAt(0) == '<') {
+ pos = 2;
+ do {
+ int end = signature.indexOf(':', pos);
+ v.visitFormalTypeParameter(signature.substring(pos - 1, end));
+ pos = end + 1;
+
+ c = signature.charAt(pos);
+ if (c == 'L' || c == '[' || c == 'T') {
+ pos = parseType(signature, pos, v.visitClassBound());
+ }
+
+ for (;;) {
+ if ((c = signature.charAt(pos++)) == ':') {
+ pos = parseType(signature, pos, v.visitInterfaceBound());
+ } else {
+ break;
+ }
+ }
+ } while (c != '>');
+ } else {
+ pos = 0;
+ }
+
+ if (signature.charAt(pos) == '(') {
+ pos = pos + 1;
+ while (signature.charAt(pos) != ')') {
+ pos = parseType(signature, pos, v.visitParameterType());
+ }
+ pos = parseType(signature, pos + 1, v.visitReturnType());
+ while (pos < len) {
+ pos = parseType(signature, pos + 1, v.visitExceptionType());
+ }
+ } else {
+ pos = parseType(signature, pos, v.visitSuperclass());
+ while (pos < len) {
+ pos = parseType(signature, pos, v.visitInterface());
+ }
+ }
+ }
+
+ /**
+ * Makes the given visitor visit the signature of this
+ * {@link SignatureReader}. This signature is the one specified in the
+ * constructor (see {@link #SignatureReader(String) SignatureReader}). This
+ * method is intended to be called on a {@link SignatureReader} that was
+ * created using a <i>FieldTypeSignature</i>, such as the
+ * <code>signature</code> parameter of the
+ * {@link org.objectweb.asm.ClassVisitor#visitField
+ * ClassVisitor.visitField} or {@link
+ * org.objectweb.asm.MethodVisitor#visitLocalVariable
+ * MethodVisitor.visitLocalVariable} methods.
+ *
+ * @param v the visitor that must visit this signature.
+ */
+ public void acceptType(final SignatureVisitor v) {
+ parseType(this.signature, 0, v);
+ }
+
+ /**
+ * Parses a field type signature and makes the given visitor visit it.
+ *
+ * @param signature a string containing the signature that must be parsed.
+ * @param pos index of the first character of the signature to parsed.
+ * @param v the visitor that must visit this signature.
+ * @return the index of the first character after the parsed signature.
+ */
+ private static int parseType(
+ final String signature,
+ int pos,
+ final SignatureVisitor v)
+ {
+ char c;
+ int start, end;
+ boolean visited, inner;
+ String name;
+
+ switch (c = signature.charAt(pos++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ case 'V':
+ v.visitBaseType(c);
+ return pos;
+
+ case '[':
+ return parseType(signature, pos, v.visitArrayType());
+
+ case 'T':
+ end = signature.indexOf(';', pos);
+ v.visitTypeVariable(signature.substring(pos, end));
+ return end + 1;
+
+ default: // case 'L':
+ start = pos;
+ visited = false;
+ inner = false;
+ for (;;) {
+ switch (c = signature.charAt(pos++)) {
+ case '.':
+ case ';':
+ if (!visited) {
+ name = signature.substring(start, pos - 1);
+ if (inner) {
+ v.visitInnerClassType(name);
+ } else {
+ v.visitClassType(name);
+ }
+ }
+ if (c == ';') {
+ v.visitEnd();
+ return pos;
+ }
+ start = pos;
+ visited = false;
+ inner = true;
+ break;
+
+ case '<':
+ name = signature.substring(start, pos - 1);
+ if (inner) {
+ v.visitInnerClassType(name);
+ } else {
+ v.visitClassType(name);
+ }
+ visited = true;
+ top: for (;;) {
+ switch (c = signature.charAt(pos)) {
+ case '>':
+ break top;
+ case '*':
+ ++pos;
+ v.visitTypeArgument();
+ break;
+ case '+':
+ case '-':
+ pos = parseType(signature,
+ pos + 1,
+ v.visitTypeArgument(c));
+ break;
+ default:
+ pos = parseType(signature,
+ pos,
+ v.visitTypeArgument('='));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureVisitor.java 2007-01-07 13:44:38 UTC (rev 3031)
@@ -0,0 +1,185 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.signature;
+
+/**
+ * A visitor to visit a generic signature. The methods of this interface must be
+ * called in one of the three following orders (the last one is the only valid
+ * order for a {@link SignatureVisitor} that is returned by a method of this
+ * interface): <ul> <li><i>ClassSignature</i> = (
+ * <tt>visitFormalTypeParameter</tt>
+ * <tt>visitClassBound</tt>?
+ * <tt>visitInterfaceBound</tt>* )* ( <tt>visitSuperClass</tt>
+ * <tt>visitInterface</tt>* )</li>
+ * <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
+ * <tt>visitClassBound</tt>?
+ * <tt>visitInterfaceBound</tt>* )* ( <tt>visitParameterType</tt>*
+ * <tt>visitReturnType</tt>
+ * <tt>visitExceptionType</tt>* )</li> <li><i>TypeSignature</i> =
+ * <tt>visitBaseType</tt> | <tt>visitTypeVariable</tt> |
+ * <tt>visitArrayType</tt> | (
+ * <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
+ * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )*
+ * <tt>visitEnd</tt> ) )</li> </ul>
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public interface SignatureVisitor {
+
+ /**
+ * Wildcard for an "extends" type argument.
+ */
+ char EXTENDS = '+';
+
+ /**
+ * Wildcard for a "super" type argument.
+ */
+ char SUPER = '-';
+
+ /**
+ * Wildcard for a normal type argument.
+ */
+ char INSTANCEOF = '=';
+
+ /**
+ * Visits a formal type parameter.
+ *
+ * @param name the name of the formal parameter.
+ */
+ void visitFormalTypeParameter(String name);
+
+ /**
+ * Visits the class bound of the last visited formal type parameter.
+ *
+ * @return a non null visitor to visit the signature of the class bound.
+ */
+ SignatureVisitor visitClassBound();
+
+ /**
+ * Visits an interface bound of the last visited formal type parameter.
+ *
+ * @return a non null visitor to visit the signature of the interface bound.
+ */
+ SignatureVisitor visitInterfaceBound();
+
+ /**
+ * Visits the type of the super class.
+ *
+ * @return a non null visitor to visit the signature of the super class
+ * type.
+ */
+ SignatureVisitor visitSuperclass();
+
+ /**
+ * Visits the type of an interface implemented by the class.
+ *
+ * @return a non null visitor to visit the signature of the interface type.
+ */
+ SignatureVisitor visitInterface();
+
+ /**
+ * Visits the type of a method parameter.
+ *
+ * @return a non null visitor to visit the signature of the parameter type.
+ */
+ SignatureVisitor visitParameterType();
+
+ /**
+ * Visits the return type of the method.
+ *
+ * @return a non null visitor to visit the signature of the return type.
+ */
+ SignatureVisitor visitReturnType();
+
+ /**
+ * Visits the type of a method exception.
+ *
+ * @return a non null visitor to visit the signature of the exception type.
+ */
+ SignatureVisitor visitExceptionType();
+
+ /**
+ * Visits a signature corresponding to a primitive type.
+ *
+ * @param descriptor the descriptor of the primitive type, or 'V' for
+ * <tt>void</tt>.
+ */
+ void visitBaseType(char descriptor);
+
+ /**
+ * Visits a signature corresponding to a type variable.
+ *
+ * @param name the name of the type variable.
+ */
+ void visitTypeVariable(String name);
+
+ /**
+ * Visits a signature corresponding to an array type.
+ *
+ * @return a non null visitor to visit the signature of the array element
+ * type.
+ */
+ SignatureVisitor visitArrayType();
+
+ /**
+ * Starts the visit of a signature corresponding to a class or interface
+ * type.
+ *
+ * @param name the internal name of the class or interface.
+ */
+ void visitClassType(String name);
+
+ /**
+ * Visits an inner class.
+ *
+ * @param name the local name of the inner class in its enclosing class.
+ */
+ void visitInnerClassType(String name);
+
+ /**
+ * Visits an unbounded type argument of the last visited class or inner
+ * class type.
+ */
+ void visitTypeArgument();
+
+ /**
+ * Visits a type argument of the last visited class or inner class type.
+ *
+ * @param wildcard '+', '-' or '='.
+ * @return a non null visitor to visit the signature of the type argument.
+ */
+ SignatureVisitor visitTypeArgument(char wildcard);
+
+ /**
+ * Ends the visit of a signature corresponding to a class or interface type.
+ */
+ void visitEnd();
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureWriter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureWriter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/signature/SignatureWriter.java 2007-01-07 13:44:38 UTC (rev 3031)
@@ -0,0 +1,207 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.signature;
+
+/**
+ * A signature visitor that generates signatures in string format.
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public class SignatureWriter implements SignatureVisitor {
+
+ /**
+ * Buffer used to construct the signature.
+ */
+ private final StringBuffer buf = new StringBuffer();
+
+ /**
+ * Indicates if the signature contains formal type parameters.
+ */
+ private boolean hasFormals;
+
+ /**
+ * Indicates if the signature contains method parameter types.
+ */
+ private boolean hasParameters;
+
+ /**
+ * Stack used to keep track of class types that have arguments. Each element
+ * of this stack is a boolean encoded in one bit. The top of the stack is
+ * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping =
+ * /2.
+ */
+ private int argumentStack;
+
+ /**
+ * Constructs a new {@link SignatureWriter} object.
+ */
+ public SignatureWriter() {
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the SignatureVisitor interface
+ // ------------------------------------------------------------------------
+
+ public void visitFormalTypeParameter(String name) {
+ if (!hasFormals) {
+ hasFormals = true;
+ buf.append('<');
+ }
+ buf.append(name);
+ buf.append(':');
+ }
+
+ public SignatureVisitor visitClassBound() {
+ return this;
+ }
+
+ public SignatureVisitor visitInterfaceBound() {
+ buf.append(':');
+ return this;
+ }
+
+ public SignatureVisitor visitSuperclass() {
+ endFormals();
+ return this;
+ }
+
+ public SignatureVisitor visitInterface() {
+ return this;
+ }
+
+ public SignatureVisitor visitParameterType() {
+ endFormals();
+ if (!hasParameters) {
+ hasParameters = true;
+ buf.append('(');
+ }
+ return this;
+ }
+
+ public SignatureVisitor visitReturnType() {
+ endFormals();
+ if (!hasParameters) {
+ buf.append('(');
+ }
+ buf.append(')');
+ return this;
+ }
+
+ public SignatureVisitor visitExceptionType() {
+ buf.append('^');
+ return this;
+ }
+
+ public void visitBaseType(char descriptor) {
+ buf.append(descriptor);
+ }
+
+ public void visitTypeVariable(String name) {
+ buf.append('T');
+ buf.append(name);
+ buf.append(';');
+ }
+
+ public SignatureVisitor visitArrayType() {
+ buf.append('[');
+ return this;
+ }
+
+ public void visitClassType(String name) {
+ buf.append('L');
+ buf.append(name);
+ argumentStack *= 2;
+ }
+
+ public void visitInnerClassType(String name) {
+ endArguments();
+ buf.append('.');
+ buf.append(name);
+ argumentStack *= 2;
+ }
+
+ public void visitTypeArgument() {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ buf.append('<');
+ }
+ buf.append('*');
+ }
+
+ public SignatureVisitor visitTypeArgument(char wildcard) {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ buf.append('<');
+ }
+ if (wildcard != '=') {
+ buf.append(wildcard);
+ }
+ return this;
+ }
+
+ public void visitEnd() {
+ endArguments();
+ buf.append(';');
+ }
+
+ /**
+ * Returns the signature that was built by this signature writer.
+ *
+ * @return the signature that was built by this signature writer.
+ */
+ public String toString() {
+ return buf.toString();
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Ends the formal type parameters section of the signature.
+ */
+ private void endFormals() {
+ if (hasFormals) {
+ hasFormals = false;
+ buf.append('>');
+ }
+ }
+
+ /**
+ * Ends the type arguments of a class or inner class type.
+ */
+ private void endArguments() {
+ if (argumentStack % 2 == 1) {
+ buf.append('>');
+ }
+ argumentStack /= 2;
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/org/org/objectweb/asm/signature/package.html
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/signature/package.html (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/signature/package.html 2007-01-07 13:44:38 UTC (rev 3031)
@@ -0,0 +1,36 @@
+<html>
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<body>
+Provides support for type signatures.
+
+@since ASM 2.0
+</body>
+</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 13:44:10
|
Revision: 3030
http://jnode.svn.sourceforge.net/jnode/?rev=3030&view=rev
Author: lsantha
Date: 2007-01-07 05:44:08 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassConstantsCollector.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassOptimizer.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Constant.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ConstantPool.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/FieldConstantsCollector.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/JarOptimizer.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodConstantsCollector.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodOptimizer.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/NameMapping.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Shrinker.java
trunk/core/src/classpath/org/org/objectweb/asm/optimizer/shrink.properties
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/AnnotationConstantsCollector.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,150 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Type;
+
+/**
+ * An {@link AnnotationVisitor} that collects the {@link Constant}s of the
+ * annotations it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class AnnotationConstantsCollector implements AnnotationVisitor {
+
+ private AnnotationVisitor av;
+
+ private ConstantPool cp;
+
+ public AnnotationConstantsCollector(
+ final AnnotationVisitor av,
+ final ConstantPool cp)
+ {
+ this.av = av;
+ this.cp = cp;
+ }
+
+ public void visit(final String name, final Object value) {
+ if (name != null) {
+ cp.newUTF8(name);
+ }
+ if (value instanceof Byte) {
+ cp.newInteger(((Byte) value).byteValue());
+ } else if (value instanceof Boolean) {
+ cp.newInteger(((Boolean) value).booleanValue() ? 1 : 0);
+ } else if (value instanceof Character) {
+ cp.newInteger(((Character) value).charValue());
+ } else if (value instanceof Short) {
+ cp.newInteger(((Short) value).shortValue());
+ } else if (value instanceof Type) {
+ cp.newUTF8(((Type) value).getDescriptor());
+ } else if (value instanceof byte[]) {
+ byte[] v = (byte[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newInteger(v[i]);
+ }
+ } else if (value instanceof boolean[]) {
+ boolean[] v = (boolean[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newInteger(v[i] ? 1 : 0);
+ }
+ } else if (value instanceof short[]) {
+ short[] v = (short[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newInteger(v[i]);
+ }
+ } else if (value instanceof char[]) {
+ char[] v = (char[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newInteger(v[i]);
+ }
+ } else if (value instanceof int[]) {
+ int[] v = (int[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newInteger(v[i]);
+ }
+ } else if (value instanceof long[]) {
+ long[] v = (long[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newLong(v[i]);
+ }
+ } else if (value instanceof float[]) {
+ float[] v = (float[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newFloat(v[i]);
+ }
+ } else if (value instanceof double[]) {
+ double[] v = (double[]) value;
+ for (int i = 0; i < v.length; i++) {
+ cp.newDouble(v[i]);
+ }
+ } else {
+ cp.newConst(value);
+ }
+ av.visit(name, value);
+ }
+
+ public void visitEnum(
+ final String name,
+ final String desc,
+ final String value)
+ {
+ if (name != null) {
+ cp.newUTF8(name);
+ }
+ cp.newUTF8(desc);
+ cp.newUTF8(value);
+ av.visitEnum(name, desc, value);
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String name,
+ final String desc)
+ {
+ if (name != null) {
+ cp.newUTF8(name);
+ }
+ cp.newUTF8(desc);
+ return new AnnotationConstantsCollector(av.visitAnnotation(name, desc),
+ cp);
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ if (name != null) {
+ cp.newUTF8(name);
+ }
+ return new AnnotationConstantsCollector(av.visitArray(name), cp);
+ }
+
+ public void visitEnd() {
+ av.visitEnd();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassConstantsCollector.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassConstantsCollector.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassConstantsCollector.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,212 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ClassVisitor} that collects the {@link Constant}s of the classes it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassConstantsCollector extends ClassAdapter {
+
+ private ConstantPool cp;
+
+ public ClassConstantsCollector(final ClassVisitor cv, final ConstantPool cp)
+ {
+ super(cv);
+ this.cp = cp;
+ }
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ cp.newUTF8("Deprecated");
+ }
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ cp.newUTF8("Synthetic");
+ }
+ cp.newClass(name);
+ if (signature != null) {
+ cp.newUTF8("Signature");
+ cp.newUTF8(signature);
+ }
+ if (superName != null) {
+ cp.newClass(superName);
+ }
+ if (interfaces != null) {
+ for (int i = 0; i < interfaces.length; ++i) {
+ cp.newClass(interfaces[i]);
+ }
+ }
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ public void visitSource(final String source, final String debug) {
+ if (source != null) {
+ cp.newUTF8("SourceFile");
+ cp.newUTF8(source);
+ }
+ if (debug != null) {
+ cp.newUTF8("SourceDebugExtension");
+ }
+ cv.visitSource(source, debug);
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ cp.newUTF8("EnclosingMethod");
+ cp.newClass(owner);
+ if (name != null && desc != null) {
+ cp.newNameType(name, desc);
+ }
+ cv.visitOuterClass(owner, name, desc);
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleAnnotations");
+ }
+ return new AnnotationConstantsCollector(cv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ // can do nothing
+ cv.visitAttribute(attr);
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ cp.newUTF8("InnerClasses");
+ if (name != null) {
+ cp.newClass(name);
+ }
+ if (outerName != null) {
+ cp.newClass(outerName);
+ }
+ if (innerName != null) {
+ cp.newClass(innerName);
+ }
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ cp.newUTF8("Synthetic");
+ }
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ cp.newUTF8("Deprecated");
+ }
+ cp.newUTF8(name);
+ cp.newUTF8(desc);
+ if (signature != null) {
+ cp.newUTF8("Signature");
+ cp.newUTF8(signature);
+ }
+ if (value != null) {
+ cp.newConst(value);
+ }
+ return new FieldConstantsCollector(cv.visitField(access,
+ name,
+ desc,
+ signature,
+ value), cp);
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ cp.newUTF8("Synthetic");
+ }
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ cp.newUTF8("Deprecated");
+ }
+ cp.newUTF8(name);
+ cp.newUTF8(desc);
+ if (signature != null) {
+ cp.newUTF8("Signature");
+ cp.newUTF8(signature);
+ }
+ if (exceptions != null) {
+ cp.newUTF8("Exceptions");
+ for (int i = 0; i < exceptions.length; ++i) {
+ cp.newClass(exceptions[i]);
+ }
+ }
+ return new MethodConstantsCollector(cv.visitMethod(access,
+ name,
+ desc,
+ signature,
+ exceptions), cp);
+ }
+
+ public void visitEnd() {
+ cv.visitEnd();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassOptimizer.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassOptimizer.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ClassOptimizer.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,182 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ClassAdapter} that renames fields and methods, and removes debug
+ * info.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassOptimizer extends ClassAdapter {
+
+ private NameMapping mapping;
+
+ private String className;
+
+ private String pkgName;
+
+ public ClassOptimizer(final ClassVisitor cv, final NameMapping mapping) {
+ super(cv);
+ this.mapping = mapping;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ // ------------------------------------------------------------------------
+ // Overriden methods
+ // ------------------------------------------------------------------------
+
+ public void visit(
+ final int version,
+ final int access,
+ final String name,
+ final String signature,
+ final String superName,
+ final String[] interfaces)
+ {
+ className = name;
+ pkgName = name.substring(0, name.lastIndexOf('/'));
+ cv.visit(version,
+ access,
+ mapping.map(name),
+ null,
+ mapping.map(superName),
+ interfaces);
+ }
+
+ public void visitSource(final String source, final String debug) {
+ // remove debug info
+ }
+
+ public void visitOuterClass(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ // remove debug info
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ // remove non standard attribute
+ }
+
+ public void visitInnerClass(
+ final String name,
+ final String outerName,
+ final String innerName,
+ final int access)
+ {
+ // remove debug info
+ }
+
+ public FieldVisitor visitField(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final Object value)
+ {
+ String s = className + "." + name;
+ if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
+ if ((access & Opcodes.ACC_FINAL) != 0
+ && (access & Opcodes.ACC_STATIC) != 0 && desc.equals("I"))
+ {
+ return null;
+ }
+ if (pkgName.equals("org/objectweb/asm")
+ && mapping.map(s).equals(name))
+ {
+ System.out.println("INFO: " + s + " could be renamed");
+ }
+ cv.visitField(access,
+ mapping.map(s),
+ mapping.fix(desc),
+ null,
+ value);
+ } else {
+ if (!mapping.map(s).equals(name)) {
+ throw new RuntimeException("The public or protected field " + s
+ + " must not be renamed.");
+ }
+ cv.visitField(access, name, desc, null, value);
+ }
+ return null; // remove debug info
+ }
+
+ public MethodVisitor visitMethod(
+ final int access,
+ final String name,
+ final String desc,
+ final String signature,
+ final String[] exceptions)
+ {
+ String s = className + "." + name + desc;
+ if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
+ if (pkgName.equals("org/objectweb/asm") && !name.startsWith("<")
+ && mapping.map(s).equals(name))
+ {
+ System.out.println("INFO: " + s + " could be renamed");
+ }
+ return new MethodOptimizer(cv.visitMethod(access,
+ mapping.map(s),
+ mapping.fix(desc),
+ null,
+ exceptions), mapping);
+ } else {
+ if (!mapping.map(s).equals(name)) {
+ throw new RuntimeException("The public or protected method "
+ + s + " must not be renamed.");
+ }
+ return new MethodOptimizer(cv.visitMethod(access,
+ name,
+ desc,
+ null,
+ exceptions), mapping);
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Constant.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Constant.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Constant.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,265 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * A constant pool item.
+ *
+ * @author Eric Bruneton
+ */
+class Constant {
+
+ /**
+ * Type of this constant pool item. A single class is used to represent all
+ * constant pool item types, in order to minimize the bytecode size of this
+ * package. The value of this field is I, J, F, D, S, s, C, T, G, M, or N
+ * (for Constant Integer, Long, Float, Double, STR, UTF8, Class, NameType,
+ * Fieldref, Methodref, or InterfaceMethodref constant pool items
+ * respectively).
+ */
+ char type;
+
+ /**
+ * Value of this item, for an integer item.
+ */
+ int intVal;
+
+ /**
+ * Value of this item, for a long item.
+ */
+ long longVal;
+
+ /**
+ * Value of this item, for a float item.
+ */
+ float floatVal;
+
+ /**
+ * Value of this item, for a double item.
+ */
+ double doubleVal;
+
+ /**
+ * First part of the value of this item, for items that do not hold a
+ * primitive value.
+ */
+ String strVal1;
+
+ /**
+ * Second part of the value of this item, for items that do not hold a
+ * primitive value.
+ */
+ String strVal2;
+
+ /**
+ * Third part of the value of this item, for items that do not hold a
+ * primitive value.
+ */
+ String strVal3;
+
+ /**
+ * The hash code value of this constant pool item.
+ */
+ int hashCode;
+
+ public Constant() {
+ }
+
+ public Constant(final Constant i) {
+ type = i.type;
+ intVal = i.intVal;
+ longVal = i.longVal;
+ floatVal = i.floatVal;
+ doubleVal = i.doubleVal;
+ strVal1 = i.strVal1;
+ strVal2 = i.strVal2;
+ strVal3 = i.strVal3;
+ hashCode = i.hashCode;
+ }
+
+ /**
+ * Sets this item to an integer item.
+ *
+ * @param intVal the value of this item.
+ */
+ void set(final int intVal) {
+ this.type = 'I';
+ this.intVal = intVal;
+ this.hashCode = 0x7FFFFFFF & (type + intVal);
+ }
+
+ /**
+ * Sets this item to a long item.
+ *
+ * @param longVal the value of this item.
+ */
+ void set(final long longVal) {
+ this.type = 'J';
+ this.longVal = longVal;
+ this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
+ }
+
+ /**
+ * Sets this item to a float item.
+ *
+ * @param floatVal the value of this item.
+ */
+ void set(final float floatVal) {
+ this.type = 'F';
+ this.floatVal = floatVal;
+ this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
+ }
+
+ /**
+ * Sets this item to a double item.
+ *
+ * @param doubleVal the value of this item.
+ */
+ void set(final double doubleVal) {
+ this.type = 'D';
+ this.doubleVal = doubleVal;
+ this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
+ }
+
+ /**
+ * Sets this item to an item that do not hold a primitive value.
+ *
+ * @param type the type of this item.
+ * @param strVal1 first part of the value of this item.
+ * @param strVal2 second part of the value of this item.
+ * @param strVal3 third part of the value of this item.
+ */
+ void set(
+ final char type,
+ final String strVal1,
+ final String strVal2,
+ final String strVal3)
+ {
+ this.type = type;
+ this.strVal1 = strVal1;
+ this.strVal2 = strVal2;
+ this.strVal3 = strVal3;
+ switch (type) {
+ case 's':
+ case 'S':
+ case 'C':
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+ return;
+ case 'T':
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode());
+ return;
+ // case 'G':
+ // case 'M':
+ // case 'N':
+ default:
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode() * strVal3.hashCode());
+ }
+ }
+
+ void write(final ClassWriter cw) {
+ switch (type) {
+ case 'I':
+ cw.newConst(new Integer(intVal));
+ break;
+ case 'J':
+ cw.newConst(new Long(longVal));
+ break;
+ case 'F':
+ cw.newConst(new Float(floatVal));
+ break;
+ case 'D':
+ cw.newConst(new Double(doubleVal));
+ break;
+ case 'S':
+ cw.newConst(strVal1);
+ break;
+ case 's':
+ cw.newUTF8(strVal1);
+ break;
+ case 'C':
+ cw.newClass(strVal1);
+ break;
+ case 'T':
+ cw.newNameType(strVal1, strVal2);
+ break;
+ case 'G':
+ cw.newField(strVal1, strVal2, strVal3);
+ break;
+ case 'M':
+ cw.newMethod(strVal1, strVal2, strVal3, false);
+ break;
+ case 'N':
+ cw.newMethod(strVal1, strVal2, strVal3, true);
+ break;
+ }
+ }
+
+ public boolean equals(final Object o) {
+ if (!(o instanceof Constant)) {
+ return false;
+ }
+ Constant c = (Constant) o;
+ if (c.type == type) {
+ switch (type) {
+ case 'I':
+ return c.intVal == intVal;
+ case 'J':
+ return c.longVal == longVal;
+ case 'F':
+ return c.floatVal == floatVal;
+ case 'D':
+ return c.doubleVal == doubleVal;
+ case 's':
+ case 'S':
+ case 'C':
+ return c.strVal1.equals(strVal1);
+ case 'T':
+ return c.strVal1.equals(strVal1)
+ && c.strVal2.equals(strVal2);
+ // case 'G':
+ // case 'M':
+ // case 'N':
+ default:
+ return c.strVal1.equals(strVal1)
+ && c.strVal2.equals(strVal2)
+ && c.strVal3.equals(strVal3);
+ }
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ConstantPool.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ConstantPool.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/ConstantPool.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,198 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import java.util.HashMap;
+
+import org.objectweb.asm.Type;
+
+/**
+ * A constant pool.
+ *
+ * @author Eric Bruneton
+ */
+public class ConstantPool extends HashMap {
+
+ private Constant key1 = new Constant();
+
+ private Constant key2 = new Constant();
+
+ private Constant key3 = new Constant();
+
+ public Constant newInteger(final int value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newFloat(final float value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newLong(final long value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newDouble(final double value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newUTF8(final String value) {
+ key1.set('s', value, null, null);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ private Constant newString(final String value) {
+ key2.set('S', value, null, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(value);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newClass(final String value) {
+ key2.set('C', value, null, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(value);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newConst(final Object cst) {
+ if (cst instanceof Integer) {
+ int val = ((Integer) cst).intValue();
+ return newInteger(val);
+ } else if (cst instanceof Float) {
+ float val = ((Float) cst).floatValue();
+ return newFloat(val);
+ } else if (cst instanceof Long) {
+ long val = ((Long) cst).longValue();
+ return newLong(val);
+ } else if (cst instanceof Double) {
+ double val = ((Double) cst).doubleValue();
+ return newDouble(val);
+ } else if (cst instanceof String) {
+ return newString((String) cst);
+ } else if (cst instanceof Type) {
+ Type t = (Type) cst;
+ return newClass(t.getSort() == Type.OBJECT
+ ? t.getInternalName()
+ : t.getDescriptor());
+ } else {
+ throw new IllegalArgumentException("value " + cst);
+ }
+ }
+
+ public Constant newField(
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ key3.set('G', owner, name, desc);
+ Constant result = get(key3);
+ if (result == null) {
+ newClass(owner);
+ newNameType(name, desc);
+ result = new Constant(key3);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newMethod(
+ final String owner,
+ final String name,
+ final String desc,
+ final boolean itf)
+ {
+ key3.set(itf ? 'N' : 'M', owner, name, desc);
+ Constant result = get(key3);
+ if (result == null) {
+ newClass(owner);
+ newNameType(name, desc);
+ result = new Constant(key3);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newNameType(final String name, final String desc) {
+ key2.set('T', name, desc, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(name);
+ newUTF8(desc);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ private Constant get(final Constant key) {
+ return (Constant) get((Object) key);
+ }
+
+ private void put(final Constant cst) {
+ put(cst, cst);
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/FieldConstantsCollector.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/FieldConstantsCollector.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/FieldConstantsCollector.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,76 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.FieldVisitor;
+
+/**
+ * A {@link FieldVisitor} that collects the {@link Constant}s of the fields it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class FieldConstantsCollector implements FieldVisitor {
+
+ private FieldVisitor fv;
+
+ private ConstantPool cp;
+
+ public FieldConstantsCollector(final FieldVisitor fv, final ConstantPool cp)
+ {
+ this.fv = fv;
+ this.cp = cp;
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleAnnotations");
+ }
+ return new AnnotationConstantsCollector(fv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ public void visitAttribute(final Attribute attr) {
+ // can do nothing
+ fv.visitAttribute(attr);
+ }
+
+ public void visitEnd() {
+ fv.visitEnd();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/JarOptimizer.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/JarOptimizer.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/JarOptimizer.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,87 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * A Jar file optimizer.
+ *
+ * @author Eric Bruneton
+ */
+public class JarOptimizer {
+
+ public static void main(final String[] args) throws IOException {
+ File f = new File(args[0]);
+ optimize(f);
+ }
+
+ static void optimize(final File f) throws IOException {
+ if (f.isDirectory()) {
+ File[] files = f.listFiles();
+ for (int i = 0; i < files.length; ++i) {
+ optimize(files[i]);
+ }
+ } else if (f.getName().endsWith(".jar")) {
+ File g = new File(f.getParentFile(), f.getName() + ".new");
+ ZipFile zf = new ZipFile(f);
+ ZipOutputStream out = new ZipOutputStream(new FileOutputStream(g));
+ Enumeration e = zf.entries();
+ byte[] buf = new byte[10000];
+ while (e.hasMoreElements()) {
+ ZipEntry ze = (ZipEntry) e.nextElement();
+ if (ze.isDirectory()) {
+ continue;
+ }
+ out.putNextEntry(ze);
+ InputStream is = zf.getInputStream(ze);
+ int n;
+ do {
+ n = is.read(buf, 0, buf.length);
+ if (n != -1) {
+ out.write(buf, 0, n);
+ }
+ } while (n != -1);
+ out.closeEntry();
+ }
+ out.close();
+ zf.close();
+ f.delete();
+ g.renameTo(f);
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodConstantsCollector.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodConstantsCollector.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodConstantsCollector.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,168 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * An {@link MethodVisitor} that collects the {@link Constant}s of the methods
+ * it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class MethodConstantsCollector extends MethodAdapter {
+
+ private ConstantPool cp;
+
+ public MethodConstantsCollector(
+ final MethodVisitor mv,
+ final ConstantPool cp)
+ {
+ super(mv);
+ this.cp = cp;
+ }
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ cp.newUTF8("AnnotationDefault");
+ return new AnnotationConstantsCollector(mv.visitAnnotationDefault(), cp);
+ }
+
+ public AnnotationVisitor visitAnnotation(
+ final String desc,
+ final boolean visible)
+ {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter,
+ final String desc,
+ final boolean visible)
+ {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleParameterAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleParameterAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitParameterAnnotation(parameter,
+ desc,
+ visible),
+ cp);
+ }
+
+ public void visitTypeInsn(final int opcode, final String desc) {
+ cp.newClass(desc);
+ mv.visitTypeInsn(opcode, desc);
+ }
+
+ public void visitFieldInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ cp.newField(owner, name, desc);
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ boolean itf = opcode == Opcodes.INVOKEINTERFACE;
+ cp.newMethod(owner, name, desc, itf);
+ mv.visitMethodInsn(opcode, owner, name, desc);
+ }
+
+ public void visitLdcInsn(final Object cst) {
+ cp.newConst(cst);
+ mv.visitLdcInsn(cst);
+ }
+
+ public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ cp.newClass(desc);
+ mv.visitMultiANewArrayInsn(desc, dims);
+ }
+
+ public void visitTryCatchBlock(
+ final Label start,
+ final Label end,
+ final Label handler,
+ final String type)
+ {
+ if (type != null) {
+ cp.newClass(type);
+ }
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+
+ public void visitLocalVariable(
+ final String name,
+ final String desc,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ if (signature != null) {
+ cp.newUTF8("LocalVariableTypeTable");
+ cp.newUTF8(name);
+ cp.newUTF8(signature);
+ }
+ cp.newUTF8("LocalVariableTable");
+ cp.newUTF8(name);
+ cp.newUTF8(desc);
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+
+ public void visitLineNumber(final int line, final Label start) {
+ cp.newUTF8("LineNumberTable");
+ mv.visitLineNumber(line, start);
+ }
+
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ cp.newUTF8("Code");
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodOptimizer.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodOptimizer.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/MethodOptimizer.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,108 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * A {@link MethodAdapter} that renames fields and methods, and removes debug
+ * info.
+ *
+ * @author Eric Bruneton
+ */
+public class MethodOptimizer extends MethodAdapter {
+
+ private NameMapping mapping;
+
+ public MethodOptimizer(final MethodVisitor mv, final NameMapping mapping) {
+ super(mv);
+ this.mapping = mapping;
+ }
+
+ // ------------------------------------------------------------------------
+ // Overriden methods
+ // ------------------------------------------------------------------------
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ throw new UnsupportedOperationException();
+ }
+
+ public AnnotationVisitor visitParameterAnnotation(
+ final int parameter,
+ final String desc,
+ final boolean visible)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void visitTypeInsn(final int opcode, final String desc) {
+ mv.visitTypeInsn(opcode, desc.startsWith("[")
+ ? mapping.fix(desc)
+ : mapping.map(desc));
+ }
+
+ public void visitFieldInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ mv.visitFieldInsn(opcode, mapping.map(owner), mapping.map(owner + "."
+ + name), mapping.fix(desc));
+ }
+
+ public void visitMethodInsn(
+ final int opcode,
+ final String owner,
+ final String name,
+ final String desc)
+ {
+ mv.visitMethodInsn(opcode, mapping.map(owner), mapping.map(owner + "."
+ + name + desc), mapping.fix(desc));
+ }
+
+ public void visitLocalVariable(
+ final String name,
+ final String desc,
+ final String signature,
+ final Label start,
+ final Label end,
+ final int index)
+ {
+ // remove debug info
+ }
+
+ public void visitLineNumber(final int line, final Label start) {
+ // remove debug info
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/NameMapping.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/NameMapping.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/NameMapping.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,101 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.objectweb.asm.Type;
+
+/**
+ * A mapping from names to names, used to rename classes, fields and methods.
+ *
+ * @author Eric Bruneton
+ */
+public class NameMapping extends Properties {
+
+ public final Set unused;
+
+ public NameMapping(final String file) throws IOException {
+ load(new FileInputStream(file));
+ unused = new HashSet(keySet());
+ }
+
+ public String map(final String name) {
+ String s = (String) get(name);
+ if (s == null) {
+ int p = name.indexOf('.');
+ if (p != -1) {
+ int q = name.indexOf('(');
+ if (q != -1) {
+ s = name.substring(p + 1, q);
+ } else {
+ s = name.substring(p + 1);
+ }
+ } else {
+ s = name;
+ }
+ } else {
+ unused.remove(name);
+ }
+ return s;
+ }
+
+ public String fix(final String desc) {
+ if (desc.startsWith("(")) {
+ Type[] arguments = Type.getArgumentTypes(desc);
+ Type result = Type.getReturnType(desc);
+ for (int i = 0; i < arguments.length; ++i) {
+ arguments[i] = fix(arguments[i]);
+ }
+ result = fix(result);
+ return Type.getMethodDescriptor(result, arguments);
+ } else {
+ return fix(Type.getType(desc)).getDescriptor();
+ }
+ }
+
+ private Type fix(final Type t) {
+ if (t.getSort() == Type.OBJECT) {
+ return Type.getType("L" + map(t.getInternalName()) + ";");
+ } else if (t.getSort() == Type.ARRAY) {
+ String s = fix(t.getElementType()).getDescriptor();
+ for (int i = 0; i < t.getDimensions(); ++i) {
+ s = "[" + s;
+ }
+ return Type.getType(s);
+ } else {
+ return t;
+ }
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Shrinker.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Shrinker.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/optimizer/Shrinker.java 2007-01-07 13:44:08 UTC (rev 3030)
@@ -0,0 +1,168 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.optimizer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Comparator;
...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:40:32
|
Revision: 3029
http://jnode.svn.sourceforge.net/jnode/?rev=3029&view=rev
Author: lsantha
Date: 2007-01-07 05:40:30 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/asm/commons/
trunk/core/src/classpath/org/org/objectweb/asm/commons/AdviceAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/EmptyVisitor.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/GeneratorAdapter.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/LocalVariablesSorter.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/Method.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/SerialVersionUIDAdder.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/StaticInitMerger.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/TableSwitchGenerator.java
trunk/core/src/classpath/org/org/objectweb/asm/commons/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/commons/AdviceAdapter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/commons/AdviceAdapter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/commons/AdviceAdapter.java 2007-01-07 13:40:30 UTC (rev 3029)
@@ -0,0 +1,643 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A <code>MethodAdapter</code> to dispatch method body instruction
+ * <p>
+ * The behavior is like this:
+ * <ol>
+ *
+ * <li>as long as the INVOKESPECIAL for the object initialization has not been
+ * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
+ *
+ * <li>when this one is reached, it is only added in the ctor code visitor and
+ * a JP invoke is added</li>
+ * <li>after that, only the other code visitor receives the instructions</li>
+ *
+ * </ol>
+ *
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes {
+ private static final Object THIS = new Object();
+ private static final Object OTHER = new Object();
+
+ protected int methodAccess;
+ protected String methodDesc;
+
+ private boolean constructor;
+ private boolean superInitialized;
+ private ArrayList stackFrame;
+ private HashMap branches;
+
+
+ /**
+ * Creates a new {@link AdviceAdapter}.
+ *
+ * @param mv the method visitor to which this adapter delegates calls.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param desc the method's descriptor (see {@link Type Type}).
+ */
+ public AdviceAdapter(MethodVisitor mv, int access, String name, String desc) {
+ super(mv, access, name, desc);
+ methodAccess = access;
+ methodDesc = desc;
+
+ constructor = "<init>".equals(name);
+ if (!constructor) {
+ superInitialized = true;
+ onMethodEnter();
+ } else {
+ stackFrame = new ArrayList();
+ branches = new HashMap();
+ }
+ }
+
+ public void visitLabel(Label label) {
+ mv.visitLabel(label);
+
+ if (constructor && branches != null) {
+ ArrayList frame = (ArrayList) branches.get(label);
+ if (frame != null) {
+ stackFrame = frame;
+ branches.remove(label);
+ }
+ }
+ }
+
+ public void visitInsn(int opcode) {
+ if (constructor) {
+ switch (opcode) {
+ case RETURN: // empty stack
+ onMethodExit(opcode);
+ break;
+
+ case IRETURN: // 1 before n/a after
+ case FRETURN: // 1 before n/a after
+ case ARETURN: // 1 before n/a after
+ case ATHROW: // 1 before n/a after
+ popValue();
+ popValue();
+ onMethodExit(opcode);
+ break;
+
+ case LRETURN: // 2 before n/a after
+ case DRETURN: // 2 before n/a after
+ popValue();
+ popValue();
+ onMethodExit(opcode);
+ break;
+
+ case NOP:
+ case LALOAD: // remove 2 add 2
+ case DALOAD: // remove 2 add 2
+ case LNEG:
+ case DNEG:
+ case FNEG:
+ case INEG:
+ case L2D:
+ case D2L:
+ case F2I:
+ case I2B:
+ case I2C:
+ case I2S:
+ case I2F:
+ case Opcodes.ARRAYLENGTH:
+ break;
+
+ case ACONST_NULL:
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ case F2L: // 1 before 2 after
+ case F2D:
+ case I2L:
+ case I2D:
+ pushValue(OTHER);
+ break;
+
+ case LCONST_0:
+ case LCONST_1:
+ case DCONST_0:
+ case DCONST_1:
+ pushValue(OTHER);
+ pushValue(OTHER);
+ break;
+
+ case IALOAD: // remove 2 add 1
+ case FALOAD: // remove 2 add 1
+ case AALOAD: // remove 2 add 1
+ case BALOAD: // remove 2 add 1
+ case CALOAD: // remove 2 add 1
+ case SALOAD: // remove 2 add 1
+ case POP:
+ case IADD:
+ case FADD:
+ case ISUB:
+ case LSHL: // 3 before 2 after
+ case LSHR: // 3 before 2 after
+ case LUSHR: // 3 before 2 after
+ case L2I: // 2 before 1 after
+ case L2F: // 2 before 1 after
+ case D2I: // 2 before 1 after
+ case D2F: // 2 before 1 after
+ case FSUB:
+ case FMUL:
+ case FDIV:
+ case FREM:
+ case FCMPL: // 2 before 1 after
+ case FCMPG: // 2 before 1 after
+ case IMUL:
+ case IDIV:
+ case IREM:
+ case ISHL:
+ case ISHR:
+ case IUSHR:
+ case IAND:
+ case IOR:
+ case IXOR:
+ case MONITORENTER:
+ case MONITOREXIT:
+ popValue();
+ break;
+
+ case POP2:
+ case LSUB:
+ case LMUL:
+ case LDIV:
+ case LREM:
+ case LADD:
+ case LAND:
+ case LOR:
+ case LXOR:
+ case DADD:
+ case DMUL:
+ case DSUB:
+ case DDIV:
+ case DREM:
+ popValue();
+ popValue();
+ break;
+
+ case IASTORE:
+ case FASTORE:
+ case AASTORE:
+ case BASTORE:
+ case CASTORE:
+ case SASTORE:
+ case LCMP: // 4 before 1 after
+ case DCMPL:
+ case DCMPG:
+ popValue();
+ popValue();
+ popValue();
+ break;
+
+ case LASTORE:
+ case DASTORE:
+ popValue();
+ popValue();
+ popValue();
+ popValue();
+ break;
+
+ case DUP:
+ pushValue(peekValue());
+ break;
+
+ case DUP_X1:
+ // TODO optimize this
+ {
+ Object o1 = popValue();
+ Object o2 = popValue();
+ pushValue(o1);
+ pushValue(o2);
+ pushValue(o1);
+ }
+ break;
+
+ case DUP_X2:
+ // TODO optimize this
+ {
+ Object o1 = popValue();
+ Object o2 = popValue();
+ Object o3 = popValue();
+ pushValue(o1);
+ pushValue(o3);
+ pushValue(o2);
+ pushValue(o1);
+ }
+ break;
+
+ case DUP2:
+ // TODO optimize this
+ {
+ Object o1 = popValue();
+ Object o2 = popValue();
+ pushValue(o2);
+ pushValue(o1);
+ pushValue(o2);
+ pushValue(o1);
+ }
+ break;
+
+ case DUP2_X1:
+ // TODO optimize this
+ {
+ Object o1 = popValue();
+ Object o2 = popValue();
+ Object o3 = popValue();
+ pushValue(o2);
+ pushValue(o1);
+ pushValue(o3);
+ pushValue(o2);
+ pushValue(o1);
+ }
+ break;
+
+ case DUP2_X2:
+ // TODO optimize this
+ {
+ Object o1 = popValue();
+ Object o2 = popValue();
+ Object o3 = popValue();
+ Object o4 = popValue();
+ pushValue(o2);
+ pushValue(o1);
+ pushValue(o4);
+ pushValue(o3);
+ pushValue(o2);
+ pushValue(o1);
+ }
+ break;
+
+ case SWAP: {
+ Object o1 = popValue();
+ Object o2 = popValue();
+ pushValue(o1);
+ pushValue(o2);
+ }
+ break;
+ }
+ } else {
+ switch (opcode) {
+ case RETURN:
+ case IRETURN:
+ case FRETURN:
+ case ARETURN:
+ case LRETURN:
+ case DRETURN:
+ case ATHROW:
+ onMethodExit(opcode);
+ break;
+ }
+ }
+ mv.visitInsn(opcode);
+ }
+
+ public void visitVarInsn(int opcode, int var) {
+ super.visitVarInsn(opcode, var);
+
+ if (constructor) {
+ switch (opcode) {
+ case ILOAD:
+ case FLOAD:
+ pushValue(OTHER);
+ break;
+ case LLOAD:
+ case DLOAD:
+ pushValue(OTHER);
+ pushValue(OTHER);
+ break;
+ case ALOAD:
+ pushValue(var == 0 ? THIS : OTHER);
+ break;
+ case ASTORE:
+ case ISTORE:
+ case FSTORE:
+ popValue();
+ break;
+ case LSTORE:
+ case DSTORE:
+ popValue();
+ popValue();
+ break;
+ }
+ }
+ }
+
+ public void visitFieldInsn(
+ int opcode,
+ String owner,
+ String name,
+ String desc)
+ {
+ mv.visitFieldInsn(opcode, owner, name, desc);
+
+ if (constructor) {
+ char c = desc.charAt(0);
+ boolean longOrDouble = c == 'J' || c == 'D';
+ switch (opcode) {
+ case GETSTATIC:
+ pushValue(OTHER);
+ if (longOrDouble) {
+ pushValue(OTHER);
+ }
+ break;
+ case PUTSTATIC:
+ popValue();
+ if(longOrDouble) {
+ popValue();
+ }
+ break;
+ case PUTFIELD:
+ popValue();
+ if(longOrDouble) {
+ popValue();
+ popValue();
+ }
+ break;
+ // case GETFIELD:
+ default:
+ if (longOrDouble) {
+ pushValue(OTHER);
+ }
+ }
+ }
+ }
+
+ public void visitIntInsn(int opcode, int operand) {
+ mv.visitIntInsn(opcode, operand);
+
+ if (constructor) {
+ switch (opcode) {
+ case BIPUSH:
+ case SIPUSH:
+ pushValue(OTHER);
+ }
+ }
+ }
+
+ public void visitLdcInsn(Object cst) {
+ mv.visitLdcInsn(cst);
+
+ if (constructor) {
+ pushValue(OTHER);
+ if (cst instanceof Double || cst instanceof Long) {
+ pushValue(OTHER);
+ }
+ }
+ }
+
+ public void visitMultiANewArrayInsn(String desc, int dims) {
+ mv.visitMultiANewArrayInsn(desc, dims);
+
+ if (constructor) {
+ for (int i = 0; i < dims; i++) {
+ popValue();
+ }
+ pushValue(OTHER);
+ }
+ }
+
+ public void visitTypeInsn(int opcode, String name) {
+ mv.visitTypeInsn(opcode, name);
+
+ // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack
+ if (constructor && opcode == NEW) {
+ pushValue(OTHER);
+ }
+ }
+
+ public void visitMethodInsn(
+ int opcode,
+ String owner,
+ String name,
+ String desc)
+ {
+ mv.visitMethodInsn(opcode, owner, name, desc);
+
+ if (constructor) {
+ Type[] types = Type.getArgumentTypes(desc);
+ for (int i = 0; i < types.length; i++) {
+ popValue();
+ if (types[i].getSize() == 2) {
+ popValue();
+ }
+ }
+ switch (opcode) {
+ // case INVOKESTATIC:
+ // break;
+
+ case INVOKEINTERFACE:
+ case INVOKEVIRTUAL:
+ popValue(); // objectref
+ break;
+
+ case INVOKESPECIAL:
+ Object type = popValue(); // objectref
+ if (type == THIS && !superInitialized) {
+ onMethodEnter();
+ superInitialized = true;
+ // once super has been initialized it is no longer
+ // necessary to keep track of stack state
+ constructor = false;
+ }
+ break;
+ }
+
+ Type returnType = Type.getReturnType(desc);
+ if (returnType != Type.VOID_TYPE) {
+ pushValue(OTHER);
+ if (returnType.getSize() == 2) {
+ pushValue(OTHER);
+ }
+ }
+ }
+ }
+
+ public void visitJumpInsn(int opcode, Label label) {
+ mv.visitJumpInsn(opcode, label);
+
+ if (constructor) {
+ switch (opcode) {
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case IFNULL:
+ case IFNONNULL:
+ popValue();
+ break;
+
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ popValue();
+ popValue();
+ break;
+
+ case JSR:
+ pushValue(OTHER);
+ break;
+ }
+ addBranch(label);
+ }
+ }
+
+ public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+ mv.visitLookupSwitchInsn(dflt, keys, labels);
+
+ if (constructor) {
+ popValue();
+ addBranches(dflt, labels);
+ }
+ }
+
+ public void visitTableSwitchInsn(
+ int min,
+ int max,
+ Label dflt,
+ Label[] labels)
+ {
+ mv.visitTableSwitchInsn(min, max, dflt, labels);
+
+ if (constructor) {
+ popValue();
+ addBranches(dflt, labels);
+ }
+ }
+
+ private void addBranches(Label dflt, Label[] labels) {
+ addBranch(dflt);
+ for (int i = 0; i < labels.length; i++) {
+ addBranch(labels[i]);
+ }
+ }
+
+ private void addBranch(Label label) {
+ if (branches.containsKey(label)) {
+ return;
+ }
+ ArrayList frame = new ArrayList();
+ frame.addAll(stackFrame);
+ branches.put(label, frame);
+ }
+
+ private Object popValue() {
+ return stackFrame.remove(stackFrame.size()-1);
+ }
+
+ private Object peekValue() {
+ return stackFrame.get(stackFrame.size()-1);
+ }
+
+ private void pushValue(Object o) {
+ stackFrame.add(o);
+ }
+
+ /**
+ * Called at the beginning of the method or after super
+ * class class call in the constructor.
+ * <br><br>
+ *
+ * <i>Custom code can use or change all the local variables,
+ * but should not change state of the stack.</i>
+ */
+ protected abstract void onMethodEnter();
+
+ /**
+ * Called before explicit exit from the method using either
+ * return or throw. Top element on the stack contains the
+ * return value or exception instance. For example:
+ *
+ * <pre>
+ * public void onMethodExit(int opcode) {
+ * if(opcode==RETURN) {
+ * visitInsn(ACONST_NULL);
+ * } else if(opcode==ARETURN || opcode==ATHROW) {
+ * dup();
+ * } else {
+ * if(opcode==LRETURN || opcode==DRETURN) {
+ * dup2();
+ * } else {
+ * dup();
+ * }
+ * box(Type.getReturnType(this.methodDesc));
+ * }
+ * visitIntInsn(SIPUSH, opcode);
+ * visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
+ * }
+ *
+ * // an actual call back method
+ * public static void onExit(int opcode, Object param) {
+ * ...
+ * </pre>
+ *
+ * <br><br>
+ *
+ * <i>Custom code can use or change all the local variables,
+ * but should not change state of the stack.</i>
+ *
+ * @param opcode one of the RETURN, IRETURN, FRETURN,
+ * ARETURN, LRETURN, DRETURN or ATHROW
+ *
+ */
+ protected abstract void onMethodExit(int opcode);
+
+ // TODO onException, onMethodCall
+
+}
+
Added: trunk/core/src/classpath/org/org/objectweb/asm/commons/EmptyVisitor.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/commons/EmptyVisitor.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/commons/EmptyVisitor.java 2007-01-07 13:40:30 UTC (rev 3029)
@@ -0,0 +1,211 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * An empty implementation of the ASM visitor interfaces.
+ *
+ * @author Eric Bruneton
+ */
+public class EmptyVisitor implements
+ ClassVisitor,
+ FieldVisitor,
+ MethodVisitor,
+ AnnotationVisitor
+{
+
+ public void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces)
+ {
+ }
+
+ public void visitSource(String source, String debug) {
+ }
+
+ public void visitOuterClass(String owner, String name, String desc) {
+ }
+
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ return this;
+ }
+
+ public void visitAttribute(Attribute attr) {
+ }
+
+ public void visitInnerClass(
+ String name,
+ String outerName,
+ String innerName,
+ int access)
+ {
+ }
+
+ public FieldVisitor visitField(
+ int access,
+ String name,
+ String desc,
+ String signature,
+ Object value)
+ {
+ return this;
+ }
+
+ public MethodVisitor visitMethod(
+ int access,
+ String name,
+ String desc,
+ String signature,
+ String[] exceptions)
+ {
+ return this;
+ }
+
+ public void visitEnd() {
+ }
+
+ public AnnotationVisitor visitAnnotationDefault() {
+ return this;
+ }
+
+ public AnnotationVisitor visitParameterAnnotation(
+ int parameter,
+ String desc,
+ boolean visible)
+ {
+ return this;
+ }
+
+ public void visitCode() {
+ }
+
+ public void visitInsn(int opcode) {
+ }
+
+ public void visitIntInsn(int opcode, int operand) {
+ }
+
+ public void visitVarInsn(int opcode, int var) {
+ }
+
+ public void visitTypeInsn(int opcode, String desc) {
+ }
+
+ public void visitFieldInsn(
+ int opcode,
+ String owner,
+ String name,
+ String desc)
+ {
+ }
+
+ public void visitMethodInsn(
+ int opcode,
+ String owner,
+ String name,
+ String desc)
+ {
+ }
+
+ public void visitJumpInsn(int opcode, Label label) {
+ }
+
+ public void visitLabel(Label label) {
+ }
+
+ public void visitLdcInsn(Object cst) {
+ }
+
+ public void visitIincInsn(int var, int increment) {
+ }
+
+ public void visitTableSwitchInsn(
+ int min,
+ int max,
+ Label dflt,
+ Label labels[])
+ {
+ }
+
+ public void visitLookupSwitchInsn(Label dflt, int keys[], Label labels[]) {
+ }
+
+ public void visitMultiANewArrayInsn(String desc, int dims) {
+ }
+
+ public void visitTryCatchBlock(
+ Label start,
+ Label end,
+ Label handler,
+ String type)
+ {
+ }
+
+ public void visitLocalVariable(
+ String name,
+ String desc,
+ String signature,
+ Label start,
+ Label end,
+ int index)
+ {
+ }
+
+ public void visitLineNumber(int line, Label start) {
+ }
+
+ public void visitMaxs(int maxStack, int maxLocals) {
+ }
+
+ public void visit(String name, Object value) {
+ }
+
+ public void visitEnum(String name, String desc, String value) {
+ }
+
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ return this;
+ }
+
+ public AnnotationVisitor visitArray(String name) {
+ return this;
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/commons/GeneratorAdapter.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/commons/GeneratorAdapter.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/commons/GeneratorAdapter.java 2007-01-07 13:40:30 UTC (rev 3029)
@@ -0,0 +1,1454 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A {@link org.objectweb.asm.MethodAdapter} with convenient methods to generate
+ * code. For example, using this adapter, the class below
+ *
+ * <pre>
+ * public class Example {
+ * public static void main(String[] args) {
+ * System.out.println("Hello world!");
+ * }
+ * }
+ * </pre>
+ *
+ * can be generated as follows:
+ *
+ * <pre>
+ * ClassWriter cw = new ClassWriter(true);
+ * cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
+ *
+ * Method m = Method.getMethod("void <init> ()");
+ * GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
+ * mg.loadThis();
+ * mg.invokeConstructor(Type.getType(Object.class), m);
+ * mg.returnValue();
+ * mg.endMethod();
+ *
+ * m = Method.getMethod("void main (String[])");
+ * mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
+ * mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
+ * mg.push("Hello world!");
+ * mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println (String)"));
+ * mg.returnValue();
+ * mg.endMethod();
+ *
+ * cw.visitEnd();
+ * </pre>
+ *
+ * @author Juozas Baliuka
+ * @author Chris Nokleberg
+ * @author Eric Bruneton
+ */
+public class GeneratorAdapter extends LocalVariablesSorter {
+
+ private final static Type BYTE_TYPE = Type.getType("Ljava/lang/Byte;");
+
+ private final static Type BOOLEAN_TYPE = Type.getType("Ljava/lang/Boolean;");
+
+ private final static Type SHORT_TYPE = Type.getType("Ljava/lang/Short;");
+
+ private final static Type CHARACTER_TYPE = Type.getType("Ljava/lang/Character;");
+
+ private final static Type INTEGER_TYPE = Type.getType("Ljava/lang/Integer;");
+
+ private final static Type FLOAT_TYPE = Type.getType("Ljava/lang/Float;");
+
+ private final static Type LONG_TYPE = Type.getType("Ljava/lang/Long;");
+
+ private final static Type DOUBLE_TYPE = Type.getType("Ljava/lang/Double;");
+
+ private final static Type NUMBER_TYPE = Type.getType("Ljava/lang/Number;");
+
+ private final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
+
+ private final static Method BOOLEAN_VALUE = Method.getMethod("boolean booleanValue()");
+
+ private final static Method CHAR_VALUE = Method.getMethod("char charValue()");
+
+ private final static Method INT_VALUE = Method.getMethod("int intValue()");
+
+ private final static Method FLOAT_VALUE = Method.getMethod("float floatValue()");
+
+ private final static Method LONG_VALUE = Method.getMethod("long longValue()");
+
+ private final static Method DOUBLE_VALUE = Method.getMethod("double doubleValue()");
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int ADD = Opcodes.IADD;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int SUB = Opcodes.ISUB;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int MUL = Opcodes.IMUL;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int DIV = Opcodes.IDIV;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int REM = Opcodes.IREM;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int NEG = Opcodes.INEG;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int SHL = Opcodes.ISHL;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int SHR = Opcodes.ISHR;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int USHR = Opcodes.IUSHR;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int AND = Opcodes.IAND;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int OR = Opcodes.IOR;
+
+ /**
+ * Constant for the {@link #math math} method.
+ */
+ public final static int XOR = Opcodes.IXOR;
+
+ /**
+ * Constant for the {@link #ifCmp ifCmp} method.
+ */
+ public final static int EQ = Opcodes.IFEQ;
+
+ /**
+ * Constant for the {@link #ifCmp ifCmp} method.
+ */
+ public final static int NE = Opcodes.IFNE;
+
+ /**
+ * Constant for the {@link #ifCmp ifCmp} method.
+ */
+ public final static int LT = Opcodes.IFLT;
+
+ /**
+ * Constant for the {@link #ifCmp ifCmp} method.
+ */
+ public final static int GE = Opcodes.IFGE;
+
+ /**
+ * Constant for the {@link #ifCmp ifCmp} method.
+ */
+ public final static int GT = Opcodes.IFGT;
+
+ /**
+ * Constant for the {@link #ifCmp ifCmp} method.
+ */
+ public final static int LE = Opcodes.IFLE;
+
+ /**
+ * Access flags of the method visited by this adapter.
+ */
+ private final int access;
+
+ /**
+ * Return type of the method visited by this adapter.
+ */
+ private final Type returnType;
+
+ /**
+ * Argument types of the method visited by this adapter.
+ */
+ private final Type[] argumentTypes;
+
+ /**
+ * Types of the local variables of the method visited by this adapter.
+ */
+ private final List localTypes;
+
+ /**
+ * Creates a new {@link GeneratorAdapter}.
+ *
+ * @param mv the method visitor to which this adapter delegates calls.
+ * @param access the method's access flags (see {@link Opcodes}).
+ * @param name the method's name.
+ * @param desc the method's descriptor (see {@link Type Type}).
+ */
+ public GeneratorAdapter(
+ MethodVisitor mv,
+ int access,
+ String name,
+ String desc)
+ {
+ super(access, desc, mv);
+ this.access = access;
+ this.returnType = Type.getReturnType(desc);
+ this.argumentTypes = Type.getArgumentTypes(desc);
+ this.localTypes = new ArrayList();
+ }
+
+ /**
+ * Creates a new {@link GeneratorAdapter}.
+ *
+ * @param access access flags of the adapted method.
+ * @param method the adapted method.
+ * @param mv the method visitor to which this adapter delegates calls.
+ */
+ public GeneratorAdapter(
+ final int access,
+ final Method method,
+ final MethodVisitor mv)
+ {
+ super(access, method.getDescriptor(), mv);
+ this.access = access;
+ this.returnType = method.getReturnType();
+ this.argumentTypes = method.getArgumentTypes();
+ this.localTypes = new ArrayList();
+ }
+
+ /**
+ * Creates a new {@link GeneratorAdapter}.
+ *
+ * @param access access flags of the adapted method.
+ * @param method the adapted method.
+ * @param signature the signature of the adapted method (may be
+ * <tt>null</tt>).
+ * @param exceptions the exceptions thrown by the adapted method (may be
+ * <tt>null</tt>).
+ * @param cv the class visitor to which this adapter delegates calls.
+ */
+ public GeneratorAdapter(
+ final int access,
+ final Method method,
+ final String signature,
+ final Type[] exceptions,
+ final ClassVisitor cv)
+ {
+ this(access, method, cv.visitMethod(access,
+ method.getName(),
+ method.getDescriptor(),
+ signature,
+ getInternalNames(exceptions)));
+ }
+
+ /**
+ * Returns the internal names of the given types.
+ *
+ * @param types a set of types.
+ * @return the internal names of the given types.
+ */
+ private static String[] getInternalNames(final Type[] types) {
+ if (types == null) {
+ return null;
+ }
+ String[] names = new String[types.length];
+ for (int i = 0; i < names.length; ++i) {
+ names[i] = types[i].getInternalName();
+ }
+ return names;
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to push constants on the stack
+ // ------------------------------------------------------------------------
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final boolean value) {
+ push(value ? 1 : 0);
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final int value) {
+ if (value >= -1 && value <= 5) {
+ mv.visitInsn(Opcodes.ICONST_0 + value);
+ } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.BIPUSH, value);
+ } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+ mv.visitIntInsn(Opcodes.SIPUSH, value);
+ } else {
+ mv.visitLdcInsn(new Integer(value));
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final long value) {
+ if (value == 0L || value == 1L) {
+ mv.visitInsn(Opcodes.LCONST_0 + (int) value);
+ } else {
+ mv.visitLdcInsn(new Long(value));
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final float value) {
+ int bits = Float.floatToIntBits(value);
+ if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
+ mv.visitInsn(Opcodes.FCONST_0 + (int) value);
+ } else {
+ mv.visitLdcInsn(new Float(value));
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final double value) {
+ long bits = Double.doubleToLongBits(value);
+ if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
+ mv.visitInsn(Opcodes.DCONST_0 + (int) value);
+ } else {
+ mv.visitLdcInsn(new Double(value));
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack. May be <tt>null</tt>.
+ */
+ public void push(final String value) {
+ if (value == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ /**
+ * Generates the instruction to push the given value on the stack.
+ *
+ * @param value the value to be pushed on the stack.
+ */
+ public void push(final Type value) {
+ if (value == null) {
+ mv.visitInsn(Opcodes.ACONST_NULL);
+ } else {
+ mv.visitLdcInsn(value);
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to load and store method arguments
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the index of the given method argument in the frame's local
+ * variables array.
+ *
+ * @param arg the index of a method argument.
+ * @return the index of the given method argument in the frame's local
+ * variables array.
+ */
+ private int getArgIndex(final int arg) {
+ int index = ((access & Opcodes.ACC_STATIC) == 0 ? 1 : 0);
+ for (int i = 0; i < arg; i++) {
+ index += argumentTypes[i].getSize();
+ }
+ return index;
+ }
+
+ /**
+ * Generates the instruction to push a local variable on the stack.
+ *
+ * @param type the type of the local variable to be loaded.
+ * @param index an index in the frame's local variables array.
+ */
+ private void loadInsn(final Type type, final int index) {
+ mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in a local
+ * variable.
+ *
+ * @param type the type of the local variable to be stored.
+ * @param index an index in the frame's local variables array.
+ */
+ private void storeInsn(final Type type, final int index) {
+ mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index);
+ }
+
+ /**
+ * Generates the instruction to load 'this' on the stack.
+ */
+ public void loadThis() {
+ if ((access & Opcodes.ACC_STATIC) != 0) {
+ throw new IllegalStateException("no 'this' pointer within static method");
+ }
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ }
+
+ /**
+ * Generates the instruction to load the given method argument on the stack.
+ *
+ * @param arg the index of a method argument.
+ */
+ public void loadArg(final int arg) {
+ loadInsn(argumentTypes[arg], getArgIndex(arg));
+ }
+
+ /**
+ * Generates the instructions to load the given method arguments on the
+ * stack.
+ *
+ * @param arg the index of the first method argument to be loaded.
+ * @param count the number of method arguments to be loaded.
+ */
+ public void loadArgs(final int arg, final int count) {
+ int index = getArgIndex(arg);
+ for (int i = 0; i < count; ++i) {
+ Type t = argumentTypes[arg + i];
+ loadInsn(t, index);
+ index += t.getSize();
+ }
+ }
+
+ /**
+ * Generates the instructions to load all the method arguments on the stack.
+ */
+ public void loadArgs() {
+ loadArgs(0, argumentTypes.length);
+ }
+
+ /**
+ * Generates the instructions to load all the method arguments on the stack,
+ * as a single object array.
+ */
+ public void loadArgArray() {
+ push(argumentTypes.length);
+ newArray(OBJECT_TYPE);
+ for (int i = 0; i < argumentTypes.length; i++) {
+ dup();
+ push(i);
+ loadArg(i);
+ box(argumentTypes[i]);
+ arrayStore(OBJECT_TYPE);
+ }
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in the given
+ * method argument.
+ *
+ * @param arg the index of a method argument.
+ */
+ public void storeArg(final int arg) {
+ storeInsn(argumentTypes[arg], getArgIndex(arg));
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to load and store local variables
+ // ------------------------------------------------------------------------
+
+ /**
+ * Creates a new local variable of the given type.
+ *
+ * @param type the type of the local variable to be created.
+ * @return the identifier of the newly created local variable.
+ */
+ public int newLocal(final Type type) {
+ int local = super.newLocal(type.getSize());
+ setLocalType(local, type);
+ return local;
+ }
+
+ /**
+ * Returns the type of the given local variable.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal
+ * newLocal}.
+ * @return the type of the given local variable.
+ */
+ public Type getLocalType(final int local) {
+ return (Type) localTypes.get(local - firstLocal);
+ }
+
+ /**
+ * Sets the current type of the given local variable.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal
+ * newLocal}.
+ * @param type the type of the value being stored in the local variable
+ */
+ private void setLocalType(final int local, final Type type) {
+ int index = local - firstLocal;
+ while (localTypes.size() < index + 1)
+ localTypes.add(null);
+ localTypes.set(index, type);
+ }
+
+ /**
+ * Generates the instruction to load the given local variable on the stack.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal
+ * newLocal}.
+ */
+ public void loadLocal(final int local) {
+ loadInsn(getLocalType(local), local);
+ }
+
+ /**
+ * Generates the instruction to load the given local variable on the stack.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal
+ * newLocal}.
+ * @param type the type of this local variable.
+ */
+ public void loadLocal(final int local, final Type type) {
+ setLocalType(local, type);
+ loadInsn(type, local);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in the given local
+ * variable.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal
+ * newLocal}.
+ */
+ public void storeLocal(final int local) {
+ storeInsn(getLocalType(local), local);
+ }
+
+ /**
+ * Generates the instruction to store the top stack value in the given local
+ * variable.
+ *
+ * @param local a local variable identifier, as returned by {@link #newLocal
+ * newLocal}.
+ * @param type the type of this local variable.
+ */
+ public void storeLocal(final int local, final Type type) {
+ setLocalType(local, type);
+ storeInsn(type, local);
+ }
+
+ /**
+ * Generates the instruction to load an element from an array.
+ *
+ * @param type the type of the array element to be loaded.
+ */
+ public void arrayLoad(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
+ }
+
+ /**
+ * Generates the instruction to store an element in an array.
+ *
+ * @param type the type of the array element to be stored.
+ */
+ public void arrayStore(final Type type) {
+ mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to manage the stack
+ // ------------------------------------------------------------------------
+
+ /**
+ * Generates a POP instruction.
+ */
+ public void pop() {
+ mv.visitInsn(Opcodes.POP);
+ }
+
+ /**
+ * Generates a POP2 instruction.
+ */
+ public void pop2() {
+ mv.visitInsn(Opcodes.POP2);
+ }
+
+ /**
+ * Generates a DUP instruction.
+ */
+ public void dup() {
+ mv.visitInsn(Opcodes.DUP);
+ }
+
+ /**
+ * Generates a DUP2 instruction.
+ */
+ public void dup2() {
+ mv.visitInsn(Opcodes.DUP2);
+ }
+
+ /**
+ * Generates a DUP_X1 instruction.
+ */
+ public void dupX1() {
+ mv.visitInsn(Opcodes.DUP_X1);
+ }
+
+ /**
+ * Generates a DUP_X2 instruction.
+ */
+ public void dupX2() {
+ mv.visitInsn(Opcodes.DUP_X2);
+ }
+
+ /**
+ * Generates a DUP2_X1 instruction.
+ */
+ public void dup2X1() {
+ mv.visitInsn(Opcodes.DUP2_X1);
+ }
+
+ /**
+ * Generates a DUP2_X2 instruction.
+ */
+ public void dup2X2() {
+ mv.visitInsn(Opcodes.DUP2_X2);
+ }
+
+ /**
+ * Generates a SWAP instruction.
+ */
+ public void swap() {
+ mv.visitInsn(Opcodes.SWAP);
+ }
+
+ /**
+ * Generates the instructions to swap the top two stack values.
+ *
+ * @param prev type of the top - 1 stack value.
+ * @param type type of the top stack value.
+ */
+ public void swap(final Type prev, final Type type) {
+ if (type.getSize() == 1) {
+ if (prev.getSize() == 1) {
+ swap(); // same as dupX1(), pop();
+ } else {
+ dupX2();
+ pop();
+ }
+ } else {
+ if (prev.getSize() == 1) {
+ dup2X1();
+ pop2();
+ } else {
+ dup2X2();
+ pop2();
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to do mathematical and logical operations
+ // ------------------------------------------------------------------------
+
+ /**
+ * Generates the instruction to do the specified mathematical or logical
+ * operation.
+ *
+ * @param op a mathematical or logical operation. Must be one of ADD, SUB,
+ * MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR.
+ * @param type the type of the operand(s) for this operation.
+ */
+ public void math(final int op, final Type type) {
+ mv.visitInsn(type.getOpcode(op));
+ }
+
+ /**
+ * Generates the instructions to compute the bitwise negation of the top
+ * stack value.
+ */
+ public void not() {
+ mv.visitInsn(Opcodes.ICONST_1);
+ mv.visitInsn(Opcodes.IXOR);
+ }
+
+ /**
+ * Generates the instruction to increment the given local variable.
+ *
+ * @param local the local variable to be incremented.
+ * @param amount the amount by which the local variable must be incremented.
+ */
+ public void iinc(final int local, final int amount) {
+ mv.visitIincInsn(local, amount);
+ }
+
+ /**
+ * Generates the instructions to cast a numerical value from one type to
+ * another.
+ *
+ * @param from the type of the top stack value
+ * @param to the type into which this value must be cast.
+ */
+ public void cast(final Type from, final Type to) {
+ if (from != to) {
+ if (from == Type.DOUBLE_TYPE) {
+ if (to == Type.FLOAT_TYPE) {
+ mv.visitInsn(Opcodes.D2F);
+ } else if (to == Type.LONG_TYPE) {
+ mv.visitInsn(Opcodes.D2L);
+ } else {
+ mv.visitInsn(Opcodes.D2I);
+ cast(Type.INT_TYPE, to);
+ }
+ } else if (from == Type.FLOAT_TYPE) {
+ if (to == Type.DOUBLE_TYPE) {
+ mv.visitInsn(Opcodes.F2D);
+ } else if (to == Type.LONG_TYPE) {
+ mv.visitInsn(Opcodes.F2L);
+ } else {
+ mv.visitInsn(Opcodes.F2I);
+ cast(Type.INT_TYPE, to);
+ }
+ } else if (from == Type.LONG_TYPE) {
+ if (to == Type.DOUBLE_TYPE) {
+ mv.visitInsn(Opcodes.L2D);
+ } else if (to == Type.FLOAT_TYPE) {
+ mv.visitInsn(Opcodes.L2F);
+ } else {
+ mv.visitInsn(Opcodes.L2I);
+ cast(Type.INT_TYPE, to);
+ }
+ } else {
+ if (to == Type.BYTE_TYPE) {
+ mv.visitInsn(Opcodes.I2B);
+ } else if (to == Type.CHAR_TYPE) {
+ mv.visitInsn(Opcodes.I2C);
+ } else if (to == Type.DOUBLE_TYPE) {
+ mv.visitInsn(Opcodes.I2D);
+ } else if (to == Type.FLOAT_TYPE) {
+ mv.visitInsn(Opcodes.I2F);
+ } else if (to == Type.LONG_TYPE) {
+ mv.visitInsn(Opcodes.I2L);
+ } else if (to == Type.SHORT_TYPE) {
+ mv.visitInsn(Opcodes.I2S);
+ }
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to do boxing and unboxing operations
+ // ------------------------------------------------------------------------
+
+ /**
+ * Generates the instructions to box the top stack value. This value is
+ * replaced by its boxed equivalent on top of the stack.
+ *
+ * @param type the type of the top stack value.
+ */
+ public void box(final Type type) {
+ if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+ return;
+ }
+ if (type == Type.VOID_TYPE) {
+ push((String) null);
+ } else {
+ Type boxed = type;
+ switch (type.getSort()) {
+ case Type.BYTE:
+ boxed = BYTE_TYPE;
+ break;
+ case Type.BOOLEAN:
+ boxed = BOOLEAN_TYPE;
+ break;
+ case Type.SHORT:
+ boxed = SHORT_TYPE;
+ break;
+ case Type.CHAR:
+ boxed = CHARACTER_TYPE;
+ break;
+ case Type.INT:
+ boxed = INTEGER_TYPE;
+ break;
+ case Type.FLOAT:
+ boxed = FLOAT_TYPE;
+ break;
+ case Type.LONG:
+ boxed = LONG_TYPE;
+ break;
+ case Type.DOUBLE:
+ boxed = DOUBLE_TYPE;
+ break;
+ }
+ newInstance(boxed);
+ if (type.getSize() == 2) {
+ // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
+ dupX2();
+ dupX2();
+ pop();
+ } else {
+ // p -> po -> opo -> oop -> o
+ dupX1();
+ swap();
+ }
+ invokeConstructor(boxed, new Method("<init>",
+ Type.VOID_TYPE,
+ new Type[] { type }));
+ }
+ }
+
+ /**
+ * Generates the instructions to unbox the top stack value. This value is
+ * replaced by its unboxed equivalent on top of the stack.
+ *
+ * @param type the type of the top stack value.
+ */
+ public void unbox(final Type type) {
+ Type t = NUMBER_TYPE;
+ Method sig = null;
+ switch (type.getSort()) {
+ case Type.VOID:
+ return;
+ case Type.CHAR:
+ t = CHARACTER_TYPE;
+ sig = CHAR_VALUE;
+ break;
+ case Type.BOOLEAN:
+ t = BOOLEAN_TYPE;
+ sig = BOOLEAN_VALUE;
+ break;
+ case Type.DOUBLE:
+ sig = DOUBLE_VALUE;
+ break;
+ case Type.FLOAT:
+ sig = FLOAT_VALUE;
+ break;
+ case Type.LONG:
+ sig = LONG_VALUE;
+ break;
+ case Type.INT:
+ case Type.SHORT:
+ case Type.BYTE:
+ sig = INT_VALUE;
+ }
+ if (sig == null) {
+ checkCast(type);
+ } else {
+ checkCast(t);
+ invokeVirtual(t, sig);
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Instructions to jump to other instructions
+ // ------------------------------------------------------------------------
+
+ /**
+ * Creates a new {@link Label}.
+ *
+ * @return a new {@link Label}.
+ */
+ public Label newLabel() {
+ return new Label();
+ }
+
+ /**
+ * Marks the current code position with the given label.
+ *
+ * @param label a label.
+ */
+ public void mark(final Label label) {
+ mv.visitLabel(label);
+ }
+
+ /**
+ * Marks the current code position with a new label.
+ *
+ * @return the label that was created to mark the current code position.
+ */
+ public Label mark() {
+ Label label = new Label();
+ mv.visitLabel(label);
+ return label;
+ }
+
+ /**
+ * Generates the instructions to jump to a label based on the comparison of
+ * the top two stack values.
+ *
+ * @param type the type of the top two stack values.
+ * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT,
+ * LE.
+ * @param label where to jump if the comparison result is <tt>true</tt>.
+ */
+ public void ifCmp(final Type type, final int mode, final Label label) {
+ int intOp = -1;
+ int jumpMode = mode;
+ switch (mode) {
+ case GE:
+ jumpMode = LT;
+ break;
+ case LE:
+ jumpMode = GT;
+ break;
+ }
+ switch (type.getSort()) {
+ case Type.LONG:
+ mv.visitInsn(Opcodes.LCMP);
+ break;
+ case Type.DOUBLE:
+ mv.visitInsn(Opcodes.DCMPG);
+ break;
+ case Type.FLOAT:
+ mv.visitInsn(Opcodes.FCMPG);
+ break;
+ case Type.ARRAY:
+ case Type.OBJECT:
+ switch (mode) {
+ case EQ:
+ mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
+ return;
+ case NE:
+ mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+ return;
+ }
+ throw new IllegalArgumentException("Bad comparison for type "
+ + type);
+ default:
+ switch (mode) {
+ case EQ:
+ intOp = Opcodes.IF_ICMPEQ;
+ break;
+ case NE:
+ intOp = Opcodes.IF_ICMPNE;
+ break;
+ case GE:
+ intOp = Opcodes.IF_ICMPGE;
+ break;
+ case LT:
+ intOp = Opcodes.IF_ICMPLT;
+ break;
+ case LE:
+ intOp = Opcodes.IF_ICMPLE;
+ break;
+ case GT:
+ intOp = Opcodes.IF_ICMPGT;
+ break;
+ }
+ mv.visitJumpInsn(intOp, label);
+ return;
+ }
+ mv.visitJumpInsn(jumpMode, label);
+ }
+
+ /**
+ * Generates the instructions to jump to a label based on the comparison of
+ * the top two integer stack values.
+ *
+ * @param mode how these values must be compared. One of EQ, NE, LT, GE, GT,
+ * LE.
+ * @param label where to jump if the comparison result is <tt>true</tt>.
+ */
+ public void ifICmp(final int mode, final Label label) {
+ ifCmp(Type.INT_TYPE, mode, label);
+ }
+
+ /**
+ * Generates the instructions to jump to a label based on the comparison of
+ * the top integer stack value with zero.
+ *
+ * @param mode how the...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 13:36:57
|
Revision: 3028
http://jnode.svn.sourceforge.net/jnode/?rev=3028&view=rev
Author: lsantha
Date: 2007-01-07 05:36:55 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/org/org/objectweb/
trunk/core/src/classpath/org/org/objectweb/asm/
trunk/core/src/classpath/org/org/objectweb/asm/attrs/
trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapAttribute.java
trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapFrame.java
trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapTableAttribute.java
trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapType.java
trunk/core/src/classpath/org/org/objectweb/asm/attrs/package.html
Added: trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapAttribute.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapAttribute.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapAttribute.java 2007-01-07 13:36:55 UTC (rev 3028)
@@ -0,0 +1,378 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.attrs;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+
+/**
+ * StackMapAttribute is used by CDLC preverifier. Definition is given in
+ * appendix "CLDC Byte Code Typechecker Specification" from CDLC 1.1
+ * specification. <p> <i>Note that this implementation does not calculate
+ * StackMapFrame structures from the method bytecode. If method code is changed
+ * or generated from scratch, then developer is responsible to prepare a correct
+ * StackMapFrame structures.</i> <p> The format of the stack map in the class
+ * file is given below. In the following, <ul> <li>if the length of the
+ * method's byte code1 is 65535 or less, then <tt>uoffset</tt> represents the
+ * type u2; otherwise <tt>uoffset</tt> represents the type u4.</li> <li>If
+ * the maximum number of local variables for the method is 65535 or less, then
+ * <tt>ulocalvar</tt> represents the type u2; otherwise <tt>ulocalvar</tt>
+ * represents the type u4.</li> <li>If the maximum size of the operand stack
+ * is 65535 or less, then <tt>ustack</tt> represents the type u2; otherwise
+ * ustack represents the type u4.</li> </ul>
+ *
+ * <pre>
+ * stack_map { // attribute StackMap
+ * u2 attribute_name_index;
+ * u4 attribute_length
+ * uoffset number_of_entries;
+ * stack_map_frame entries[number_of_entries];
+ * }
+ * </pre>
+ *
+ * Each stack map frame has the following format:
+ *
+ * <pre>
+ * stack_map_frame {
+ * uoffset offset;
+ * ulocalvar number_of_locals;
+ * verification_type_info locals[number_of_locals];
+ * ustack number_of_stack_items;
+ * verification_type_info stack[number_of_stack_items];
+ * }
+ * </pre>
+ *
+ * The <tt>verification_type_info</tt> structure consists of a one-byte tag
+ * followed by zero or more bytes, giving more information about the tag. Each
+ * <tt>verification_type_info</tt> structure specifies the verification type
+ * of one or two locations.
+ *
+ * <pre>
+ * union verification_type_info {
+ * Top_variable_info;
+ * Integer_variable_info;
+ * Float_variable_info;
+ * Long_variable_info;
+ * Double_variable_info;
+ * Null_variable_info;
+ * UninitializedThis_variable_info;
+ * Object_variable_info;
+ * Uninitialized_variable_info;
+ * }
+ *
+ * Top_variable_info {
+ * u1 tag = ITEM_Top; // 0
+ * }
+ *
+ * Integer_variable_info {
+ * u1 tag = ITEM_Integer; // 1
+ * }
+ *
+ * Float_variable_info {
+ * u1 tag = ITEM_Float; // 2
+ * }
+ *
+ * Long_variable_info {
+ * u1 tag = ITEM_Long; // 4
+ * }
+ *
+ * Double_variable_info {
+ * u1 tag = ITEM_Double; // 3
+ * }
+ *
+ * Null_variable_info {
+ * u1 tag = ITEM_Null; // 5
+ * }
+ *
+ * UninitializedThis_variable_info {
+ * u1 tag = ITEM_UninitializedThis; // 6
+ * }
+ *
+ * Object_variable_info {
+ * u1 tag = ITEM_Object; // 7
+ * u2 cpool_index;
+ * }
+ *
+ * Uninitialized_variable_info {
+ * u1 tag = ITEM_Uninitialized // 8
+ * uoffset offset;
+ * }
+ * </pre>
+ *
+ * @see <a href="http://www.jcp.org/en/jsr/detail?id=139">JSR 139 : Connected
+ * Limited Device Configuration 1.1</a>
+ *
+ * @author Eugene Kuleshov
+ */
+public class StackMapAttribute extends Attribute {
+
+ static final int MAX_SIZE = 65535;
+
+ /**
+ * A List of <code>StackMapFrame</code> instances.
+ */
+ public List frames = new ArrayList();
+
+ public StackMapAttribute() {
+ super("StackMap");
+ }
+
+ public StackMapAttribute(List frames) {
+ this();
+ this.frames = frames;
+ }
+
+ public List getFrames() {
+ return frames;
+ }
+
+ public StackMapFrame getFrame(Label label) {
+ for (int i = 0; i < frames.size(); i++) {
+ StackMapFrame frame = (StackMapFrame) frames.get(i);
+ if (frame.label == label) {
+ return frame;
+ }
+ }
+ return null;
+ }
+
+ public boolean isUnknown() {
+ return false;
+ }
+
+ public boolean isCodeAttribute() {
+ return true;
+ }
+
+ protected Attribute read(
+ ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+ StackMapAttribute attr = new StackMapAttribute();
+ // note that this is not the size of Code attribute
+ boolean isExtCodeSize = cr.readInt(codeOff + 4) > MAX_SIZE;
+ boolean isExtLocals = cr.readUnsignedShort(codeOff + 2) > MAX_SIZE;
+ boolean isExtStack = cr.readUnsignedShort(codeOff) > MAX_SIZE;
+
+ int size = 0;
+ if (isExtCodeSize) {
+ size = cr.readInt(off);
+ off += 4;
+ } else {
+ size = cr.readUnsignedShort(off);
+ off += 2;
+ }
+ for (int i = 0; i < size; i++) {
+ int offset;
+ if (isExtCodeSize) {
+ offset = cr.readInt(off);
+ off += 4;
+ } else {
+ offset = cr.readUnsignedShort(off);
+ off += 2;
+ }
+
+ Label label = getLabel(offset, labels);
+ List locals = new ArrayList();
+ List stack = new ArrayList();
+
+ off = readTypeInfo(cr,
+ off,
+ locals,
+ labels,
+ buf,
+ isExtLocals,
+ isExtCodeSize);
+ off = readTypeInfo(cr,
+ off,
+ stack,
+ labels,
+ buf,
+ isExtStack,
+ isExtCodeSize);
+
+ attr.frames.add(new StackMapFrame(label, locals, stack));
+ }
+ return attr;
+ }
+
+ private int readTypeInfo(
+ ClassReader cr,
+ int off,
+ List info,
+ Label[] labels,
+ char[] buf,
+ boolean isExt,
+ boolean isExtCode)
+ {
+ int n = 0;
+ if (isExt) {
+ n = cr.readInt(off);
+ off += 4;
+ } else {
+ n = cr.readUnsignedShort(off);
+ off += 2;
+ }
+ for (int j = 0; j < n; j++) {
+ int itemType = cr.readByte(off++);
+ StackMapType typeInfo = StackMapType.getTypeInfo(itemType);
+ info.add(typeInfo);
+ switch (itemType) {
+ case StackMapType.ITEM_Object: //
+ typeInfo.setObject(cr.readClass(off, buf));
+ off += 2;
+ break;
+ case StackMapType.ITEM_Uninitialized: //
+ int offset;
+ if (isExtCode) {
+ offset = cr.readInt(off);
+ off += 4;
+ } else {
+ offset = cr.readUnsignedShort(off);
+ off += 2;
+ }
+ typeInfo.setLabel(getLabel(offset, labels));
+ break;
+ }
+ }
+ return off;
+ }
+
+ private void writeTypeInfo(ByteVector bv, ClassWriter cw, List info, int max)
+ {
+ if (max > StackMapAttribute.MAX_SIZE) {
+ bv.putInt(info.size());
+ } else {
+ bv.putShort(info.size());
+ }
+ for (int j = 0; j < info.size(); j++) {
+ StackMapType typeInfo = (StackMapType) info.get(j);
+ bv.putByte(typeInfo.getType());
+ switch (typeInfo.getType()) {
+ case StackMapType.ITEM_Object: //
+ bv.putShort(cw.newClass(typeInfo.getObject()));
+ break;
+
+ case StackMapType.ITEM_Uninitialized: //
+ bv.putShort(typeInfo.getLabel().getOffset());
+ break;
+
+ }
+ }
+ }
+
+ private Label getLabel(int offset, Label[] labels) {
+ Label l = labels[offset];
+ if (l != null) {
+ return l;
+ }
+ return labels[offset] = new Label();
+ }
+
+ protected ByteVector write(
+ ClassWriter cw,
+ byte[] code,
+ int len,
+ int maxStack,
+ int maxLocals)
+ {
+ ByteVector bv = new ByteVector();
+ if (code != null && code.length > MAX_SIZE) { // TODO verify value
+ bv.putInt(frames.size());
+ } else {
+ bv.putShort(frames.size());
+ }
+ for (int i = 0; i < frames.size(); i++) {
+ writeFrame((StackMapFrame) frames.get(i),
+ cw,
+ maxStack,
+ maxLocals,
+ bv);
+ }
+ return bv;
+ }
+
+ protected Label[] getLabels() {
+ HashSet labels = new HashSet();
+ for (int i = 0; i < frames.size(); i++) {
+ getFrameLabels((StackMapFrame) frames.get(i), labels);
+ }
+ return (Label[]) labels.toArray(new Label[labels.size()]);
+ }
+
+ private void writeFrame(
+ StackMapFrame frame,
+ ClassWriter cw,
+ int maxStack,
+ int maxLocals,
+ ByteVector bv)
+ {
+ bv.putShort(frame.label.getOffset());
+ writeTypeInfo(bv, cw, frame.locals, maxLocals);
+ writeTypeInfo(bv, cw, frame.stack, maxStack);
+ }
+
+ private void getFrameLabels(StackMapFrame frame, Set labels) {
+ labels.add(frame.label);
+ getTypeInfoLabels(labels, frame.locals);
+ getTypeInfoLabels(labels, frame.stack);
+ }
+
+ private void getTypeInfoLabels(Set labels, List info) {
+ for (Iterator it = info.iterator(); it.hasNext();) {
+ StackMapType typeInfo = (StackMapType) it.next();
+ if (typeInfo.getType() == StackMapType.ITEM_Uninitialized) {
+ labels.add(typeInfo.getLabel());
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer("StackMap[");
+ for (int i = 0; i < frames.size(); i++) {
+ sb.append('\n').append('[').append(frames.get(i)).append(']');
+ }
+ sb.append("\n]");
+ return sb.toString();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapFrame.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapFrame.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapFrame.java 2007-01-07 13:36:55 UTC (rev 3028)
@@ -0,0 +1,82 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.attrs;
+
+import java.util.List;
+
+import org.objectweb.asm.Label;
+
+/**
+ * Holds the state of the stack and local variables for a single execution
+ * branch.
+ *
+ * <i>Note that Long and Double types are represented by two entries in locals
+ * and stack. Second entry should be always of type Top.</i>
+ *
+ * @see <a href="http://www.jcp.org/en/jsr/detail?id=139">JSR 139 : Connected
+ * Limited Device Configuration 1.1</a>
+ *
+ * @see "ClassFileFormat-Java6.fm Page 138 Friday, April 15, 2005 3:22 PM"
+ *
+ * @author Eugene Kuleshov
+ */
+public class StackMapFrame {
+
+ /**
+ * A <code>Label</code> for frame offset within method bytecode.
+ */
+ public Label label;
+
+ /**
+ * A List of <code>StackMapType</code> instances that represent locals for
+ * this frame.
+ */
+ public List locals;
+
+ /**
+ * A List of <code>StackMapType</code> instances that represent stack for
+ * this frame.
+ */
+ public List stack;
+
+ public StackMapFrame(Label label, List locals, List stack) {
+ this.label = label;
+ this.locals = locals;
+ this.stack = stack;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer("Frame:L");
+ sb.append(System.identityHashCode(label));
+ sb.append(" locals").append(locals);
+ sb.append(" stack").append(stack);
+ return sb.toString();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapTableAttribute.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapTableAttribute.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapTableAttribute.java 2007-01-07 13:36:55 UTC (rev 3028)
@@ -0,0 +1,927 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.attrs;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * The stack map attribute is used during the process of verification by
+ * typechecking (\xA74.11.1). <br> <br> A stack map attribute consists of zero or
+ * more stack map frames. Each stack map frame specifies (either explicitly or
+ * implicitly) a bytecode offset, the verification types (\xA74.11.1) for the local
+ * variables, and the verification types for the operand stack. <br> <br> The
+ * type checker deals with and manipulates the expected types of a method's
+ * local variables and operand stack. Throughout this section, a location refers
+ * to either a single local variable or to a single operand stack entry. <br>
+ * <br> We will use the terms stack frame map and type state interchangeably to
+ * describe a mapping from locations in the operand stack and local variables of
+ * a method to verification types. We will usually use the term stack frame map
+ * when such a mapping is provided in the class file, and the term type state
+ * when the mapping is inferred by the type checker. <br> <br> If a method's
+ * Code attribute does not have a StackMapTable attribute, it has an implicit
+ * stack map attribute. This implicit stack map attribute is equivalent to a
+ * StackMapTable attribute with number_of_entries equal to zero. A method's Code
+ * attribute may have at most one StackMapTable attribute, otherwise a
+ * java.lang.ClassFormatError is thrown. <br> <br> The format of the stack map
+ * in the class file is given below. In the following, if the length of the
+ * method's byte code is 65535 or less, then uoffset represents the type u2;
+ * otherwise uoffset represents the type u4. If the maximum number of local
+ * variables for the method is 65535 or less, then <code>ulocalvar</code>
+ * represents the type u2; otherwise ulocalvar represents the type u4. If the
+ * maximum size of the operand stack is 65535 or less, then <code>ustack</code>
+ * represents the type u2; otherwise ustack represents the type u4.
+ *
+ * <pre>
+ * stack_map { // attribute StackMapTable
+ * u2 attribute_name_index;
+ * u4 attribute_length
+ * uoffset number_of_entries;
+ * stack_map_frame entries[number_of_entries];
+ * }
+ * </pre>
+ *
+ * Each stack_map_frame structure specifies the type state at a particular byte
+ * code offset. Each frame type specifies (explicitly or implicitly) a value,
+ * offset_delta, that is used to calulate the actual byte code offset at which
+ * it applies. The byte code offset at which the frame applies is given by
+ * adding <code>1 + offset_delta</code> to the <code>offset</code> of the
+ * previous frame, unless the previous frame is the initial frame of the method,
+ * in which case the byte code offset is <code>offset_delta</code>. <br> <br>
+ * <i>Note that the length of the byte codes is not the same as the length of
+ * the Code attribute. The byte codes are embedded in the Code attribute, along
+ * with other information.</i> <br> <br> By using an offset delta rather than
+ * the actual byte code offset we ensure, by definition, that stack map frames
+ * are in the correctly sorted order. Furthermore, by consistently using the
+ * formula <code>offset_delta + 1</code> for all explicit frames, we guarantee
+ * the absence of duplicates. <br> <br> All frame types, even full_frame, rely
+ * on the previous frame for some of their semantics. This raises the question
+ * of what is the very first frame? The initial frame is implicit, and computed
+ * from the method descriptor. See the Prolog code for methodInitialStacFrame.
+ * <br> <br> The stack_map_frame structure consists of a one-byte tag followed
+ * by zero or more bytes, giving more information, depending upon the tag. <br>
+ * <br> A stack map frame may belong to one of several frame types
+ *
+ * <pre>
+ * union stack_map_frame {
+ * same_frame;
+ * same_locals_1_stack_item_frame;
+ * chop_frame;
+ * same_frame_extended;
+ * append_frame;
+ * full_frame;
+ * }
+ * </pre>
+ *
+ * The frame type same_frame is represented by tags in the range [0-63]. If the
+ * frame type is same_frame, it means the frame has exactly the same locals as
+ * the previous stack map frame and that the number of stack items is zero. The
+ * offset_delta value for the frame is the value of the tag field, frame_type.
+ * The form of such a frame is then:
+ *
+ * <pre>
+ * same_frame {
+ * u1 frame_type = SAME; // 0-63
+ * }
+ * </pre>
+ *
+ * The frame type same_locals_1_stack_item_frame is represented by tags in the
+ * range [64, 127]. If the frame_type is same_locals_1_stack_item_frame, it
+ * means the frame has exactly the same locals as the previous stack map frame
+ * and that the number of stack items is 1. The offset_delta value for the frame
+ * is the value (frame_type - 64). There is a verification_type_info following
+ * the frame_type for the one stack item. The form of such a frame is then:
+ *
+ * <pre>
+ * same_locals_1_stack_item_frame {
+ * u1 frame_type = SAME_LOCALS_1_STACK_ITEM; // 64-127
+ * verification_type_info stack[1];
+ * }
+ * </pre>
+ *
+ * Tags in the range [128-247] are reserved for future use. <br> <br> The frame
+ * type chop_frame is represented by tags in the range [248-250]. If the
+ * frame_type is chop_frame, it means that the current locals are the same as
+ * the locals in the previous frame, except that the k last locals are absent.
+ * The value of k is given by the formula 251-frame_type. <br> <br> The form of
+ * such a frame is then:
+ *
+ * <pre>
+ * chop_frame {
+ * u1 frame_type=CHOP; // 248-250
+ * uoffset offset_delta;
+ * }
+ * </pre>
+ *
+ * The frame type same_frame_extended is represented by the tag value 251. If
+ * the frame type is same_frame_extended, it means the frame has exactly the
+ * same locals as the previous stack map frame and that the number of stack
+ * items is zero. The form of such a frame is then:
+ *
+ * <pre>
+ * same_frame_extended {
+ * u1 frame_type = SAME_FRAME_EXTENDED; // 251
+ * uoffset offset_delta;
+ * }
+ * </pre>
+ *
+ * The frame type append_frame is represented by tags in the range [252-254]. If
+ * the frame_type is append_frame, it means that the current locals are the same
+ * as the locals in the previous frame, except that k additional locals are
+ * defined. The value of k is given by the formula frame_type-251. <br> <br> The
+ * form of such a frame is then:
+ *
+ * <pre>
+ * append_frame {
+ * u1 frame_type =APPEND; // 252-254
+ * uoffset offset_delta;
+ * verification_type_info locals[frame_type -251];
+ * }
+ * </pre>
+ *
+ * The 0th entry in locals represents the type of the first additional local
+ * variable. If locals[M] represents local variable N, then locals[M+1]
+ * represents local variable N+1 if locals[M] is one of Top_variable_info,
+ * Integer_variable_info, Float_variable_info, Null_variable_info,
+ * UninitializedThis_variable_info, Object_variable_info, or
+ * Uninitialized_variable_info, otherwise locals[M+1] represents local variable
+ * N+2. It is an error if, for any index i, locals[i] represents a local
+ * variable whose index is greater than the maximum number of local variables
+ * for the method. <br> <br> The frame type full_frame is represented by the tag
+ * value 255. The form of such a frame is then:
+ *
+ * <pre>
+ * full_frame {
+ * u1 frame_type = FULL_FRAME; // 255
+ * uoffset offset_delta;
+ * ulocalvar number_of_locals;
+ * verification_type_info locals[number_of_locals];
+ * ustack number_of_stack_items;
+ * verification_type_info stack[number_of_stack_items];
+ * }
+ * </pre>
+ *
+ * The 0th entry in locals represents the type of local variable 0. If locals[M]
+ * represents local variable N, then locals[M+1] represents local variable N+1
+ * if locals[M] is one of Top_variable_info, Integer_variable_info,
+ * Float_variable_info, Null_variable_info, UninitializedThis_variable_info,
+ * Object_variable_info, or Uninitialized_variable_info, otherwise locals[M+1]
+ * represents local variable N+2. It is an error if, for any index i, locals[i]
+ * represents a local variable whose index is greater than the maximum number of
+ * local variables for the method. <br> <br> The 0th entry in stack represents
+ * the type of the bottom of the stack, and subsequent entries represent types
+ * of stack elements closer to the top of the operand stack. We shall refer to
+ * the bottom element of the stack as stack element 0, and to subsequent
+ * elements as stack element 1, 2 etc. If stack[M] represents stack element N,
+ * then stack[M+1] represents stack element N+1 if stack[M] is one of
+ * Top_variable_info, Integer_variable_info, Float_variable_info,
+ * Null_variable_info, UninitializedThis_variable_info, Object_variable_info, or
+ * Uninitialized_variable_info, otherwise stack[M+1] represents stack element
+ * N+2. It is an error if, for any index i, stack[i] represents a stack entry
+ * whose index is greater than the maximum operand stack size for the method.
+ * <br> <br> We say that an instruction in the byte code has a corresponding
+ * stack map frame if the offset in the offset field of the stack map frame is
+ * the same as the offset of the instruction in the byte codes. <br> <br> The
+ * verification_type_info structure consists of a one-byte tag followed by zero
+ * or more bytes, giving more information about the tag. Each
+ * verification_type_info structure specifies the verification type of one or
+ * two locations.
+ *
+ * <pre>
+ * union verification_type_info {
+ * Top_variable_info;
+ * Integer_variable_info;
+ * Float_variable_info;
+ * Long_variable_info;
+ * Double_variable_info;
+ * Null_variable_info;
+ * UninitializedThis_variable_info;
+ * Object_variable_info;
+ * Uninitialized_variable_info;
+ * }
+ * </pre>
+ *
+ * The Top_variable_info type indicates that the local variable has the
+ * verification type top (T.)
+ *
+ * <pre>
+ * Top_variable_info {
+ * u1 tag = ITEM_Top; // 0
+ * }
+ * </pre>
+ *
+ * The Integer_variable_info type indicates that the location contains the
+ * verification type int.
+ *
+ * <pre>
+ * Integer_variable_info {
+ * u1 tag = ITEM_Integer; // 1
+ * }
+ * </pre>
+ *
+ * The Float_variable_info type indicates that the location contains the
+ * verification type float.
+ *
+ * <pre>
+ * Float_variable_info {
+ * u1 tag = ITEM_Float; // 2
+ * }
+ * </pre>
+ *
+ * The Long_variable_info type indicates that the location contains the
+ * verification type long. If the location is a local variable, then:
+ *
+ * <ul> <li>It must not be the local variable with the highest index.</li>
+ * <li>The next higher numbered local variable contains the verification type
+ * T.</li> </ul>
+ *
+ * If the location is an operand stack entry, then:
+ *
+ * <ul> <li>The current location must not be the topmost location of the
+ * operand stack.</li> <li>the next location closer to the top of the operand
+ * stack contains the verification type T.</li> </ul>
+ *
+ * This structure gives the contents of two locations in the operand stack or in
+ * the local variables.
+ *
+ * <pre>
+ * Long_variable_info {
+ * u1 tag = ITEM_Long; // 4
+ * }
+ * </pre>
+ *
+ * The Double_variable_info type indicates that the location contains the
+ * verification type double. If the location is a local variable, then:
+ *
+ * <ul> <li>It must not be the local variable with the highest index.</li>
+ * <li>The next higher numbered local variable contains the verification type
+ * T. <li> </ul>
+ *
+ * If the location is an operand stack entry, then:
+ *
+ * <ul> <li>The current location must not be the topmost location of the
+ * operand stack.</li> <li>the next location closer to the top of the operand
+ * stack contains the verification type T.</li> </ul>
+ *
+ * This structure gives the contents of two locations in in the operand stack or
+ * in the local variables.
+ *
+ * <pre>
+ * Double_variable_info {
+ * u1 tag = ITEM_Double; // 3
+ * }
+ * </pre>
+ *
+ * The Null_variable_info type indicates that location contains the verification
+ * type null.
+ *
+ * <pre>
+ * Null_variable_info {
+ * u1 tag = ITEM_Null; // 5
+ * }
+ * </pre>
+ *
+ * The UninitializedThis_variable_info type indicates that the location contains
+ * the verification type uninitializedThis.
+ *
+ * <pre>
+ * UninitializedThis_variable_info {
+ * u1 tag = ITEM_UninitializedThis; // 6
+ * }
+ * </pre>
+ *
+ * The Object_variable_info type indicates that the location contains an
+ * instance of the class referenced by the constant pool entry.
+ *
+ * <pre>
+ * Object_variable_info {
+ * u1 tag = ITEM_Object; // 7
+ * u2 cpool_index;
+ * }
+ * </pre>
+ *
+ * The Uninitialized_variable_info indicates that the location contains the
+ * verification type uninitialized(offset). The offset item indicates the offset
+ * of the new instruction that created the object being stored in the location.
+ *
+ * <pre>
+ * Uninitialized_variable_info {
+ * u1 tag = ITEM_Uninitialized // 8
+ * uoffset offset;
+ * }
+ * </pre>
+ *
+ * @see "ClassFileFormat-Java6.fm Page 138 Friday, April 15, 2005 3:22 PM"
+ *
+ * @author Eugene Kuleshov
+ */
+public class StackMapTableAttribute extends Attribute {
+ /**
+ * Frame has exactly the same locals as the previous stack map frame and
+ * number of stack items is zero.
+ */
+ public static final int SAME_FRAME = 0; // to 63 (0-3f)
+
+ /**
+ * Frame has exactly the same locals as the previous stack map frame and
+ * number of stack items is 1
+ */
+ public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127
+
+ // (40-7f)
+
+ /**
+ * Reserved for future use
+ */
+ public static final int RESERVED = 128;
+
+ /**
+ * Frame has exactly the same locals as the previous stack map frame and
+ * number of stack items is 1. Offset is bigger then 63;
+ */
+ public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; // f7
+
+ /**
+ * Frame where current locals are the same as the locals in the previous
+ * frame, except that the k last locals are absent. The value of k is given
+ * by the formula 251-frame_type.
+ */
+ public static final int CHOP_FRAME = 248; // to 250 (f8-fA)
+
+ /**
+ * Frame has exactly the same locals as the previous stack map frame and
+ * number of stack items is zero. Offset is bigger then 63;
+ */
+ public static final int SAME_FRAME_EXTENDED = 251; // fb
+
+ /**
+ * Frame where current locals are the same as the locals in the previous
+ * frame, except that k additional locals are defined. The value of k is
+ * given by the formula frame_type-251.
+ */
+ public static final int APPEND_FRAME = 252; // to 254 // fc-fe
+
+ /**
+ * Full frame
+ */
+ public static final int FULL_FRAME = 255; // ff
+
+ private static final int MAX_SHORT = 65535;
+
+ /**
+ * A <code>List</code> of <code>StackMapFrame</code> instances.
+ */
+ private List frames;
+
+ public StackMapTableAttribute() {
+ super("StackMapTable");
+ }
+
+ public StackMapTableAttribute(List frames) {
+ this();
+ this.frames = frames;
+ }
+
+ public List getFrames() {
+ return frames;
+ }
+
+ public StackMapFrame getFrame(Label label) {
+ for (int i = 0; i < frames.size(); i++) {
+ StackMapFrame frame = (StackMapFrame) frames.get(i);
+ if (frame.label == label) {
+ return frame;
+ }
+ }
+ return null;
+ }
+
+ public boolean isUnknown() {
+ return false;
+ }
+
+ public boolean isCodeAttribute() {
+ return true;
+ }
+
+ protected Attribute read(
+ ClassReader cr,
+ int off,
+ int len,
+ char[] buf,
+ int codeOff,
+ Label[] labels)
+ {
+
+ ArrayList frames = new ArrayList();
+
+ // note that this is not the size of Code attribute
+ boolean isExtCodeSize = cr.readInt(codeOff + 4) > MAX_SHORT;
+ boolean isExtLocals = cr.readUnsignedShort(codeOff + 2) > MAX_SHORT;
+ boolean isExtStack = cr.readUnsignedShort(codeOff) > MAX_SHORT;
+
+ int offset = 0;
+
+ int methodOff = getMethodOff(cr, codeOff, buf);
+ StackMapFrame frame = new StackMapFrame(getLabel(offset, labels),
+ calculateLocals(cr.readClass(cr.header + 2, buf), // owner
+ cr.readUnsignedShort(methodOff), // method access
+ cr.readUTF8(methodOff + 2, buf), // method name
+ cr.readUTF8(methodOff + 4, buf)), // method desc
+ Collections.EMPTY_LIST);
+ frames.add(frame);
+
+ // System.err.println( cr.readUTF8( methodOff + 2, buf));
+ // System.err.println( offset +" delta:" + 0 +" : "+ frame);
+
+ int size;
+ if (isExtCodeSize) {
+ size = cr.readInt(off);
+ off += 4;
+ } else {
+ size = cr.readUnsignedShort(off);
+ off += 2;
+ }
+
+ for (; size > 0; size--) {
+ int tag = cr.readByte(off); // & 0xff;
+ off++;
+
+ List stack;
+ List locals;
+
+ int offsetDelta;
+ if (tag < SAME_LOCALS_1_STACK_ITEM_FRAME) { // SAME_FRAME
+ offsetDelta = tag;
+
+ locals = new ArrayList(frame.locals);
+ stack = Collections.EMPTY_LIST;
+
+ } else if (tag < RESERVED) { // SAME_LOCALS_1_STACK_ITEM_FRAME
+ offsetDelta = tag - SAME_LOCALS_1_STACK_ITEM_FRAME;
+
+ locals = new ArrayList(frame.locals);
+ stack = new ArrayList();
+ // read verification_type_info stack[1];
+ off = readType(stack, isExtCodeSize, cr, off, labels, buf);
+
+ } else {
+ if (isExtCodeSize) {
+ offsetDelta = cr.readInt(off);
+ off += 4;
+ } else {
+ offsetDelta = cr.readUnsignedShort(off);
+ off += 2;
+ }
+
+ if (tag == SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED
+ locals = new ArrayList(frame.locals);
+ stack = new ArrayList();
+ // read verification_type_info stack[1];
+ off = readType(stack, isExtCodeSize, cr, off, labels, buf);
+
+ } else if (tag >= CHOP_FRAME && tag < SAME_FRAME_EXTENDED) { // CHOP_FRAME
+ stack = Collections.EMPTY_LIST;
+
+ int k = SAME_FRAME_EXTENDED - tag;
+ // copy locals from prev frame and chop last k
+ locals = new ArrayList(frame.locals.subList(0,
+ frame.locals.size() - k));
+
+ } else if (tag == SAME_FRAME_EXTENDED) { // SAME_FRAME_EXTENDED
+ stack = Collections.EMPTY_LIST;
+ locals = new ArrayList(frame.locals);
+
+ } else if ( /* tag>=APPEND && */tag < FULL_FRAME) { // APPEND_FRAME
+ stack = Collections.EMPTY_LIST;
+
+ // copy locals from prev frame and append new k
+ locals = new ArrayList(frame.locals);
+ for (int k = tag - SAME_FRAME_EXTENDED; k > 0; k--) {
+ off = readType(locals,
+ isExtCodeSize,
+ cr,
+ off,
+ labels,
+ buf);
+ }
+
+ } else if (tag == FULL_FRAME) { // FULL_FRAME
+ // read verification_type_info locals[number_of_locals];
+ locals = new ArrayList();
+ off = readTypes(locals,
+ isExtLocals,
+ isExtCodeSize,
+ cr,
+ off,
+ labels,
+ buf);
+
+ // read verification_type_info stack[number_of_stack_items];
+ stack = new ArrayList();
+ off = readTypes(stack,
+ isExtStack,
+ isExtCodeSize,
+ cr,
+ off,
+ labels,
+ buf);
+
+ } else {
+ throw new RuntimeException("Unknown frame type " + tag
+ + " after offset " + offset);
+
+ }
+ }
+
+ offset += offsetDelta;
+
+ Label offsetLabel = getLabel(offset, labels);
+
+ frame = new StackMapFrame(offsetLabel, locals, stack);
+ frames.add(frame);
+ // System.err.println( tag +" " + offset +" delta:" + offsetDelta +
+ // " frameType:"+ frameType+" : "+ frame);
+
+ offset++;
+ }
+
+ return new StackMapTableAttribute(frames);
+ }
+
+ protected ByteVector write(
+ ClassWriter cw,
+ byte[] code,
+ int len,
+ int maxStack,
+ int maxLocals)
+ {
+ ByteVector bv = new ByteVector();
+ // TODO verify this value (MAX_SHORT)
+ boolean isExtCodeSize = code != null && code.length > MAX_SHORT;
+ writeSize(frames.size() - 1, bv, isExtCodeSize);
+
+ if (frames.size() < 2) {
+ return bv;
+ }
+
+ boolean isExtLocals = maxLocals > MAX_SHORT;
+ boolean isExtStack = maxStack > MAX_SHORT;
+
+ // skip the first frame
+ StackMapFrame frame = (StackMapFrame) frames.get(0);
+ List locals = frame.locals;
+ int offset = frame.label.getOffset();
+
+ for (int i = 1; i < frames.size(); i++) {
+ frame = (StackMapFrame) frames.get(i);
+
+ List clocals = frame.locals;
+ List cstack = frame.stack;
+ int coffset = frame.label.getOffset();
+
+ int clocalsSize = clocals.size();
+ int cstackSize = cstack.size();
+
+ int localsSize = locals.size();
+
+ int delta = coffset - offset;
+
+ int type = FULL_FRAME;
+ int k = 0;
+ if (cstackSize == 0) {
+ k = clocalsSize - localsSize;
+ switch (k) {
+ case -3:
+ case -2:
+ case -1:
+ type = CHOP_FRAME; // CHOP or FULL
+ localsSize = clocalsSize; // for full_frame check
+ break;
+
+ case 0:
+ // SAME, SAME_EXTENDED or FULL
+ type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ type = APPEND_FRAME; // APPEND or FULL
+ break;
+ }
+ } else if (localsSize == clocalsSize && cstackSize == 1) {
+ // SAME_LOCAL_1_STACK or FULL
+ type = delta < 63
+ ? SAME_LOCALS_1_STACK_ITEM_FRAME
+ : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
+ }
+
+ if (type != FULL_FRAME) {
+ // verify if stack and locals are the same
+ for (int j = 0; j < localsSize && type != FULL_FRAME; j++) {
+ if (!locals.get(j).equals(clocals.get(j)))
+ type = FULL_FRAME;
+ }
+ }
+
+ switch (type) {
+ case SAME_FRAME:
+ bv.putByte(delta);
+ break;
+
+ case SAME_LOCALS_1_STACK_ITEM_FRAME:
+ bv.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+ writeTypeInfos(bv, cw, cstack, 0, 1);
+ break;
+
+ case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+ bv.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED);
+ writeSize(delta, bv, isExtCodeSize);
+ writeTypeInfos(bv, cw, cstack, 0, 1);
+ break;
+
+ case SAME_FRAME_EXTENDED:
+ bv.putByte(SAME_FRAME_EXTENDED);
+ writeSize(delta, bv, isExtCodeSize);
+ break;
+
+ case CHOP_FRAME:
+ bv.putByte(SAME_FRAME_EXTENDED + k); // negative k
+ writeSize(delta, bv, isExtCodeSize);
+ break;
+
+ case APPEND_FRAME:
+ bv.putByte(SAME_FRAME_EXTENDED + k); // positive k
+ writeSize(delta, bv, isExtCodeSize);
+ writeTypeInfos(bv,
+ cw,
+ clocals,
+ clocalsSize - 1,
+ clocalsSize);
+ break;
+
+ case FULL_FRAME:
+ bv.putByte(FULL_FRAME);
+ writeSize(delta, bv, isExtCodeSize);
+ writeSize(clocalsSize, bv, isExtLocals);
+ writeTypeInfos(bv, cw, clocals, 0, clocalsSize);
+ writeSize(cstackSize, bv, isExtStack);
+ writeTypeInfos(bv, cw, cstack, 0, cstackSize);
+ break;
+
+ default:
+ throw new RuntimeException();
+ }
+ offset = coffset + 1; // compensating non first offset
+ locals = clocals;
+ }
+ return bv;
+ }
+
+ private void writeSize(int delta, ByteVector bv, boolean isExt) {
+ if (isExt) {
+ bv.putInt(delta);
+ } else {
+ bv.putShort(delta);
+ }
+ }
+
+ private void writeTypeInfos(
+ ByteVector bv,
+ ClassWriter cw,
+ List info,
+ int start,
+ int end)
+ {
+ for (int j = start; j < end; j++) {
+ StackMapType typeInfo = (StackMapType) info.get(j);
+ bv.putByte(typeInfo.getType());
+
+ switch (typeInfo.getType()) {
+ case StackMapType.ITEM_Object: //
+ bv.putShort(cw.newClass(typeInfo.getObject()));
+ break;
+
+ case StackMapType.ITEM_Uninitialized: //
+ bv.putShort(typeInfo.getLabel().getOffset());
+ break;
+
+ }
+ }
+ }
+
+ public static int getMethodOff(ClassReader cr, int codeOff, char[] buf) {
+ int off = cr.header + 6;
+
+ int interfacesCount = cr.readUnsignedShort(off);
+ off += 2 + interfacesCount * 2;
+
+ int fieldsCount = cr.readUnsignedShort(off);
+ off += 2;
+ for (; fieldsCount > 0; --fieldsCount) {
+ int attrCount = cr.readUnsignedShort(off + 6); // field attributes
+ off += 8;
+ for (; attrCount > 0; --attrCount) {
+ off += 6 + cr.readInt(off + 2);
+ }
+ }
+
+ int methodsCount = cr.readUnsignedShort(off);
+ off += 2;
+ for (; methodsCount > 0; --methodsCount) {
+ int methodOff = off;
+ int attrCount = cr.readUnsignedShort(off + 6); // method attributes
+ off += 8;
+ for (; attrCount > 0; --attrCount) {
+ String attrName = cr.readUTF8(off, buf);
+ off += 6;
+ if (attrName.equals("Code")) {
+ if (codeOff == off) {
+ return methodOff;
+ }
+ }
+ off += cr.readInt(off - 4);
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Use method signature and access flags to resolve initial locals state.
+ *
+ * @param className name of the method's owner class.
+ * @param access access flags of the method.
+ * @param methodName name of the method.
+ * @param methodDesc descriptor of the method.
+ * @return list of <code>StackMapType</code> instances representing locals
+ * for an initial frame.
+ */
+ public static List calculateLocals(
+ String className,
+ int access,
+ String methodName,
+ String methodDesc)
+ {
+ List locals = new ArrayList();
+
+ // TODO
+ if ("<init>".equals(methodName)
+ && !className.equals("java/lang/Object"))
+ {
+ StackMapType typeInfo = StackMapType.getTypeInfo(StackMapType.ITEM_UninitializedThis);
+ typeInfo.setObject(className); // this
+ locals.add(typeInfo);
+ } else if ((access & Opcodes.ACC_STATIC) == 0) {
+ StackMapType typeInfo = StackMapType.getTypeInfo(StackMapType.ITEM_Object);
+ typeInfo.setObject(className); // this
+ locals.add(typeInfo);
+ }
+
+ Type[] types = Type.getArgumentTypes(methodDesc);
+ for (int i = 0; i < types.length; i++) {
+ Type t = types[i];
+ StackMapType smt;
+ switch (t.getSort()) {
+ case Type.LONG:
+ smt = StackMapType.getTypeInfo(StackMapType.ITEM_Long);
+ break;
+ case Type.DOUBLE:
+ smt = StackMapType.getTypeInfo(StackMapType.ITEM_Double);
+ break;
+
+ case Type.FLOAT:
+ smt = StackMapType.getTypeInfo(StackMapType.ITEM_Float);
+ break;
+
+ case Type.ARRAY:
+ case Type.OBJECT:
+ smt = StackMapType.getTypeInfo(StackMapType.ITEM_Object);
+ smt.setObject(t.getDescriptor()); // TODO verify name
+ break;
+
+ default:
+ smt = StackMapType.getTypeInfo(StackMapType.ITEM_Integer);
+ break;
+ }
+ }
+
+ return locals;
+ }
+
+ private int readTypes(
+ List info,
+ boolean isExt,
+ boolean isExtCodeSize,
+ ClassReader cr,
+ int off,
+ Label[] labels,
+ char[] buf)
+ {
+ int n = 0;
+ if (isExt) {
+ n = cr.readInt(off);
+ off += 4;
+ } else {
+ n = cr.readUnsignedShort(off);
+ off += 2;
+ }
+
+ for (; n > 0; n--) {
+ off = readType(info, isExtCodeSize, cr, off, labels, buf);
+ }
+ return off;
+ }
+
+ private int readType(
+ List info,
+ boolean isExtCodeSize,
+ ClassReader cr,
+ int off,
+ Label[] labels,
+ char[] buf)
+ {
+ int itemType = cr.readByte(off++);
+ StackMapType typeInfo = StackMapType.getTypeInfo(itemType);
+ info.add(typeInfo);
+ switch (itemType) {
+ // case StackMapType.ITEM_Long: //
+ // case StackMapType.ITEM_Double: //
+ // info.add(StackMapType.getTypeInfo(StackMapType.ITEM_Top));
+ // break;
+
+ case StackMapType.ITEM_Object: //
+ typeInfo.setObject(cr.readClass(off, buf));
+ off += 2;
+ break;
+
+ case StackMapType.ITEM_Uninitialized: //
+ int offset;
+ if (isExtCodeSize) {
+ offset = cr.readInt(off);
+ off += 4;
+ } else {
+ offset = cr.readUnsignedShort(off);
+ off += 2;
+ }
+
+ typeInfo.setLabel(getLabel(offset, labels));
+ break;
+ }
+ return off;
+ }
+
+ private Label getLabel(int offset, Label[] labels) {
+ Label l = labels[offset];
+ if (l != null) {
+ return l;
+ }
+ return labels[offset] = new Label();
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer("StackMapTable[");
+ for (int i = 0; i < frames.size(); i++) {
+ sb.append('\n').append('[').append(frames.get(i)).append(']');
+ }
+ sb.append("\n]");
+ return sb.toString();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapType.java
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapType.java (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/attrs/StackMapType.java 2007-01-07 13:36:55 UTC (rev 3028)
@@ -0,0 +1,114 @@
+/**
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.attrs;
+
+import org.objectweb.asm.Label;
+
+/**
+ * Verification type info used by {@link StackMapAttribute}.
+ *
+ * @see <a href="http://www.jcp.org/en/jsr/detail?id=139">JSR 139 : Connected
+ * Limited Device Configuration 1.1</a>
+ *
+ * @see "ClassFileFormat-Java6.fm Page 138 Friday, April 15, 2005 3:22 PM"
+ *
+ * @author Eugene Kuleshov
+ */
+
+public class StackMapType {
+
+ public static final int ITEM_Top = 0;
+ public static final int ITEM_Integer = 1;
+ public static final int ITEM_Float = 2;
+ public static final int ITEM_Double = 3;
+ public static final int ITEM_Long = 4;
+ public static final int ITEM_Null = 5;
+ public static final int ITEM_UninitializedThis = 6;
+ public static final int ITEM_Object = 7;
+ public static final int ITEM_Uninitialized = 8;
+
+ public static final String[] ITEM_NAMES = {
+ "Top",
+ "Integer",
+ "Float",
+ "Double",
+ "Long",
+ "Null",
+ "UninitializedThis",
+ "Object",
+ "Uninitialized" };
+
+ private int type;
+ private Label offset;
+ private String object;
+
+ private StackMapType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public static StackMapType getTypeInfo(int itemType) {
+ if (itemType < ITEM_Top || itemType > ITEM_Uninitialized) {
+ throw new IllegalArgumentException("" + itemType);
+ }
+ return new StackMapType(itemType);
+ }
+
+ public void setLabel(Label offset) {
+ this.offset = offset;
+ }
+
+ public void setObject(String object) {
+ this.object = object;
+ }
+
+ public Label getLabel() {
+ return offset;
+ }
+
+ public String getObject() {
+ return object;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer(ITEM_NAMES[type]);
+ if (type == ITEM_Object) {
+ sb.append(":").append(object);
+ }
+ if (type == ITEM_Uninitialized) {
+ sb.append(":L").append(System.identityHashCode(offset));
+ }
+ return sb.toString();
+ }
+}
Added: trunk/core/src/classpath/org/org/objectweb/asm/attrs/package.html
===================================================================
--- trunk/core/src/classpath/org/org/objectweb/asm/attrs/package.html (rev 0)
+++ trunk/core/src/classpath/org/org/objectweb/asm/attrs/package.html 2007-01-07 13:36:55 UTC (rev 3028)
@@ -0,0 +1,48 @@
+<html>
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<body>
+Provides an implementation for optional class, field and method attributes.
+
+<p>
+
+By default ASM strips optional attributes, in order to keep them in
+the bytecode that is being readed you should pass an array of required attribute
+instances to {@link org.objectweb.asm.ClassReader#accept(org.objectweb.asm.ClassVisitor, org.objectweb.asm.Attribute[], boolean) ClassReader.accept()} method.
+In order to add custom attributes to the manually constructed bytecode concrete
+subclasses of the {@link org.objectweb.asm.Attribute Attribute} can be passed to
+the visitAttribute methods of the
+{@link org.objectweb.asm.ClassVisitor ClassVisitor},
+{@link org.objectweb.asm.FieldVisitor FieldVisitor} and
+{@link org.objectweb.asm.MethodVisitor MethodVisitor} interfaces.
+
+@since ASM 1.4.1
+</body>
+</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 13:28:26
|
Revision: 3027
http://jnode.svn.sourceforge.net/jnode/?rev=3027&view=rev
Author: lsantha
Date: 2007-01-07 05:28:25 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Added Paths:
-----------
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/AbstractMethodGenerator.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/ClassRmicCompiler.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/CompilationError.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/Generator.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/GiopIo.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/HashFinder.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/Main.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/Messages.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/MethodGenerator.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/RMICException.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/RmiMethodGenerator.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/RmicBackend.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/SourceGiopRmicCompiler.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/SourceRmicCompiler.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/Variables.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/WrapUnWrapper.java
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/messages.properties
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/ImplTie.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/Stub.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/StubMethod.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/StubMethodVoid.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/Stub_12.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/Stub_12Method.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/Stub_12MethodVoid.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/Tie.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/TieMethod.jav
trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/templates/TieMethodVoid.jav
Added: trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/AbstractMethodGenerator.java
===================================================================
--- trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/AbstractMethodGenerator.java (rev 0)
+++ trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/AbstractMethodGenerator.java 2007-01-07 13:28:25 UTC (rev 3027)
@@ -0,0 +1,53 @@
+/* AbstractMethodGenerator.java -- the abstract method generator
+ Copyright (C) 2006 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 gnu.classpath.tools.rmic;
+
+public interface AbstractMethodGenerator
+{
+ /**
+ * Generate this method for the Stub (remote caller) class.
+ */
+ String generateStubMethod();
+
+ /**
+ * Generate this method for the Tie (remote servant) class.
+ */
+ String generateTieMethod();
+
+}
Added: trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/ClassRmicCompiler.java
===================================================================
--- trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/ClassRmicCompiler.java (rev 0)
+++ trunk/core/src/classpath/tools/gnu/classpath/tools/rmic/ClassRmicCompiler.java 2007-01-07 13:28:25 UTC (rev 3027)
@@ -0,0 +1,1824 @@
+/* ClassRmicCompiler.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA. */
+
+package gnu.classpath.tools.rmic;
+
+import gnu.java.rmi.server.RMIHashes;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.rmi.MarshalException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.Operation;
+import java.rmi.server.RemoteCall;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.Skeleton;
+import java.rmi.server.SkeletonMismatchException;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Type;
+
+public class ClassRmicCompiler
+ implements RmicBackend
+{
+ private String[] args;
+ private int next;
+ private List errors = new ArrayList();
+ private boolean keep = false;
+ private boolean need11Stubs = true;
+ private boolean need12Stubs = true;
+ private boolean compile = true;
+ private boolean verbose;
+ private boolean noWrite;
+ private String destination;
+ private String classpath;
+ private ClassLoader loader;
+ private int errorCount = 0;
+
+ private Class clazz;
+ private String classname;
+ private String classInternalName;
+ private String fullclassname;
+ private MethodRef[] remotemethods;
+ private String stubname;
+ private String skelname;
+ private List mRemoteInterfaces;
+
+ /**
+ * @return true if run was successful
+ */
+ public boolean run(String[] inputFiles)
+ {
+ args = inputFiles;
+
+ if (next >= args.length)
+ return false;
+
+ for (int i = next; i < args.length; i++)
+ {
+ try
+ {
+ if (verbose)
+ System.out.println("[Processing class " + args[i] + ".class]");
+ processClass(args[i].replace(File.separatorChar, '.'));
+ }
+ catch (IOException e)
+ {
+ errors.add(e);
+ }
+ catch (RMICException e)
+ {
+ errors.add(e);
+ }
+ }
+ if (errors.size() > 0)
+ {
+ for (Iterator it = errors.iterator(); it.hasNext(); )
+ {
+ Exception ex = (Exception) it.next();
+ logError(ex);
+ }
+ }
+
+ return errorCount == 0;
+ }
+
+ private void processClass(String cls) throws IOException, RMICException
+ {
+ // reset class specific vars
+ clazz = null;
+ classname = null;
+ classInternalName = null;
+ fullclassname = null;
+ remotemethods = null;
+ stubname = null;
+ skelname = null;
+ mRemoteInterfaces = new ArrayList();
+
+ analyzeClass(cls);
+ generateStub();
+ if (need11Stubs)
+ generateSkel();
+ }
+
+ private void analyzeClass(String cname)
+ throws RMICException
+ {
+ if (verbose)
+ System.out.println("[analyze class " + cname + "]");
+ int p = cname.lastIndexOf('.');
+ if (p != -1)
+ classname = cname.substring(p + 1);
+ else
+ classname = cname;
+ fullclassname = cname;
+
+ findClass();
+ findRemoteMethods();
+ }
+
+ /**
+ * @deprecated
+ */
+ public Exception getException()
+ {
+ return errors.size() == 0 ? null : (Exception) errors.get(0);
+ }
+
+ private void findClass()
+ throws RMICException
+ {
+ ClassLoader cl = (loader == null
+ ? ClassLoader.getSystemClassLoader()
+ : loader);
+ try
+ {
+ clazz = Class.forName(fullclassname, false, cl);
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ throw new RMICException
+ ("Class " + fullclassname + " not found in classpath", cnfe);
+ }
+
+ if (! Remote.class.isAssignableFrom(clazz))
+ {
+ throw new RMICException
+ ("Class " + clazz.getName()
+ + " does not implement a remote interface.");
+ }
+ }
+
+ private static Type[] typeArray(Class[] cls)
+ {
+ Type[] t = new Type[cls.length];
+ for (int i = 0; i < cls.length; i++)
+ {
+ t[i] = Type.getType(cls[i]);
+ }
+
+ return t;
+ }
+
+ private static String[] internalNameArray(Type[] t)
+ {
+ String[] s = new String[t.length];
+ for (int i = 0; i < t.length; i++)
+ {
+ s[i] = t[i].getInternalName();
+ }
+
+ return s;
+ }
+
+ private static String[] internalNameArray(Class[] c)
+ {
+ return internalNameArray(typeArray(c));
+ }
+
+ private static final String forName = "class$";
+
+ private static Object param(Method m, int argIndex)
+ {
+ List l = new ArrayList();
+ l.add(m);
+ l.add(new Integer(argIndex));
+ return l;
+ }
+
+ private static void generateClassForNamer(ClassVisitor cls)
+ {
+ MethodVisitor cv =
+ cls.visitMethod
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, forName,
+ Type.getMethodDescriptor
+ (Type.getType(Class.class), new Type[] { Type.getType(String.class) }),
+ null, null);
+
+ Label start = new Label();
+ cv.visitLabel(start);
+ cv.visitVarInsn(Opcodes.ALOAD, 0);
+ cv.visitMethodInsn
+ (Opcodes.INVOKESTATIC,
+ Type.getInternalName(Class.class),
+ "forName",
+ Type.getMethodDescriptor
+ (Type.getType(Class.class), new Type[] { Type.getType(String.class) }));
+ cv.visitInsn(Opcodes.ARETURN);
+
+ Label handler = new Label();
+ cv.visitLabel(handler);
+ cv.visitVarInsn(Opcodes.ASTORE, 1);
+ cv.visitTypeInsn(Opcodes.NEW, typeArg(NoClassDefFoundError.class));
+ cv.visitInsn(Opcodes.DUP);
+ cv.visitVarInsn(Opcodes.ALOAD, 1);
+ cv.visitMethodInsn
+ (Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName(ClassNotFoundException.class),
+ "getMessage",
+ Type.getMethodDescriptor(Type.getType(String.class), new Type[] {}));
+ cv.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(NoClassDefFoundError.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
+ cv.visitInsn(Opcodes.ATHROW);
+ cv.visitTryCatchBlock
+ (start, handler, handler,
+ Type.getInternalName(ClassNotFoundException.class));
+ cv.visitMaxs(-1, -1);
+ }
+
+ private void generateClassConstant(MethodVisitor cv, Class cls) {
+ if (cls.isPrimitive())
+ {
+ Class boxCls;
+ if (cls.equals(Boolean.TYPE))
+ boxCls = Boolean.class;
+ else if (cls.equals(Character.TYPE))
+ boxCls = Character.class;
+ else if (cls.equals(Byte.TYPE))
+ boxCls = Byte.class;
+ else if (cls.equals(Short.TYPE))
+ boxCls = Short.class;
+ else if (cls.equals(Integer.TYPE))
+ boxCls = Integer.class;
+ else if (cls.equals(Long.TYPE))
+ boxCls = Long.class;
+ else if (cls.equals(Float.TYPE))
+ boxCls = Float.class;
+ else if (cls.equals(Double.TYPE))
+ boxCls = Double.class;
+ else if (cls.equals(Void.TYPE))
+ boxCls = Void.class;
+ else
+ throw new IllegalArgumentException("unknown primitive type " + cls);
+
+ cv.visitFieldInsn
+ (Opcodes.GETSTATIC, Type.getInternalName(boxCls), "TYPE",
+ Type.getDescriptor(Class.class));
+ return;
+ }
+ cv.visitLdcInsn(cls.getName());
+ cv.visitMethodInsn
+ (Opcodes.INVOKESTATIC, classInternalName, forName,
+ Type.getMethodDescriptor
+ (Type.getType(Class.class),
+ new Type[] { Type.getType(String.class) }));
+ }
+
+ private void generateClassArray(MethodVisitor code, Class[] classes)
+ {
+ code.visitLdcInsn(new Integer(classes.length));
+ code.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Class.class));
+ for (int i = 0; i < classes.length; i++)
+ {
+ code.visitInsn(Opcodes.DUP);
+ code.visitLdcInsn(new Integer(i));
+ generateClassConstant(code, classes[i]);
+ code.visitInsn(Opcodes.AASTORE);
+ }
+ }
+
+ private void fillOperationArray(MethodVisitor clinit)
+ {
+ // Operations array
+ clinit.visitLdcInsn(new Integer(remotemethods.length));
+ clinit.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Operation.class));
+ clinit.visitFieldInsn
+ (Opcodes.PUTSTATIC, classInternalName, "operations",
+ Type.getDescriptor(Operation[].class));
+
+ for (int i = 0; i < remotemethods.length; i++)
+ {
+ Method m = remotemethods[i].meth;
+
+ StringBuffer desc = new StringBuffer();
+ desc.append(getPrettyName(m.getReturnType()) + " ");
+ desc.append(m.getName() + "(");
+
+ // signature
+ Class[] sig = m.getParameterTypes();
+ for (int j = 0; j < sig.length; j++)
+ {
+ desc.append(getPrettyName(sig[j]));
+ if (j + 1 < sig.length)
+ desc.append(", ");
+ }
+
+ // push operations array
+ clinit.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName, "operations",
+ Type.getDescriptor(Operation[].class));
+
+ // push array index
+ clinit.visitLdcInsn(new Integer(i));
+
+ // instantiate operation and leave a copy on the stack
+ clinit.visitTypeInsn(Opcodes.NEW, typeArg(Operation.class));
+ clinit.visitInsn(Opcodes.DUP);
+ clinit.visitLdcInsn(desc.toString());
+ clinit.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(Operation.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
+
+ // store in operations array
+ clinit.visitInsn(Opcodes.AASTORE);
+ }
+ }
+
+ private void generateStaticMethodObjs(MethodVisitor clinit)
+ {
+ for (int i = 0; i < remotemethods.length; i++)
+ {
+ Method m = remotemethods[i].meth;
+
+ /*
+ * $method_<i>m.getName()</i>_<i>i</i> =
+ * <i>m.getDeclaringClass()</i>.class.getMethod
+ * (m.getName(), m.getParameterType())
+ */
+ String methodVar = "$method_" + m.getName() + "_" + i;
+ generateClassConstant(clinit, m.getDeclaringClass());
+ clinit.visitLdcInsn(m.getName());
+ generateClassArray(clinit, m.getParameterTypes());
+ clinit.visitMethodInsn
+ (Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName(Class.class),
+ "getMethod",
+ Type.getMethodDescriptor
+ (Type.getType(Method.class),
+ new Type[] { Type.getType(String.class),
+ Type.getType(Class[].class) }));
+
+ clinit.visitFieldInsn
+ (Opcodes.PUTSTATIC, classInternalName, methodVar,
+ Type.getDescriptor(Method.class));
+ }
+ }
+
+ private void generateStub()
+ throws IOException
+ {
+ stubname = fullclassname + "_Stub";
+ String stubclassname = classname + "_Stub";
+ File file = new File((destination == null ? "." : destination)
+ + File.separator
+ + stubname.replace('.', File.separatorChar)
+ + ".class");
+
+ if (verbose)
+ System.out.println("[Generating class " + stubname + "]");
+
+ final ClassWriter stub = new ClassWriter(true);
+ classInternalName = stubname.replace('.', '/');
+ final String superInternalName =
+ Type.getType(RemoteStub.class).getInternalName();
+
+ String[] remoteInternalNames =
+ internalNameArray((Class[]) mRemoteInterfaces.toArray(new Class[] {}));
+ stub.visit
+ (Opcodes.V1_2, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL, classInternalName,
+ null, superInternalName, remoteInternalNames);
+
+ if (need12Stubs)
+ {
+ stub.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "serialVersionUID",
+ Type.LONG_TYPE.getDescriptor(), null, new Long(2L));
+ }
+
+ if (need11Stubs)
+ {
+ stub.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL,
+ "interfaceHash", Type.LONG_TYPE.getDescriptor(), null,
+ new Long(RMIHashes.getInterfaceHash(clazz)));
+
+ if (need12Stubs)
+ {
+ stub.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, "useNewInvoke",
+ Type.BOOLEAN_TYPE.getDescriptor(), null, null);
+ }
+
+ stub.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL,
+ "operations", Type.getDescriptor(Operation[].class), null, null);
+ }
+
+ // Set of method references.
+ if (need12Stubs)
+ {
+ for (int i = 0; i < remotemethods.length; i++)
+ {
+ Method m = remotemethods[i].meth;
+ String slotName = "$method_" + m.getName() + "_" + i;
+ stub.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, slotName,
+ Type.getDescriptor(Method.class), null, null);
+ }
+ }
+
+ MethodVisitor clinit = stub.visitMethod
+ (Opcodes.ACC_STATIC, "<clinit>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
+
+ if (need11Stubs)
+ {
+ fillOperationArray(clinit);
+ if (! need12Stubs)
+ clinit.visitInsn(Opcodes.RETURN);
+ }
+
+ if (need12Stubs)
+ {
+ // begin of try
+ Label begin = new Label();
+
+ // beginning of catch
+ Label handler = new Label();
+ clinit.visitLabel(begin);
+
+ // Initialize the methods references.
+ if (need11Stubs)
+ {
+ /*
+ * RemoteRef.class.getMethod("invoke", new Class[] {
+ * Remote.class, Method.class, Object[].class, long.class })
+ */
+ generateClassConstant(clinit, RemoteRef.class);
+ clinit.visitLdcInsn("invoke");
+ generateClassArray
+ (clinit, new Class[] { Remote.class, Method.class,
+ Object[].class, long.class });
+ clinit.visitMethodInsn
+ (Opcodes.INVOKEVIRTUAL,
+ Type.getInternalName(Class.class),
+ "getMethod",
+ Type.getMethodDescriptor
+ (Type.getType(Method.class),
+ new Type[] { Type.getType(String.class),
+ Type.getType(Class[].class) }));
+
+ // useNewInvoke = true
+ clinit.visitInsn(Opcodes.ICONST_1);
+ clinit.visitFieldInsn
+ (Opcodes.PUTSTATIC, classInternalName, "useNewInvoke",
+ Type.BOOLEAN_TYPE.getDescriptor());
+ }
+
+ generateStaticMethodObjs(clinit);
+
+ // jump past handler
+ clinit.visitInsn(Opcodes.RETURN);
+ clinit.visitLabel(handler);
+ if (need11Stubs)
+ {
+ // useNewInvoke = false
+ clinit.visitInsn(Opcodes.ICONST_0);
+ clinit.visitFieldInsn
+ (Opcodes.PUTSTATIC, classInternalName, "useNewInvoke",
+ Type.BOOLEAN_TYPE.getDescriptor());
+ clinit.visitInsn(Opcodes.RETURN);
+ }
+ else
+ {
+ // throw NoSuchMethodError
+ clinit.visitTypeInsn(Opcodes.NEW, typeArg(NoSuchMethodError.class));
+ clinit.visitInsn(Opcodes.DUP);
+ clinit.visitLdcInsn("stub class initialization failed");
+ clinit.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(NoSuchMethodError.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(String.class) }));
+ clinit.visitInsn(Opcodes.ATHROW);
+ }
+
+ clinit.visitTryCatchBlock
+ (begin, handler, handler,
+ Type.getInternalName(NoSuchMethodException.class));
+
+ }
+
+ clinit.visitMaxs(-1, -1);
+
+ generateClassForNamer(stub);
+
+ // Constructors
+ if (need11Stubs)
+ {
+ // no arg public constructor
+ MethodVisitor code = stub.visitMethod
+ (Opcodes.ACC_PUBLIC, "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}),
+ null, null);
+ code.visitVarInsn(Opcodes.ALOAD, 0);
+ code.visitMethodInsn
+ (Opcodes.INVOKESPECIAL, superInternalName, "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
+ code.visitInsn(Opcodes.RETURN);
+
+ code.visitMaxs(-1, -1);
+ }
+
+ // public RemoteRef constructor
+ MethodVisitor constructor = stub.visitMethod
+ (Opcodes.ACC_PUBLIC, "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] {Type.getType(RemoteRef.class)}),
+ null, null);
+ constructor.visitVarInsn(Opcodes.ALOAD, 0);
+ constructor.visitVarInsn(Opcodes.ALOAD, 1);
+ constructor.visitMethodInsn
+ (Opcodes.INVOKESPECIAL, superInternalName, "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] {Type.getType(RemoteRef.class)}));
+ constructor.visitInsn(Opcodes.RETURN);
+ constructor.visitMaxs(-1, -1);
+
+ // Method implementations
+ for (int i = 0; i < remotemethods.length; i++)
+ {
+ Method m = remotemethods[i].meth;
+ Class[] sig = m.getParameterTypes();
+ Class returntype = m.getReturnType();
+ Class[] except = sortExceptions
+ ((Class[]) remotemethods[i].exceptions.toArray(new Class[0]));
+
+ MethodVisitor code = stub.visitMethod
+ (Opcodes.ACC_PUBLIC,
+ m.getName(),
+ Type.getMethodDescriptor(Type.getType(returntype), typeArray(sig)),
+ null,
+ internalNameArray(typeArray(except)));
+
+ final Variables var = new Variables();
+
+ // this and parameters are the declared vars
+ var.declare("this");
+ for (int j = 0; j < sig.length; j++)
+ var.declare(param(m, j), size(sig[j]));
+
+ Label methodTryBegin = new Label();
+ code.visitLabel(methodTryBegin);
+
+ if (need12Stubs)
+ {
+ Label oldInvoke = new Label();
+ if (need11Stubs)
+ {
+ // if not useNewInvoke jump to old invoke
+ code.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName, "useNewInvoke",
+ Type.getDescriptor(boolean.class));
+ code.visitJumpInsn(Opcodes.IFEQ, oldInvoke);
+ }
+
+ // this.ref
+ code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
+ code.visitFieldInsn
+ (Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class),
+ "ref", Type.getDescriptor(RemoteRef.class));
+
+ // "this" is first arg to invoke
+ code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
+
+ // method object is second arg to invoke
+ String methName = "$method_" + m.getName() + "_" + i;
+ code.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName, methName,
+ Type.getDescriptor(Method.class));
+
+ // args to remote method are third arg to invoke
+ if (sig.length == 0)
+ code.visitInsn(Opcodes.ACONST_NULL);
+ else
+ {
+ // create arg Object[] (with boxed primitives) and push it
+ code.visitLdcInsn(new Integer(sig.length));
+ code.visitTypeInsn(Opcodes.ANEWARRAY, typeArg(Object.class));
+
+ var.allocate("argArray");
+ code.visitVarInsn(Opcodes.ASTORE, var.get("argArray"));
+
+ for (int j = 0; j < sig.length; j++)
+ {
+ int size = size(sig[j]);
+ int insn = loadOpcode(sig[j]);
+ Class box = sig[j].isPrimitive() ? box(sig[j]) : null;
+
+ code.visitVarInsn(Opcodes.ALOAD, var.get("argArray"));
+ code.visitLdcInsn(new Integer(j));
+
+ // put argument on stack
+ if (box != null)
+ {
+ code.visitTypeInsn(Opcodes.NEW, typeArg(box));
+ code.visitInsn(Opcodes.DUP);
+ code.visitVarInsn(insn, var.get(param(m, j)));
+ code.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(box),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(sig[j]) }));
+ }
+ else
+ code.visitVarInsn(insn, var.get(param(m, j)));
+
+ code.visitInsn(Opcodes.AASTORE);
+ }
+
+ code.visitVarInsn(Opcodes.ALOAD, var.deallocate("argArray"));
+ }
+
+ // push remote operation opcode
+ code.visitLdcInsn(new Long(remotemethods[i].hash));
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteRef.class),
+ "invoke",
+ Type.getMethodDescriptor
+ (Type.getType(Object.class),
+ new Type[] { Type.getType(Remote.class),
+ Type.getType(Method.class),
+ Type.getType(Object[].class),
+ Type.LONG_TYPE }));
+
+ if (! returntype.equals(Void.TYPE))
+ {
+ int retcode = returnOpcode(returntype);
+ Class boxCls =
+ returntype.isPrimitive() ? box(returntype) : null;
+ code.visitTypeInsn
+ (Opcodes.CHECKCAST, typeArg(boxCls == null ? returntype : boxCls));
+ if (returntype.isPrimitive())
+ {
+ // unbox
+ code.visitMethodInsn
+ (Opcodes.INVOKEVIRTUAL,
+ Type.getType(boxCls).getInternalName(),
+ unboxMethod(returntype),
+ Type.getMethodDescriptor
+ (Type.getType(returntype), new Type[] {}));
+ }
+
+ code.visitInsn(retcode);
+ }
+ else
+ code.visitInsn(Opcodes.RETURN);
+
+
+ if (need11Stubs)
+ code.visitLabel(oldInvoke);
+ }
+
+ if (need11Stubs)
+ {
+
+ // this.ref.newCall(this, operations, index, interfaceHash)
+ code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
+ code.visitFieldInsn
+ (Opcodes.GETFIELD,
+ Type.getInternalName(RemoteObject.class),
+ "ref",
+ Type.getDescriptor(RemoteRef.class));
+
+ // "this" is first arg to newCall
+ code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
+
+ // operations is second arg to newCall
+ code.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName, "operations",
+ Type.getDescriptor(Operation[].class));
+
+ // method index is third arg
+ code.visitLdcInsn(new Integer(i));
+
+ // interface hash is fourth arg
+ code.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName, "interfaceHash",
+ Type.LONG_TYPE.getDescriptor());
+
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteRef.class),
+ "newCall",
+ Type.getMethodDescriptor
+ (Type.getType(RemoteCall.class),
+ new Type[] { Type.getType(RemoteObject.class),
+ Type.getType(Operation[].class),
+ Type.INT_TYPE,
+ Type.LONG_TYPE }));
+
+ // store call object on stack and leave copy on stack
+ var.allocate("call");
+ code.visitInsn(Opcodes.DUP);
+ code.visitVarInsn(Opcodes.ASTORE, var.get("call"));
+
+ Label beginArgumentTryBlock = new Label();
+ code.visitLabel(beginArgumentTryBlock);
+
+ // ObjectOutput out = call.getOutputStream();
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteCall.class),
+ "getOutputStream",
+ Type.getMethodDescriptor
+ (Type.getType(ObjectOutput.class), new Type[] {}));
+
+ for (int j = 0; j < sig.length; j++)
+ {
+ // dup the ObjectOutput
+ code.visitInsn(Opcodes.DUP);
+
+ // get j'th arg to remote method
+ code.visitVarInsn(loadOpcode(sig[j]), var.get(param(m, j)));
+
+ Class argCls =
+ sig[j].isPrimitive() ? sig[j] : Object.class;
+
+ // out.writeFoo
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(ObjectOutput.class),
+ writeMethod(sig[j]),
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(argCls) }));
+ }
+
+ // pop ObjectOutput
+ code.visitInsn(Opcodes.POP);
+
+ Label iohandler = new Label();
+ Label endArgumentTryBlock = new Label();
+ code.visitJumpInsn(Opcodes.GOTO, endArgumentTryBlock);
+ code.visitLabel(iohandler);
+
+ // throw new MarshalException(msg, ioexception);
+ code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
+ code.visitTypeInsn(Opcodes.NEW, typeArg(MarshalException.class));
+ code.visitInsn(Opcodes.DUP);
+ code.visitLdcInsn("error marshalling arguments");
+ code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
+ code.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(MarshalException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(String.class),
+ Type.getType(Exception.class) }));
+ code.visitInsn(Opcodes.ATHROW);
+
+ code.visitLabel(endArgumentTryBlock);
+ code.visitTryCatchBlock
+ (beginArgumentTryBlock, iohandler, iohandler,
+ Type.getInternalName(IOException.class));
+
+ // this.ref.invoke(call)
+ code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
+ code.visitFieldInsn
+ (Opcodes.GETFIELD, Type.getInternalName(RemoteObject.class),
+ "ref", Type.getDescriptor(RemoteRef.class));
+ code.visitVarInsn(Opcodes.ALOAD, var.get("call"));
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteRef.class),
+ "invoke",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(RemoteCall.class) }));
+
+ // handle return value
+ boolean needcastcheck = false;
+
+ Label beginReturnTryCatch = new Label();
+ code.visitLabel(beginReturnTryCatch);
+
+ int returncode = returnOpcode(returntype);
+
+ if (! returntype.equals(Void.TYPE))
+ {
+ // call.getInputStream()
+ code.visitVarInsn(Opcodes.ALOAD, var.get("call"));
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteCall.class),
+ "getInputStream",
+ Type.getMethodDescriptor
+ (Type.getType(ObjectInput.class), new Type[] {}));
+
+ Class readCls =
+ returntype.isPrimitive() ? returntype : Object.class;
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(ObjectInput.class),
+ readMethod(returntype),
+ Type.getMethodDescriptor
+ (Type.getType(readCls), new Type[] {}));
+
+ boolean castresult = false;
+
+ if (! returntype.isPrimitive())
+ {
+ if (! returntype.equals(Object.class))
+ castresult = true;
+ else
+ needcastcheck = true;
+ }
+
+ if (castresult)
+ code.visitTypeInsn(Opcodes.CHECKCAST, typeArg(returntype));
+
+ // leave result on stack for return
+ }
+
+ // this.ref.done(call)
+ code.visitVarInsn(Opcodes.ALOAD, var.get("this"));
+ code.visitFieldInsn
+ (Opcodes.GETFIELD,
+ Type.getInternalName(RemoteObject.class),
+ "ref",
+ Type.getDescriptor(RemoteRef.class));
+ code.visitVarInsn(Opcodes.ALOAD, var.deallocate("call"));
+ code.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteRef.class),
+ "done",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(RemoteCall.class) }));
+
+ // return; or return result;
+ code.visitInsn(returncode);
+
+ // exception handler
+ Label handler = new Label();
+ code.visitLabel(handler);
+ code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
+
+ // throw new UnmarshalException(msg, e)
+ code.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class));
+ code.visitInsn(Opcodes.DUP);
+ code.visitLdcInsn("error unmarshalling return");
+ code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
+ code.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(UnmarshalException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(String.class),
+ Type.getType(Exception.class) }));
+ code.visitInsn(Opcodes.ATHROW);
+
+ Label endReturnTryCatch = new Label();
+
+ // catch IOException
+ code.visitTryCatchBlock
+ (beginReturnTryCatch, handler, handler,
+ Type.getInternalName(IOException.class));
+
+ if (needcastcheck)
+ {
+ // catch ClassNotFoundException
+ code.visitTryCatchBlock
+ (beginReturnTryCatch, handler, handler,
+ Type.getInternalName(ClassNotFoundException.class));
+ }
+ }
+
+ Label rethrowHandler = new Label();
+ code.visitLabel(rethrowHandler);
+ // rethrow declared exceptions
+ code.visitInsn(Opcodes.ATHROW);
+
+ boolean needgeneral = true;
+ for (int j = 0; j < except.length; j++)
+ {
+ if (except[j] == Exception.class)
+ needgeneral = false;
+ }
+
+ for (int j = 0; j < except.length; j++)
+ {
+ code.visitTryCatchBlock
+ (methodTryBegin, rethrowHandler, rethrowHandler,
+ Type.getInternalName(except[j]));
+ }
+
+ if (needgeneral)
+ {
+ // rethrow unchecked exceptions
+ code.visitTryCatchBlock
+ (methodTryBegin, rethrowHandler, rethrowHandler,
+ Type.getInternalName(RuntimeException.class));
+
+ Label generalHandler = new Label();
+ code.visitLabel(generalHandler);
+ String msg = "undeclared checked exception";
+
+ // throw new java.rmi.UnexpectedException(msg, e)
+ code.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
+ code.visitTypeInsn(Opcodes.NEW, typeArg(UnexpectedException.class));
+ code.visitInsn(Opcodes.DUP);
+ code.visitLdcInsn(msg);
+ code.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
+ code.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(UnexpectedException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type [] { Type.getType(String.class),
+ Type.getType(Exception.class) }));
+ code.visitInsn(Opcodes.ATHROW);
+
+ code.visitTryCatchBlock
+ (methodTryBegin, rethrowHandler, generalHandler,
+ Type.getInternalName(Exception.class));
+ }
+
+ code.visitMaxs(-1, -1);
+ }
+
+ stub.visitEnd();
+ byte[] classData = stub.toByteArray();
+ if (!noWrite)
+ {
+ if (file.exists())
+ file.delete();
+ if (file.getParentFile() != null)
+ file.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(classData);
+ fos.flush();
+ fos.close();
+ }
+ }
+
+ private void generateSkel() throws IOException
+ {
+ skelname = fullclassname + "_Skel";
+ String skelclassname = classname + "_Skel";
+ File file = new File(destination == null ? "" : destination
+ + File.separator
+ + skelname.replace('.', File.separatorChar)
+ + ".class");
+ if (verbose)
+ System.out.println("[Generating class " + skelname + "]");
+
+ final ClassWriter skel = new ClassWriter(true);
+ classInternalName = skelname.replace('.', '/');
+ skel.visit
+ (Opcodes.V1_1, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL,
+ classInternalName, Type.getInternalName(Object.class), null,
+ new String[] { Type.getType(Skeleton.class).getInternalName() });
+
+ skel.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "interfaceHash",
+ Type.LONG_TYPE.getDescriptor(), null,
+ new Long(RMIHashes.getInterfaceHash(clazz)));
+
+ skel.visitField
+ (Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "operations",
+ Type.getDescriptor(Operation[].class), null, null);
+
+ MethodVisitor clinit = skel.visitMethod
+ (Opcodes.ACC_STATIC, "<clinit>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
+
+ fillOperationArray(clinit);
+ clinit.visitInsn(Opcodes.RETURN);
+
+ clinit.visitMaxs(-1, -1);
+
+ // no arg public constructor
+ MethodVisitor init = skel.visitMethod
+ (Opcodes.ACC_PUBLIC, "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
+ init.visitVarInsn(Opcodes.ALOAD, 0);
+ init.visitMethodInsn
+ (Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
+ init.visitInsn(Opcodes.RETURN);
+ init.visitMaxs(-1, -1);
+
+ /*
+ * public Operation[] getOperations()
+ * returns a clone of the operations array
+ */
+ MethodVisitor getOp = skel.visitMethod
+ (Opcodes.ACC_PUBLIC, "getOperations",
+ Type.getMethodDescriptor
+ (Type.getType(Operation[].class), new Type[] {}),
+ null, null);
+ getOp.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName, "operations",
+ Type.getDescriptor(Operation[].class));
+ getOp.visitMethodInsn
+ (Opcodes.INVOKEVIRTUAL, Type.getInternalName(Object.class),
+ "clone", Type.getMethodDescriptor(Type.getType(Object.class),
+ new Type[] {}));
+ getOp.visitTypeInsn(Opcodes.CHECKCAST, typeArg(Operation[].class));
+ getOp.visitInsn(Opcodes.ARETURN);
+ getOp.visitMaxs(-1, -1);
+
+ // public void dispatch(Remote, RemoteCall, int opnum, long hash)
+ MethodVisitor dispatch = skel.visitMethod
+ (Opcodes.ACC_PUBLIC,
+ "dispatch",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE,
+ new Type[] { Type.getType(Remote.class),
+ Type.getType(RemoteCall.class),
+ Type.INT_TYPE, Type.LONG_TYPE }), null,
+ new String[] { Type.getInternalName(Exception.class) });
+
+ Variables var = new Variables();
+ var.declare("this");
+ var.declare("remoteobj");
+ var.declare("remotecall");
+ var.declare("opnum");
+ var.declareWide("hash");
+
+ /*
+ * if opnum >= 0
+ * XXX it is unclear why there is handling of negative opnums
+ */
+ dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum"));
+ Label nonNegativeOpnum = new Label();
+ Label opnumSet = new Label();
+ dispatch.visitJumpInsn(Opcodes.IFGE, nonNegativeOpnum);
+
+ for (int i = 0; i < remotemethods.length; i++)
+ {
+ // assign opnum if hash matches supplied hash
+ dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash"));
+ dispatch.visitLdcInsn(new Long(remotemethods[i].hash));
+ Label notIt = new Label();
+ dispatch.visitInsn(Opcodes.LCMP);
+ dispatch.visitJumpInsn(Opcodes.IFNE, notIt);
+
+ // opnum = <opnum>
+ dispatch.visitLdcInsn(new Integer(i));
+ dispatch.visitVarInsn(Opcodes.ISTORE, var.get("opnum"));
+ dispatch.visitJumpInsn(Opcodes.GOTO, opnumSet);
+ dispatch.visitLabel(notIt);
+ }
+
+ // throw new SkeletonMismatchException
+ Label mismatch = new Label();
+ dispatch.visitJumpInsn(Opcodes.GOTO, mismatch);
+
+ dispatch.visitLabel(nonNegativeOpnum);
+
+ // if opnum is already set, check that the hash matches the interface
+ dispatch.visitVarInsn(Opcodes.LLOAD, var.get("hash"));
+ dispatch.visitFieldInsn
+ (Opcodes.GETSTATIC, classInternalName,
+ "interfaceHash", Type.LONG_TYPE.getDescriptor());
+ dispatch.visitInsn(Opcodes.LCMP);
+ dispatch.visitJumpInsn(Opcodes.IFEQ, opnumSet);
+
+ dispatch.visitLabel(mismatch);
+ dispatch.visitTypeInsn
+ (Opcodes.NEW, typeArg(SkeletonMismatchException.class));
+ dispatch.visitInsn(Opcodes.DUP);
+ dispatch.visitLdcInsn("interface hash mismatch");
+ dispatch.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(SkeletonMismatchException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
+ dispatch.visitInsn(Opcodes.ATHROW);
+
+ // opnum has been set
+ dispatch.visitLabel(opnumSet);
+
+ dispatch.visitVarInsn(Opcodes.ALOAD, var.get("remoteobj"));
+ dispatch.visitTypeInsn(Opcodes.CHECKCAST, typeArg(clazz));
+ dispatch.visitVarInsn(Opcodes.ASTORE, var.get("remoteobj"));
+
+ Label deflt = new Label();
+ Label[] methLabels = new Label[remotemethods.length];
+ for (int i = 0; i < methLabels.length; i++)
+ methLabels[i] = new Label();
+
+ // switch on opnum
+ dispatch.visitVarInsn(Opcodes.ILOAD, var.get("opnum"));
+ dispatch.visitTableSwitchInsn
+ (0, remotemethods.length - 1, deflt, methLabels);
+
+ // Method dispatch
+ for (int i = 0; i < remotemethods.length; i++)
+ {
+ dispatch.visitLabel(methLabels[i]);
+ Method m = remotemethods[i].meth;
+ generateMethodSkel(dispatch, m, var);
+ }
+
+ dispatch.visitLabel(deflt);
+ dispatch.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class));
+ dispatch.visitInsn(Opcodes.DUP);
+ dispatch.visitLdcInsn("invalid method number");
+ dispatch.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(UnmarshalException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(String.class) }));
+ dispatch.visitInsn(Opcodes.ATHROW);
+
+ dispatch.visitMaxs(-1, -1);
+
+ skel.visitEnd();
+ byte[] classData = skel.toByteArray();
+ if (!noWrite)
+ {
+ if (file.exists())
+ file.delete();
+ if (file.getParentFile() != null)
+ file.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(classData);
+ fos.flush();
+ fos.close();
+ }
+ }
+
+ private void generateMethodSkel(MethodVisitor cv, Method m, Variables var)
+ {
+ Class[] sig = m.getParameterTypes();
+
+ Label readArgs = new Label();
+ cv.visitLabel(readArgs);
+
+ boolean needcastcheck = false;
+
+ // ObjectInput in = call.getInputStream();
+ cv.visitVarInsn(Opcodes.ALOAD, var.get("remotecall"));
+ cv.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteCall.class), "getInputStream",
+ Type.getMethodDescriptor
+ (Type.getType(ObjectInput.class), new Type[] {}));
+ cv.visitVarInsn(Opcodes.ASTORE, var.allocate("objectinput"));
+
+ for (int i = 0; i < sig.length; i++)
+ {
+ // dup input stream
+ cv.visitVarInsn(Opcodes.ALOAD, var.get("objectinput"));
+
+ Class readCls = sig[i].isPrimitive() ? sig[i] : Object.class;
+
+ // in.readFoo()
+ cv.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(ObjectInput.class),
+ readMethod(sig[i]),
+ Type.getMethodDescriptor
+ (Type.getType(readCls), new Type [] {}));
+
+ if (! sig[i].isPrimitive() && ! sig[i].equals(Object.class))
+ {
+ needcastcheck = true;
+ cv.visitTypeInsn(Opcodes.CHECKCAST, typeArg(sig[i]));
+ }
+
+ // store arg in variable
+ cv.visitVarInsn
+ (storeOpcode(sig[i]), var.allocate(param(m, i), size(sig[i])));
+ }
+
+ var.deallocate("objectinput");
+
+ Label doCall = new Label();
+ Label closeInput = new Label();
+
+ cv.visitJumpInsn(Opcodes.JSR, closeInput);
+ cv.visitJumpInsn(Opcodes.GOTO, doCall);
+
+ // throw new UnmarshalException
+ Label handler = new Label();
+ cv.visitLabel(handler);
+ cv.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
+ cv.visitTypeInsn(Opcodes.NEW, typeArg(UnmarshalException.class));
+ cv.visitInsn(Opcodes.DUP);
+ cv.visitLdcInsn("error unmarshalling arguments");
+ cv.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
+ cv.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(UnmarshalException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(String.class),
+ Type.getType(Exception.class) }));
+ cv.visitVarInsn(Opcodes.ASTORE, var.allocate("toThrow"));
+ cv.visitJumpInsn(Opcodes.JSR, closeInput);
+ cv.visitVarInsn(Opcodes.ALOAD, var.get("toThrow"));
+ cv.visitInsn(Opcodes.ATHROW);
+
+ cv.visitTryCatchBlock
+ (readArgs, handler, handler, Type.getInternalName(IOException.class));
+ if (needcastcheck)
+ {
+ cv.visitTryCatchBlock
+ (readArgs, handler, handler,
+ Type.getInternalName(ClassCastException.class));
+ }
+
+ // finally block
+ cv.visitLabel(closeInput);
+ cv.visitVarInsn(Opcodes.ASTORE, var.allocate("retAddress"));
+ cv.visitVarInsn(Opcodes.ALOAD, var.get("remotecall"));
+ cv.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteCall.class),
+ "releaseInputStream",
+ Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
+ cv.visitVarInsn(Opcodes.RET, var.deallocate("retAddress"));
+ var.deallocate("toThrow");
+
+ // do the call using args stored as variables
+ cv.visitLabel(doCall);
+ cv.visitVarInsn(Opcodes.ALOAD, var.get("remoteobj"));
+ for (int i = 0; i < sig.length; i++)
+ cv.visitVarInsn(loadOpcode(sig[i]), var.deallocate(param(m, i)));
+ cv.visitMethodInsn
+ (Opcodes.INVOKEVIRTUAL, Type.getInternalName(clazz), m.getName(),
+ Type.getMethodDescriptor(m));
+
+ Class returntype = m.getReturnType();
+ if (! returntype.equals(Void.TYPE))
+ {
+ cv.visitVarInsn
+ (storeOpcode(returntype), var.allocate("result", size(returntype)));
+ }
+
+ // write result to result stream
+ Label writeResult = new Label();
+ cv.visitLabel(writeResult);
+ cv.visitVarInsn(Opcodes.ALOAD, var.get("remotecall"));
+ cv.visitInsn(Opcodes.ICONST_1);
+ cv.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(RemoteCall.class),
+ "getResultStream",
+ Type.getMethodDescriptor
+ (Type.getType(ObjectOutput.class),
+ new Type[] { Type.BOOLEAN_TYPE }));
+
+ if (! returntype.equals(Void.TYPE))
+ {
+ // out.writeFoo(result)
+ cv.visitVarInsn(loadOpcode(returntype), var.deallocate("result"));
+ Class writeCls = returntype.isPrimitive() ? returntype : Object.class;
+ cv.visitMethodInsn
+ (Opcodes.INVOKEINTERFACE,
+ Type.getInternalName(ObjectOutput.class),
+ writeMethod(returntype),
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(writeCls) }));
+ }
+
+ cv.visitInsn(Opcodes.RETURN);
+
+ // throw new MarshalException
+ Label marshalHandler = new Label();
+ cv.visitLabel(marshalHandler);
+ cv.visitVarInsn(Opcodes.ASTORE, var.allocate("exception"));
+ cv.visitTypeInsn(Opcodes.NEW, typeArg(MarshalException.class));
+ cv.visitInsn(Opcodes.DUP);
+ cv.visitLdcInsn("error marshalling return");
+ cv.visitVarInsn(Opcodes.ALOAD, var.deallocate("exception"));
+ cv.visitMethodInsn
+ (Opcodes.INVOKESPECIAL,
+ Type.getInternalName(MarshalException.class),
+ "<init>",
+ Type.getMethodDescriptor
+ (Type.VOID_TYPE, new Type[] { Type.getType(String.class),
+ Type.getType(Exception.class) }));
+ cv.visitInsn(Opcodes.ATHROW);
+ cv.visitTryCatchBlock
+ (writeResult, marshalHandler, marshalHandler,
+ Type.getInternalName(IOException.class));
+ }
+
+ private static String typeArg(Class cls)
+ {
+ if (cls.isArray())
+ return Type.getDescriptor(cls);
+
+ return Type.getInternalName(cls);
+ }
+
+ private static String readMethod(Class cls)
+ {
+ if (cls.equals(Void.TYPE))
+ throw new IllegalArgumentException("can not read void");
+
+ String method;
+ if (cls.equals(Boolean.TYPE))
+ method = "readBoolean";
+ else if (cls.equals(Byte.TYPE))
+ method = "readByte";
+ else if (cls.equals(Character.TYPE))
+ method = "readChar";
+ else if (cls.equals(Short.TYPE))
+ method = "readShort";
+ else if (cls.equals(Integer.TYPE))
+ method = "readInt";
+ else if (cls.equals(Long.TYPE))
+ method = "readLong";
+ else if (cls.equals(Float.TYPE))
+ method = "readFloat";
+ else if (cls.equals(Double.TYPE))
+ method = "readDouble";
+ else
+ method = "readObject";
+
+ return method;
+ }
+
+ private static String writeMethod(Class cls)
+ {
+ if (cls.equals(Void.TYPE))
+ throw new IllegalArgumentException("can not read void");
+
+ String method;
+ if (cls.equals(Boolean.TYPE))
+ method = "writeBoolean";
+ else if (cls.equals(Byte.TYPE))
+ method = "writeByte";
+ else if (cls.equals(Character.TYPE))
+ method = "writeChar";
+ else if (cls.equals(Short.TYPE))
+ method = "writeShort";
+ else if (cls.equals(Integer.TYPE))
+ method = "writeInt";
+ else if (cls.equals(Long.TYPE))
+ method = "writeLong";
+ else if (cls.equals(Float.TYPE))
+ method = "writeFloat";
+ else if (cls.equals(Double.TYPE))
+ method = "writeDouble";
+ else
+ method = "writeObject";
+
+ return method;
+ }
+
+ private static int returnOpcode(Class cls)
+ {
+ int returncode;
+ if (cls.equals(Boolean.TYPE))
+ returncode = Opcodes.IRETURN;
+ else if (cls.equals(Byte.TYPE))
+ returncode = Opcodes.IRETURN;
+ else if (cls.equals(Character.TYPE))
+ returncode = Opcodes.IRETURN;
+ else if (cls.equals(Short.TYPE))
+ returncode = Opcodes.IRETURN;
+ else if (cls.equals(Integer.TYPE))
+ returncode = Opcodes.IRETURN;
+ else if (cls.equals(Long.TYPE))
+ returncode = Opcodes.LRETURN;
+ else if (cls.equals(Float.TYPE))
+ returncode = Opcodes.FRETURN;
+ else if (cls.equals(Double.TYPE))
+ returncode = Opcodes.DRETURN;
+ else if (cls.equals(Void.TYPE))
+ returncode = Opcodes.RETURN;
+ else
+ returncode = Opcodes.ARETURN;
+
+ return returncode;
+ }
+
+ private static int loadOpcode(Class cls)
+ {
+ if (cls.equals(Void.TYPE))
+ throw new IllegalArgumentException("can not load void");
+
+ int loadcode;
+ if (cls.equals(Boolean.TYPE))
+ loadcode = Opcodes.ILOAD;
+ else if (cls.equals(Byte.TYPE))
+ loadcode = Opcodes.ILOAD;
+ else if (cls.equals(Character.TYPE))
+ loadcode = Opcodes.ILOAD;
+ else if (cls.equals(Short.TYPE))
+ loadcode = Opcodes.ILOAD;
+ else if (cls.equals(Integer.TYPE))
+ loadcode = Opcodes.ILOAD;
+ else if (cls.equals(Long.TYPE))
+ loadcode = Opcodes.LLOAD;
+ else if (cls.equals(Float.TYPE))
+ loadcode = Opcodes.FLOAD;
+ else if (cls.equals(Double.TYPE))
+ loadcode = Opcodes.DLOAD;
+ else
+ loadcode = Opcodes.ALOAD;
+
+ return loadcode;
+ }
+
+ private static int storeOpcode(Class cls)
+ {
+ if (cls.equals(Void.TYPE))
+ throw new IllegalArgumentException("can not load void");
+
+ int storecode;
+ if (cls.equals(Boolean.TYPE))
+ storecode = Opcodes.ISTORE;
+ else if (cls.equals(Byte.TYPE))
+ storecode = Opcodes.ISTORE;
+ else if (cls.equals(Character.TYPE))
+ storecode = Opcodes.ISTORE;
+ else if (cls.equals(Short.TYPE))
+ storecode = Opcodes.ISTORE;
+ else if (cls.equals(Integer.TYPE))
+ storecode = Opcodes.ISTORE;
+ else if (cls.equals(Long.TYPE))
+ storecode = Opcodes.LSTORE;
+ else if (cls.equals(Float.TYPE))
+ storecode = Opcodes.FSTORE;
+ else if (cls.equals(Double.TYPE))
+ storecode = Opcodes.DSTORE;
+ else
+ storecode = Opcodes.ASTORE;
+
+ return storecode;
+ }
+
+ private static String unboxMethod(Class primitive)
+ {
+ if (! primitive.isPrimitive())
+ throw new IllegalArgumentException("can not unbox nonprimitive");
+
+ String method;
+ if (primitive.equals(Boolean.TYPE))
+ method = "booleanValue";
+ else if (primitive.equals(Byte.TYPE))
+ method = "byteValue";
+ else if (primitive.equals(Character.TYPE))
+ method = "charValue";
+ else if (primitive.equals(Short.TYPE))
+ method = "shortValue";
+ else if (primitive.equals(Integer.TYPE))
+ method = "intValue";
+ else if (primitive.equals(Long.TYPE))
+ method = "longValue";
+ else if (primitive.equals(Float.TYPE))
+ method = "floatValue";
+ else if (primitive.equals(Double.TYPE))
+ method = "doubleValue";
+ else
+ throw new IllegalStateException("unknown primitive class " + primitive);
+
+ return method;
+ }
+
+ public static Class box(Class cls)
+ {
+ if (! cls.isPrimitive())
+ throw new IllegalArgumentException("can only box primitive");
+
+ Class box;
+ if (cls.equals(Boolean.TYPE))
+ box = Boolean.class;
+ else if (cls.equals(Byte.TYPE))
+ box = Byte.class;
+ else if (cls.equals(Character.TYPE))
+ box = Character.class;
+ else if (cls.equals(Short.TYPE))
+ box = Short.class;
+ else if (cls.equals(Integer.TYPE))
+ box = Integer.class;
+ else if (cls.equals(Long.TYPE))
+ box = Long.class;
+ else if (cls.equals(Float.TYPE))
+ box = Float.class;
+ else if (cls.equals(Double.TYPE))
+ box = Double.class;
+ else
+ throw new IllegalStateException("unknown primitive type " + cls);
+
+ return box;
+ }
+
+ private static int size(Class cls) {
+ if (cls.equals(Long.TYPE) || cls.equals(Double.TYPE))
+ return 2;
+ else
+ return 1;
+ }
+
+ /**
+ * Sort exceptions so the most general go last.
+ */
+ private Class[] sortExceptions(Class[] except)
+ {
+ for (int i = 0; i < except.length; i++)
+ {
+ for (int j = i + 1; j < except.length; j++)
+ {
+ if (except[i].isAssignableFrom(except[j]))
+ {
+ Class tmp = except[i];
+ except[i] = except[j];
+ except[j] = tmp;
+ }
+ }
+ }
+ return (except);
+ }
+
+ public void setup(boolean keep, boolean need11Stubs, boolean need12Stubs,
+ boolean iiop, boolean poa, boolean debug, boolean warnings,
+ boolean noWrite, boolean verbose, boolean force, String classpath,
+ String bootclasspath, String extdirs, String outputDirectory)
+ {
+ this.keep = keep;
+ this.need11Stubs = need11Stubs;
+ this.need12Stubs = need12Stubs;
+ this.verbose = verbose;
+ this.noWrite = noWrite;
+
+ // Set up classpath.
+ this.classpath = classpath;
+ StringTokenizer st =
+ new StringTokenizer(classpath, File.pathSeparator);
+ URL[] u = new URL[st...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 12:59:53
|
Revision: 3026
http://jnode.svn.sourceforge.net/jnode/?rev=3026&view=rev
Author: lsantha
Date: 2007-01-07 04:59:51 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java
trunk/core/src/classpath/vm/java/lang/Class.java
trunk/core/src/classpath/vm/java/lang/Thread.java
trunk/core/src/classpath/vm/java/lang/VMSystem.java
trunk/core/src/classpath/vm/java/lang/reflect/Method.java
Added Paths:
-----------
trunk/core/src/classpath/vm/java/lang/VMProcess.java
Modified: trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java
===================================================================
--- trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/tools/gnu/classpath/tools/rmid/ActivationSystemImpl.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -238,6 +238,6 @@
ClassNotFoundException
{
// Write no fields.
- };
+ }
}
Modified: trunk/core/src/classpath/vm/java/lang/Class.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/Class.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/Class.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -1,24 +1,41 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
+/* Class.java -- Representation of a Java class.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation
+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.lang;
import gnu.java.lang.VMClassHelper;
@@ -56,10 +73,34 @@
import org.jnode.vm.classmgr.VmType;
/**
- * Class. If you change any fields in this class, also change
- * <code>emitClass</code> in <code>org.jnode.build.ObjectEmitter</code>.
+ * A Class represents a Java type. There will never be multiple Class
+ * objects with identical names and ClassLoaders. Primitive types, array
+ * types, and void also have a Class object.
*
- * @author epr
+ * <p>Arrays with identical type and number of dimensions share the same class.
+ * The array class ClassLoader is the same as the ClassLoader of the element
+ * type of the array (which can be null to indicate the bootstrap classloader).
+ * The name of an array class is <code>[<signature format>;</code>.
+ * <p> For example,
+ * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte,
+ * short, char, int, long, float and double have the "type name" of
+ * Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a
+ * multidimensioned array, the same principle applies:
+ * <code>int[][][]</code> == <code>[[[I</code>.
+ *
+ * <p>There is no public constructor - Class objects are obtained only through
+ * the virtual machine, as defined in ClassLoaders.
+ *
+ * @serialData Class objects serialize specially:
+ * <code>TC_CLASS ClassDescriptor</code>. For more serialization information,
+ * see {@link ObjectStreamClass}.
+ *
+ * @author John Keiser
+ * @author Eric Blake (eb...@em...)
+ * @author Tom Tromey (tr...@re...)
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.0
+ * @see ClassLoader
*/
public final class Class<T> implements AnnotatedElement, Serializable, Type,
GenericDeclaration {
@@ -369,7 +410,7 @@
* @throws InstantiationException
* @throws IllegalAccessException
*/
- public final Object newInstance() throws InstantiationException,
+ public final T newInstance() throws InstantiationException,
IllegalAccessException {
if (defaultConstructor == null) {
defaultConstructor = getLinkedVmClass().getDeclaredMethod("<init>",
@@ -379,7 +420,7 @@
throw new InstantiationException("No default constructor");
}
try {
- return VmReflection.newInstance(defaultConstructor);
+ return (T)VmReflection.newInstance(defaultConstructor);
} catch (InvocationTargetException ex) {
final InstantiationException ie = new InstantiationException();
ie.initCause(ex);
Modified: trunk/core/src/classpath/vm/java/lang/Thread.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -1,21 +1,18 @@
-/*
- * $Id$
+/* Thread -- an independent thread of executable code
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
*
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful, but
+ * This library 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 Lesser General Public
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
@@ -712,7 +709,37 @@
}
return locals;
}
+ /**
+ * <p>
+ * Represents the current state of a thread, according to the VM rather
+ * than the operating system. It can be one of the following:
+ * </p>
+ * <ul>
+ * <li>NEW -- The thread has just been created but is not yet running.</li>
+ * <li>RUNNABLE -- The thread is currently running or can be scheduled
+ * to run.</li>
+ * <li>BLOCKED -- The thread is blocked waiting on an I/O operation
+ * or to obtain a lock.</li>
+ * <li>WAITING -- The thread is waiting indefinitely for another thread
+ * to do something.</li>
+ * <li>TIMED_WAITING -- The thread is waiting for a specific amount of time
+ * for another thread to do something.</li>
+ * <li>TERMINATED -- The thread has exited.</li>
+ * </ul>
+ *
+ * @since 1.5
+ */
+ public enum State
+ {
+ BLOCKED, NEW, RUNNABLE, TERMINATED, TIMED_WAITING, WAITING;
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = 605505746047245783L;
+ }
+
+
/**
* Returns the current state of the thread. This
* is designed for monitoring thread behaviour, rather
@@ -720,9 +747,9 @@
*
* @return the current thread state.
*/
- public String getState()
+ public State getState()
{
//todo implement
- return "UNKNOWN";
+ throw new UnsupportedClassVersionError();
}
}
Added: trunk/core/src/classpath/vm/java/lang/VMProcess.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/VMProcess.java (rev 0)
+++ trunk/core/src/classpath/vm/java/lang/VMProcess.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -0,0 +1,410 @@
+/* java.lang.VMProcess -- VM implementation of java.lang.Process
+ 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.lang;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents one external process. Each instance of this class is in
+ * one of three states: INITIAL, RUNNING, or TERMINATED. The instance
+ * is {@link Object#notifyAll notifyAll()}'d each time the state changes.
+ * The state of all instances is managed by a single dedicated thread
+ * which does the actual fork()/exec() and wait() system calls. User
+ * threads {@link Object#wait()} on the instance when creating the
+ * process or waiting for it to terminate.
+ *
+ * <p>
+ * See
+ * <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11801">GCC bug
+ * #11801</a> for the motivation behind the design of this class.
+ *
+ * @author Archie Cobbs
+ * @see Process
+ * @see Runtime#exec(String)
+ */
+final class VMProcess extends Process
+{
+
+ // Possible states for a VMProcess
+ private static final int INITIAL = 0;
+ private static final int RUNNING = 1;
+ private static final int TERMINATED = 2;
+
+ // Dedicated thread that does all the fork()'ing and wait()'ing.
+ static Thread processThread;
+
+ // New processes waiting to be spawned by processThread.
+ static final LinkedList workList = new LinkedList();
+
+ // Return values set by nativeReap() when a child is reaped.
+ // These are only accessed by processThread so no locking required.
+ static long reapedPid;
+ static int reapedExitValue;
+
+ // Information about this process
+ int state; // current state of process
+ final String[] cmd; // copied from Runtime.exec()
+ final String[] env; // copied from Runtime.exec()
+ final File dir; // copied from Runtime.exec()
+ Throwable exception; // if process failed to start
+ long pid; // process id
+ OutputStream stdin; // process input stream
+ InputStream stdout; // process output stream
+ InputStream stderr; // process error stream
+ int exitValue; // process exit value
+ boolean redirect; // redirect stderr -> stdout
+
+ //
+ // Dedicated thread that does all the fork()'ing and wait()'ing
+ // for external processes. This is needed because some systems like
+ // Linux use a process-per-thread model, which means the same thread
+ // that did the fork()/exec() must also do the wait().
+ //
+ private static class ProcessThread extends Thread
+ {
+
+ // Max time (in ms) we'll delay before trying to reap another child.
+ private static final int MAX_REAP_DELAY = 1000;
+
+ // Processes created but not yet terminated; maps Long(pid) -> VMProcess
+ // Only used in run() and spawn() method from this Thread, so no locking.
+ private final HashMap activeMap = new HashMap();
+
+ // We have an explicit constructor, because the default
+ // constructor will be private, which means the compiler will have
+ // to generate a second package-private constructor, which is
+ // bogus.
+ ProcessThread ()
+ {
+ }
+
+ public void run()
+ {
+ final LinkedList workList = VMProcess.workList;
+ while (true)
+ {
+
+ // Get the next process to spawn (if any) and spawn it. Spawn
+ // at most one at a time before checking for reapable children.
+ VMProcess process = null;
+ synchronized (workList)
+ {
+ if (!workList.isEmpty())
+ process = (VMProcess)workList.removeFirst();
+ }
+
+ if (process != null)
+ spawn(process);
+
+
+ // Check for termination of active child processes
+ while (!activeMap.isEmpty() && VMProcess.nativeReap())
+ {
+ long pid = VMProcess.reapedPid;
+ int exitValue = VMProcess.reapedExitValue;
+ process = (VMProcess)activeMap.remove(new Long(pid));
+ if (process != null)
+ {
+ synchronized (process)
+ {
+ process.exitValue = exitValue;
+ process.state = TERMINATED;
+ process.notify();
+ }
+ }
+ else
+ System.err.println("VMProcess WARNING reaped unknown process: "
+ + pid);
+ }
+
+
+ // If there are more new processes to create, go do that now.
+ // If there is nothing left to do, exit this thread. Otherwise,
+ // sleep a little while, and then check again for reapable children.
+ // We will get woken up immediately if there are new processes to
+ // spawn, but not if there are new children to reap. So we only
+ // sleep a short time, in effect polling while processes are active.
+ synchronized (workList)
+ {
+ if (!workList.isEmpty())
+ continue;
+ if (activeMap.isEmpty())
+ {
+ processThread = null;
+ break;
+ }
+
+ try
+ {
+ workList.wait(MAX_REAP_DELAY);
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ // Spawn a process
+ private void spawn(VMProcess process)
+ {
+
+ // Spawn the process and put it in our active map indexed by pid.
+ // If the spawn operation fails, store the exception with the process.
+ // In either case, wake up thread that created the process.
+ synchronized (process)
+ {
+ try
+ {
+ process.nativeSpawn(process.cmd, process.env, process.dir,
+ process.redirect);
+ process.state = RUNNING;
+ activeMap.put(new Long(process.pid), process);
+ }
+ catch (ThreadDeath death)
+ {
+ throw death;
+ }
+ catch (Throwable t)
+ {
+ process.state = TERMINATED;
+ process.exception = t;
+ }
+ process.notify();
+ }
+ }
+ }
+
+ // Constructor
+ private VMProcess(String[] cmd, String[] env, File dir, boolean redirect)
+ throws IOException
+ {
+
+ // Initialize this process
+ this.state = INITIAL;
+ this.cmd = cmd;
+ this.env = env;
+ this.dir = dir;
+ this.redirect = redirect;
+
+ // Add process to the new process work list and wakeup processThread
+ synchronized (workList)
+ {
+ workList.add(this);
+ if (processThread == null)
+ {
+ processThread = new ProcessThread();
+ processThread.setDaemon(true);
+ processThread.start();
+ }
+ else
+ {
+ workList.notify();
+ }
+ }
+
+ // Wait for processThread to spawn this process and update its state
+ synchronized (this)
+ {
+ while (state == INITIAL)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+
+ // If spawning failed, rethrow the exception in this thread
+ if (exception != null)
+ {
+ exception.fillInStackTrace();
+ if (exception instanceof IOException)
+ throw (IOException)exception;
+
+ if (exception instanceof Error)
+ throw (Error)exception;
+
+ if (exception instanceof RuntimeException)
+ throw (RuntimeException)exception;
+
+ throw new RuntimeException(exception);
+ }
+ }
+
+ // Invoked by native code (from nativeSpawn()) to record process info.
+ private void setProcessInfo(OutputStream stdin,
+ InputStream stdout, InputStream stderr, long pid)
+ {
+ this.stdin = stdin;
+ this.stdout = stdout;
+ if (stderr == null)
+ this.stderr = new InputStream()
+ {
+ public int read() throws IOException
+ {
+ return -1;
+ }
+ };
+ else
+ this.stderr = stderr;
+ this.pid = pid;
+ }
+
+ /**
+ * Entry point from Runtime.exec().
+ */
+ static Process exec(String[] cmd, String[] env, File dir) throws IOException
+ {
+ return new VMProcess(cmd, env, dir, false);
+ }
+
+ static Process exec(List cmd, Map env,
+ File dir, boolean redirect) throws IOException
+ {
+ String[] acmd = (String[]) cmd.toArray(new String[cmd.size()]);
+ String[] aenv = new String[env.size()];
+
+ int i = 0;
+ Iterator iter = env.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ aenv[i++] = entry.getKey() + "=" + entry.getValue();
+ }
+
+ return new VMProcess(acmd, aenv, dir, redirect);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return stdin;
+ }
+
+ public InputStream getInputStream()
+ {
+ return stdout;
+ }
+
+ public InputStream getErrorStream()
+ {
+ return stderr;
+ }
+
+ public synchronized int waitFor() throws InterruptedException
+ {
+ while (state != TERMINATED)
+ wait();
+ return exitValue;
+ }
+
+ public synchronized int exitValue()
+ {
+ if (state != TERMINATED)
+ throw new IllegalThreadStateException();
+ return exitValue;
+ }
+
+ public synchronized void destroy()
+ {
+ if (state == TERMINATED)
+ return;
+
+ nativeKill(pid);
+
+ while (state != TERMINATED)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ /* ignore */
+ }
+ }
+ }
+
+ /**
+ * Does the fork()/exec() thing to create the O/S process.
+ * Must invoke setProcessInfo() before returning successfully.
+ * This method is only invoked by processThread.
+ *
+ * @throws IOException if the O/S process could not be created.
+ */
+ void nativeSpawn(String[] cmd, String[] env, File dir,
+ boolean redirect) throws IOException{
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ };
+
+ /**
+ * Test for a reapable child process, and reap if so. Does not block.
+ * If a child was reaped, this method must set reapedPid and
+ * reapedExitValue appropriately before returning.
+ * This method is only invoked by processThread.
+ *
+ * @return true if a child was reaped, otherwise false
+ */
+ // This is not private as it is called from an inner class.
+ static boolean nativeReap(){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Kill a process. This sends it a fatal signal but does not reap it.
+ */
+ private static void nativeKill(long pid){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ }
+}
Modified: trunk/core/src/classpath/vm/java/lang/VMSystem.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/VMSystem.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/VMSystem.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -1,29 +1,46 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
+/* VMSystem.java -- helper for java.lang.system
+ Copyright (C) 1998, 2002, 2004 Free Software Foundation
+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.lang;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.ByteOrder;
+import java.util.List;
import org.jnode.util.EmptyInputStream;
import org.jnode.util.SystemInputStream;
@@ -152,14 +169,53 @@
return VmSystem.currentTimeMillis();
}
- /**
+ /**
+ * <p>
+ * Returns the current value of a nanosecond-precise system timer.
+ * The value of the timer is an offset relative to some arbitrary fixed
+ * time, which may be in the future (making the value negative). This
+ * method is useful for timing events where nanosecond precision is
+ * required. This is achieved by calling this method before and after the
+ * event, and taking the difference betweent the two times:
+ * </p>
+ * <p>
+ * <code>long startTime = System.nanoTime();</code><br />
+ * <code>... <emph>event code</emph> ...</code><br />
+ * <code>long endTime = System.nanoTime();</code><br />
+ * <code>long duration = endTime - startTime;</code><br />
+ * </p>
+ * <p>
+ * Note that the value is only nanosecond-precise, and not accurate; there
+ * is no guarantee that the difference between two values is really a
+ * nanosecond. Also, the value is prone to overflow if the offset
+ * exceeds 2^63.
+ * </p>
+ *
+ * @return the time of a system timer in nanoseconds.
+ * @since 1.5
+ */
+ public static long nanoTime(){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ };
+
+ /**
+ * Returns a list of 'name=value' pairs representing the current environment
+ * variables.
+ *
+ * @return a list of 'name=value' pairs.
+ */
+ static List environ(){
+ //TODO implement it
+ throw new UnsupportedOperationException();
+ }
+ /**
* Helper method which creates the standard input stream. VM implementors
* may choose to construct these streams differently. This method can also
* return null if the stream is created somewhere else in the VM startup
* sequence.
*/
-
- static InputStream makeStandardInputStream() {
+ static InputStream makeStandardInputStream() {
return SystemInputStream.getInstance(); // JNode specific
}
@@ -169,7 +225,6 @@
* return null if the stream is created somewhere else in the VM startup
* sequence.
*/
-
static PrintStream makeStandardOutputStream() {
return VmSystem.getSystemOut();
}
Modified: trunk/core/src/classpath/vm/java/lang/reflect/Method.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/Method.java 2007-01-07 12:57:57 UTC (rev 3025)
+++ trunk/core/src/classpath/vm/java/lang/reflect/Method.java 2007-01-07 12:59:51 UTC (rev 3026)
@@ -323,7 +323,7 @@
* @throws ExceptionInInitializerError if accessing a static method triggered
* class initialization, which then failed
*/
- public Object invoke(Object o, Object[] args)
+ public Object invoke(Object o, Object... args)
throws IllegalAccessException, InvocationTargetException {
return VmReflection.invoke(vmMethod, o, args);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-07 12:57:58
|
Revision: 3025
http://jnode.svn.sourceforge.net/jnode/?rev=3025&view=rev
Author: lsantha
Date: 2007-01-07 04:57:57 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/crypto/CipherOutputStream.java
trunk/core/src/classpath/javax/javax/crypto/Mac.java
trunk/core/src/classpath/javax/javax/crypto/MacSpi.java
trunk/core/src/classpath/javax/javax/net/ssl/HandshakeCompletedEvent.java
trunk/core/src/classpath/javax/javax/net/ssl/HttpsURLConnection.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLContext.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLContextSpi.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLServerSocketFactory.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLSession.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLSocketFactory.java
Added Paths:
-----------
trunk/core/src/classpath/javax/javax/management/MBeanServerPermission.java
trunk/core/src/classpath/javax/javax/net/ssl/CertPathTrustManagerParameters.java
trunk/core/src/classpath/javax/javax/net/ssl/KeyStoreBuilderParameters.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLEngine.java
trunk/core/src/classpath/javax/javax/net/ssl/SSLEngineResult.java
trunk/core/src/classpath/javax/javax/net/ssl/X509ExtendedKeyManager.java
trunk/core/src/classpath/javax/javax/swing/text/html/CSSParser.java
Modified: trunk/core/src/classpath/javax/javax/crypto/CipherOutputStream.java
===================================================================
--- trunk/core/src/classpath/javax/javax/crypto/CipherOutputStream.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/crypto/CipherOutputStream.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -50,33 +50,12 @@
*/
public class CipherOutputStream extends FilterOutputStream
{
-
- // Fields.
- // ------------------------------------------------------------------------
-
/** The underlying cipher. */
private Cipher cipher;
- private byte[][] inBuffer;
-
- private int inLength;
-
- private byte[] outBuffer;
-
- private static final int FIRST_TIME = 0;
- private static final int SECOND_TIME = 1;
- private static final int SEASONED = 2;
- private int state;
-
- /** True if the cipher is a stream cipher (blockSize == 1) */
- private boolean isStream;
-
- // Constructors.
- // ------------------------------------------------------------------------
-
/**
- * Create a new cipher output stream. The cipher argument must have
- * already been initialized.
+ * Create a new cipher output stream. The cipher argument must have already
+ * been initialized.
*
* @param out The sink for transformed data.
* @param cipher The cipher to transform data with.
@@ -84,20 +63,7 @@
public CipherOutputStream(OutputStream out, Cipher cipher)
{
super(out);
- if (cipher != null)
- {
- this.cipher = cipher;
- if (!(isStream = cipher.getBlockSize() == 1))
- {
- inBuffer = new byte[2][];
- inBuffer[0] = new byte[cipher.getBlockSize()];
- inBuffer[1] = new byte[cipher.getBlockSize()];
- inLength = 0;
- state = FIRST_TIME;
- }
- }
- else
- this.cipher = new NullCipher();
+ this.cipher = (cipher != null) ? cipher : new NullCipher();
}
/**
@@ -110,52 +76,36 @@
super(out);
}
- // Instance methods.
- // ------------------------------------------------------------------------
-
/**
* Close this output stream, and the sink output stream.
+ * <p>
+ * This method will first invoke the {@link Cipher#doFinal()} method of the
+ * underlying {@link Cipher}, and writes the output of that method to the
+ * sink output stream.
*
- * <p>This method will first invoke the {@link Cipher#doFinal()}
- * method of the underlying {@link Cipher}, and writes the output of
- * that method to the sink output stream.
- *
- * @throws java.io.IOException If an I/O error occurs, or if an error
- * is caused by finalizing the transformation.
+ * @throws IOException If an I/O error occurs, or if an error is caused by
+ * finalizing the transformation.
*/
public void close() throws IOException
{
try
{
- int len;
- if (state != FIRST_TIME)
- {
- len = cipher.update(inBuffer[0], 0, inBuffer[0].length, outBuffer);
- out.write(outBuffer, 0, len);
- }
- len = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer);
- out.write(outBuffer, 0, len);
+ out.write(cipher.doFinal());
+ out.flush();
+ out.close();
}
- catch (javax.crypto.IllegalBlockSizeException ibse)
+ catch (Exception cause)
{
- throw new IOException(ibse.toString());
+ IOException ioex = new IOException(String.valueOf(cause));
+ ioex.initCause(cause);
+ throw ioex;
}
- catch (javax.crypto.BadPaddingException bpe)
- {
- throw new IOException(bpe.toString());
- }
- catch (ShortBufferException sbe)
- {
- throw new IOException(sbe.toString());
- }
- out.flush();
- out.close();
}
/**
* Flush any pending output.
*
- * @throws java.io.IOException If an I/O error occurs.
+ * @throws IOException If an I/O error occurs.
*/
public void flush() throws IOException
{
@@ -166,38 +116,20 @@
* Write a single byte to the output stream.
*
* @param b The next byte.
- * @throws java.io.IOException If an I/O error occurs, or if the
- * underlying cipher is not in the correct state to transform
- * data.
+ * @throws IOException If an I/O error occurs, or if the underlying cipher is
+ * not in the correct state to transform data.
*/
public void write(int b) throws IOException
{
- if (isStream)
- {
- byte[] buf = new byte[] { (byte) b };
- try
- {
- cipher.update(buf, 0, 1, buf, 0);
- }
- catch (ShortBufferException sbe)
- {
- throw new IOException(sbe.toString());
- }
- out.write(buf);
- return;
- }
- inBuffer[1][inLength++] = (byte) b;
- if (inLength == inBuffer[1].length)
- process();
+ write(new byte[] { (byte) b }, 0, 1);
}
/**
* Write a byte array to the output stream.
*
* @param buf The next bytes.
- * @throws java.io.IOException If an I/O error occurs, or if the
- * underlying cipher is not in the correct state to transform
- * data.
+ * @throws IOException If an I/O error occurs, or if the underlying cipher is
+ * not in the correct state to transform data.
*/
public void write(byte[] buf) throws IOException
{
@@ -210,59 +142,11 @@
* @param buf The next bytes.
* @param off The offset in the byte array to start.
* @param len The number of bytes to write.
- * @throws java.io.IOException If an I/O error occurs, or if the
- * underlying cipher is not in the correct state to transform
- * data.
+ * @throws IOException If an I/O error occurs, or if the underlying cipher is
+ * not in the correct state to transform data.
*/
public void write(byte[] buf, int off, int len) throws IOException
{
- if (isStream)
- {
out.write(cipher.update(buf, off, len));
- return;
- }
- int count = 0;
- while (count < len)
- {
- int l = Math.min(inBuffer[1].length - inLength, len - count);
- System.arraycopy(buf, off+count, inBuffer[1], inLength, l);
- count += l;
- inLength += l;
- if (inLength == inBuffer[1].length)
- process();
- }
}
-
- // Own method.
- // -------------------------------------------------------------------------
-
- private void process() throws IOException
- {
- if (state == SECOND_TIME)
- {
- state = SEASONED;
- }
- else
- {
- byte[] temp = inBuffer[0];
- inBuffer[0] = inBuffer[1];
- inBuffer[1] = temp;
- }
- if (state == FIRST_TIME)
- {
- inLength = 0;
- state = SECOND_TIME;
- return;
- }
- try
- {
- cipher.update(inBuffer[0], 0, inBuffer[0].length, outBuffer);
- }
- catch (ShortBufferException sbe)
- {
- throw new IOException(sbe.toString());
- }
- out.write(outBuffer);
- inLength = 0;
- }
}
Modified: trunk/core/src/classpath/javax/javax/crypto/Mac.java
===================================================================
--- trunk/core/src/classpath/javax/javax/crypto/Mac.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/crypto/Mac.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -41,6 +41,7 @@
import gnu.java.security.Engine;
import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -406,6 +407,18 @@
}
/**
+ * Update this MAC with the remaining bytes in the given buffer
+ * @param buffer The input buffer.
+ * @since 1.5
+ */
+ public final void update (final ByteBuffer buffer)
+ {
+ if (virgin)
+ throw new IllegalStateException ("not initialized");
+ macSpi.engineUpdate(buffer);
+ }
+
+ /**
* Clone this instance, if the underlying implementation supports it.
*
* @return A clone of this instance.
Modified: trunk/core/src/classpath/javax/javax/crypto/MacSpi.java
===================================================================
--- trunk/core/src/classpath/javax/javax/crypto/MacSpi.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/crypto/MacSpi.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -38,6 +38,7 @@
package javax.crypto;
+import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -142,4 +143,21 @@
* @param length The number of bytes to update.
*/
protected abstract void engineUpdate(byte[] input, int offset, int length);
+
+ /**
+ * Update this MAC with the remaining bytes of a buffer.
+ *
+ * @param buffer The input buffer.
+ * @since 1.5
+ */
+ protected void engineUpdate (final ByteBuffer buffer)
+ {
+ byte[] buf = new byte[1024];
+ while (buffer.hasRemaining ())
+ {
+ int n = Math.min (buffer.remaining (), buf.length);
+ buffer.get (buf, 0, n);
+ engineUpdate (buf, 0, n);
+ }
+ }
}
Added: trunk/core/src/classpath/javax/javax/management/MBeanServerPermission.java
===================================================================
--- trunk/core/src/classpath/javax/javax/management/MBeanServerPermission.java (rev 0)
+++ trunk/core/src/classpath/javax/javax/management/MBeanServerPermission.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -0,0 +1,470 @@
+/* MBeanServerPermission.java -- Permissions controlling server creation.
+ Copyright (C) 2006 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 javax.management;
+
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * <p>
+ * Represents the permissions required to perform
+ * operations provided by the {@link MBeanServerFactory}.
+ * As with all {@link java.security.Permission} objects, an
+ * instance of this class either represents a permission
+ * already held or one that is required to access a
+ * particular service. In the case of {@link MBeanServerPermission}s,
+ * implication checks are made using an instance of this class
+ * when a user requests an operation from the factory, and a
+ * {@link SecurityManager} is in place.
+ * </p>
+ * <p>
+ * The permission is defined by its name, which may be
+ * either a <code>'*'</code> (to allow all) or one or
+ * more of the following, separated by a <code>','</code>:
+ * </p>
+ * <ul>
+ * <li><code>createMBeanServer</code> -- allows a registered
+ * instance of a server to be obtained from the factory.</li>
+ * <li><code>findMBeanServer</code> -- allows all or one
+ * particular server instance to be retrieved from the factory.</li>
+ * <li><code>newMBeanServer</code> -- allows an unregistered
+ * instance of a server to be obtained from the factory.</li>
+ * <li><code>releaseMBeanServer</code> -- allows a reference to
+ * a server instance to be removed from the factory.</li>
+ * </ul>
+ * <p>
+ * The names may be surrounded by arbitrary amounts of whitespace.
+ * <code>createMBeanServer</code> implies <code>newMBeanServer</code>.
+ * </p>
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.5
+ */
+public class MBeanServerPermission
+ extends BasicPermission
+{
+
+ /**
+ * Compatible with JDK 1.5
+ */
+ private static final long serialVersionUID = -5661980843569388590L;
+
+ /**
+ * <p>
+ * Constructs a new {@link MBeanServerPermission} with
+ * the given name. The name must not be <code>null</code>
+ * and must be equal to either <code>"*"</code> or a
+ * comma-separated list of valid permissions. The four
+ * valid constraints are:
+ * </p>
+ * <ol>
+ * <li><code>createMBeanServer</code></li>
+ * <li><code>findMBeanServer</code></li>
+ * <li><code>newMBeanServer</code></li>
+ * <li><code>releaseMBeanServer</code></li>
+ * </ol>
+ * <p>
+ * Calling this constructor is equivalent to calling
+ * <code>MBeanPermission(name, null)</code>.
+ * </p>
+ *
+ * @param name the name of this permission.
+ * @throws NullPointerException if <code>name</code>
+ * is <code>null</code>.
+ * @throws IllegalArgumentException if <code>name</code>
+ * is not either equal to
+ * <code>"*"</code> or forms
+ * a comma-separated list of
+ * valid constraints.
+ * @see #MBeanServerPermission(String,String)
+ */
+ public MBeanServerPermission(String name)
+ {
+ this(name, null);
+ }
+
+ /**
+ * <p>
+ * Constructs a new {@link MBeanServerPermission} with
+ * the given name and actions. The actions are unused,
+ * and must be either <code>null</code> or the empty
+ * string. The name must not be <code>null</code>
+ * and must be equal to either <code>"*"</code> or a
+ * comma-separated list of valid permissions. The four
+ * valid constraints are:
+ * </p>
+ * <ol>
+ * <li><code>createMBeanServer</code></li>
+ * <li><code>findMBeanServer</code></li>
+ * <li><code>newMBeanServer</code></li>
+ * <li><code>releaseMBeanServer</code></li>
+ * </ol>
+ * <p>
+ * Calling this constructor is equivalent to calling
+ * <code>MBeanPermission(name, null)</code>.
+ * </p>
+ *
+ * @param name the name of this permission.
+ * @throws NullPointerException if <code>name</code>
+ * is <code>null</code>.
+ * @throws IllegalArgumentException if <code>name</code>
+ * is not either equal to
+ * <code>"*"</code> or forms
+ * a comma-separated list of
+ * valid constraints, or if
+ * <code>actions</code> is not
+ * <code>null</code> or the
+ * empty string.
+ * @see #MBeanServerPermission(String,String)
+ */
+ public MBeanServerPermission(String name, String actions)
+ {
+ super(checkName(name), actions);
+ if (actions != null && actions.length() > 0)
+ throw new IllegalArgumentException("The supplied action list " +
+ "was not equal to null or the " +
+ "empty string.");
+ }
+
+ /**
+ * Returns true if the given object is also an {@link MBeanServerPermission}
+ * with the same name.
+ *
+ * @param obj the object to compare with this one.
+ * @return true if the object is an {@link MBeanPermission}
+ * with the same name.
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof MBeanServerPermission)
+ {
+ MBeanServerPermission o = (MBeanServerPermission) obj;
+ return o.getName().equals(getName());
+ }
+ return false;
+ }
+
+ /**
+ * Returns a unique hash code for this permission.
+ * This is simply the hashcode of {@link BasicPermission#getName()}.
+ *
+ * @return the hashcode of this permission.
+ */
+ public int hashCode()
+ {
+ return getName().hashCode();
+ }
+
+ /**
+ * Returns true if this {@link MBeanServerPermission} implies
+ * the given permission. This occurs if the given permission
+ * is also an {@link MBeanServerPermission} and its target names
+ * are a subset of the target names of this permission. Note that
+ * the name <code>createMBeanServer</code> implies
+ * <code>newMBeanServer</code>.
+ *
+ * @param p the permission to check for implication.
+ * @return true if this permission implies <code>p</code>.
+ */
+ public boolean implies(Permission p)
+ {
+ if (p instanceof MBeanServerPermission)
+ {
+ if (getName().equals("*"))
+ return true;
+ MBeanServerPermission msp = (MBeanServerPermission) p;
+ String[] thisCaps = getName().split(",");
+ String[] mspCaps = msp.getName().split(",");
+ for (int a = 0; a < mspCaps.length; ++a)
+ {
+ boolean found = false;
+ String mc = mspCaps[a].trim();
+ for (int b = 0; b < thisCaps.length; ++b)
+ {
+ String tc = thisCaps[b].trim();
+ if (tc.equals(mc))
+ found = true;
+ if (tc.equals("createMBeanServer") &&
+ mc.equals("newMBeanServer"))
+ found = true;
+ }
+ if (!found)
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a {@link PermissionCollection} which stores
+ * a series of {@link MBeanServerPermission}s as the union
+ * of their capabilities.
+ *
+ * @return a collection for {@link MBeanServerPermission}s.
+ */
+ public PermissionCollection newPermissionCollection()
+ {
+ return new MBeanServerPermissionCollection();
+ }
+
+ /**
+ * A collection of {@link MBeanServerPermission}s, stored
+ * as a single permission with the union of the capabilities
+ * as its capabilities.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.5
+ */
+ private class MBeanServerPermissionCollection
+ extends PermissionCollection
+ {
+
+ /**
+ * Compatible with JDK 1.5
+ */
+ private static final long serialVersionUID = -5661980843569388590L;
+
+ /**
+ * The collected permission. This is <code>null</code> or
+ * the union of the permissions held by all the collected
+ * permissions.
+ */
+ private MBeanServerPermission collectionPermission;
+
+ /**
+ * Adds a new permission by unifying it with the existing
+ * collection permission.
+ *
+ * @param p the permission to add.
+ * @throws SecurityException if the collection is read only.
+ * @see #isReadOnly()
+ * @see #setReadOnly(boolean)
+ */
+ public void add(Permission p)
+ {
+ if (isReadOnly())
+ throw new SecurityException("This collection is read only.");
+ if (p instanceof MBeanServerPermission)
+ {
+ MBeanServerPermission msp = (MBeanServerPermission) p;
+ if (collectionPermission == null)
+ collectionPermission = msp;
+ else
+ {
+ String finalString = collectionPermission.getName();
+ String[] cp = finalString.split(",");
+ String[] np = msp.getName().split(",");
+ int createms = finalString.indexOf("createMBeanServer");
+ int newms = finalString.indexOf("newMBeanServer");
+ for (int a = 0; a < np.length; ++a)
+ {
+ boolean found = false;
+ String nps = np[a].trim();
+ for (int b = 0; b < cp.length; ++b)
+ {
+ String cps = cp[b].trim();
+ if (cps.equals(nps))
+ found = true;
+ if (np.equals("newMBeanServer")
+ && createms != -1)
+ found = true;
+ if (np.equals("createMBeanServer")
+ && newms != -1)
+ finalString.replace("newMBeanServer",
+ "createMBeanServer");
+ }
+ if (!found)
+ finalString += "," + nps;
+ }
+ collectionPermission =
+ new MBeanServerPermission(finalString);
+ }
+ }
+ }
+
+ /**
+ * Returns an enumeration over the single permission.
+ *
+ * @return an enumeration over the collection permission.
+ */
+ public Enumeration elements()
+ {
+ return new
+ MBeanServerPermissionEnumeration(collectionPermission);
+ }
+
+ /**
+ * Provides an enumeration over a comma-separated list
+ * of capabilities.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.5
+ */
+ private class MBeanServerPermissionEnumeration
+ implements Enumeration
+ {
+
+ /**
+ * The collected permission.
+ */
+ private MBeanServerPermission p;
+
+ /**
+ * True if we have returned the permission.
+ */
+ private boolean done;
+
+ /**
+ * Constructs a new {@link MBeanServerPermissionEnumeration}
+ * using the given collected permission.
+ *
+ * @param p the collected permission.
+ */
+ public MBeanServerPermissionEnumeration(MBeanServerPermission p)
+ {
+ this.p = p;
+ done = false;
+ }
+
+ /**
+ * Returns true if there are more capabilities to return.
+ *
+ * @return true if there are more capabilities available.
+ */
+ public boolean hasMoreElements()
+ {
+ return !done;
+ }
+
+ /**
+ * Returns the next capability.
+ *
+ * @return the next capability.
+ */
+ public Object nextElement()
+ {
+ if (hasMoreElements())
+ {
+ done = true;
+ return p;
+ }
+ else
+ throw new NoSuchElementException("No more elements are available.");
+ }
+
+ }
+
+ /**
+ * Returns true if the collected {@link MBeanServerPermission}
+ * implies the given permission. This occurs if the given permission
+ * is also an {@link MBeanServerPermission} and its target names
+ * are a subset of the target names of this permission. Note that
+ * the name <code>createMBeanServer</code> implies
+ * <code>newMBeanServer</code>.
+ *
+ * @param p the permission to check for implication.
+ * @return true if this permission implies <code>p</code>.
+ */
+ public boolean implies(Permission p)
+ {
+ return collectionPermission.implies(p);
+ }
+ }
+
+ /**
+ * Checks the name is valid, including removing
+ * the <code>newMBeanServer</code> permission when
+ * <code>createMBeanServer</code> is present.
+ *
+ * @param name the name to check.
+ * @throws NullPointerException if <code>name</code>
+ * is <code>null</code>.
+ * @throws IllegalArgumentException if <code>name</code>
+ * is not either equal to
+ * <code>"*"</code> or forms
+ * a comma-separated list of
+ * valid constraints.
+ */
+ private static String checkName(String name)
+ {
+ if (!(name.equals("*")))
+ {
+ String[] constraints = name.split(",");
+ name = "";
+ boolean seenCreate = false;
+ boolean seenNew = false;
+ boolean start = true;
+ for (int a = 0; a < constraints.length; ++a)
+ {
+ String next = constraints[a].trim();
+ if (!(next.equals("createMBeanServer") ||
+ next.equals("findMBeanServer") ||
+ next.equals("newMBeanServer") ||
+ next.equals("releaseMBeanServer")))
+ throw new IllegalArgumentException("An invalid constraint, " +
+ next + ", was specified.");
+ if (next.equals("newMBeanServer"))
+ seenNew = true;
+ else if (next.equals("createMBeanServer"))
+ seenCreate = true;
+ else
+ {
+ if (!start)
+ name += ",";
+ name += next;
+ start = false;
+ }
+ }
+ if (seenNew && !seenCreate)
+ name += (start ? "" : ",") + "newMBeanServer";
+ else if (seenCreate)
+ name += (start ? "" : ",") + "createMBeanServer";
+ }
+ return name;
+ }
+
+}
+
+
+
+
Added: trunk/core/src/classpath/javax/javax/net/ssl/CertPathTrustManagerParameters.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/CertPathTrustManagerParameters.java (rev 0)
+++ trunk/core/src/classpath/javax/javax/net/ssl/CertPathTrustManagerParameters.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -0,0 +1,71 @@
+/* CertPathTrustManagerParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 javax.net.ssl;
+
+import java.security.cert.CertPathParameters;
+
+/**
+ * Trust manager parameters for certification paths.
+ */
+public class CertPathTrustManagerParameters implements ManagerFactoryParameters
+{
+ private final CertPathParameters params;
+
+ /**
+ * Creates a new trust manager parameter instance. The argument is
+ * cloned to prevent modification of this instance.
+ *
+ * @param params The certificate path parameters.
+ * @throws NullPointerException If params is null.
+ */
+ public CertPathTrustManagerParameters (final CertPathParameters params)
+ {
+ this.params = (CertPathParameters) params.clone ();
+ }
+
+ /**
+ * Returns a copy of the certificate path parameters.
+ *
+ * @return A copy of the certificate path parameters.
+ */
+ public CertPathParameters getParameters ()
+ {
+ return (CertPathParameters) params.clone ();
+ }
+}
Modified: trunk/core/src/classpath/javax/javax/net/ssl/HandshakeCompletedEvent.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/HandshakeCompletedEvent.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/net/ssl/HandshakeCompletedEvent.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -38,6 +38,7 @@
package javax.net.ssl;
+import java.security.Principal;
import java.security.cert.Certificate;
import javax.security.cert.X509Certificate;
@@ -108,6 +109,20 @@
}
/**
+ * Returns the local identity used in this connection, or
+ * <code>null</code> if there is none.
+ *
+ * @return The local identity.
+ * @since 1.5
+ */
+ public Principal getLocalPrincipal ()
+ {
+ if (session != null)
+ return session.getLocalPrincipal ();
+ return null;
+ }
+
+ /**
* Returns the peer's certificates being used in this connection.
*
* @return The peer's certificates.
@@ -129,6 +144,22 @@
}
/**
+ * Returns the peer's identity, or <code>null</code> if there is
+ * none.
+ *
+ * @return The peer's identity.
+ * @throws SSLPeerUnverifiedException If the remote peer's identity
+ * could not be verified.
+ * @since 1.5
+ */
+ public Principal getPeerPrincipal () throws SSLPeerUnverifiedException
+ {
+ if (session != null)
+ return session.getPeerPrincipal ();
+ return null;
+ }
+
+ /**
* Returns the SSL session object associated with this connection.
*
* @return The session object.
Modified: trunk/core/src/classpath/javax/javax/net/ssl/HttpsURLConnection.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/HttpsURLConnection.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/net/ssl/HttpsURLConnection.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -38,9 +38,12 @@
package javax.net.ssl;
+import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.security.Principal;
import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
/**
* A URL connection that connects via the <i>Secure Socket Layer</i>
@@ -245,6 +248,48 @@
this.factory = factory;
}
+ /**
+ * Returns the local principal for this connection.
+ *
+ * <p>The default implementation will return the {@link
+ * javax.security.x500.X500Principal} for the end entity certificate
+ * in the local certificate chain if those certificates are of type
+ * {@link java.security.cert.X509Certificate}. Otherwise, this
+ * method returns <code>null</code>.
+ *
+ * @return The local principal.
+ * @since 1.5
+ */
+ public Principal getLocalPrincipal ()
+ {
+ Certificate[] c = getLocalCertificates ();
+ if (c != null && c.length > 0 && (c[0] instanceof X509Certificate))
+ return ((X509Certificate) c[0]).getSubjectX500Principal ();
+ return null;
+ }
+
+ /**
+ * Returns the remote peer's principal for this connection.
+ *
+ * <p>The default implementation will return the {@link
+ * javax.security.x500.X500Principal} for the end entity certificate
+ * in the remote peer's certificate chain if those certificates are
+ * of type {@link java.security.cert.X509Certificate}. Otherwise,
+ * this method returns <code>null</code>.
+ *
+ * @return The remote principal.
+ * @throws SSLPeerUnverifiedException If the remote peer has not
+ * been verified.
+ * @since 1.5
+ */
+ public Principal getPeerPrincipal () throws SSLPeerUnverifiedException
+ {
+ Certificate[] c = getServerCertificates ();
+ if (c != null && c.length > 0 && (c[0] instanceof X509Certificate))
+ return ((X509Certificate) c[0]).getSubjectX500Principal ();
+ return null;
+ }
+
// Abstract methods.
// -------------------------------------------------------------------
Added: trunk/core/src/classpath/javax/javax/net/ssl/KeyStoreBuilderParameters.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/KeyStoreBuilderParameters.java (rev 0)
+++ trunk/core/src/classpath/javax/javax/net/ssl/KeyStoreBuilderParameters.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -0,0 +1,48 @@
+/* KeyStoreBuilderParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 javax.net.ssl;
+
+/**
+ * <p style="color: red;"><b>FIXME</b> this class is currently a stub;
+ * it depends on an implementation of {@link
+ * java.security.KeyStore.Builder}</p>.
+ */
+public class KeyStoreBuilderParameters implements ManagerFactoryParameters
+{
+}
Modified: trunk/core/src/classpath/javax/javax/net/ssl/SSLContext.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/SSLContext.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/net/ssl/SSLContext.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -189,6 +189,31 @@
}
/**
+ * Creates a new {@link SSLEngine} for this context.
+ *
+ * @return The new SSLEngine.
+ * @since 1.5
+ */
+ public final SSLEngine createSSLEngine ()
+ {
+ return ctxSpi.engineCreateSSLEngine ();
+ }
+
+ /**
+ * Creates a new {@link SSLEngine} for this context, with a given
+ * host name and port number.
+ *
+ * @param host The local host name.
+ * @param port The local port number.
+ * @return The new SSLEngine.
+ * @since 1.5
+ */
+ public final SSLEngine createSSLEngine (final String host, final int port)
+ {
+ return ctxSpi.engineCreateSSLEngine (host, port);
+ }
+
+ /**
* Returns the set of SSL contexts available for client connections.
*
* @return The set of SSL contexts available for client connections.
Modified: trunk/core/src/classpath/javax/javax/net/ssl/SSLContextSpi.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/SSLContextSpi.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/net/ssl/SSLContextSpi.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -64,7 +64,29 @@
// Abstract methods.
// -------------------------------------------------------------------
+ // Sun, you've broken existing applications by introducing new
+ // abstract methods! Goodjob!!!
+
/**
+ * Returns a new {@link SSLEngine} for this context.
+ *
+ * @return A new SSLEngine.
+ * @since 1.5
+ */
+ protected abstract SSLEngine engineCreateSSLEngine ();
+
+ /**
+ * Returns a new {@link SSLEngine} for this context, for the given
+ * host name and port number.
+ *
+ * @param host The local host name.
+ * @param port The local port number.
+ * @return A new SSLEngine.
+ * @since 1.5
+ */
+ protected abstract SSLEngine engineCreateSSLEngine (String host, int port);
+
+ /**
* Returns the set of SSL sessions available for client connections.
*
* @return The set of SSL sessions available for client connections.
Added: trunk/core/src/classpath/javax/javax/net/ssl/SSLEngine.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/SSLEngine.java (rev 0)
+++ trunk/core/src/classpath/javax/javax/net/ssl/SSLEngine.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -0,0 +1,442 @@
+/* SSLEngine.java -- advanced, generic utility for manipulating SSL messages.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 javax.net.ssl;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A class for low-level message wrapping and unwrapping of SSL
+ * messages.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ * @since 1.5
+ */
+public abstract class SSLEngine
+{
+ private final String peerHost;
+ private final int peerPort;
+
+ /**
+ * Creates a new SSLEngine with no peer host name or port number.
+ */
+ protected SSLEngine ()
+ {
+ this (null, -1);
+ }
+
+ /**
+ * Creates a new SSLEngine with the specified peer host name and
+ * port number.
+ *
+ * @param peerHost The peer's host name.
+ * @param peerPort The peer's port number.
+ */
+ protected SSLEngine (String peerHost, int peerPort)
+ {
+ this.peerHost = peerHost;
+ this.peerPort = peerPort;
+ }
+
+
+
+ /**
+ * Begin, or restart, the SSL handshake.
+ *
+ * @throws SSLException
+ */
+ public abstract void beginHandshake () throws SSLException;
+
+ /**
+ * Close the inbound state.
+ *
+ * @throws SSLException
+ */
+ public abstract void closeInbound () throws SSLException;
+
+ /**
+ * Close the outbound state.
+ */
+ public abstract void closeOutbound ();
+
+ /**
+ *
+ */
+ public abstract Runnable getDelegatedTask ();
+
+ /**
+ * Returns the peer host name this SSL session is connected to, or
+ * <code>null</code> if this value was not set.
+ *
+ * @return The peer host's name.
+ */
+ public String getPeerHost ()
+ {
+ return peerHost;
+ }
+
+ /**
+ * Returns the peer IP port number this SSL session in communicating
+ * on, or -1 if this value was not set.
+ *
+ * @return The peer's port number.
+ */
+ public int getPeerPort ()
+ {
+ return peerPort;
+ }
+
+ /**
+ * Returns a list of SSL cipher suite names this SSLEngine is
+ * configured to use.
+ *
+ * @return The list of enabled cipher suite names.
+ */
+ public abstract String[] getEnabledCipherSuites();
+
+ /**
+ * Returns a list of SSL protocol version names this SSLEngine is
+ * configured to use.
+ *
+ * @return The list of enabled protocol names.
+ */
+ public abstract String[] getEnabledProtocols ();
+
+ /**
+ * Tells if sessions will be created by this engine, and therefore
+ * may be resumed at a later time.
+ *
+ * @return True if sessions will be created.
+ */
+ public abstract boolean getEnableSessionCreation();
+
+ /**
+ * Return the current handshake status.
+ *
+ * @return The current handshake status.
+ */
+ public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus ();
+
+ /**
+ * Tells if this SSLEngine is configured to require client
+ * authentication when in server mode.
+ *
+ * @return True iff client authentication is required.
+ */
+ public abstract boolean getNeedClientAuth ();
+
+ /**
+ * Return the {@link SSLSession} object this connection represents.
+ *
+ * @return The SSL session.
+ */
+ public abstract SSLSession getSession ();
+
+ /**
+ * Returns a list of SSL cipher suite names this SSLEngine
+ * implementation supports.
+ *
+ * @return The list of cipher suite names supported by this
+ * implementation.
+ */
+ public abstract String[] getSupportedCipherSuites ();
+
+ /**
+ * Returns a list of SSL protocol version names this SSLEngine
+ * implementation supports. SSL protocol names include things like
+ * "SSLv3" or "TLSv1".
+ *
+ * @return The list of SSL protocol names
+ */
+ public abstract String[] getSupportedProtocols ();
+
+ /**
+ * Tells if this SSLEngine is a "client" session.
+ *
+ * @return True iff this session is configured for client mode.
+ */
+ public abstract boolean getUseClientMode ();
+
+ /**
+ * Tells if client authentication is requested, but not required,
+ * for sessions in server mode. If true, a server session will
+ * request an authentication message from connecting clients, but
+ * will still allow clients to connect if they cannot be
+ * authenticated.
+ *
+ * @return True iff client authentication is requested.
+ */
+ public abstract boolean getWantClientAuth ();
+
+ /**
+ * Tells if the incoming data stream is finished, and thus if no
+ * more data will be available to be unwrapped.
+ *
+ * @return True if no more data is to be unwrapped.
+ */
+ public abstract boolean isInboundDone ();
+
+ /**
+ * Tells if the outgoing data stream is finished, and thus if no
+ * more data may be wrapped.
+ *
+ * @return True if no more data may be wrapped.
+ */
+ public abstract boolean isOutboundDone ();
+
+ /**
+ * Sets the list of enabled cipher suites. The argument is an array
+ * of strings of the canonical suite names.
+ *
+ * @param suites The cipher suites to enable.
+ * @throws IllegalArgumentException If any of the specified suite
+ * strings is not supported by this implementation, or if the
+ * argument is null.
+ */
+ public abstract void setEnabledCipherSuites (String[] suites);
+
+ /**
+ * Sets the list of enabled protocol versions. The argument is an
+ * array of strings of the canonical protocol version names, such as
+ * "TLSv1".
+ *
+ * @param protocols The protocol versions to enable.
+ * @throws IllegalArgumentException If any of the specified
+ * protocols are not supported, or if the argument is null.
+ */
+ public abstract void setEnabledProtocols (String[] protocols);
+
+ /**
+ * Enables or disables session creation. If enabled, each connection
+ * will create session that may be resumed by another connection.
+ *
+ * @param create Whether or not to enable session creation.
+ */
+ public abstract void setEnableSessionCreation (boolean create);
+
+ /**
+ * Enables client or server mode. If the argument is true, this
+ * engine will run in client mode; if false, server mode.
+ *
+ * @param clientMode Whether or not to use client mode.
+ */
+ public abstract void setUseClientMode (boolean clientMode);
+
+ /**
+ * Enables or disables required client authentication. If enabled,
+ * clients may only connect if they provide proper identification.
+ *
+ * <p>This parameter is only used in server mode.
+ *
+ * @param needAuth Whether or not client authentication is required.
+ */
+ public abstract void setNeedClientAuth (boolean needAuth);
+
+ /**
+ * Enables or disables requested client authentication. If enabled,
+ * clients will be asked to provide proper identification, but will
+ * still be allowed to connect if they do not provide it.
+ *
+ * <p>This parameter is only used in server mode.
+ *
+ * @param wantAuth Whether or not client authentication will be
+ * requested, but not required.
+ */
+ public abstract void setWantClientAuth (boolean wantAuth);
+
+ /**
+ * Unwraps a byte buffer recieved from the network, storing the
+ * decrypted, unwrapped bytes into the given buffer.
+ *
+ * <p>This call is exactly equivalent to <code>unwrap (source, new
+ * ByteBuffer[] { sink }, 0, 1)</code>.
+ *
+ * @param source The source bytes, coming from the network.
+ * @param sink The buffer to hold the unwrapped message.
+ * @return An engine result object for the operation.
+ * @throws SSLException If an SSL message parsing error occurs.
+ * @throws java.nio.ReadOnlyBufferException If 'sink' is not
+ * writable.
+ * @throws IllegalArgumentException If either 'source' or 'sink' is
+ * null.
+ * @throws IllegalStateException If this engine has not been put
+ * into client or server mode.
+ */
+ public SSLEngineResult unwrap (ByteBuffer source, ByteBuffer sink)
+ throws SSLException
+ {
+ return unwrap (source, new ByteBuffer[] { sink }, 0, 1);
+ }
+
+ /**
+ * Unwraps a byte buffer recieved from the network, storing the
+ * decrypted, unwrapped bytes into the given buffers.
+ *
+ * <p>This call is exactly equivalent to <code>unwrap (source,
+ * sinks, 0, sinks.length)</code>.
+ *
+ * @param source The source bytes, coming from the network.
+ * @param sinks The buffers to hold the unwrapped message.
+ * @return An engine result object for the operation.
+ * @throws SSLException If an SSL message parsing error occurs.
+ * @throws java.nio.ReadOnlyBufferException If any buffer in 'sinks'
+ * is not writable.
+ * @throws IllegalArgumentException If either 'source' or 'sinks' is
+ * null.
+ * @throws IllegalStateException If this engine has not been put
+ * into client or server mode.
+ */
+ public SSLEngineResult unwrap (ByteBuffer source, ByteBuffer[] sinks)
+ throws SSLException
+ {
+ return unwrap (source, sinks, 0, sinks.length);
+ }
+
+ /**
+ * Unwraps a byte buffer received from the network, storing the
+ * decrypted, unwrapped bytes into the given buffers. After
+ * unwrapping, the bytes placed into the sink buffers are ready for
+ * consumption by the application.
+ *
+ * <p>This method may place no bytes in the destination buffer; for
+ * example, if this engine is still performing the SSL handshake,
+ * only handshake data will be consumed, and no application data.
+ *
+ * <p>It is stated that this method may modify the source buffer,
+ * and that it must not be passed to another SSLEngine (SSL
+ * connections are independent, so another SSLEngine will not have
+ * the parameters or state to handle messages meant for this
+ * engine).
+ *
+ * @param source The source bytes, coming from the network.
+ * @param sinks The buffers to hold the unwrapped message.
+ * @param offset The index of the first buffer in 'sinks' to use.
+ * @param length The number of buffers in 'sinks' to use.
+ * @return An engine result object for the operation.
+ * @throws SSLException If an SSL message parsing error occurs.
+ * @throws java.nio.ReadOnlyBufferException If any buffer in 'sinks'
+ * is not writable.
+ * @throws IllegalArgumentException If either 'source' or 'sinks' is
+ * null.
+ * @throws IllegalStateException If this engine has not been put
+ * into client or server mode.
+ * @throws IndexOutOfBoundsException If 'offset' or 'length' is
+ * negative, or if 'length+offset' is greater than 'sinks.length'.
+ */
+ public abstract SSLEngineResult unwrap (ByteBuffer source,
+ ByteBuffer[] sinks, int offset,
+ int length)
+ throws javax.net.ssl.SSLException;
+
+ /**
+ * Wraps a byte buffer into an SSL message, for preparation to send
+ * it over the network.
+ *
+ * <p>This method is exactly equivalent to <code>wrap (new
+ * ByteBuffer[] { source }, 0, 1, sink)</code>.
+ *
+ * @param source The source buffer with application data.
+ * @param sink The buffer to hold the wrapped data.
+ * @return An engine result object for the operation.
+ * @throws SSLException If an SSL error occurs.
+ * @throws java.nio.ReadOnlyBufferException If 'sink' is read-only.
+ * @throws IllegalArgumentException If either 'source' or 'sink' is
+ * null.
+ * @throws IllegalStateException If this engine has not been put
+ * into client or server mode.
+ */
+ public SSLEngineResult wrap (ByteBuffer source, ByteBuffer sink)
+ throws SSLException
+ {
+ return wrap (new ByteBuffer[] { source }, 0, 1, sink);
+ }
+
+ /**
+ * Wraps byte buffers into an SSL message, for preparation to send
+ * them over the network.
+ *
+ * <p>This method is exactly equivalent to <code>wrap (sources, 0,
+ * 1, sink)</code>.
+ *
+ * @param sources The source buffers with application data.
+ * @param sink The buffer to hold the wrapped data.
+ * @return An engine result object for the operation.
+ * @throws SSLException If an SSL error occurs.
+ * @throws java.nio.ReadOnlyBufferException If 'sink' is read-only.
+ * @throws IllegalArgumentException If either 'sources' or 'sink' is
+ * null.
+ * @throws IllegalStateException If this engine has not been put
+ * into client or server mode.
+ */
+ public SSLEngineResult wrap (ByteBuffer[] sources, ByteBuffer sink)
+ throws SSLException
+ {
+ return wrap (sources, 0, sources.length, sink);
+ }
+
+ /**
+ * Wraps byte buffers into an SSL message, for preparation to send
+ * them over the network. After wrapping, the data in the sink
+ * buffer is ready to be sent over the transport layer.
+ *
+ * <p>This method may consume no data from the source buffers, and
+ * yet still produce output that should be sent accross the wire;
+ * for example if this engine has not yet completed the SSL
+ * handshake, the sink buffer will be filled with handshake
+ * messages.
+ *
+ * @param sources The source buffers with application data.
+ * @param offset The offset into the source buffers to start reading
+ * application data.
+ * @param length The number of buffers to read from 'sources'.
+ * @param sink The buffer to hold the wrapped data.
+ * @return An engine result object for the operation.
+ * @throws SSLException If an SSL error occurs.
+ * @throws java.nio.ReadOnlyBufferException If 'sink' is read-only.
+ * @throws IllegalArgumentException If either 'sources' or 'sink' is
+ * null.
+ * @throws IllegalStateException If this engine has not been put
+ * into client or server mode.
+ * @throws IndexOutOfBoundsException If 'offset' or 'length' is
+ * negative, or if 'length+offset' is greater than 'sources.length'.
+ */
+ public abstract SSLEngineResult wrap (ByteBuffer[] sources, int offset,
+ int length, ByteBuffer sink)
+ throws SSLException;
+
+}
Added: trunk/core/src/classpath/javax/javax/net/ssl/SSLEngineResult.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/SSLEngineResult.java (rev 0)
+++ trunk/core/src/classpath/javax/javax/net/ssl/SSLEngineResult.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -0,0 +1,194 @@
+/* SSLEngineResult.java --
+ Copyright (C) 2006 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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 javax.net.ssl;
+
+/**
+ * A result from an {@link SSLEngine} <code>wrap</code> or
+ * <code>unwrap</code> operation. This class conveys a possibly
+ * intermediate result, and may ask for more input data or request
+ * that output data be sent over a connection.
+ */
+public class SSLEngineResult
+{
+ private final HandshakeStatus handshakeStatus;
+ private final Status status;
+ private final int bytesConsumed;
+ private final int bytesProduced;
+
+ /**
+ * Creates a new SSL engine result.
+ *
+ * @param status The status of the SSL connection.
+ * @param handshakeStatus The status of the SSL handshake.
+ * @param bytesConsumed The number of bytes consumed by the previous
+ * operation.
+ * @param bytesProduced The number of bytes produced by the previous
+ * operation.
+ * @throws IllegalArgumentException If either enum value is
+ * <code>null</code>, or if either integer is negative.
+ */
+ public SSLEngineResult (Status status, HandshakeStatus handshakeStatus,
+ int bytesConsumed, int bytesProduced)
+ {
+ if (status == null)
+ throw new IllegalArgumentException ("'status' may not be null");
+ if (handshakeStatus == null)
+ throw new IllegalArgumentException ("'handshakeStatus' may not be null");
+ if (bytesConsumed < 0)
+ throw new IllegalArgumentException ("'bytesConumed' must be nonnegative");
+ if (bytesProduced < 0)
+ throw new IllegalArgumentException ("'bytesProduced' must be nonnegative");
+ this.status = status;
+ this.handshakeStatus = handshakeStatus;
+ this.bytesConsumed = bytesConsumed;
+ this.bytesProduced = bytesProduced;
+ }
+
+
+
+ /**
+ * An enumeration of possible general states.
+ */
+ public static enum Status
+ {
+
+ /**
+ * There were not enough input bytes available to complete the
+ * operation.
+ */
+ BUFFER_UNDERFLOW,
+
+ /**
+ * There was not enough space for the output message.
+ */
+ BUFFER_OVERFLOW,
+
+ /**
+ * Okay. No error.
+ */
+ OK,
+
+ /**
+ * The connection is closed.
+ */
+ CLOSED
+ }
+
+ /**
+ * An enumeration of possible handshake status states.
+ */
+ public static enum HandshakeStatus
+ {
+
+ /**
+ * Not currently handshaking.
+ */
+ NOT_HANDSHAKING,
+
+ /**
+ * The handshake is finished.
+ */
+ FINISHED,
+
+ /**
+ * Needs the status of one or more delegated tasks.
+ */
+ NEED_TASK,
+
+ /**
+ * Has data prepared for output, and needs a new call to
+ * <code>wrap</code>.
+ */
+ NEED_WRAP,
+
+ /**
+ * Is waiting for more input.
+ */
+ NEED_UNWRAP
+ }
+
+
+
+ /**
+ * Returns the number of bytes consumed by the previous operation.
+ *
+ * @return The number of bytes consumed.
+ */
+ public int bytesConsumed ()
+ {
+ return bytesConsumed;
+ }
+
+ /**
+ * Returns the number of bytes produced by the previous operation.
+ *
+ * @return The number of bytes produced.
+ */
+ public int bytesProduced ()
+ {
+ return bytesProduced;
+ }
+
+ /**
+ * Returns the handshake status.
+ *
+ * @return The handshake status.
+ */
+ public HandshakeStatus getHandshakeStatus ()
+ {
+ return handshakeStatus;
+ }
+
+ /**
+ * Returns the connection status.
+ *
+ * @return The connection status.
+ */
+ public Status getStatus ()
+ {
+ return status;
+ }
+
+ public String toString ()
+ {
+ return (super.toString () + " [ status: " + status + "; handshakeStatus: "
+ + handshakeStatus + "; bytesConsumed: " + bytesConsumed
+ + "; bytesProduced: " + bytesProduced + " ]");
+ }
+}
Modified: trunk/core/src/classpath/javax/javax/net/ssl/SSLServerSocketFactory.java
===================================================================
--- trunk/core/src/classpath/javax/javax/net/ssl/SSLServerSocketFactory.java 2007-01-07 12:55:51 UTC (rev 3024)
+++ trunk/core/src/classpath/javax/javax/net/ssl/SSLServerSocketFactory.java 2007-01-07 12:57:57 UTC (rev 3025)
@@ -38,6 +38,9 @@
package javax.net.ssl;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
import java.security.KeyStore;
import java.security.Security;
@@ -138,8 +141,9 @@
}
catch (Exception ex)
{
- throw new RuntimeException("error instantiating default server socket factory: "
- + ex.toString());
+ return ne...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 12:55:52
|
Revision: 3024
http://jnode.svn.sourceforge.net/jnode/?rev=3024&view=rev
Author: lsantha
Date: 2007-01-07 04:55:51 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/print/PrintService.java
trunk/core/src/classpath/javax/javax/print/attribute/Attribute.java
trunk/core/src/classpath/javax/javax/print/attribute/AttributeSet.java
trunk/core/src/classpath/javax/javax/print/attribute/AttributeSetUtilities.java
trunk/core/src/classpath/javax/javax/print/attribute/HashAttributeSet.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Chromaticity.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/ColorSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Compression.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Copies.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/CopiesSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCompleted.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCreation.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtProcessing.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Destination.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/DocumentName.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Fidelity.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Finishings.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobHoldUntil.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressions.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsCompleted.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctets.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsProcessed.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheets.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsCompleted.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMessageFromOperator.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobName.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobOriginatingUserName.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPriority.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPrioritySupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobSheets.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobState.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReason.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReasons.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Media.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaPrintableArea.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaSize.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/MultipleDocumentHandling.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfDocuments.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfInterveningJobs.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUp.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUpSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/OrientationRequested.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/OutputDeviceAssigned.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PDLOverrideSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PageRanges.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinute.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinuteColor.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PresentationDirection.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrintQuality.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterInfo.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterIsAcceptingJobs.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterLocation.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMakeAndModel.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMessageFromOperator.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMoreInfo.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMoreInfoManufacturer.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterName.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterResolution.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterState.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterStateReason.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterStateReasons.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterURI.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/QueuedJobCount.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/ReferenceUriSchemesSupported.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/RequestingUserName.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Severity.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/SheetCollate.java
trunk/core/src/classpath/javax/javax/print/attribute/standard/Sides.java
Modified: trunk/core/src/classpath/javax/javax/print/PrintService.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/PrintService.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/PrintService.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -89,7 +89,7 @@
* @throws IllegalArgumentException if category is not a class that
* implements <code>PrintServiceAttribute</code>.
*/
- PrintServiceAttribute getAttribute(Class category);
+ <T extends PrintServiceAttribute> T getAttribute(Class<T> category);
/**
* Returns the attributes describing this print service. The returned
@@ -123,7 +123,7 @@
* @throws IllegalArgumentException if <code>category</code> is a class
* not implementing <code>Attribute</code>
*/
- Object getDefaultAttributeValue(Class category);
+ Object getDefaultAttributeValue(Class<? extends Attribute> category);
/**
* Returns the name of this print service.
@@ -145,7 +145,7 @@
*
* @return The class array of all supported attribute categories.
*/
- Class[] getSupportedAttributeCategories();
+ Class<?>[] getSupportedAttributeCategories();
/**
* Determines and returns all supported attribute values of a given
@@ -177,7 +177,9 @@
* implementing <code>Attribute</code>, or if <code>flavor</code> is not
* supported
*/
- Object getSupportedAttributeValues(Class category, DocFlavor flavor, AttributeSet attributes);
+ Object getSupportedAttributeValues(Class<? extends Attribute> category,
+ DocFlavor flavor,
+ AttributeSet attributes);
/**
* Determines and returns an array of all supported document flavors which
@@ -189,7 +191,7 @@
* the specific doc flavor and attributes set.
* </p>
*
- * @return The supported document flavors.
+ * @return the supported document flavors
*/
DocFlavor[] getSupportedDocFlavors();
@@ -240,7 +242,7 @@
* @throws IllegalArgumentException if <code>category</code> is a class not
* implementing <code>Attribute</code>.
*/
- boolean isAttributeCategorySupported(Class category);
+ boolean isAttributeCategorySupported(Class<? extends Attribute> category);
/**
* Determines if a given attribute value is supported when creating a print
Modified: trunk/core/src/classpath/javax/javax/print/attribute/Attribute.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/Attribute.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/Attribute.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -52,7 +52,7 @@
*
* @return The concrete {@link Class} instance of the attribute class.
*/
- Class getCategory ();
+ Class< ? extends Attribute> getCategory ();
/**
* Returns the descriptive name of the attribute category.
Modified: trunk/core/src/classpath/javax/javax/print/attribute/AttributeSet.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/AttributeSet.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/AttributeSet.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -110,7 +110,7 @@
* @return <code>true</code> if an attribute of the category is contained
* in the set, <code>false</code> otherwise.
*/
- boolean containsKey (Class category);
+ boolean containsKey (Class<?> category);
/**
* Checks if this attribute set contains the given attribute.
@@ -143,7 +143,7 @@
* @throws ClassCastException if category is not implementing
* <code>Attribute</code>.
*/
- Attribute get (Class category);
+ Attribute get (Class<?> category);
/**
* Returns the hashcode value. The hashcode value is the sum of all hashcodes
@@ -178,7 +178,7 @@
* @return <code>true</code> if an attribute is removed, false in all other cases.
* @throws UnmodifiableSetException if the set does not support modification.
*/
- boolean remove (Class category);
+ boolean remove (Class<?> category);
/**
* Returns the number of elements in this attribute set.
Modified: trunk/core/src/classpath/javax/javax/print/attribute/AttributeSetUtilities.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/AttributeSetUtilities.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/AttributeSetUtilities.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -435,8 +435,8 @@
* that implements interfaceName
* @exception NullPointerException if object is null
*/
- public static Class verifyAttributeCategory(Object object,
- Class interfaceName)
+ public static Class<?> verifyAttributeCategory(Object object,
+ Class<?> interfaceName)
{
if (object == null)
throw new NullPointerException("object may not be null");
@@ -461,7 +461,7 @@
* @exception NullPointerException if object is null
*/
public static Attribute verifyAttributeValue(Object object,
- Class interfaceName)
+ Class<?> interfaceName)
{
if (object == null)
throw new NullPointerException("object may not be null");
@@ -482,7 +482,7 @@
* @exception IllegalArgumentException if the categories are not equal
* @exception NullPointerException if category is null
*/
- public static void verifyCategoryForValue(Class category,
+ public static void verifyCategoryForValue(Class<?> category,
Attribute attribute)
{
if (category == null || attribute == null)
Modified: trunk/core/src/classpath/javax/javax/print/attribute/HashAttributeSet.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/HashAttributeSet.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/HashAttributeSet.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -110,7 +110,7 @@
*
* @exception NullPointerException if interfaceName is null
*/
- protected HashAttributeSet(Class interfaceName)
+ protected HashAttributeSet(Class<?> interfaceName)
{
if (interfaceName == null)
throw new NullPointerException("interfaceName may not be null");
@@ -129,7 +129,7 @@
* interfaceName
* @exception NullPointerException if attribute or interfaceName is null
*/
- protected HashAttributeSet(Attribute attribute, Class interfaceName)
+ protected HashAttributeSet(Attribute attribute, Class<?> interfaceName)
{
this(interfaceName);
@@ -151,7 +151,7 @@
* interface of interfaceName
* @exception NullPointerException if attributes or interfaceName is null
*/
- protected HashAttributeSet(Attribute[] attributes, Class interfaceName)
+ protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName)
{
this(interfaceName);
@@ -173,7 +173,7 @@
* @exception ClassCastException if any element of attributes is not an
* interface of interfaceName
*/
- protected HashAttributeSet(AttributeSet attributes, Class interfaceName)
+ protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName)
{
this(interfaceName);
@@ -256,7 +256,7 @@
* @return <code>true</code> if an attribute of the category is contained
* in the set, <code>false</code> otherwise.
*/
- public boolean containsKey(Class category)
+ public boolean containsKey(Class<?> category)
{
return attributeMap.containsKey(category);
}
@@ -301,7 +301,7 @@
* @throws ClassCastException if category is not implementing
* <code>Attribute</code>.
*/
- public Attribute get(Class category)
+ public Attribute get(Class<?> category)
{
if (category == null)
throw new NullPointerException("category may not be null");
@@ -359,7 +359,7 @@
* @return <code>true</code> if an attribute is removed, false in all other cases.
* @throws UnmodifiableSetException if the set does not support modification.
*/
- public boolean remove(Class category)
+ public boolean remove(Class<?> category)
{
if (category == null)
return false;
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Chromaticity.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Chromaticity.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Chromaticity.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -38,6 +38,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -94,7 +95,7 @@
*
* @return The class <code>Chromaticity</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Chromaticity.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/ColorSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/ColorSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/ColorSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintServiceAttribute;
@@ -88,7 +89,7 @@
*
* @return The class <code>ColorSupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return ColorSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Compression.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Compression.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Compression.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.EnumSyntax;
@@ -91,7 +92,7 @@
*
* @return The class <code>Compression</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Compression.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Copies.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Copies.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Copies.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -97,7 +98,7 @@
*
* @return The class <code>Copies</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Copies.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/CopiesSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/CopiesSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/CopiesSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.SupportedValuesAttribute;
@@ -112,7 +113,7 @@
*
* @return The class <code>CopiesSupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return CopiesSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCompleted.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCompleted.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCompleted.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Date;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DateTimeSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -92,7 +93,7 @@
*
* @return The class <code>DateTimeAtCompleted</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return DateTimeAtCompleted.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCreation.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCreation.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtCreation.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Date;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DateTimeSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -92,7 +93,7 @@
*
* @return The class <code>DateTimeAtCreation</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return DateTimeAtCreation.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtProcessing.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtProcessing.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/DateTimeAtProcessing.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Date;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DateTimeSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -92,7 +93,7 @@
*
* @return The class <code>DateTimeAtProcessing</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return DateTimeAtProcessing.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Destination.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Destination.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Destination.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.net.URI;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
import javax.print.attribute.URISyntax;
@@ -104,7 +105,7 @@
*
* @return The class <code>Destination</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Destination.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/DocumentName.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/DocumentName.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/DocumentName.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.TextSyntax;
@@ -98,7 +99,7 @@
*
* @return The class <code>DocumentName</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return DocumentName.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Fidelity.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Fidelity.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Fidelity.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -38,6 +38,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -107,7 +108,7 @@
*
* @return The class <code>Fidelity</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Fidelity.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Finishings.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Finishings.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Finishings.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -38,6 +38,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -238,7 +239,7 @@
*
* @return the class <code>Finishings</code> itself
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Finishings.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobHoldUntil.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobHoldUntil.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobHoldUntil.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Date;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DateTimeSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -98,7 +99,7 @@
*
* @return The class <code>JobHoldUntil</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobHoldUntil.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressions.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressions.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressions.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -110,7 +111,7 @@
*
* @return The class <code>JobImpressions</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobImpressions.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsCompleted.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsCompleted.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsCompleted.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -101,7 +102,7 @@
*
* @return The class <code>JobImpressionsCompleted</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobImpressionsCompleted.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobImpressionsSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.SupportedValuesAttribute;
@@ -96,7 +97,7 @@
*
* @return The class <code>JobImpressionsSupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobImpressionsSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctets.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctets.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctets.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -110,7 +111,7 @@
*
* @return The class <code>JobKOctets</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobKOctets.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsProcessed.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsProcessed.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsProcessed.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -102,7 +103,7 @@
*
* @return The class <code>JobKOctetsProcessed</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobKOctetsProcessed.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobKOctetsSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.SupportedValuesAttribute;
@@ -96,7 +97,7 @@
*
* @return The class <code>JobKOctetsSupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobKOctetsSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheets.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheets.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheets.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -107,7 +108,7 @@
*
* @return The class <code>JobMediaSheets</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobMediaSheets.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsCompleted.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsCompleted.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsCompleted.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -96,7 +97,7 @@
*
* @return The class <code>JobMediaSheetsCompleted</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobMediaSheetsCompleted.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMediaSheetsSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.SupportedValuesAttribute;
@@ -96,7 +97,7 @@
*
* @return The class <code>JobMediaSheetsSupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobMediaSheetsSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMessageFromOperator.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMessageFromOperator.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobMessageFromOperator.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.TextSyntax;
@@ -95,7 +96,7 @@
*
* @return The class <code>JobMessageFromOperator</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobMessageFromOperator.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobName.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobName.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobName.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
import javax.print.attribute.TextSyntax;
@@ -93,7 +94,7 @@
*
* @return The class <code>JobName</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobName.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobOriginatingUserName.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobOriginatingUserName.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobOriginatingUserName.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.TextSyntax;
@@ -92,7 +93,7 @@
*
* @return The class <code>JobOriginatingUserName</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobOriginatingUserName.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPriority.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPriority.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPriority.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -97,7 +98,7 @@
*
* @return The class <code>JobPriority</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobPriority.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPrioritySupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPrioritySupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobPrioritySupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.SupportedValuesAttribute;
@@ -99,7 +100,7 @@
*
* @return The class <code>JobPrioritySupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobPrioritySupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobSheets.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobSheets.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobSheets.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -88,7 +89,7 @@
*
* @return The class <code>JobSheets</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobSheets.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobState.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobState.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobState.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -137,7 +138,7 @@
*
* @return The class <code>JobState</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobState.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReason.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReason.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReason.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -262,7 +262,7 @@
*
* @return The class <code>JobStateReason</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobStateReason.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReasons.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReasons.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/JobStateReasons.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -42,6 +42,7 @@
import java.util.HashSet;
import java.util.Iterator;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintJobAttribute;
/**
@@ -56,7 +57,7 @@
* @author Michael Koch (kon...@gm...)
* @author Wolfgang Baer (WB...@gm...)
*/
-public final class JobStateReasons extends HashSet
+public final class JobStateReasons extends HashSet<JobStateReason>
implements PrintJobAttribute
{
private static final long serialVersionUID = 8849088261264331812L;
@@ -108,12 +109,11 @@
* @throws ClassCastException if values of collection are not of type
* <code>JobStateReason</code>.
*/
- public JobStateReasons(Collection collection)
+ public JobStateReasons(Collection<JobStateReason> collection)
{
super(collection.size(), 0.75f);
- Iterator it = collection.iterator();
- while (it.hasNext())
- add(it.next());
+ for (JobStateReason reason : collection)
+ add(reason);
}
/**
@@ -126,12 +126,12 @@
* @throws ClassCastException if given object is not an instance of
* <code>JobStateReason</code>.
*/
- public boolean add(Object o)
+ public boolean add(JobStateReason o)
{
if (o == null)
throw new NullPointerException("reason is null");
- return super.add((JobStateReason) o);
+ return add(o);
}
/**
@@ -139,7 +139,7 @@
*
* @return The class <code>JobStateReasons</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return JobStateReasons.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/Media.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/Media.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/Media.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -105,7 +106,7 @@
*
* @return The class <code>Media</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return Media.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaPrintableArea.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaPrintableArea.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaPrintableArea.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -38,6 +38,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -152,7 +153,7 @@
*
* @return The class <code>MediaPrintableArea</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return MediaPrintableArea.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaSize.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaSize.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/MediaSize.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -67,11 +67,11 @@
{
private static final long serialVersionUID = -1967958664615414771L;
- private static ArrayList mediaCache;
+ private static ArrayList<MediaSize> mediaCache;
static
{
- mediaCache = new ArrayList();
+ mediaCache = new ArrayList<MediaSize>();
// We call one instance of every container class to make sure it gets
// loaded during class initialization and therefore all other static
@@ -180,11 +180,12 @@
*
* @return The class <code>MediaSize</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return MediaSize.class;
}
+
/**
* Searches for a MediaSize object with the given dimensions.
* If none is found with exact dimensions, the closest match is used.
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/MultipleDocumentHandling.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/MultipleDocumentHandling.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/MultipleDocumentHandling.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -108,7 +109,7 @@
*
* @return The class <code>MultipleDocumentHandling</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return MultipleDocumentHandling.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfDocuments.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfDocuments.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfDocuments.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -90,7 +91,7 @@
*
* @return The class <code>NumberOfDocuments</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return NumberOfDocuments.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfInterveningJobs.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfInterveningJobs.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberOfInterveningJobs.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -91,7 +92,7 @@
*
* @return The class <code>NumberOfInterveningJobs</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return NumberOfInterveningJobs.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUp.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUp.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUp.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -95,7 +96,7 @@
*
* @return The class <code>NumberUp</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return NumberUp.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUpSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUpSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/NumberUpSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.SupportedValuesAttribute;
@@ -128,7 +129,7 @@
*
* @return The class <code>NumberUpSupported</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return NumberUpSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/OrientationRequested.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/OrientationRequested.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/OrientationRequested.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -112,7 +113,7 @@
*
* @return The class <code>OrientationRequested</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return OrientationRequested.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/OutputDeviceAssigned.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/OutputDeviceAssigned.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/OutputDeviceAssigned.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.TextSyntax;
@@ -98,7 +99,7 @@
*
* @return The class <code>OutputDeviceAssigned</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return OutputDeviceAssigned.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PDLOverrideSupported.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PDLOverrideSupported.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PDLOverrideSupported.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintServiceAttribute;
@@ -91,7 +92,7 @@
*
* @return The class <code>PDLOverrideSupported</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PDLOverrideSupported.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PageRanges.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PageRanges.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PageRanges.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -38,6 +38,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -154,7 +155,7 @@
*
* @return The class <code>PageRanges</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PageRanges.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinute.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinute.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinute.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -38,6 +38,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintServiceAttribute;
@@ -92,7 +93,7 @@
*
* @return The class <code>PagesPerMinute</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PagesPerMinute.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinuteColor.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinuteColor.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PagesPerMinuteColor.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintServiceAttribute;
@@ -91,7 +92,7 @@
*
* @return The class <code>PagesPerMinuteColor</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PagesPerMinuteColor.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PresentationDirection.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PresentationDirection.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PresentationDirection.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
import javax.print.attribute.PrintRequestAttribute;
@@ -138,7 +139,7 @@
*
* @return The class <code>PresentationDirection</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PresentationDirection.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrintQuality.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrintQuality.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrintQuality.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.DocAttribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintJobAttribute;
@@ -92,7 +93,7 @@
*
* @return The class <code>PrintQuality</code> itself.
*/
- public final Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PrintQuality.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterInfo.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterInfo.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterInfo.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.TextSyntax;
@@ -92,7 +93,7 @@
*
* @return The class <code>PrinterInfo</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PrinterInfo.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterIsAcceptingJobs.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterIsAcceptingJobs.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterIsAcceptingJobs.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -37,6 +37,7 @@
package javax.print.attribute.standard;
+import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.PrintServiceAttribute;
@@ -93,7 +94,7 @@
*
* @return The class <code>PrinterIsAcceptingJobs</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PrinterIsAcceptingJobs.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterLocation.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterLocation.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterLocation.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.TextSyntax;
@@ -92,7 +93,7 @@
*
* @return The class <code>PrinterLocation</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PrinterLocation.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMakeAndModel.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMakeAndModel.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMakeAndModel.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.TextSyntax;
@@ -92,7 +93,7 @@
*
* @return The class <code>PrinterMakeAndModel</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PrinterMakeAndModel.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMessageFromOperator.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMessageFromOperator.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMessageFromOperator.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java.util.Locale;
+import javax.print.attribute.Attribute;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.TextSyntax;
@@ -95,7 +96,7 @@
*
* @return The class <code>PrinterMessageFromOperator</code> itself.
*/
- public Class getCategory()
+ public Class< ? extends Attribute> getCategory()
{
return PrinterMessageFromOperator.class;
}
Modified: trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMoreInfo.java
===================================================================
--- trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMoreInfo.java 2007-01-07 12:54:15 UTC (rev 3023)
+++ trunk/core/src/classpath/javax/javax/print/attribute/standard/PrinterMoreInfo.java 2007-01-07 12:55:51 UTC (rev 3024)
@@ -40,6 +40,7 @@
import java....
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 12:54:17
|
Revision: 3023
http://jnode.svn.sourceforge.net/jnode/?rev=3023&view=rev
Author: lsantha
Date: 2007-01-07 04:54:15 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/io/StreamTokenizer.java
trunk/core/src/classpath/java/java/net/URI.java
trunk/core/src/classpath/java/java/rmi/activation/ActivationID.java
trunk/core/src/classpath/java/java/rmi/server/LoaderHandler.java
trunk/core/src/classpath/java/java/rmi/server/RMIClassLoader.java
trunk/core/src/classpath/java/java/rmi/server/RMIClassLoaderSpi.java
trunk/core/src/classpath/java/java/rmi/server/UnicastRemoteObject.java
trunk/core/src/classpath/java/java/security/AccessController.java
trunk/core/src/classpath/java/java/security/MessageDigest.java
trunk/core/src/classpath/java/java/security/MessageDigestSpi.java
trunk/core/src/classpath/java/java/security/Signature.java
trunk/core/src/classpath/java/java/security/SignatureSpi.java
trunk/core/src/classpath/java/java/security/UnresolvedPermission.java
trunk/core/src/classpath/java/java/security/acl/Acl.java
trunk/core/src/classpath/java/java/security/acl/AclEntry.java
trunk/core/src/classpath/java/java/security/acl/Group.java
trunk/core/src/classpath/java/java/security/cert/CertPath.java
trunk/core/src/classpath/java/java/security/cert/CertStore.java
trunk/core/src/classpath/java/java/security/cert/CertStoreSpi.java
trunk/core/src/classpath/java/java/security/cert/CertificateFactory.java
trunk/core/src/classpath/java/java/security/cert/CertificateFactorySpi.java
trunk/core/src/classpath/java/java/security/cert/CollectionCertStoreParameters.java
trunk/core/src/classpath/java/java/security/cert/PKIXBuilderParameters.java
trunk/core/src/classpath/java/java/security/cert/PKIXCertPathChecker.java
trunk/core/src/classpath/java/java/security/cert/PKIXParameters.java
trunk/core/src/classpath/java/java/security/cert/PolicyNode.java
trunk/core/src/classpath/java/java/security/cert/PolicyQualifierInfo.java
trunk/core/src/classpath/java/java/security/cert/X509CRL.java
trunk/core/src/classpath/java/java/security/cert/X509CRLSelector.java
trunk/core/src/classpath/java/java/security/cert/X509CertSelector.java
trunk/core/src/classpath/java/java/security/cert/X509Certificate.java
trunk/core/src/classpath/java/java/security/cert/X509Extension.java
trunk/core/src/classpath/java/java/util/zip/Deflater.java
Added Paths:
-----------
trunk/core/src/classpath/java/java/awt/datatransfer/MimeType.java
trunk/core/src/classpath/java/java/beans/ConstructorProperties.java
trunk/core/src/classpath/java/java/math/RoundingMode.java
trunk/core/src/classpath/java/java/net/Proxy.java
trunk/core/src/classpath/java/java/net/ProxySelector.java
trunk/core/src/classpath/java/java/net/ResolverCache.java
Added: trunk/core/src/classpath/java/java/awt/datatransfer/MimeType.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/datatransfer/MimeType.java (rev 0)
+++ trunk/core/src/classpath/java/java/awt/datatransfer/MimeType.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -0,0 +1,281 @@
+/* MimeType.java -- A helper class for mime handling in DataFlavor
+ Copyright (C) 2006 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.awt.datatransfer;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * A helper class for mime handling in DataFlavor.
+ *
+ * A Mauve test for DataFlavor.writeExternal() shows that a non-public
+ * class java.awt.datatransfer.MimeType gets serialized. This class
+ * is mainly here for serialization compatibility. Of course,
+ * now that we have it here, we can just as well implement some
+ * mime handling facility here.
+ */
+class MimeType
+ implements Externalizable
+{
+
+ /**
+ * The primary type.
+ */
+ private String primaryType;
+
+ /**
+ * The subtype.
+ */
+ private String subType;
+
+ /**
+ * Additional parameters to be appended to the mime string.
+ */
+ private HashMap parameters;
+
+ /**
+ * This is only here for deserialization.
+ */
+ public MimeType()
+ {
+ parameters = new HashMap();
+ }
+
+ /**
+ * Creates a new MimeType object.
+ *
+ * @param mime the mime type
+ */
+ MimeType(String mime)
+ throws MimeTypeParseException
+ {
+ this();
+ parse(mime);
+ }
+
+ /**
+ * Adds a mime parameter.
+ *
+ * @param param the parameter key
+ * @param value the parameter value
+ */
+ void addParameter(String param, String value)
+ {
+ parameters.put(param, value);
+ }
+
+ /**
+ * Removes the parameter with the specified key.
+ *
+ * @param param the parameter to remove
+ */
+ void removeParameter(String param)
+ {
+ parameters.remove(param);
+ }
+
+ /**
+ * Returns the parameter for the <code>key</code>.
+ *
+ * @param key the parameter key
+ *
+ * @return the parameter for the <code>key</code>
+ */
+ String getParameter(String key)
+ {
+ return (String) parameters.get(key);
+ }
+
+ /**
+ * Returns the primary type.
+ *
+ * @return the primary type
+ */
+ String getPrimaryType()
+ {
+ return primaryType;
+ }
+
+ String getSubType()
+ {
+ return subType;
+ }
+
+ /**
+ * Returns the base type of this mime type. This is the primary
+ * type plus the subtype, separated by '/'.
+ *
+ * @return the base type of this mime type
+ */
+ String getBaseType()
+ {
+ return primaryType + '/' + subType;
+ }
+
+ /**
+ * Returns <code>true</code> if this mime type and another mime type
+ * match. This will be true when their primary types are equal, and their
+ * subtypes are equal (or when either subtype is * ).
+ *
+ * @param other the other mime type
+ *
+ * @return <code>true</code> if the mime types match, <code>false</code>
+ * otherwise
+ */
+ boolean matches(MimeType other)
+ {
+ boolean match = false;
+ if (other != null)
+ {
+ match = primaryType.equals(other.primaryType)
+ && (subType.equals("*") || other.subType.equals("*")
+ || subType.equals(other.subType));
+ }
+ return match;
+ }
+
+ /**
+ * Serializes the mime type.
+ *
+ * @param in the input stream to read from
+ *
+ * @throws ClassNotFoundException not thrown here
+ * @throws IOException when something goes wrong on the input stream,
+ * or when the mime type can't be parsed
+ */
+ public void readExternal(ObjectInput in)
+ throws ClassNotFoundException, IOException
+ {
+ String mime = in.readUTF();
+ parameters.clear();
+ try
+ {
+ parse(mime);
+ }
+ catch (MimeTypeParseException ex)
+ {
+ IOException ioEx = new IOException();
+ ioEx.initCause(ex);
+ throw ioEx;
+ }
+ }
+
+ /**
+ * Serializes this mime type.
+ *
+ * @param out the output stream
+ *
+ * @throws IOException when something goes wrong on the output stream
+ */
+ public void writeExternal(ObjectOutput out)
+ throws IOException
+ {
+ out.writeUTF(toString());
+ }
+
+ /**
+ * Creates a string representation of this mime type.
+ *
+ * @return a string representation of this mime type
+ */
+ public String toString()
+ {
+ StringBuilder s = new StringBuilder();
+ s.append(primaryType);
+ s.append('/');
+ s.append(subType);
+ if (parameters.size() > 0)
+ {
+ Set entries = parameters.entrySet();
+ for (Iterator i = entries.iterator(); i.hasNext();)
+ {
+ s.append("; ");
+ Map.Entry entry = (Map.Entry) i.next();
+ s.append(entry.getKey());
+ s.append('=');
+ s.append(entry.getValue());
+ }
+ }
+ return s.toString();
+ }
+
+ /**
+ * Parses the specified mime type string and initializes the fields
+ * of this object.
+ *
+ * @param mime the mime type string
+ */
+ private void parse(String mime)
+ throws MimeTypeParseException
+ {
+ // FIXME: Maybe implement more sophisticated mime string parsing according
+ // to RFC 2045 and 2046.
+ StringTokenizer tokenizer = new StringTokenizer(mime);
+ try
+ {
+ primaryType = tokenizer.nextToken("/");
+ subType = tokenizer.nextToken("/;");
+ }
+ catch (NoSuchElementException ex)
+ {
+ throw new MimeTypeParseException("Expected / separator");
+ }
+
+ // Add any parameters.
+ while (tokenizer.hasMoreTokens())
+ {
+ String keyValuePair = tokenizer.nextToken(";");
+ int i = keyValuePair.indexOf('=');
+ if (i == -1)
+ throw new MimeTypeParseException("Expected = as parameter separator");
+ String key = keyValuePair.substring(0, i).trim();
+ String value = keyValuePair.substring(i + 1).trim();
+ parameters.put(key, value);
+ }
+ }
+
+}
Added: trunk/core/src/classpath/java/java/beans/ConstructorProperties.java
===================================================================
--- trunk/core/src/classpath/java/java/beans/ConstructorProperties.java (rev 0)
+++ trunk/core/src/classpath/java/java/beans/ConstructorProperties.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -0,0 +1,72 @@
+/* ConstructorProperties.java - Associate constructor params with props
+ Copyright (C) 2006 Free Software Foundation
+
+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.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+
+/**
+ * An annotation used to associate the parameters of a
+ * constructor with the accessor methods that later provide
+ * access to these values. For example, the parameters of
+ * the constructor <code>Person(String name, int age)</code>
+ * may be linked to the bean's two accessors, <code>getName()</code>
+ * and <code>getAge()</code> using
+ * <code>@ConstructorProperties({"name","age"})</code>.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.6
+ */
+@Documented @Retention(RUNTIME) @Target(CONSTRUCTOR)
+public @interface ConstructorProperties
+{
+
+ /**
+ * Contains the name of the accessor methods associated
+ * with each constructor parameter.
+ *
+ * @return the accessor method names corresponding to the
+ * constructor parameters.
+ */
+ String[] value();
+
+}
Modified: trunk/core/src/classpath/java/java/io/StreamTokenizer.java
===================================================================
--- trunk/core/src/classpath/java/java/io/StreamTokenizer.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/io/StreamTokenizer.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -330,6 +330,7 @@
{
while ((ch = in.read()) != '\n' && ch != '\r' && ch != TT_EOF)
;
+
if (ch != TT_EOF)
in.unread(ch);
return nextToken(); // Recursive, but not too deep in normal cases
@@ -431,6 +432,7 @@
{
while ((ch = in.read()) != '\n' && ch != '\r' && ch != TT_EOF)
;
+
if (ch != TT_EOF)
in.unread(ch);
return nextToken(); // Recursive, but not too deep in normal cases.
Added: trunk/core/src/classpath/java/java/math/RoundingMode.java
===================================================================
--- trunk/core/src/classpath/java/java/math/RoundingMode.java (rev 0)
+++ trunk/core/src/classpath/java/java/math/RoundingMode.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -0,0 +1,89 @@
+/* RoundingMode.java -- An Enum to replace BigDecimal rounding constants.
+ Copyright (C) 1999, 2000, 2002, 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.math;
+
+/**
+ * An enum to specify rounding behaviour for numerical operations that may
+ * discard precision.
+ * @author Anthony Balkissoon abalkiss at redhat dot com
+ *
+ */
+public enum RoundingMode
+{
+ UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY;
+
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = 432302042773881265L;
+
+ /**
+ * Returns the RoundingMode object corresponding to the legacy rounding modes
+ * in BigDecimal.
+ * @param rm the legacy rounding mode
+ * @return the corresponding RoundingMode
+ */
+ public static RoundingMode valueOf(int rm)
+ {
+ switch (rm)
+ {
+ case BigDecimal.ROUND_CEILING:
+ return CEILING;
+ case BigDecimal.ROUND_FLOOR:
+ return FLOOR;
+ case BigDecimal.ROUND_DOWN:
+ return DOWN;
+ case BigDecimal.ROUND_UP:
+ return UP;
+ case BigDecimal.ROUND_HALF_UP:
+ return HALF_UP;
+ case BigDecimal.ROUND_HALF_DOWN:
+ return HALF_DOWN;
+ case BigDecimal.ROUND_HALF_EVEN:
+ return HALF_EVEN;
+ case BigDecimal.ROUND_UNNECESSARY:
+ return UNNECESSARY;
+ default:
+ throw new
+ IllegalArgumentException("invalid argument: " + rm +
+ ". Argument should be one of the " +
+ "rounding modes defined in BigDecimal.");
+ }
+ }
+}
Added: trunk/core/src/classpath/java/java/net/Proxy.java
===================================================================
--- trunk/core/src/classpath/java/java/net/Proxy.java (rev 0)
+++ trunk/core/src/classpath/java/java/net/Proxy.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -0,0 +1,137 @@
+/* Proxy.java -- Represends a proxy for a network connection
+ Copyright (C) 2006 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.net;
+
+
+/**
+ * Defines a proxy setting. This setting contains a type (https, socks,
+ * direct) and a socket address.
+ *
+ * @since 1.5
+ */
+public class Proxy
+{
+ /**
+ * Represents the proxy type.
+ */
+ public enum Type
+ {
+ DIRECT, HTTP, SOCKS;
+
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = -2231209257930100533L;
+ }
+
+ public static final Proxy NO_PROXY = new Proxy(Type.DIRECT, null);
+
+ private Type type;
+ private SocketAddress address;
+
+ /**
+ * Creates a new <code>Proxy</code> object.
+ *
+ * @param type The type for this proxy
+ * @param address The address of this proxy
+ */
+ public Proxy(Type type, SocketAddress address)
+ {
+ this.type = type;
+ this.address = address;
+ }
+
+ /**
+ * Returns the socket address for this proxy object.
+ *
+ * @return the socket address
+ */
+ public SocketAddress address()
+ {
+ return address;
+ }
+
+ /**
+ * Returns the of this proxy instance.
+ *
+ * @return the type
+ *
+ * @see Type
+ */
+ public Type type()
+ {
+ return type;
+ }
+
+ /**
+ * Compares the given object with this object.
+ *
+ * @return <code>true</code> if both objects or equals,
+ * <code>false</code> otherwise.
+ */
+ public final boolean equals(Object obj)
+ {
+ if (! (obj instanceof Proxy))
+ return false;
+
+ Proxy tmp = (Proxy) obj;
+
+ return (type.equals(tmp.type)
+ && address.equals(tmp.address));
+ }
+
+ /**
+ * Returns the hashcode for this <code>Proxy</code> object.
+ *
+ * @return the hashcode
+ */
+ public final int hashCode()
+ {
+ return type.hashCode() ^ address.hashCode();
+ }
+
+ /**
+ * Returns a string representation of this <code>Proxy</code> object.
+ *
+ * @return the string
+ */
+ public String toString()
+ {
+ return type.toString() + ":" + address.toString();
+ }
+}
Added: trunk/core/src/classpath/java/java/net/ProxySelector.java
===================================================================
--- trunk/core/src/classpath/java/java/net/ProxySelector.java (rev 0)
+++ trunk/core/src/classpath/java/java/net/ProxySelector.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -0,0 +1,117 @@
+/* ProxySelector.java -- A proxy selector class
+ Copyright (C) 2006 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.net;
+
+import gnu.java.net.DefaultProxySelector;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Class for handling proxies for different connections.
+ *
+ * @since 1.5
+ */
+public abstract class ProxySelector
+{
+ /**
+ * Default proxy selector.
+ */
+ private static ProxySelector defaultSelector = new DefaultProxySelector();
+
+ /**
+ * Creates a new <code>ProxySelector</code> object.
+ */
+ public ProxySelector()
+ {
+ // Do nothing here.
+ }
+
+ /**
+ * Returns the default proxy selector.
+ *
+ * @return the default proxy selector
+ *
+ * @throws SecurityException If a security manager is installed and it
+ * denies NetPermission("getProxySelector")
+ */
+ public static ProxySelector getDefault()
+ {
+ SecurityManager sm = System.getSecurityManager();
+
+ if (sm != null)
+ sm.checkPermission(new NetPermission("getProxySelector"));
+
+ return defaultSelector;
+ }
+
+ /**
+ * Sets the default proxy selector.
+ *
+ * @param selector the defualt proxy selector
+ *
+ * @throws SecurityException If a security manager is installed and it
+ * denies NetPermission("setProxySelector")
+ */
+ public static void setDefault(ProxySelector selector)
+ {
+ SecurityManager sm = System.getSecurityManager();
+
+ if (sm != null)
+ sm.checkPermission(new NetPermission("setProxySelector"));
+
+ defaultSelector = selector;
+ }
+
+ /**
+ * Signals to the selector that a proxy was no available.
+ *
+ * @throws IllegalArgumentException If one argument is null
+ */
+ public abstract void connectFailed(URI uri, SocketAddress address,
+ IOException exception);
+
+ /**
+ * Returns the list of proxy settings for a given URI.
+ *
+ * @return list of proxy settings
+ *
+ * @throws IllegalArgumentException If uri is null
+ */
+ public abstract List<Proxy> select(URI uri);
+}
Added: trunk/core/src/classpath/java/java/net/ResolverCache.java
===================================================================
--- trunk/core/src/classpath/java/java/net/ResolverCache.java (rev 0)
+++ trunk/core/src/classpath/java/java/net/ResolverCache.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -0,0 +1,269 @@
+/* ResolverCache.java -- A cache of resolver lookups for InetAddress.
+ Copyright (C) 2006 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.net;
+
+import java.security.Security;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * This class provides a cache of name service resolutions. By
+ * default successful resolutions are cached forever to guard
+ * against DNS spoofing attacks and failed resolutions are cached
+ * for 10 seconds to improve performance. The length of time that
+ * results remain in the cache is determined by the following
+ * security properties:
+ * <dl>
+ * <dt><code>networkaddress.cache.ttl</code></dt>
+ * <dd>
+ * This property specifies the length of time in seconds that
+ * successful resolutions remain in the cache. The default is
+ * -1, indicating to cache forever.
+ * </dd>
+ * <dt><code>networkaddress.cache.negative.ttl</code></dt>
+ * <dd>
+ * This property specifies the length of time in seconds that
+ * unsuccessful resolutions remain in the cache. The default
+ * is 10, indicating to cache for 10 seconds.
+ * </dd>
+ * In both cases, a value of -1 indicates to cache forever and a
+ * value of 0 indicates not to cache.
+ *
+ * @author Gary Benson (gb...@re...)
+ */
+class ResolverCache
+{
+ /**
+ * The time in seconds for which successful lookups are cached.
+ */
+ private static final int POSITIVE_TTL =
+ getTTL("networkaddress.cache.ttl", -1);
+
+ /**
+ * The time in seconds for which unsuccessful lookups are cached.
+ */
+ private static final int NEGATIVE_TTL =
+ getTTL("networkaddress.cache.negative.ttl", 10);
+
+ /**
+ * Helper function to set the TTLs.
+ */
+ private static int getTTL(String propName, int defaultValue)
+ {
+ String propValue = Security.getProperty(propName);
+ if (propValue == null)
+ return defaultValue;
+
+ return Integer.parseInt(propValue);
+ }
+
+ /**
+ * The cache itself.
+ */
+ private static HashMap<Object, Entry> cache = new HashMap<Object, Entry>();
+
+ /**
+ * List of entries which may expire.
+ */
+ private static LinkedList<Entry> killqueue = new LinkedList<Entry>();
+
+ /**
+ * Return the hostname for the specified IP address.
+ *
+ * @param ip The IP address as a byte array
+ *
+ * @return The hostname
+ *
+ * @exception UnknownHostException If the reverse lookup fails
+ */
+ public static String getHostByAddr(byte[] addr) throws UnknownHostException
+ {
+ Object key = makeHashableAddress(addr);
+ Entry entry = (Entry) get(key);
+ if (entry != null)
+ {
+ if (entry.value == null)
+ throw new UnknownHostException();
+ return (String) entry.value;
+ }
+
+ try
+ {
+ String hostname = VMInetAddress.getHostByAddr(addr);
+ put(new Entry(key, hostname));
+ return hostname;
+ }
+ catch (UnknownHostException e)
+ {
+ put(new Entry(key, null));
+ throw e;
+ }
+ }
+
+ /**
+ * Return a list of all IP addresses for the specified hostname.
+ *
+ * @param hostname The hostname
+ *
+ * @return An list of IP addresses as byte arrays
+ *
+ * @exception UnknownHostException If the lookup fails
+ */
+ public static byte[][] getHostByName(String hostname)
+ throws UnknownHostException
+ {
+ Entry entry = (Entry) get(hostname);
+ if (entry != null)
+ {
+ if (entry.value == null)
+ throw new UnknownHostException();
+ return (byte[][]) entry.value;
+ }
+
+ try
+ {
+ byte[][] addrs = VMInetAddress.getHostByName(hostname);
+ put(new Entry(hostname, addrs));
+ return addrs;
+ }
+ catch (UnknownHostException e)
+ {
+ put(new Entry(hostname, null));
+ throw e;
+ }
+ }
+
+ /**
+ * Convert an IP address expressed as a byte array into something
+ * we can use as a hashtable key.
+ */
+ private static Object makeHashableAddress(byte[] addr)
+ {
+ char[] chars = new char[addr.length];
+ for (int i = 0; i < addr.length; i++)
+ chars[i] = (char) addr[i];
+ return new String(chars);
+ }
+
+ /**
+ * Return the entry in the cache associated with the supplied key,
+ * or <code>null</code> if the cache does not contain an entry
+ * associated with this key.
+ */
+ private static synchronized Entry get(Object key)
+ {
+ reap();
+ return (Entry) cache.get(key);
+ }
+
+ /**
+ * Insert the supplied entry into the cache.
+ */
+ private static synchronized void put(Entry entry)
+ {
+ reap();
+ if (entry.expires != 0)
+ {
+ if (entry.expires != -1)
+ killqueue.add(entry);
+ cache.put(entry.key, entry);
+ }
+ }
+
+ /**
+ * Clear expired entries. This method is not synchronized, so
+ * it must only be called by methods that are.
+ */
+ private static void reap()
+ {
+ if (!killqueue.isEmpty())
+ {
+ long now = System.currentTimeMillis();
+
+ Iterator iter = killqueue.iterator();
+ while (iter.hasNext())
+ {
+ Entry entry = (Entry) iter.next();
+ if (entry.expires > now)
+ break;
+ cache.remove(entry.key);
+ iter.remove();
+ }
+ }
+ }
+
+ /**
+ * An entry in the cache.
+ */
+ private static class Entry
+ {
+ /**
+ * The key by which this entry is referenced.
+ */
+ public final Object key;
+
+ /**
+ * The entry itself. A null value indicates a failed lookup.
+ */
+ public final Object value;
+
+ /**
+ * The time when this cache entry expires. If set to -1 then
+ * this entry will never expire. If set to 0 then this entry
+ * expires immediately and will not be inserted into the cache.
+ */
+ public final long expires;
+
+ /**
+ * Constructor.
+ */
+ public Entry(Object key, Object value)
+ {
+ this.key = key;
+ this.value = value;
+
+ int ttl = value != null ? POSITIVE_TTL : NEGATIVE_TTL;
+ if (ttl < 1)
+ expires = ttl;
+ else
+ expires = System.currentTimeMillis() + ttl * 1000;
+ }
+ }
+}
Modified: trunk/core/src/classpath/java/java/net/URI.java
===================================================================
--- trunk/core/src/classpath/java/java/net/URI.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/net/URI.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -156,7 +156,7 @@
* @since 1.4
*/
public final class URI
- implements Comparable, Serializable
+ implements Comparable<URI>, Serializable
{
/**
* For serialization compatability.
@@ -1229,7 +1229,7 @@
}
/**
- * Compare the URI with another object that must also be a URI.
+ * Compare the URI with another URI.
* Undefined components are taken to be less than any other component.
* The following criteria are observed:
* </p>
@@ -1265,16 +1265,14 @@
* </ul>
* </ul>
*
- * @param obj This object to compare this URI with
+ * @param uri The other URI to compare this URI with
* @return a negative integer, zero or a positive integer depending
* on whether this URI is less than, equal to or greater
* than that supplied, respectively.
- * @throws ClassCastException if the given object is not a URI
*/
- public int compareTo(Object obj)
+ public int compareTo(URI uri)
throws ClassCastException
{
- URI uri = (URI) obj;
if (scheme == null && uri.getScheme() != null)
return -1;
if (scheme != null)
Modified: trunk/core/src/classpath/java/java/rmi/activation/ActivationID.java
===================================================================
--- trunk/core/src/classpath/java/java/rmi/activation/ActivationID.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/rmi/activation/ActivationID.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -174,7 +174,7 @@
{
out.writeObject(uid);
out.writeObject(activator);
- };
+ }
/**
* Compare by .equals if both a and b are not null, compare directly if at
Modified: trunk/core/src/classpath/java/java/rmi/server/LoaderHandler.java
===================================================================
--- trunk/core/src/classpath/java/java/rmi/server/LoaderHandler.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/rmi/server/LoaderHandler.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -42,6 +42,7 @@
/**
* @deprecated
+ * @since 1.1
*/
public interface LoaderHandler
{
@@ -54,13 +55,13 @@
/**
* @deprecated
*/
- Class loadClass(String name)
+ Class<?> loadClass(String name)
throws MalformedURLException, ClassNotFoundException;
/**
* @deprecated
*/
- Class loadClass(URL codebase, String name)
+ Class<?> loadClass(URL codebase, String name)
throws MalformedURLException, ClassNotFoundException;
/**
Modified: trunk/core/src/classpath/java/java/rmi/server/RMIClassLoader.java
===================================================================
--- trunk/core/src/classpath/java/java/rmi/server/RMIClassLoader.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/rmi/server/RMIClassLoader.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -51,6 +51,7 @@
* network-based class loading in RMI. These methods are called by RMI's
* internal marshal streams to implement the dynamic class loading of types for
* RMI parameters and return values.
+ * @since 1.1
*/
public class RMIClassLoader
{
@@ -62,13 +63,13 @@
/**
* @deprecated
*/
- public static Class loadClass(String name)
+ public static Class<?> loadClass(String name)
throws MalformedURLException, ClassNotFoundException
{
return loadClass("", name);
}
- public static Class loadClass(String codebase, String name)
+ public static Class<?> loadClass(String codebase, String name)
throws MalformedURLException, ClassNotFoundException
{
RMIClassLoaderSpi spi = getProviderInstance();
@@ -77,7 +78,7 @@
return spi.loadClass(codebase, name, null);
}
- public static Class loadClass(String codebase, String name,
+ public static Class<?> loadClass(String codebase, String name,
ClassLoader defaultLoader)
throws MalformedURLException, ClassNotFoundException
{
@@ -87,7 +88,7 @@
return spi.loadClass(codebase, name, defaultLoader);
}
- public static Class loadProxyClass (String codeBase, String[] interfaces,
+ public static Class<?> loadProxyClass (String codeBase, String[] interfaces,
ClassLoader defaultLoader)
throws MalformedURLException, ClassNotFoundException
{
@@ -114,7 +115,7 @@
* @throws MalformedURLException if the URL is not well formed
* @throws ClassNotFoundException if the requested class cannot be found
*/
- public static Class loadClass(URL codeBase, String name)
+ public static Class<?> loadClass(URL codeBase, String name)
throws MalformedURLException, ClassNotFoundException
{
RMIClassLoaderSpi spi = getProviderInstance();
@@ -151,7 +152,7 @@
* @return a space seperated list of URLs where the class-definition
* of cl may be found
*/
- public static String getClassAnnotation(Class cl)
+ public static String getClassAnnotation(Class<?> cl)
{
RMIClassLoaderSpi spi = getProviderInstance();
if (spi == null)
Modified: trunk/core/src/classpath/java/java/rmi/server/RMIClassLoaderSpi.java
===================================================================
--- trunk/core/src/classpath/java/java/rmi/server/RMIClassLoaderSpi.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/rmi/server/RMIClassLoaderSpi.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -49,16 +49,16 @@
{
}
- public abstract Class loadClass (String codeBase, String name,
+ public abstract Class<?> loadClass (String codeBase, String name,
ClassLoader defaultLoader)
throws MalformedURLException, ClassNotFoundException;
- public abstract Class loadProxyClass (String codeBase, String[] interfaces,
+ public abstract Class<?> loadProxyClass (String codeBase, String[] interfaces,
ClassLoader defaultLoader)
throws MalformedURLException, ClassNotFoundException;
public abstract ClassLoader getClassLoader (String codebase)
throws MalformedURLException;
- public abstract String getClassAnnotation (Class cl);
+ public abstract String getClassAnnotation (Class<?> cl);
}
Modified: trunk/core/src/classpath/java/java/rmi/server/UnicastRemoteObject.java
===================================================================
--- trunk/core/src/classpath/java/java/rmi/server/UnicastRemoteObject.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/rmi/server/UnicastRemoteObject.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -239,11 +239,12 @@
(UnicastServerRef) ((RemoteObject) obj).getRef();
return sref.unexportObject(obj, force);
}
- else
+ // FIXME
+ /* else
{
- // FIXME
;
}
+ */
return true;
}
Modified: trunk/core/src/classpath/java/java/security/AccessController.java
===================================================================
--- trunk/core/src/classpath/java/java/security/AccessController.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/security/AccessController.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -91,12 +91,12 @@
* should be be called.
* @return the result of the <code>action.run()</code> method.
*/
- public static Object doPrivileged(PrivilegedAction action)
+ public static <T> T doPrivileged(PrivilegedAction<T> action)
{
if (action == null) {
Unsafe.debug("action == null!! ");
}
- return VmAccessController.doPrivileged(action, null);
+ return (T) VmAccessController.doPrivileged(action, null);
}
/**
@@ -135,10 +135,10 @@
* @exception PrivilegedActionException wrapped around any exception that
* is thrown in the <code>run()</code> method.
*/
- public static Object doPrivileged(PrivilegedExceptionAction action)
+ public static <T> T doPrivileged(PrivilegedExceptionAction<T> action)
throws PrivilegedActionException
{
- return VmAccessController.doPrivileged(action, null);
+ return (T) VmAccessController.doPrivileged(action, null);
}
/**
Modified: trunk/core/src/classpath/java/java/security/MessageDigest.java
===================================================================
--- trunk/core/src/classpath/java/java/security/MessageDigest.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/security/MessageDigest.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -38,7 +38,10 @@
package java.security;
import gnu.java.security.Engine;
+import java.nio.ByteBuffer;
+import java.lang.reflect.InvocationTargetException;
+
/**
* Message digests are secure one-way hash functions that take arbitrary-sized
* data and output a fixed-length hash value.
@@ -72,28 +75,29 @@
* Returns a new instance of <code>MessageDigest</code> representing the
* specified algorithm.
*
- * @param algorithm
- * the name of the digest algorithm to use.
+ * @param algorithm the name of the digest algorithm to use.
* @return a new instance representing the desired algorithm.
- * @throws NoSuchAlgorithmException
- * if the algorithm is not implemented by any provider.
+ * @throws NoSuchAlgorithmException if the algorithm is not implemented by any
+ * provider.
+ * @throws IllegalArgumentException if <code>algorithm</code> is
+ * <code>null</code> or is an empty string.
*/
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
+ NoSuchAlgorithmException lastException = null;
for (int i = 0; i < p.length; i++)
- {
try
{
return getInstance(algorithm, p[i]);
}
- catch (NoSuchAlgorithmException ignored)
+ catch (NoSuchAlgorithmException x)
{
- // Ignore.
+ lastException = x;
}
- }
-
+ if (lastException != null)
+ throw lastException;
throw new NoSuchAlgorithmException(algorithm);
}
@@ -101,29 +105,26 @@
* Returns a new instance of <code>MessageDigest</code> representing the
* specified algorithm from a named provider.
*
- * @param algorithm
- * the name of the digest algorithm to use.
- * @param provider
- * the name of the provider to use.
+ * @param algorithm the name of the digest algorithm to use.
+ * @param provider the name of the provider to use.
* @return a new instance representing the desired algorithm.
- * @throws NoSuchAlgorithmException
- * if the algorithm is not implemented by the named provider.
- * @throws NoSuchProviderException
- * if the named provider was not found.
+ * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
+ * named provider.
+ * @throws NoSuchProviderException if the named provider was not found.
+ * @throws IllegalArgumentException if either <code>algorithm</code> or
+ * <code>provider</code> is <code>null</code> or empty.
*/
public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
- if (provider != null)
+ if (provider == null)
+ throw new IllegalArgumentException("provider MUST NOT be null");
provider = provider.trim();
-
- if (provider == null || provider.length() == 0)
- throw new IllegalArgumentException("Illegal provider");
-
+ if (provider.length() == 0)
+ throw new IllegalArgumentException("provider MUST NOT be empty");
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException(provider);
-
return getInstance(algorithm, p);
}
@@ -131,39 +132,43 @@
* Returns a new instance of <code>MessageDigest</code> representing the
* specified algorithm from a designated {@link Provider}.
*
- * @param algorithm
- * the name of the digest algorithm to use.
- * @param provider
- * the {@link Provider} to use.
+ * @param algorithm the name of the digest algorithm to use.
+ * @param provider the {@link Provider} to use.
* @return a new instance representing the desired algorithm.
- * @throws IllegalArgumentException
- * if <code>provider</code> is <code>null</code>.
- * @throws NoSuchAlgorithmException
- * if the algorithm is not implemented by {@link Provider}.
+ * @throws NoSuchAlgorithmException if the algorithm is not implemented by
+ * {@link Provider}.
+ * @throws IllegalArgumentException if either <code>algorithm</code> or
+ * <code>provider</code> is <code>null</code>, or if
+ * <code>algorithm</code> is an empty string.
* @since 1.4
* @see Provider
*/
public static MessageDigest getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- if (provider == null)
- throw new IllegalArgumentException("Illegal provider");
-
- MessageDigest result = null;
- Object o = null;
+ StringBuilder sb = new StringBuilder("MessageDigest for algorithm [")
+ .append(algorithm).append("] from provider[")
+ .append(provider).append("] ");
+ Object o;
try
{
o = Engine.getInstance(MESSAGE_DIGEST, algorithm, provider);
}
- catch (java.lang.reflect.InvocationTargetException ite)
+ catch (InvocationTargetException x)
{
- throw new NoSuchAlgorithmException(algorithm);
+ Throwable cause = x.getCause();
+ if (cause instanceof NoSuchAlgorithmException)
+ throw (NoSuchAlgorithmException) cause;
+ if (cause == null)
+ cause = x;
+ sb.append("could not be created");
+ NoSuchAlgorithmException y = new NoSuchAlgorithmException(sb.toString());
+ y.initCause(cause);
+ throw y;
}
-
+ MessageDigest result;
if (o instanceof MessageDigestSpi)
- {
result = new DummyMessageDigest((MessageDigestSpi) o, algorithm);
- }
else if (o instanceof MessageDigest)
{
result = (MessageDigest) o;
@@ -171,7 +176,8 @@
}
else
{
- throw new NoSuchAlgorithmException(algorithm);
+ sb.append("is of an unexpected Type: ").append(o.getClass().getName());
+ throw new NoSuchAlgorithmException(sb.toString());
}
result.provider = provider;
return result;
@@ -224,6 +230,17 @@
}
/**
+ * Updates the digest with the remaining bytes of a buffer.
+ *
+ * @param input The input byte buffer.
+ * @since 1.5
+ */
+ public void update (ByteBuffer input)
+ {
+ engineUpdate (input);
+ }
+
+ /**
* Computes the final digest of the stored data.
*
* @return a byte array representing the message digest.
Modified: trunk/core/src/classpath/java/java/security/MessageDigestSpi.java
===================================================================
--- trunk/core/src/classpath/java/java/security/MessageDigestSpi.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/security/MessageDigestSpi.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -37,6 +37,8 @@
package java.security;
+import java.nio.ByteBuffer;
+
/**
This is the Service Provider Interface (SPI) for MessageDigest
class in java.security. It provides the back end functionality
@@ -98,6 +100,23 @@
protected abstract void engineUpdate(byte[]input, int offset, int len);
/**
+ * Updates this digest with the remaining bytes of a byte buffer.
+ *
+ * @param input The input buffer.
+ * @since 1.5
+ */
+ protected void engineUpdate (ByteBuffer input)
+ {
+ byte[] buf = new byte[1024];
+ while (input.hasRemaining())
+ {
+ int n = Math.min(input.remaining(), buf.length);
+ input.get (buf, 0, n);
+ engineUpdate (buf, 0, n);
+ }
+ }
+
+ /**
Computes the final digest of the stored bytes and returns
them. It performs any necessary padding. The message digest
should reset sensitive data after performing the digest.
Modified: trunk/core/src/classpath/java/java/security/Signature.java
===================================================================
--- trunk/core/src/classpath/java/java/security/Signature.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/security/Signature.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -40,6 +40,8 @@
import gnu.java.security.Engine;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
@@ -127,28 +129,29 @@
* Returns an instance of <code>Signature</code> representing the specified
* signature.
*
- * @param algorithm
- * the algorithm to use.
+ * @param algorithm the algorithm to use.
* @return a new instance repesenting the desired algorithm.
- * @throws NoSuchAlgorithmException
- * if the algorithm is not implemented by any provider.
+ * @throws NoSuchAlgorithmException if the algorithm is not implemented by any
+ * provider.
+ * @throws IllegalArgumentException if <code>algorithm</code> is
+ * <code>null</code> or is an empty string.
*/
public static Signature getInstance(String algorithm)
throws NoSuchAlgorithmException
{
Provider[] p = Security.getProviders();
+ NoSuchAlgorithmException lastException = null;
for (int i = 0; i < p.length; i++)
- {
try
{
return getInstance(algorithm, p[i]);
}
- catch (NoSuchAlgorithmException e)
+ catch (NoSuchAlgorithmException x)
{
- // Ignored.
+ lastException = x;
}
- }
-
+ if (lastException != null)
+ throw lastException;
throw new NoSuchAlgorithmException(algorithm);
}
@@ -156,28 +159,26 @@
* Returns an instance of <code>Signature</code> representing the specified
* signature from the named provider.
*
- * @param algorithm
- * the algorithm to use.
- * @param provider
- * the name of the provider to use.
+ * @param algorithm the algorithm to use.
+ * @param provider the name of the provider to use.
* @return a new instance repesenting the desired algorithm.
- * @throws IllegalArgumentException if <code>provider</code> is
- * <code>null</code> or is an empty string.
- * @throws NoSuchProviderException
- * if the named provider was not found.
- * @throws NoSuchAlgorithmException
- * if the algorithm is not implemented by the named provider.
+ * @throws NoSuchProviderException if the named provider was not found.
+ * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
+ * named provider.
+ * @throws IllegalArgumentException if either <code>algorithm</code> or
+ * <code>provider</code> is <code>null</code> or empty.
*/
public static Signature getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
- if (provider == null || provider.length() == 0)
- throw new IllegalArgumentException("Illegal provider");
-
+ if (provider == null)
+ throw new IllegalArgumentException("provider MUST NOT be null");
+ provider = provider.trim();
+ if (provider.length() == 0)
+ throw new IllegalArgumentException("provider MUST NOT be empty");
Provider p = Security.getProvider(provider);
if (p == null)
throw new NoSuchProviderException(provider);
-
return getInstance(algorithm, p);
}
@@ -185,35 +186,41 @@
* Returns an instance of <code>Signature</code> representing the specified
* signature from the specified {@link Provider}.
*
- * @param algorithm
- * the algorithm to use.
- * @param provider
- * the {@link Provider} to use.
+ * @param algorithm the algorithm to use.
+ * @param provider the {@link Provider} to use.
* @return a new instance repesenting the desired algorithm.
- * @throws NoSuchAlgorithmException
- * if the algorithm is not implemented by the {@link Provider}.
+ * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
+ * {@link Provider}.
+ * @throws IllegalArgumentException if either <code>algorithm</code> or
+ * <code>provider</code> is <code>null</code>, or if
+ * <code>algorithm</code> is an empty string.
*/
public static Signature getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException
{
- if (provider == null)
- throw new IllegalArgumentException("Illegal provider");
-
- Signature result = null;
- Object o = null;
+ StringBuilder sb = new StringBuilder("Signature algorithm [")
+ .append(algorithm).append("] from provider[")
+ .append(provider).append("] ");
+ Object o;
try
{
o = Engine.getInstance(SIGNATURE, algorithm, provider);
}
- catch (java.lang.reflect.InvocationTargetException ite)
+ catch (InvocationTargetException x)
{
- throw new NoSuchAlgorithmException(algorithm);
+ Throwable cause = x.getCause();
+ if (cause instanceof NoSuchAlgorithmException)
+ throw (NoSuchAlgorithmException) cause;
+ if (cause == null)
+ cause = x;
+ sb.append("could not be created");
+ NoSuchAlgorithmException y = new NoSuchAlgorithmException(sb.toString());
+ y.initCause(cause);
+ throw y;
}
-
+ Signature result;
if (o instanceof SignatureSpi)
- {
result = new DummySignature((SignatureSpi) o, algorithm);
- }
else if (o instanceof Signature)
{
result = (Signature) o;
@@ -221,7 +228,8 @@
}
else
{
- throw new NoSuchAlgorithmException(algorithm);
+ sb.append("is of an unexpected Type: ").append(o.getClass().getName());
+ throw new NoSuchAlgorithmException(sb.toString());
}
result.provider = provider;
return result;
@@ -469,6 +477,22 @@
}
/**
+ * Update this signature with the {@link java.nio.Buffer#remaining()}
+ * bytes of the input buffer.
+ *
+ * @param input The input buffer.
+ * @throws SignatureException If this instance was not properly
+ * initialized.
+ */
+ public final void update(ByteBuffer input) throws SignatureException
+ {
+ if (state != UNINITIALIZED)
+ engineUpdate(input);
+ else
+ throw new SignatureException("not initialized");
+ }
+
+ /**
* Returns the name of the algorithm currently used. The names of algorithms
* are usually SHA/DSA or SHA/RSA.
*
Modified: trunk/core/src/classpath/java/java/security/SignatureSpi.java
===================================================================
--- trunk/core/src/classpath/java/java/security/SignatureSpi.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/security/SignatureSpi.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -37,6 +37,7 @@
package java.security;
+import java.nio.ByteBuffer;
import java.security.spec.AlgorithmParameterSpec;
/**
@@ -131,6 +132,24 @@
throws SignatureException;
/**
+ * Update this signature with the {@link java.nio.Buffer#remaining()}
+ * bytes of the given buffer.
+ *
+ * @param input The input buffer.
+ * @throws SignatureException
+ */
+ protected void engineUpdate(ByteBuffer input) throws SignatureException
+ {
+ byte[] buf = new byte[4096];
+ while (input.hasRemaining())
+ {
+ int l = Math.min(input.remaining(), buf.length);
+ input.get(buf, 0, l);
+ engineUpdate(buf, 0, l);
+ }
+ }
+
+ /**
* Returns the signature bytes of all the data fed to this instance. The
* format of the output depends on the underlying signature algorithm.
*
Modified: trunk/core/src/classpath/java/java/security/UnresolvedPermission.java
===================================================================
--- trunk/core/src/classpath/java/java/security/UnresolvedPermission.java 2007-01-07 12:53:02 UTC (rev 3022)
+++ trunk/core/src/classpath/java/java/security/UnresolvedPermission.java 2007-01-07 12:54:15 UTC (rev 3023)
@@ -201,6 +201,47 @@
{
return new UnresolvedPermissionCollection();
}
+
+ /**
+ * Return the name of the class of the unresolved permission.
+ * @since 1.5
+ */
+ public String getUnresolvedType()
+ {
+ return type;
+ }
+
+ /**
+ * Return the name of the unresolved permission.
+ * @since 1.5
+ */
+ public String getUnresolvedName()
+ {
+ return name;
+ }
+
+ /**
+ * Return the actions of the unresolved permission, or null
+ * if there are no actions.
+ * @since 1.5
+ */
+ public String getUnresolvedActions()
+ {
+ return actions;
+ }
+
+ /**
+ * Return the certificates of the unresolved permission.
+ * If there are no certificates, null is returned. Otherwise,
+ * a new array is returned.
+ * @since 1.5
+ */
+ public Certificate[] getUnresolvedCerts()
+ {
+ if (certs == null)
+ return null;
+ return (Certificate[]) certs.clone();
+ }
} // class UnresolvedPermission
/**
Modified: trunk/core/src/class...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 12:53:05
|
Revision: 3022
http://jnode.svn.sourceforge.net/jnode/?rev=3022&view=rev
Author: lsantha
Date: 2007-01-07 04:53:02 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/Character.java
trunk/core/src/classpath/java/java/lang/Enum.java
trunk/core/src/classpath/java/java/lang/System.java
trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java
trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java
trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java
trunk/core/src/classpath/java/java/lang/management/OperatingSystemMXBean.java
trunk/core/src/classpath/java/java/lang/management/RuntimeMXBean.java
trunk/core/src/classpath/java/java/lang/management/ThreadInfo.java
trunk/core/src/classpath/java/java/lang/management/ThreadMXBean.java
Added Paths:
-----------
trunk/core/src/classpath/java/java/lang/ProcessBuilder.java
trunk/core/src/classpath/java/java/lang/management/LockInfo.java
trunk/core/src/classpath/java/java/lang/management/MemoryType.java
trunk/core/src/classpath/java/java/lang/management/MonitorInfo.java
Modified: trunk/core/src/classpath/java/java/lang/Character.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Character.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/Character.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -156,7 +156,7 @@
private final String canonicalName;
/** Enumeration for the <code>forName()</code> method */
- private enum NameType { CANONICAL, NO_SPACES, CONSTANT; };
+ private enum NameType { CANONICAL, NO_SPACES, CONSTANT; }
/**
* Constructor for strictly defined blocks.
Modified: trunk/core/src/classpath/java/java/lang/Enum.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Enum.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/Enum.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -60,13 +60,13 @@
/**
* The name of this enum constant.
*/
- String name;
+ final String name;
/**
* The number of this enum constant. Each constant is given a number
* which matches the order in which it was declared, starting with zero.
*/
- int ordinal;
+ final int ordinal;
/**
* This constructor is used by the compiler to create enumeration constants.
@@ -220,4 +220,14 @@
k = k.getSuperclass();
return k;
}
+
+ /**
+ * Enumerations can not have finalization methods.
+ *
+ * @since 1.6
+ */
+ protected final void finalize()
+ {
+ }
+
}
Added: trunk/core/src/classpath/java/java/lang/ProcessBuilder.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/ProcessBuilder.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/ProcessBuilder.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -0,0 +1,337 @@
+/* ProcessBuilder.java - Represent spawned system process
+ 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.lang;
+
+import java.io.File;
+import java.io.IOException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * This class is used to construct new operating system processes.
+ * A <code>ProcessBuilder</code> instance basically represent a
+ * template for a new process. Actual processes are generated from
+ * this template via use of the <code>start()</code> method, which
+ * may be invoked multiple times, with each invocation spawning a
+ * new process with the current attributes of the
+ * <code>ProcessBuilder</code> object. Each spawned process is
+ * independent of the <code>ProcessBuilder</code> object, and is
+ * unaffected by changes in its attributes.
+ * </p>
+ * <p>
+ * The following attributes define a process:
+ * </p>
+ * <ul>
+ * <li>The <emphasis>working directory</emphasis>; the activities of a
+ * process begin with the current directory set to this. By default,
+ * this is the working directory of the current process, as defined
+ * by the <code>user.dir</code> property.</li>
+ * <li>The <emphasis>command</emphasis> which invokes the process. This
+ * usually consists of the name of the program binary followed by an
+ * arbitrary number of arguments. For example, <code>find -type f</code>
+ * invokes the <code>find</code> binary with the arguments "-type" and "f".
+ * The command is provided a list, the elements of which are defined in a
+ * system dependent manner; the layout is affected by expected operating
+ * system conventions. A common method is to split the command on each
+ * space within the string. Thus, <code>find -type f</code> forms a
+ * three element list. However, in some cases, the expectation is that
+ * this split is performed by the program itself; thus, the list consists
+ * of only two elements (the program name and its arguments).</li>
+ * <li>The <emphasis>environment map</emphasis>, which links environment
+ * variables to their corresponding values. The initial contents of the map
+ * are the current environment values i.e. it contains the contents of the
+ * map returned by <code>System.getenv()</code>.</li>
+ * <li>The <emphasis>redirection flag</emphasis>, which specifies whether
+ * or not the contents of the error stream should be redirected to standard
+ * output. By default, this is false, and there are two output streams, one
+ * for normal data ({@link Process#getOutputStream()}) and one for error data
+ * ({@link Process#getErrorStream()}). When set to true, the two are merged,
+ * which simplifies the interleaving of the two streams. Data is read using
+ * the stream returned by {@link Process#getOutputStream()}, and the
+ * stream returned by {@link Process#getErrorStream()} throws an immediate
+ * end-of-file exception.</li>
+ * </ul>
+ * <p>
+ * All checks on attribute validity are delayed until <code>start()</code>
+ * is called. <code>ProcessBuilder</code> objects are <strong>not
+ * synchronized</strong>; the user must provide external synchronization
+ * where multiple threads may interact with the same
+ * <code>ProcessBuilder</code> object.
+ * </p>
+ *
+ * @author Tom Tromey (tr...@re...)
+ * @author Andrew John Hughes (gnu...@me...)
+ * @see Process
+ * @see System#getenv()
+ * @since 1.5
+ */
+public final class ProcessBuilder
+{
+
+ /**
+ * The working directory of the process.
+ */
+ private File directory = new File(System.getProperty("user.dir"));
+
+ /**
+ * The command line syntax for invoking the process.
+ */
+ private List<String> command;
+
+ /**
+ * The mapping of environment variables to values.
+ */
+ private Map<String, String> environment =
+ new System.EnvironmentMap(System.getenv());
+
+ /**
+ * A flag indicating whether to redirect the error stream to standard
+ * output.
+ */
+ private boolean redirect = false;
+
+ /**
+ * Constructs a new <code>ProcessBuilder</code> with the specified
+ * command being used to invoke the process. The list is used directly;
+ * external changes are reflected in the <code>ProcessBuilder</code>.
+ *
+ * @param command the name of the program followed by its arguments.
+ */
+ public ProcessBuilder(List<String> command)
+ {
+ this.command = command;
+ }
+
+ /**
+ * Constructs a new <code>ProcessBuilder</code> with the specified
+ * command being used to invoke the process. This constructor
+ * simplifies creating a new <code>ProcessBuilder</code> by
+ * converting the provided series of constructor arguments into a
+ * list of command-line arguments.
+ *
+ * @param command the name of the program followed by its arguments.
+ */
+ public ProcessBuilder(String... command)
+ {
+ this.command = Arrays.asList(command);
+ }
+
+ /**
+ * Returns the current command line, used to invoke the process.
+ * The return value is simply a reference to the list of command
+ * line arguments used by the <code>ProcessBuilder</code> object;
+ * any changes made to it will be reflected in the operation of
+ * the <code>ProcessBuilder</code>.
+ *
+ * @return the list of command-line arguments.
+ */
+ public List<String> command()
+ {
+ return command;
+ }
+
+ /**
+ * Sets the command-line arguments to those specified. The list is
+ * used directly; external changes are reflected in the
+ * <code>ProcessBuilder</code>.
+ *
+ * @param command the name of the program followed by its arguments.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder command(List<String> command)
+ {
+ this.command = command;
+ return this;
+ }
+
+ /**
+ * Sets the command-line arguments to those specified.
+ * This simplifies modifying the arguments by converting
+ * the provided series of constructor arguments into a
+ * list of command-line arguments.
+ *
+ * @param command the name of the program followed by its arguments.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder command(String... command)
+ {
+ this.command = Arrays.asList(command);
+ return this;
+ }
+
+ /**
+ * Returns the working directory of the process. The
+ * returned value may be <code>null</code>; this
+ * indicates that the default behaviour of using the
+ * working directory of the current process should
+ * be adopted.
+ *
+ * @return the working directory.
+ */
+ public File directory()
+ {
+ return directory;
+ }
+
+ /**
+ * Sets the working directory to that specified.
+ * The supplied argument may be <code>null</code>,
+ * which indicates the default value should be used.
+ * The default is the working directory of the current
+ * process.
+ *
+ * @param directory the new working directory.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder directory(File directory)
+ {
+ this.directory = directory;
+ return this;
+ }
+
+ /**
+ * <p>
+ * Returns the system environment variables of the process.
+ * If the underlying system does not support environment variables,
+ * an empty map is returned.
+ * </p>
+ * <p>
+ * The returned map does not accept queries using
+ * null keys or values, or those of a type other than
+ * <code>String</code>. Attempts to pass in a null value will
+ * throw a <code>NullPointerException</code>. Types other than
+ * <code>String</code> throw a <code>ClassCastException</code>.
+ * </p>
+ * <p>
+ * As the returned map is generated using data from the underlying
+ * platform, it may not comply with the <code>equals()</code>
+ * and <code>hashCode()</code> contracts. It is also likely that
+ * the keys of this map will be case-sensitive.
+ * </p>
+ * <p>
+ * Modification of the map is reliant on the underlying platform;
+ * some may not allow any changes to the environment variables or
+ * may prevent certain values being used. Attempts to do so will
+ * throw an <code>UnsupportedOperationException</code> or
+ * <code>IllegalArgumentException</code>, respectively.
+ * </p>
+ * <p>
+ * Use of this method may require a security check for the
+ * RuntimePermission "getenv.*".
+ * </p>
+ *
+ * @return a map of the system environment variables for the process.
+ * @throws SecurityException if the checkPermission method of
+ * an installed security manager prevents access to
+ * the system environment variables.
+ * @since 1.5
+ */
+ public Map<String, String> environment()
+ {
+ return environment;
+ }
+
+ /**
+ * Returns true if the output stream and error stream of the
+ * process will be merged to form one composite stream. The
+ * default return value is <code>false</code>.
+ *
+ * @return true if the output stream and error stream are to
+ * be merged.
+ */
+ public boolean redirectErrorStream()
+ {
+ return redirect;
+ }
+
+ /**
+ * Sets the error stream redirection flag. If set, the output
+ * and error streams are merged to form one composite stream.
+ *
+ * @param redirect the new value of the redirection flag.
+ * @return a reference to this process builder.
+ */
+ public ProcessBuilder redirectErrorStream(boolean redirect)
+ {
+ this.redirect = redirect;
+ return this;
+ }
+
+ /**
+ * <p>
+ * Starts execution of a new process, based on the attributes of
+ * this <code>ProcessBuilder</code> object. This is the point
+ * at which the command-line arguments are checked. The list
+ * must be non-empty and contain only non-null string objects.
+ * The other attributes have default values which are used in
+ * cases where their values are not explicitly specified.
+ * </p>
+ * <p>
+ * If a security manager is in place, then the
+ * {@link SecurityManager#checkExec()} method is called to
+ * ensure that permission is given to execute the process.
+ * </p>
+ * <p>
+ * The execution of the process is system-dependent. Various
+ * exceptions may result, due to problems at the operating system
+ * level. These are all returned as a form of {@link IOException}.
+ * </p>
+ *
+ * @return a <code>Process</code> object, representing the spawned
+ * subprocess.
+ * @throws IOException if a problem occurs with executing the process
+ * at the operating system level.
+ * @throws IndexOutOfBoundsException if the command to execute is
+ * actually an empty list.
+ * @throws NullPointerException if the command to execute is null
+ * or the list contains null elements.
+ * @throws SecurityException if a security manager exists and prevents
+ * execution of the subprocess.
+ */
+ public Process start() throws IOException
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExec(command.get(0));
+ return VMProcess.exec(command, environment, directory, redirect);
+ }
+}
Modified: trunk/core/src/classpath/java/java/lang/System.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/System.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -149,7 +149,6 @@
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPermission(new RuntimePermission("setIO"));
-
VMSystem.setOut(out);
}
@@ -263,9 +262,7 @@
*/
public static long nanoTime()
{
- //todo
- throw new RuntimeException("Implement it");
- //return VMSystem.nanoTime();
+ return VMSystem.nanoTime();
}
/**
@@ -464,6 +461,29 @@
}
/**
+ * Remove a single system property by name. A security check may be
+ * performed, <code>checkPropertyAccess(key, "write")</code>.
+ *
+ * @param key the name of the system property to remove
+ * @return the previous value, or null
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ * @since 1.5
+ */
+ public static String clearProperty(String key)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new PropertyPermission(key, "write"));
+ // This handles both the null pointer exception and the illegal
+ // argument exception.
+ if (key.length() == 0)
+ throw new IllegalArgumentException("key can't be empty");
+ return SystemProperties.remove(key);
+ }
+
+ /**
* Gets the value of an environment variable.
*
* @param name the name of the environment variable
@@ -486,6 +506,60 @@
}
/**
+ * <p>
+ * Returns an unmodifiable view of the system environment variables.
+ * If the underlying system does not support environment variables,
+ * an empty map is returned.
+ * </p>
+ * <p>
+ * The returned map is read-only and does not accept queries using
+ * null keys or values, or those of a type other than <code>String</code>.
+ * Attempts to modify the map will throw an
+ * <code>UnsupportedOperationException</code>, while attempts
+ * to pass in a null value will throw a
+ * <code>NullPointerException</code>. Types other than <code>String</code>
+ * throw a <code>ClassCastException</code>.
+ * </p>
+ * <p>
+ * As the returned map is generated using data from the underlying
+ * platform, it may not comply with the <code>equals()</code>
+ * and <code>hashCode()</code> contracts. It is also likely that
+ * the keys of this map will be case-sensitive.
+ * </p>
+ * <p>
+ * Use of this method may require a security check for the
+ * RuntimePermission "getenv.*".
+ * </p>
+ *
+ * @return a map of the system environment variables.
+ * @throws SecurityException if the checkPermission method of
+ * an installed security manager prevents access to
+ * the system environment variables.
+ * @since 1.5
+ */
+ public static Map<String, String> getenv()
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getenv.*"));
+ if (environmentMap == null)
+ {
+ List<String> environ = (List<String>)VMSystem.environ();
+ Map<String,String> variables = new EnvironmentMap();
+ for (String pair : environ)
+ {
+ String[] parts = pair.split("=");
+ if (parts.length == 2)
+ variables.put(parts[0], parts[1]);
+ else
+ variables.put(parts[0], "");
+ }
+ environmentMap = Collections.unmodifiableMap(variables);
+ }
+ return environmentMap;
+ }
+
+ /**
* Terminate the Virtual Machine. This just calls
* <code>Runtime.getRuntime().exit(status)</code>, and never returns.
* Obviously, a security check is in order, <code>checkExit</code>.
@@ -597,4 +671,419 @@
return VMRuntime.mapLibraryName(libname);
}
+
+ /**
+ * This is a specialised <code>Collection</code>, providing
+ * the necessary provisions for the collections used by the
+ * environment variable map. Namely, it prevents
+ * querying anything but <code>String</code>s.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ */
+ private static class EnvironmentCollection
+ extends AbstractCollection<String>
+ {
+
+ /**
+ * The wrapped collection.
+ */
+ protected Collection<String> c;
+
+ /**
+ * Constructs a new environment collection, which
+ * wraps the elements of the supplied collection.
+ *
+ * @param coll the collection to use as a base for
+ * this collection.
+ */
+ public EnvironmentCollection(Collection<String> coll)
+ {
+ c = coll;
+ }
+
+ /**
+ * Blocks queries containing a null object or an object which
+ * isn't of type <code>String</code>. All other queries
+ * are forwarded to the underlying collection.
+ *
+ * @param obj the object to look for.
+ * @return true if the object exists in the collection.
+ * @throws NullPointerException if the specified object is null.
+ * @throws ClassCastException if the specified object is not a String.
+ */
+ public boolean contains(Object obj)
+ {
+ if (obj == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(obj instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ return c.contains(obj);
+ }
+
+ /**
+ * Blocks queries where the collection contains a null object or
+ * an object which isn't of type <code>String</code>. All other
+ * queries are forwarded to the underlying collection.
+ *
+ * @param coll the collection of objects to look for.
+ * @return true if the collection contains all elements in the collection.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean containsAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.containsAll(coll);
+ }
+
+ /**
+ * This returns an iterator over the map elements, with the
+ * same provisions as for the collection and underlying map.
+ *
+ * @return an iterator over the map elements.
+ */
+ public Iterator<String> iterator()
+ {
+ return c.iterator();
+ }
+
+ /**
+ * Blocks the removal of elements from the collection.
+ *
+ * @return true if the removal was sucessful.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean remove(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ return c.contains(key);
+ }
+
+ /**
+ * Blocks the removal of all elements in the specified
+ * collection from the collection.
+ *
+ * @param coll the collection of elements to remove.
+ * @return true if the elements were removed.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean removeAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.removeAll(coll);
+ }
+
+ /**
+ * Blocks the retention of all elements in the specified
+ * collection from the collection.
+ *
+ * @param c the collection of elements to retain.
+ * @return true if the other elements were removed.
+ * @throws NullPointerException if the collection is null.
+ * @throws NullPointerException if any collection entry is null.
+ * @throws ClassCastException if any collection entry is not a String.
+ */
+ public boolean retainAll(Collection<?> coll)
+ {
+ for (Object o: coll)
+ {
+ if (o == null)
+ throw new
+ NullPointerException("This collection does not support " +
+ "null values.");
+ if (!(o instanceof String))
+ throw new
+ ClassCastException("This collection only supports Strings.");
+ }
+ return c.containsAll(coll);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @return the size of the underlying collection.
+ */
+ public int size()
+ {
+ return c.size();
+ }
+
+ } // class EnvironmentCollection<String>
+
+ /**
+ * This is a specialised <code>HashMap</code>, which
+ * prevents the addition or querying of anything other than
+ * <code>String</code> objects.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ */
+ static class EnvironmentMap
+ extends HashMap<String,String>
+ {
+
+ /**
+ * Cache the entry set.
+ */
+ private transient Set<Map.Entry<String,String>> entries;
+
+ /**
+ * Cache the key set.
+ */
+ private transient Set<String> keys;
+
+ /**
+ * Cache the value collection.
+ */
+ private transient Collection<String> values;
+
+ /**
+ * Constructs a new empty <code>EnvironmentMap</code>.
+ */
+ EnvironmentMap()
+ {
+ super();
+ }
+
+ /**
+ * Constructs a new <code>EnvironmentMap</code> containing
+ * the contents of the specified map.
+ *
+ * @param m the map to be added to this.
+ * @throws NullPointerException if a key or value is null.
+ * @throws ClassCastException if a key or value is not a String.
+ */
+ EnvironmentMap(Map<String,String> m)
+ {
+ super(m);
+ }
+
+ /**
+ * Blocks queries containing a null key or one which is not
+ * of type <code>String</code>. All other queries
+ * are forwarded to the superclass.
+ *
+ * @param key the key to look for in the map.
+ * @return true if the key exists in the map.
+ * @throws NullPointerException if the specified key is null.
+ */
+ public boolean containsKey(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.containsKey(key);
+ }
+
+ /**
+ * Blocks queries using a null or non-<code>String</code> value.
+ * All other queries are forwarded to the superclass.
+ *
+ * @param value the value to look for in the map.
+ * @return true if the value exists in the map.
+ * @throws NullPointerException if the specified value is null.
+ */
+ public boolean containsValue(Object value)
+ {
+ if (value == null)
+ throw new
+ NullPointerException("This map does not support null values.");
+ if (!(value instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.containsValue(value);
+ }
+
+ /**
+ * Returns a set view of the map entries, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a set containing the map entries.
+ */
+ public Set<Map.Entry<String,String>> entrySet()
+ {
+ if (entries == null)
+ entries = super.entrySet();
+ return entries;
+ }
+
+ /**
+ * Blocks queries containing a null or non-<code>String</code> key.
+ * All other queries are passed on to the superclass.
+ *
+ * @param key the key to retrieve the value for.
+ * @return the value associated with the given key.
+ * @throws NullPointerException if the specified key is null.
+ * @throws ClassCastException if the specified key is not a String.
+ */
+ public String get(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.get(key);
+ }
+
+ /**
+ * Returns a set view of the keys, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a set containing the keys.
+ */
+ public Set<String> keySet()
+ {
+ if (keys == null)
+ keys = new EnvironmentSet(super.keySet());
+ return keys;
+ }
+
+ /**
+ * Associates the given key to the given value. If the
+ * map already contains the key, its value is replaced.
+ * The map does not accept null keys or values, or keys
+ * and values not of type {@link String}.
+ *
+ * @param key the key to map.
+ * @param value the value to be mapped.
+ * @return the previous value of the key, or null if there was no mapping
+ * @throws NullPointerException if a key or value is null.
+ * @throws ClassCastException if a key or value is not a String.
+ */
+ public String put(String key, String value)
+ {
+ if (key == null)
+ throw new NullPointerException("A new key is null.");
+ if (value == null)
+ throw new NullPointerException("A new value is null.");
+ if (!(key instanceof String))
+ throw new ClassCastException("A new key is not a String.");
+ if (!(value instanceof String))
+ throw new ClassCastException("A new value is not a String.");
+ return super.put(key, value);
+ }
+
+ /**
+ * Removes a key-value pair from the map. The queried key may not
+ * be null or of a type other than a <code>String</code>.
+ *
+ * @param key the key of the entry to remove.
+ * @return the removed value.
+ * @throws NullPointerException if the specified key is null.
+ * @throws ClassCastException if the specified key is not a String.
+ */
+ public String remove(Object key)
+ {
+ if (key == null)
+ throw new
+ NullPointerException("This map does not support null keys.");
+ if (!(key instanceof String))
+ throw new
+ ClassCastException("This map only allows queries using Strings.");
+ return super.remove(key);
+ }
+
+ /**
+ * Returns a collection view of the values, with the same
+ * provisions as for the underlying map.
+ *
+ * @return a collection containing the values.
+ */
+ public Collection<String> values()
+ {
+ if (values == null)
+ values = new EnvironmentCollection(super.values());
+ return values;
+ }
+
+ }
+
+ /**
+ * This is a specialised <code>Set</code>, providing
+ * the necessary provisions for the collections used by the
+ * environment variable map. Namely, it prevents
+ * modifications and the use of queries with null
+ * or non-<code>String</code> values.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ */
+ private static class EnvironmentSet
+ extends EnvironmentCollection
+ implements Set<String>
+ {
+
+ /**
+ * Constructs a new environment set, which
+ * wraps the elements of the supplied set.
+ *
+ * @param set the set to use as a base for
+ * this set.
+ */
+ public EnvironmentSet(Set<String> set)
+ {
+ super(set);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @param obj the object to compare with.
+ * @return true if the two objects are equal.
+ */
+ public boolean equals(Object obj)
+ {
+ return c.equals(obj);
+ }
+
+ /**
+ * This simply calls the same method on the wrapped
+ * collection.
+ *
+ * @return the hashcode of the collection.
+ */
+ public int hashCode()
+ {
+ return c.hashCode();
+ }
+
+ } // class EnvironmentSet<String>
+
} // class System
Added: trunk/core/src/classpath/java/java/lang/management/LockInfo.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/LockInfo.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/management/LockInfo.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -0,0 +1,114 @@
+/* LockInfo.java - Information on a lock.
+ Copyright (C) 2006 Free Software Foundation
+
+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.lang.management;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * Provides information on a lock held by a thread.
+ * A lock can be either a built-in monitor, an
+ * <emph>ownable synchronizer</emph> (i.e. a subclass
+ * of {@link java.util.concurrent.locks.AbstractOwnableSynchronizer}),
+ * or a {@link java.util.concurrent.locks.Condition}
+ * object.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.6
+ */
+public class LockInfo
+{
+
+ /**
+ * The class name of the lock object.
+ */
+ private String className;
+
+ /**
+ * The identity hash code of the lock object.
+ */
+ private int identityHashCode;
+
+ /**
+ * Constructs a new {@link LockInfo} object with the
+ * specified class name and identity hash code.
+ *
+ * @param className the name of the class of the lock object.
+ * @param identityHashCode the identity hash code of the
+ * lock object.
+ */
+ @ConstructorProperties({"className","identityHashCode"})
+ public LockInfo(String className, int identityHashCode)
+ {
+ this.className = className;
+ this.identityHashCode = identityHashCode;
+ }
+
+ /**
+ * Returns the class name of the lock object.
+ *
+ * @return the class name of the lock object.
+ */
+ public String getClassName()
+ {
+ return className;
+ }
+
+ /**
+ * Returns the identity hash code of the lock object.
+ *
+ * @return the identity hash code of the lock object.
+ */
+ public int getIdentityHashCode()
+ {
+ return identityHashCode;
+ }
+
+ /**
+ * Returns a textual representation of the lock,
+ * constructed by concatenating the class name,
+ * <code>'@'</code> and the identity hash code
+ * in unsigned hexadecimal form.
+ *
+ * @return a textual representation of the lock.
+ */
+ public String toString()
+ {
+ return className + '@' + Integer.toHexString(identityHashCode);
+ }
+
+}
Modified: trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/management/ManagementFactory.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -49,11 +49,36 @@
import gnu.java.lang.management.RuntimeMXBeanImpl;
import gnu.java.lang.management.ThreadMXBeanImpl;
+import java.io.IOException;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.logging.LogManager;
+
+import javax.management.Attribute;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
/**
* <p>
* Provides access to the system's management beans via a series
@@ -66,6 +91,11 @@
* <ol>
* <li>Calling the appropriate static method of this factory.
* </li>
+ * <li>Using the platform {@link javax.management.MBeanServer}
+ * to access the beans locally, or an
+ * {@link javax.management.MBeanServerConnection} for remote
+ * access. The attributes and operations use the limited
+ * range of data types specified below.</li>
* </ol>
* <h2>Open Data Types</h2>
* <p>
@@ -118,6 +148,60 @@
{
/**
+ * The object name for the class loading bean.
+ */
+ public static final String CLASS_LOADING_MXBEAN_NAME =
+ "java.lang:type=ClassLoading";
+
+ /**
+ * The object name for the compilation bean.
+ */
+ public static final String COMPILATION_MXBEAN_NAME =
+ "java.lang:type=Compilation";
+
+ /**
+ * The domain for the garbage collecting beans.
+ */
+ public static final String GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE =
+ "java.lang:type=GarbageCollector";
+
+ /**
+ * The domain for the memory manager beans.
+ */
+ public static final String MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE =
+ "java.lang:type=MemoryManager";
+
+ /**
+ * The object name for the memory bean.
+ */
+ public static final String MEMORY_MXBEAN_NAME =
+ "java.lang:type=Memory";
+
+ /**
+ * The domain for the memory pool beans.
+ */
+ public static final String MEMORY_POOL_MXBEAN_DOMAIN_TYPE =
+ "java.lang:type=MemoryPool";
+
+ /**
+ * The object name for the operating system bean.
+ */
+ public static final String OPERATING_SYSTEM_MXBEAN_NAME =
+ "java.lang:type=OperatingSystem";
+
+ /**
+ * The object name for the runtime bean.
+ */
+ public static final String RUNTIME_MXBEAN_NAME =
+ "java.lang:type=Runtime";
+
+ /**
+ * The object name for the threading bean.
+ */
+ public static final String THREAD_MXBEAN_NAME =
+ "java.lang:type=Threading";
+
+ /**
* The operating system management bean.
*/
private static OperatingSystemMXBean osBean;
@@ -148,6 +232,11 @@
private static CompilationMXBean compilationBean;
/**
+ * The platform server.
+ */
+ private static MBeanServer platformServer;
+
+ /**
* Private constructor to prevent instance creation.
*/
private ManagementFactory() {}
@@ -301,9 +390,10 @@
*
* @return a list of memory pool beans, one for each pool.
*/
- public static List getMemoryPoolMXBeans()
+ public static List<MemoryPoolMXBean> getMemoryPoolMXBeans()
{
- List poolBeans = new ArrayList();
+ List<MemoryPoolMXBean> poolBeans =
+ new ArrayList<MemoryPoolMXBean>();
String[] names = VMManagementFactory.getMemoryPoolNames();
for (int a = 0; a < names.length; ++a)
try
@@ -326,9 +416,10 @@
*
* @return a list of memory manager beans, one for each manager.
*/
- public static List getMemoryManagerMXBeans()
+ public static List<MemoryManagerMXBean> getMemoryManagerMXBeans()
{
- List managerBeans = new ArrayList();
+ List<MemoryManagerMXBean> managerBeans =
+ new ArrayList<MemoryManagerMXBean>();
String[] names = VMManagementFactory.getMemoryManagerNames();
for (int a = 0; a < names.length; ++a)
try
@@ -352,9 +443,10 @@
*
* @return a list of garbage collector beans, one for each pool.
*/
- public static List getGarbageCollectorMXBeans()
+ public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans()
{
- List gcBeans = new ArrayList();
+ List<GarbageCollectorMXBean> gcBeans =
+ new ArrayList<GarbageCollectorMXBean>();
String[] names = VMManagementFactory.getGarbageCollectorNames();
for (int a = 0; a < names.length; ++a)
try
@@ -371,4 +463,355 @@
return gcBeans;
}
+ /**
+ * <p>
+ * Returns the platform {@link javax.management.MBeanServer}. On the
+ * first call to this method, a server instance is retrieved from
+ * the {@link javax.management.MBeanServerFactory} and each of the
+ * beans are registered with it. Subsequent calls return the existing
+ * instance. If the property <code>javax.management.builder.initial</code>
+ * is set, its value will be used as the name of the class which is used
+ * to provide the server instance.
+ * </p>
+ * <p>
+ * It is recommended that the platform server is used for other beans as
+ * well, in order to simplify their discovery and publication. Name conflicts
+ * should be avoided.
+ * </p>
+ *
+ * @return the platform {@link javax.management.MBeanServer}
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanServerPermission(String)}("createMBeanServer")
+ * @see javax.management.MBeanServerFactory
+ * @see javax.management.MBeanServerFactory#createMBeanServer()
+ */
+ public static MBeanServer getPlatformMBeanServer()
+ {
+ if (platformServer == null)
+ {
+ platformServer = MBeanServerFactory.createMBeanServer();
+ try
+ {
+ platformServer.registerMBean(getOperatingSystemMXBean(),
+ new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME));
+ platformServer.registerMBean(getRuntimeMXBean(),
+ new ObjectName(RUNTIME_MXBEAN_NAME));
+ platformServer.registerMBean(getClassLoadingMXBean(),
+ new ObjectName(CLASS_LOADING_MXBEAN_NAME));
+ platformServer.registerMBean(getThreadMXBean(),
+ new ObjectName(THREAD_MXBEAN_NAME));
+ platformServer.registerMBean(getMemoryMXBean(),
+ new ObjectName(MEMORY_MXBEAN_NAME));
+ CompilationMXBean compBean = getCompilationMXBean();
+ if (compBean != null)
+ platformServer.registerMBean(compBean,
+ new ObjectName(COMPILATION_MXBEAN_NAME));
+ Iterator beans = getMemoryPoolMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ MemoryPoolMXBean bean = (MemoryPoolMXBean) beans.next();
+ platformServer.registerMBean(bean,
+ new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE +
+ ",name=" +
+ bean.getName()));
+ }
+ beans = getMemoryManagerMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ MemoryManagerMXBean bean = (MemoryManagerMXBean) beans.next();
+ platformServer.registerMBean(bean,
+ new ObjectName(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE +
+ ",name=" +
+ bean.getName()));
+ }
+ beans = getGarbageCollectorMXBeans().iterator();
+ while (beans.hasNext())
+ {
+ GarbageCollectorMXBean bean = (GarbageCollectorMXBean) beans.next();
+ platformServer.registerMBean(bean,
+ new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
+ ",name=" +
+ bean.getName()));
+ }
+ platformServer.registerMBean(LogManager.getLoggingMXBean(),
+ new ObjectName(LogManager.LOGGING_MXBEAN_NAME));
+ }
+ catch (InstanceAlreadyExistsException e)
+ {
+ throw (Error)
+ (new InternalError("One of the management beans is " +
+ "already registered.").initCause(e));
+ }
+ catch (MBeanRegistrationException e)
+ {
+ throw (Error)
+ (new InternalError("One of the management beans' preRegister " +
+ "methods threw an exception.").initCause(e));
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("One of the management beans is " +
+ "not compliant.").initCause(e));
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw (Error)
+ (new InternalError("The object name of a management bean is " +
+ "not compliant.").initCause(e));
+ }
+ }
+ return platformServer;
+ }
+
+ /**
+ * <p>
+ * Returns a proxy for the specified platform bean. A proxy object is created
+ * using <code>Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
+ * new Class[] { mxbeanInterface }, handler)</code>. The
+ * {@link javax.management.NotificationEmitter} class is also added to the
+ * array if the bean provides notifications. <code>handler</code> refers
+ * to the invocation handler which forwards calls to the connection, and
+ * also provides translation between the Java data types used in the
+ * bean interfaces and the open data types, as specified in the description
+ * of this class. It is this translation that makes the
+ * usual {@link javax.management.MBeanServerInvocationHandler} inappropriate
+ * for providing such a proxy.
+ * </p>
+ * <p>
+ * <strong>Note</strong>: use of the proxy may result in
+ * {@link java.io.IOException}s from the underlying {@link MBeanServerConnection}
+ * and a {@link java.io.InvalidObjectException} if enum constants
+ * used on the client and the server don't match.
+ * </p>
+ *
+ * @param connection the server connection to use to access the bean.
+ * @param mxbeanName the {@link javax.management.ObjectName} of the
+ * bean to provide a proxy for.
+ * @param mxbeanInterface the interface for the bean being proxied.
+ * @return a proxy for the specified bean.
+ * @throws IllegalArgumentException if <code>mxbeanName</code> is not a valid
+ * {@link javax.management.ObjectName},
+ * the interface and name do not match the
+ * same bean, the name does not refer to a
+ * platform bean or the bean is not registered
+ * with the server accessed by <code>connection</code>.
+ * @throws IOException if the connection throws one.
+ */
+ public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection,
+ String mxbeanName,
+ Class<T> mxbeanInterface)
+ throws IOException
+ {
+ if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) ||
+ mxbeanName.equals(COMPILATION_MXBEAN_NAME) ||
+ mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) ||
+ mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) ||
+ mxbeanName.equals(MEMORY_MXBEAN_NAME) ||
+ mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) ||
+ mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) ||
+ mxbeanName.equals(RUNTIME_MXBEAN_NAME) ||
+ mxbeanName.equals(THREAD_MXBEAN_NAME)))
+ {
+ throw new IllegalArgumentException("The named bean, " + mxbeanName +
+ ", is not a platform name.");
+ }
+ if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) &&
+ mxbeanInterface != ClassLoadingMXBean.class) ||
+ (mxbeanName.equals(COMPILATION_MXBEAN_NAME) &&
+ mxbeanInterface != CompilationMXBean.class) ||
+ (mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) &&
+ mxbeanInterface != GarbageCollectorMXBean.class) ||
+ (mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) &&
+ mxbeanInterface != MemoryManagerMXBean.class) ||
+ (mxbeanName.equals(MEMORY_MXBEAN_NAME) &&
+ mxbeanInterface != MemoryMXBean.class) ||
+ (mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) &&
+ mxbeanInterface != MemoryPoolMXBean.class) ||
+ (mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) &&
+ mxbeanInterface != OperatingSystemMXBean.class) ||
+ (mxbeanName.equals(RUNTIME_MXBEAN_NAME) &&
+ mxbeanInterface != RuntimeMXBean.class) ||
+ (mxbeanName.equals(THREAD_MXBEAN_NAME) &&
+ mxbeanInterface != ThreadMXBean.class))
+ throw new IllegalArgumentException("The interface, " + mxbeanInterface +
+ ", does not match the bean, " + mxbeanName);
+ ObjectName bean;
+ try
+ {
+ bean = new ObjectName(mxbeanName);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw new IllegalArgumentException("The named bean is invalid.");
+ }
+ if (!(connection.isRegistered(bean)))
+ throw new IllegalArgumentException("The bean is not registered on this connection.");
+ Class[] interfaces;
+ if (mxbeanName.equals(MEMORY_MXBEAN_NAME))
+ interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class };
+ else
+ interfaces = new Class[] { mxbeanInterface };
+ return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
+ interfaces,
+ new ManagementInvocationHandler(connection, bean));
+ }
+
+ /**
+ * This invocation handler provides method calls for a platform bean
+ * by forwarding them to a {@link MBeanServerConnection}. Translation from
+ * Java data types to open data types is performed as specified above.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.5
+ */
+ private static class ManagementInvocationHandler
+ implements InvocationHandler
+ {
+
+ /**
+ * The encapsulated connection.
+ */
+ private MBeanServerConnection conn;
+
+ /**
+ * The bean being proxied.
+ */
+ private ObjectName bean;
+
+ /**
+ * Constructs a new {@link InvocationHandler} which proxies
+ * for the specified bean using the supplied connection.
+ *
+ * @param conn the connection on which to forward method calls.
+ * @param bean the bean to proxy.
+ */
+ public ManagementInvocationHandler(MBeanServerConnection conn,
+ ObjectName bean)
+ throws IOException
+ {
+ this.conn = conn;
+ this.bean = bean;
+ }
+
+ /**
+ * Called by the proxy class whenever a method is called. The method
+ * is emulated by retrieving an attribute from, setting an attribute on
+ * or invoking a method on the server connection as required. Translation
+ * between the Java data types supplied as arguments to the open types used
+ * by the bean is provided, as well as translation of the return value back
+ * in to the appropriate Java type.
+ *
+ * @param proxy the proxy on which the method was called.
+ * @param method the method which was called.
+ * @param args the arguments supplied to the method.
+ * @return the return value from the method.
+ * @throws Throwable if an exception is thrown in performing the
+ * method emulation.
+ */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable
+ {
+ String name = method.getName();
+ if (name.equals("toString"))
+ return "Proxy for " + bean + " using " + conn;
+ if (name.equals("addNotificationListener"))
+ {
+ conn.addNotificationListener(bean,
+ (NotificationListener) args[0],
+ (NotificationFilter) args[1],
+ args[2]);
+ return null;
+ }
+ if (name.equals("getNotificationInfo"))
+ return conn.getMBeanInfo(bean).getNotifications();
+ if (name.equals("removeNotificationListener"))
+ {
+ if (args.length == 1)
+ conn.removeNotificationListener(bean,
+ (NotificationListener)
+ args[0]);
+ else
+ conn.removeNotificationListener(bean,
+ (NotificationListener)
+ args[0],
+ (NotificationFilter)
+ args[1], args[2]);
+ return null;
+ }
+ String attrib = null;
+ if (name.startsWith("get"))
+ attrib = name.substring(3);
+ else if (name.startsWith("is"))
+ attrib = name.substring(2);
+ if (attrib != null)
+ return translate(conn.getAttribute(bean, attrib), method);
+ else if (name.startsWith("set"))
+ {
+ conn.setAttribute(bean, new Attribute(name.substring(3),
+ args[0]));
+ return null;
+ }
+ else
+ return translate(conn.invoke(bean, name, args, null), method);
+ }
+
+ /**
+ * Translates the returned open data type to the value
+ * required by the interface.
+ *
+ * @param otype the open type returned by the method call.
+ * @param method the method that was called.
+ * @return the equivalent return type required by the interface.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ private final Object translate(Object otype, Method method)
+ throws Throwable
+ {
+ Class<?> returnType = method.getReturnType();
+ if (returnType.isEnum())
+ {
+ String ename = (String) otype;
+ Enum[] constants = (Enum[]) returnType.getEnumConstants();
+ for (Enum c : constants)
+ if (c.name().equals(ename))
+ return c;
+ }
+ if (List.class.isAssignableFrom(returnType))
+ {
+ Object[] elems = (Object[]) otype;
+ List l = new ArrayList(elems.length);
+ for (Object elem : elems)
+ l.add(elem);
+ return l;
+ }
+ if (Map.class.isAssignableFrom(returnType))
+ {
+ TabularData data = (TabularData) otype;
+ Map m = new HashMap(data.size());
+ for (Object val : data.values())
+ {
+ CompositeData vals = (CompositeData) val;
+ m.put(vals.get("key"), vals.get("value"));
+ }
+ return m;
+ }
+ try
+ {
+ Method m = returnType.getMethod("from",
+ new Class[]
+ { CompositeData.class });
+ return m.invoke(null, (CompositeData) otype);
+ }
+ catch (NoSuchMethodException e)
+ {
+ /* Ignored; we expect this if this
+ isn't a from(CompositeData) class */
+ }
+ return otype;
+ }
+
+ }
}
Modified: trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/management/MemoryPoolMXBean.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -162,7 +162,7 @@
*
* @return the type of this pool.
*/
- String getType();
+ MemoryType getType();
/**
* Returns memory usage statistics for the current memory usage
Added: trunk/core/src/classpath/java/java/lang/management/MemoryType.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/MemoryType.java (rev 0)
+++ trunk/core/src/classpath/java/java/lang/management/MemoryType.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -0,0 +1,51 @@
+/* MemoryType.java - Enumeration of the types of memory pools.
+ Copyright (C) 2006 Free Software Foundation
+
+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.lang.management;
+
+/**
+ * Enumerates the possible types of memory pools. A value of this
+ * type is returned by {@link MemoryPoolMXBean#getMemoryType()}.
+ *
+ * @author Andrew John Hughes (gnu...@me...)
+ * @since 1.5
+ */
+public enum MemoryType
+{
+ HEAP, NON_HEAP;
+}
+
Modified: trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java 2007-01-07 12:51:25 UTC (rev 3021)
+++ trunk/core/src/classpath/java/java/lang/management/MemoryUsage.java 2007-01-07 12:53:02 UTC (rev 3022)
@@ -180,14 +180,14 @@
if (data == null)
return null;
CompositeType type = data.getCompositeType();
- ThreadInfo.checkAttribute(type, "init", SimpleType.LONG);
- ThreadInfo.checkAttribute(type, "used", SimpleType.LONG);
- ThreadInfo.checkAttribute(type, "committed", SimpleType.LONG);
- ThreadInfo.checkAttribute(type, "max", SimpleType.LONG);
- return new MemoryUsage(((Long) data.get("init")).longValue(),
- ((Long) data.get("used")).longValue(),
- ((Long) data.get("committed")).longValue(),
- ((Long) data.get("max")).longValue());
+ ThreadInfo.checkAttribute(type, "Init", SimpleType.LONG);
+ ThreadInfo.checkAttribute(type, "Used", SimpleType.LONG);
+ ThreadInfo.checkAttribute(type, "Committed", SimpleType.LONG);
+ ThreadInfo.checkAttribute(type, "Max", SimpleType.LONG);
+ return new MemoryUsage(((Long) data.get("Init")).longValue(),
+ ((Long) data.get("Used")).longVa...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 12:51:26
|
Revision: 3021
http://jnode.svn.sourceforge.net/jnode/?rev=3021&view=rev
Author: lsantha
Date: 2007-01-07 04:51:25 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PrivateCredentials.java
Added Paths:
-----------
trunk/core/src/classpath/gnu/gnu/javax/crypto/key/GnuPBEKey.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/AbstractSessionContext.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManager.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLCipherSuite.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLProtocolVersion.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLRecordHandler.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/Session.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SessionStoreException.java
trunk/core/src/classpath/gnu/gnu/javax/security/auth/callback/CertificateCallback.java
trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
Removed Paths:
-------------
trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/parser/HTML_401Swing.java
Added: trunk/core/src/classpath/gnu/gnu/javax/crypto/key/GnuPBEKey.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/crypto/key/GnuPBEKey.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/crypto/key/GnuPBEKey.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,95 @@
+/* GnuPBEKey.java -- A password-based encryption key.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.crypto.key;
+
+import javax.crypto.interfaces.PBEKey;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * An implementation of a password-based encryption key.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class GnuPBEKey
+ implements PBEKey
+{
+ private final PBEKeySpec spec;
+
+ public GnuPBEKey (final PBEKeySpec spec)
+ {
+ if (spec == null)
+ throw new NullPointerException ();
+ this.spec = spec;
+ }
+
+ public GnuPBEKey (char[] password, byte[] salt, int iterationCount)
+ {
+ this (new PBEKeySpec (password, salt, iterationCount));
+ }
+
+ public int getIterationCount ()
+ {
+ return spec.getIterationCount ();
+ }
+
+ public char[] getPassword ()
+ {
+ return spec.getPassword ();
+ }
+
+ public byte[] getSalt ()
+ {
+ return spec.getSalt ();
+ }
+
+ public String getAlgorithm ()
+ {
+ return "PBE";
+ }
+
+ public String getFormat ()
+ {
+ return "NONE"; // FIXME?
+ }
+
+ public byte[] getEncoded ()
+ {
+ return null; // FIXME?
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/AbstractSessionContext.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/AbstractSessionContext.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/AbstractSessionContext.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,288 @@
+/* AbstractSessionContext -- stores SSL sessions, possibly persistently.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import gnu.java.security.Requires;
+
+import gnu.javax.net.ssl.provider.SimpleSessionContext;
+
+import java.util.Enumeration;
+
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPermission;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionContext;
+
+/**
+ * A skeletal implementation of {@link SSLSessionContext}. This class may
+ * be subclassed to add extended functionality to session contexts, such
+ * as by storing sessions in files on disk, or by sharing contexts
+ * across different JVM instances.
+ *
+ * <p>In order to securely store sessions, along with private key data,
+ * the abstract methods {@lnk {@link #load(char[])} and {@link #store(char[])}
+ * come into play. When storing sessions, a session context implementation
+ * must pass this password to the {@link Session#prepare(char[])} method,
+ * before either writing the {@link java.io.Serializable} session to the
+ * underlying store, or getting the opaque {@link Session#privateData()}
+ * class from the session, and storing that.
+ *
+ * <p>As a simple example, that writes sessions to some object output
+ * stream:
+ *
+ * <pre>
+ char[] password = ...;
+ ObjectOutputStream out = ...;
+ ...
+ for (Session s : this)
+ {
+ s.prepare(password);
+ out.writeObject(s);
+ }</pre>
+ *
+ * <p>The reverse must be done when deserializing sessions, by using the
+ * {@link Session#repair(char[])} method, possibly by first calling
+ * {@link Session#setPrivateData(java.io.Serializable)} with the read,
+ * opaque private data type. Thus an example of reading may be:
+ *
+ * <pre>
+ char[] password = ...;
+ ObjectInputStream in = ...;
+ ...
+ while (hasMoreSessions(in))
+ {
+ Session s = (Session) in.readObject();
+ s.repair(password);
+ addToThisStore(s);
+ }</pre>
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+public abstract class AbstractSessionContext implements SSLSessionContext
+{
+ protected long timeout;
+ private static Class<? extends AbstractSessionContext>
+ implClass = SimpleSessionContext.class;
+
+ /**
+ * Create a new instance of a session context, according to the configured
+ * implementation class.
+ *
+ * @return The new session context.
+ * @throws SSLException If an error occurs in creating the instance.
+ */
+ public static AbstractSessionContext newInstance () throws SSLException
+ {
+ try
+ {
+ return implClass.newInstance();
+ }
+ catch (IllegalAccessException iae)
+ {
+ throw new SSLException(iae);
+ }
+ catch (InstantiationException ie)
+ {
+ throw new SSLException(ie);
+ }
+ }
+
+ /**
+ * Reconfigure this instance to use a different session context
+ * implementation.
+ *
+ * <p><strong>Note:</strong> this method requires that the caller have
+ * {@link SSLPermission} with target
+ * <code>gnu.javax.net.ssl.AbstractSessionContext</code> and action
+ * <code>setImplClass</code>.
+ *
+ * @param clazz The new implementation class.
+ * @throws SecurityException If the caller does not have permission to
+ * change the session context.
+ */
+ @Requires(permissionClass = SSLPermission.class,
+ target = "gnu.javax.net.ssl.AbstractSessionContext",
+ action = "setImplClass")
+ public static synchronized void setImplClass
+ (Class<? extends AbstractSessionContext> clazz)
+ throws SecurityException
+ {
+ SecurityManager sm = System.getSecurityManager ();
+ if (sm != null)
+ sm.checkPermission(new SSLPermission("gnu.javax.net.ssl.AbstractSessionContext",
+ "setImplClass"));
+ implClass = clazz;
+ }
+
+ /**
+ * @param timeout The initial session timeout.
+ */
+ protected AbstractSessionContext (final int timeout)
+ {
+ setSessionTimeout(timeout);
+ }
+
+ /**
+ * Fetch a saved session by its ID. This method will (possibly)
+ * deserialize and return the SSL session with that ID, or null if
+ * the requested session does not exist, or has expired.
+ *
+ * <p>Subclasses implementing this class <strong>must not</strong>
+ * perform any blocking operations in this method. If any blocking
+ * behavior is required, it must be done in the {@link load(char[])}
+ * method.
+ *
+ * @param sessionId The ID of the session to get.
+ * @return The found session, or null if no such session was found,
+ * or if that session has expired.
+ */
+ public final SSLSession getSession (byte[] sessionId)
+ {
+ Session s = implGet (sessionId);
+ if (s != null
+ && System.currentTimeMillis () - s.getLastAccessedTime () > timeout)
+ {
+ remove (sessionId);
+ return null;
+ }
+ return s;
+ }
+
+ public final SSLSession getSession(String host, int port)
+ {
+ for (Enumeration e = getIds(); e.hasMoreElements(); )
+ {
+ byte[] id = (byte[]) e.nextElement();
+ SSLSession s = getSession(id);
+ if (s == null) // session expired.
+ continue;
+ String host2 = s.getPeerHost();
+ if (host == null)
+ {
+ if (host2 != null)
+ continue;
+ }
+ else if (!host.equals(host2))
+ continue;
+ int port2 = s.getPeerPort();
+ if (port != port2)
+ continue;
+
+ // Else, a match.
+ return s;
+ }
+
+ return null;
+ }
+
+ /**
+ * To be implemented by subclasses. Subclasses do not need to check
+ * timeouts in this method.
+ *
+ * @param sessionId The session ID.
+ * @return The session, or <code>null</code> if the requested session
+ * was not found.
+ */
+ protected abstract Session implGet (byte[] sessionId);
+
+ public int getSessionTimeout()
+ {
+ return (int) (timeout / 1000);
+ }
+
+ /**
+ * Load this session store from the underlying media, if supported
+ * by the implementation.
+ *
+ * @param password The password that protects the sensitive data in
+ * this store.
+ * @throws SessionStoreException If reading this store fails, such
+ * as when an I/O exception occurs, or if the password is incorrect.
+ */
+ public abstract void load (char[] password) throws SessionStoreException;
+
+ /**
+ * Add a new session to the store. The underlying implementation
+ * will add the session to its store, possibly overwriting any
+ * existing session with the same ID.
+ *
+ * <p>Subclasses implementing this class <strong>must not</strong>
+ * perform any blocking operations in this method. If any blocking
+ * behavior is required, it must be done in the {@link
+ * #store(char[])} method.
+ *
+ * @param session The session to add.
+ * @throws NullPointerException If the argument is null.
+ */
+ public abstract void put (Session session);
+
+ /**
+ * Remove a session from this store.
+ *
+ * <p>Subclasses implementing this class <strong>must not</strong>
+ * perform any blocking operations in this method. If any blocking
+ * behavior is required, it must be done in the {@link
+ * #store(char[])} method.
+ *
+ * @param sessionId The ID of the session to remove.
+ */
+ public abstract void remove (byte[] sessionId);
+
+ /**
+ *
+ */
+ public final void setSessionTimeout(int seconds)
+ {
+ if (timeout < 0)
+ throw new IllegalArgumentException("timeout may not be negative");
+ this.timeout = (long) seconds * 1000;
+ }
+
+ /**
+ * Commit this session store to the underlying media. For session
+ * store implementations that support saving sessions across
+ * invocations of the JVM, this method will save any sessions that
+ * have not expired to some persistent media, so they may be loaded
+ * and used again later.
+ *
+ * @param password The password that will protect the sensitive data
+ * in this store.
+ */
+ public abstract void store (char[] password) throws SessionStoreException;
+}
\ No newline at end of file
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManager.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManager.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManager.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,54 @@
+/* PreSharedKeyManager.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import java.security.KeyManagementException;
+
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+
+/**
+ * @author Casey Marshall (cs...@gn...)
+ */
+public interface PreSharedKeyManager extends KeyManager
+{
+ SecretKey getKey(String name) throws KeyManagementException;
+
+ String chooseIdentityHint();
+}
\ No newline at end of file
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,83 @@
+/* PreSharedKeyManagerParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+import javax.crypto.SecretKey;
+import javax.net.ssl.ManagerFactoryParameters;
+
+/**
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class PreSharedKeyManagerParameters
+ implements ManagerFactoryParameters
+{
+ private final LinkedHashMap<String, SecretKey> keys;
+
+ public PreSharedKeyManagerParameters()
+ {
+ keys = new LinkedHashMap<String, SecretKey>();
+ }
+
+ public SecretKey getKey(String name)
+ {
+ name.getClass();
+ return keys.get(name);
+ }
+
+ public void putKey(String name, SecretKey key)
+ {
+ name.getClass();
+ key.getClass();
+ keys.put(name, key);
+ }
+
+ public boolean removeKey(String name)
+ {
+ name.getClass();
+ return keys.remove(name) != null;
+ }
+
+ public Iterator<String> identities()
+ {
+ return keys.keySet().iterator();
+ }
+}
Modified: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PrivateCredentials.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PrivateCredentials.java 2007-01-07 12:50:40 UTC (rev 3020)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/PrivateCredentials.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -51,6 +51,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
+import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -95,16 +96,16 @@
public static final String BEGIN_RSA = "-----BEGIN RSA PRIVATE KEY";
public static final String END_RSA = "-----END RSA PRIVATE KEY";
- private List privateKeys;
- private List certChains;
+ private List<PrivateKey> privateKeys;
+ private List<X509Certificate[]> certChains;
// Constructor.
// -------------------------------------------------------------------------
public PrivateCredentials()
{
- privateKeys = new LinkedList();
- certChains = new LinkedList();
+ privateKeys = new LinkedList<PrivateKey>();
+ certChains = new LinkedList<X509Certificate[]>();
}
// Instance methods.
@@ -115,7 +116,7 @@
IOException, NoSuchAlgorithmException, WrongPaddingException
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
- Collection certs = cf.generateCertificates(certChain);
+ Collection<? extends Certificate> certs = cf.generateCertificates(certChain);
X509Certificate[] chain = (X509Certificate[]) certs.toArray(new X509Certificate[0]);
String alg = null;
@@ -199,11 +200,12 @@
(BigInteger) der.read().getValue(), // d mod (q-1)
(BigInteger) der.read().getValue()); // coefficient
}
+
privateKeys.add(kf.generatePrivate(spec));
certChains.add(chain);
}
- public List getPrivateKeys()
+ public List<PrivateKey> getPrivateKeys()
{
if (isDestroyed())
{
@@ -212,7 +214,7 @@
return privateKeys;
}
- public List getCertChains()
+ public List<X509Certificate[]> getCertChains()
{
return certChains;
}
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLCipherSuite.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLCipherSuite.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLCipherSuite.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,142 @@
+/* SSLCipherSuite.java -- an SSL cipher suite.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import gnu.java.security.Engine;
+
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * An SSL cipher suite.
+ */
+public abstract class SSLCipherSuite
+{
+ private static final String SERVICE = "SSLCipherSuite";
+ private final String algorithm;
+ private final byte[] id;
+ private final SSLProtocolVersion version;
+ private Provider provider;
+
+ protected SSLCipherSuite (final String algorithm, final byte[] id,
+ final SSLProtocolVersion version)
+ {
+ this.algorithm = algorithm;
+ if (id.length != 2)
+ throw new IllegalArgumentException ("cipher suite ID must be two bytes");
+ this.id = (byte[]) id.clone ();
+ this.version = version;
+ }
+
+ public static final SSLCipherSuite getInstance (SSLProtocolVersion version, byte[] id)
+ throws NoSuchAlgorithmException
+ {
+ return getInstance (version + "-" + ((id[0] & 0xFF) + "/" + (id[1] & 0xFF)));
+ }
+
+ public static final SSLCipherSuite getInstance (SSLProtocolVersion version,
+ byte[] id, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ return getInstance (version + "-" + (id[0] & 0xFF) + "/" + (id[1] & 0xFF), provider);
+ }
+
+ public static final SSLCipherSuite getInstance (String name)
+ throws NoSuchAlgorithmException
+ {
+ Provider[] providers = Security.getProviders ();
+ for (int i = 0; i < providers.length; i++)
+ {
+ try
+ {
+ return getInstance (name, providers[i]);
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ // Ignore.
+ }
+ }
+
+ throw new NoSuchAlgorithmException (SERVICE + ": " + name);
+ }
+
+ public static final SSLCipherSuite getInstance (String name, Provider provider)
+ throws NoSuchAlgorithmException
+ {
+ SSLCipherSuite suite = null;
+ try
+ {
+ suite = (SSLCipherSuite) Engine.getInstance (SERVICE, name, provider);
+ suite.provider = provider;
+ }
+ catch (InvocationTargetException ite)
+ {
+ // XXX
+ NoSuchAlgorithmException nsae = new NoSuchAlgorithmException (name);
+ nsae.initCause (ite);
+ throw nsae;
+ }
+ return suite;
+ }
+
+ public final String getAlgorithm ()
+ {
+ return algorithm;
+ }
+
+ public final byte[] getId ()
+ {
+ return (byte[]) id.clone ();
+ }
+
+ public final Provider getProvider ()
+ {
+ return provider;
+ }
+
+ public final SSLProtocolVersion getProtocolVersion ()
+ {
+ return version;
+ }
+
+ public abstract void encipher (ByteBuffer in, ByteBuffer out);
+}
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLProtocolVersion.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLProtocolVersion.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLProtocolVersion.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,54 @@
+/* SSLProtocolVersion.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+public enum SSLProtocolVersion
+{
+ SSLv3 (3, 0),
+ TLSv1 (3, 1);
+
+ public final int major;
+ public final int minor;
+
+ private SSLProtocolVersion (int major, int minor)
+ {
+ this.major = major;
+ this.minor = minor;
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLRecordHandler.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLRecordHandler.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SSLRecordHandler.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,101 @@
+/* SSLRecordHandler.java -- a class that handles SSL record layer messages.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+
+public abstract class SSLRecordHandler
+{
+ private final byte contentType;
+
+ /**
+ * Create a new record handler for the given content type.
+ */
+ protected SSLRecordHandler (final byte contentType)
+ {
+ this.contentType = contentType;
+ }
+
+ /**
+ * Handle an SSL record layer message, encapsulated in the supplied
+ * input buffer, and writing any output bytes to the output
+ * buffer. The input buffer is always only limited to the bytes that
+ * encapsulate the <em>fragment</em> of the record layer message
+ * — that is, the content-type, version, and length fields are
+ * not present in the input buffer, and the limit of the input
+ * buffer is always only as large as the fragment. If the message
+ * being read is not contained entirely within the given buffer,
+ * then the implementation should cache the bytes read as input, and
+ * wait until subsequent calls finish the object being read.
+ *
+ * <p>Technically, we expect only APPLICATION messages to ever
+ * produce output, but do suppose that extensions to the SSL
+ * protocol could allow other channels that produce output.
+ *
+ * @param input The input buffer.
+ * @param output The output buffer.
+ */
+ public abstract void handle (final ByteBuffer input,
+ final ByteBuffer output)
+ throws SSLException;
+
+ /**
+ * Returns the record layer content type that this handler is for.
+ *
+ * @return The content type value.
+ */
+ public final byte contentType ()
+ {
+ return contentType;
+ }
+
+ public boolean equals (final Object o)
+ {
+ if (!(o instanceof SSLRecordHandler))
+ return false;
+ return ((SSLRecordHandler) o).contentType == contentType;
+ }
+
+ public int hashCode ()
+ {
+ return contentType & 0xFF;
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/Session.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/Session.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/Session.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,364 @@
+/* SessionImpl.java -- concrete definition of SSLSession.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import java.io.Serializable;
+
+import java.security.Principal;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Set;
+
+import javax.crypto.SealedObject;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSessionBindingEvent;
+import javax.net.ssl.SSLSessionBindingListener;
+import javax.net.ssl.SSLSessionContext;
+import javax.security.cert.X509Certificate;
+
+/**
+ * A concrete implementation of the {@link SSLSession} interface. This
+ * class is provided to allow pluggable {@link AbstractSessionContext}
+ * implementations.
+ */
+public abstract class Session implements SSLSession, Serializable
+{
+ protected final long creationTime;
+ protected long lastAccessedTime;
+ protected int applicationBufferSize;
+
+ protected ID sessionId;
+ protected Certificate[] localCerts;
+ protected Certificate[] peerCerts;
+ protected X509Certificate[] peerCertChain;
+ protected String peerHost;
+ protected int peerPort;
+ protected boolean peerVerified;
+ protected HashMap<String,Object> values;
+ protected boolean valid;
+ protected boolean truncatedMac = false;
+ transient protected SecureRandom random;
+ transient protected SSLSessionContext context;
+
+ protected Session()
+ {
+ creationTime = System.currentTimeMillis();
+ values = new HashMap<String, Object>();
+ applicationBufferSize = (1 << 14);
+ }
+
+ public void access()
+ {
+ lastAccessedTime = System.currentTimeMillis ();
+ }
+
+ public int getApplicationBufferSize()
+ {
+ return applicationBufferSize;
+ }
+
+ public String getCipherSuite()
+ {
+ return null;
+ }
+
+ public long getCreationTime()
+ {
+ return creationTime;
+ }
+
+ public byte[] getId()
+ {
+ return sessionId.id();
+ }
+
+ public ID id()
+ {
+ return sessionId;
+ }
+
+ public long getLastAccessedTime()
+ {
+ return lastAccessedTime;
+ }
+
+ public Certificate[] getLocalCertificates()
+ {
+ if (localCerts == null)
+ return null;
+ return (Certificate[]) localCerts.clone();
+ }
+
+ public Principal getLocalPrincipal()
+ {
+ if (localCerts != null)
+ {
+ if (localCerts[0] instanceof java.security.cert.X509Certificate)
+ return ((java.security.cert.X509Certificate) localCerts[0]).getSubjectDN();
+ }
+ return null;
+ }
+
+ public int getPacketBufferSize()
+ {
+ return applicationBufferSize + 2048;
+ }
+
+ public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
+ {
+ if (!peerVerified)
+ throw new SSLPeerUnverifiedException("peer not verified");
+ if (peerCerts == null)
+ return null;
+ return (Certificate[]) peerCerts.clone();
+ }
+
+ public X509Certificate[] getPeerCertificateChain()
+ throws SSLPeerUnverifiedException
+ {
+ if (!peerVerified)
+ throw new SSLPeerUnverifiedException("peer not verified");
+ if (peerCertChain == null)
+ return null;
+ return (X509Certificate[]) peerCertChain.clone();
+ }
+
+ public String getPeerHost()
+ {
+ return peerHost;
+ }
+
+ public int getPeerPort()
+ {
+ return peerPort;
+ }
+
+ public Principal getPeerPrincipal() throws SSLPeerUnverifiedException
+ {
+ if (!peerVerified)
+ throw new SSLPeerUnverifiedException("peer not verified");
+ if (peerCertChain == null)
+ return null;
+ return peerCertChain[0].getSubjectDN();
+ }
+
+ public SSLSessionContext getSessionContext()
+ {
+ return context;
+ }
+
+ public String[] getValueNames()
+ {
+ Set<String> keys = this.values.keySet();
+ return keys.toArray(new String[keys.size()]);
+ }
+
+ public Object getValue(String name)
+ {
+ return values.get(name);
+ }
+
+ public void invalidate()
+ {
+ valid = false;
+ }
+
+ public boolean isValid()
+ {
+ return valid;
+ }
+
+ public void putValue(String name, Object value)
+ {
+ values.put(name, value);
+ try
+ {
+ if (value instanceof SSLSessionBindingListener)
+ ((SSLSessionBindingListener) value).valueBound
+ (new SSLSessionBindingEvent(this, name));
+ }
+ catch (Exception x)
+ {
+ }
+ }
+
+ public void removeValue(String name)
+ {
+ Object value = values.remove(name);
+ try
+ {
+ if (value instanceof SSLSessionBindingListener)
+ ((SSLSessionBindingListener) value).valueUnbound
+ (new SSLSessionBindingEvent(this, name));
+ }
+ catch (Exception x)
+ {
+ }
+ }
+
+ public final boolean isTruncatedMac()
+ {
+ return truncatedMac;
+ }
+
+ /**
+ * Prepare this session for serialization. Private data will be encrypted
+ * with the given password, and this object will then be ready to be
+ * serialized.
+ *
+ * @param password The password to protect this session with.
+ * @throws SSLException If encrypting this session's private data fails.
+ */
+ public abstract void prepare (char[] password) throws SSLException;
+
+ /**
+ * Repair this session's private data after deserialization. This method
+ * will decrypt this session's private data, and prepare the session for
+ * use in new SSL connections.
+ *
+ * @param password The password to decrypt the private data with.
+ * @throws SSLException
+ */
+ public abstract void repair(char[] password) throws SSLException;
+
+ /**
+ * Get the private data of this session. This method may only be called
+ * after first calling {@link #prepare(char[])}.
+ *
+ * @return The sealed private data.
+ * @throws SSLException If the private data have not been sealed.
+ */
+ public abstract SealedObject privateData() throws SSLException;
+
+ /**
+ * Set the private data of this session.
+ * @param data
+ * @throws SSLException
+ */
+ public abstract void setPrivateData(SealedObject data) throws SSLException;
+
+ // Inner classes.
+ // -------------------------------------------------------------------------
+
+ /**
+ * An SSL or TLS session ID.
+ */
+ public static final class ID implements Comparable, Serializable
+ {
+
+ // Fields.
+ // -----------------------------------------------------------------------
+
+ static final long serialVersionUID = 7887036954666565936L;
+ /** The ID itself. */
+ private final byte[] id;
+
+ // Constructor.
+ // -----------------------------------------------------------------------
+
+ /**
+ * Creates a new ID.
+ *
+ * @param id The ID. The array is cloned.
+ */
+ public ID (final byte[] id)
+ {
+ if (id.length > 32)
+ throw new IllegalArgumentException ("session ID's are limited to 32 bytes");
+ this.id = (byte[]) id.clone();
+ }
+
+ // Instance methods.
+ // -----------------------------------------------------------------------
+
+ public byte[] id()
+ {
+ return (byte[]) id.clone();
+ }
+
+ public boolean equals(Object other)
+ {
+ if (!(other instanceof ID))
+ return false;
+ return Arrays.equals(id, ((ID) other).id);
+ }
+
+ public int hashCode()
+ {
+ int code = 0;
+ for (int i = 0; i < id.length; i++)
+ code |= (id[i] & 0xFF) << ((i & 3) << 3);
+ return code;
+ }
+
+ public int compareTo(Object other)
+ {
+ byte[] id2 = ((ID) other).id;
+ if (id.length != id2.length)
+ return (id.length < id2.length) ? -1 : 1;
+ for (int i = 0; i < id.length; i++)
+ {
+ if ((id[i] & 0xFF) < (id2[i] & 0xFF))
+ return -1;
+ if ((id[i] & 0xFF) > (id2[i] & 0xFF))
+ return 1;
+ }
+ return 0;
+ }
+
+ public String toString()
+ {
+ StringBuffer str = new StringBuffer (3 * id.length + 1);
+ for (int i = 0; i < id.length; i++)
+ {
+ int x = id[i] & 0xFF;
+ str.append (Character.forDigit ((x >>> 4) & 0xF, 16));
+ str.append (Character.forDigit (x & 0xF, 16));
+ if (i != id.length - 1)
+ str.append (':');
+ }
+ return str.toString ();
+ }
+ }
+}
\ No newline at end of file
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SessionStoreException.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SessionStoreException.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/SessionStoreException.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,59 @@
+/* SessionStoreException.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl;
+
+import javax.net.ssl.SSLException;
+
+public class SessionStoreException extends SSLException
+{
+ public SessionStoreException (final String message)
+ {
+ super (message);
+ }
+
+ public SessionStoreException (final String message, final Throwable cause)
+ {
+ super (message, cause);
+ }
+
+ public SessionStoreException (final Throwable cause)
+ {
+ super (cause);
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/javax/security/auth/callback/CertificateCallback.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/security/auth/callback/CertificateCallback.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/security/auth/callback/CertificateCallback.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,64 @@
+/* CertificateCallback.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.security.auth.callback;
+
+import java.security.cert.Certificate;
+
+import javax.security.auth.callback.ConfirmationCallback;
+
+/**
+ * A {@link javax.security.auth.callback.Callback} for confirming whether or
+ * not a certificate may be used. This works similarly to
+ * {@link ConfirmationCallback}, but additionally contains the certificate
+ * being verified. Thus, handlers may present the certificate to the user, when
+ * handling this callback.
+ *
+ * @author Casey Marshall (cs...@gn...)
+ */
+public class CertificateCallback extends ConfirmationCallback
+{
+ static final long serialVersionUID = 8343869651419225634L;
+ public final Certificate certificate;
+
+ public CertificateCallback(Certificate cert, String prompt)
+ {
+ super(prompt, ERROR, YES_NO_OPTION, NO);
+ this.certificate = cert;
+ }
+}
Added: trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/CharacterAttributeTranslator.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/CharacterAttributeTranslator.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/CharacterAttributeTranslator.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -0,0 +1,192 @@
+/* CharacterAttributeTranslator.java --
+ Copyright (C) 2006 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 gnu.javax.swing.text.html;
+
+import java.awt.Color;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.html.HTML.Attribute;
+import javax.swing.text.html.HTML.Tag;
+
+/**
+ * This is a small utility class to translate HTML character attributes to
+ * Swing StyleConstants
+ */
+public class CharacterAttributeTranslator
+{
+ /**
+ * Maps color name to its hex encoding.
+ */
+ private static final HashMap colorMap = new HashMap();
+ static
+ {
+ colorMap.put("aqua" , "#00FFFF");
+ colorMap.put("blue" , "#0000FF");
+ colorMap.put("black", "#000000");
+ colorMap.put("fuchsia" , "#FF00FF");
+ colorMap.put("gray" , "#808080");
+ colorMap.put("green" , "#008000");
+ colorMap.put("lime" , "#00FF00");
+ colorMap.put("maroon" , "#800000");
+ colorMap.put("navy" , "#000080");
+ colorMap.put("olive" , "#808000");
+ colorMap.put("purple" , "#800080");
+ colorMap.put("red" , "#FF0000");
+ colorMap.put("silver" , "#C0C0C0");
+ colorMap.put("teal" , "#008080");
+ colorMap.put("white" , "#FFFFFF");
+ colorMap.put("yellow" , "#FFFF00");
+ }
+
+ /**
+ * Convert the color string represenation into java.awt.Color. The valid
+ * values are like "aqua" , "#00FFFF" or "rgb(1,6,44)".
+ *
+ * @param colorName the color to convert.
+ * @return the matching java.awt.color
+ */
+ public static Color getColor(String colorName)
+ {
+ colorName = colorName.toLowerCase();
+ try
+ {
+ if (colorName.startsWith("rgb"))
+ {
+ // rgb(red, green, blue) notation.
+ StringTokenizer st = new StringTokenizer(colorName, " ,()");
+ String representation = st.nextToken();
+
+ // Return null if the representation is not supported.
+ if (! representation.equals("rgb"))
+ return null;
+ int red = Integer.parseInt(st.nextToken());
+ int green = Integer.parseInt(st.nextToken());
+ int blue = Integer.parseInt(st.nextToken());
+
+ return new Color(red, green, blue);
+ }
+ else
+ {
+ String s2 = (String) colorMap.get(colorName);
+ if (s2 == null)
+ s2 = colorName;
+ return Color.decode(s2);
+ }
+ }
+ catch (Exception nex)
+ {
+ // Can be either number format exception or illegal argument
+ // exception.
+ return null;
+ }
+ }
+
+ /**
+ * Translate the HTML character attribute to the Swing style constant.
+ *
+ * @param charAttr the character attributes of the html tag
+ * @param t the html tag itself
+ * @param a the attribute set where the translated attributes will be stored
+ *
+ * @return true if some attributes were translated, false otherwise.
+ */
+ public static boolean translateTag(MutableAttributeSet charAttr,
+ Tag t, MutableAttributeSet a)
+ {
+ if(t == Tag.FONT)
+ {
+ Object color = a.getAttribute(Attribute.COLOR);
+ if(color != null)
+ {
+ Color c = getColor(color.toString());
+ if( c == null )
+ return false;
+ charAttr.addAttribute(StyleConstants.Foreground, c);
+ return true;
+ }
+
+ if(a.getAttribute(Attribute.SIZE) != null)
+ {
+ // FIXME
+ // charAttr.addAttribute(StyleConstants.FontSize,
+ // new java.lang.Integer(72));
+ return true;
+ }
+ }
+
+ if( t == Tag.B )
+ {
+ charAttr.addAttribute(StyleConstants.Bold, Boolean.TRUE);
+ return true;
+ }
+
+ if( t == Tag.I )
+ {
+ charAttr.addAttribute(StyleConstants.Italic, Boolean.TRUE);
+ return true;
+ }
+
+ if( t == Tag.U )
+ {
+ charAttr.addAttribute(StyleConstants.Underline, Boolean.TRUE);
+ return true;
+ }
+
+ if( t == Tag.STRIKE )
+ {
+ charAttr.addAttribute(StyleConstants.StrikeThrough, Boolean.TRUE);
+ return true;
+ }
+
+ if( t == Tag.SUP )
+ {
+ charAttr.addAttribute(StyleConstants.Superscript, Boolean.TRUE);
+ return true;
+ }
+
+ if( t == Tag.SUB )
+ {
+ charAttr.addAttribute(StyleConstants.Subscript, Boolean.TRUE);
+ return true;
+ }
+ return false;
+ }
+}
Deleted: trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/parser/HTML_401Swing.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/parser/HTML_401Swing.java 2007-01-07 12:50:40 UTC (rev 3020)
+++ trunk/core/src/classpath/gnu/gnu/javax/swing/text/html/parser/HTML_401Swing.java 2007-01-07 12:51:25 UTC (rev 3021)
@@ -1,91 +0,0 @@
-/* HTML_401Swing.java -- The HTML 4.01 DTD, adapted for HTML rendering in Swing
- Copyright (C) 2006 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 gnu.javax.swing.text.html.parser;
-
-import javax.swing.text.html.parser.DTD;
-
-/**
- * This class is necessary because the current implementation of the GNU
- * Classpath Swing requires always enclose the text into paragraphs.
- *
- * @author Audrius Meskauskas (Aud...@Bi...)
- */
-public class HTML_401Swing extends HTML_401F
-{
- /**
- * The singleton instance;
- */
- final static HTML_401Swing singleton = new HTML_401Swing();
-
- /**
- * Either takes the document (by name) from DTD table, or
- * creates a new instance and registers it in the tabe.
- * The document is registerd under name "-//W3C//DTD HTML 4.01 Frameset//EN".
- * @return The new or existing DTD for parsing HTML 4.01 Frameset.
- */
- public static DTD getInstance()
- {
- return singleton;
- }
-
- /**
- * Get elements that are allowed in the document body, at the zero level.
- * This list disallows the text at this level (the implied P tag will be
- * generated). It also disallows A, B, I, U, CITE and other similar
- * elements that have the plain text inside. They will also be placed
- * inside the generated implied P tags.
- */
- protected String[] getBodyElements()
- {
- return new String[] {
- APPLET, BASEFONT,
- BR, BUTTON,
- IFRAME, IMG,
- INPUT, LABEL, MAP, OBJECT,
- SCRIPT, SELECT,
- TEXTAREA,
- BLOCKQUOTE, CENTER, DEL, DIR,
- DIV, DL, FIELDSET, FORM, H1,
- H2, H3, H4, H5, H6,...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-07 12:50:41
|
Revision: 3020
http://jnode.svn.sourceforge.net/jnode/?rev=3020&view=rev
Author: lsantha
Date: 2007-01-07 04:50:40 -0800 (Sun, 07 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extension.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Finished.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Handshake.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Jessie.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ProtocolVersion.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Random.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerHello.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerKeyExchange.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Signature.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Util.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/X509TrustManagerFactory.java
Added Paths:
-----------
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExchangeKeys.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExtensionList.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/HelloRequest.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/InputSecurityParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/MacAlgorithm.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/MaxFragmentLength.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/OutputSecurityParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Record.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLContextImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLEngineImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLRSASignatureImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLServerSocketFactoryImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLServerSocketImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLSocketFactoryImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLSocketImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLv3HMacMD5Impl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLv3HMacSHAImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerDHParams.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerHandshake.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerHelloBuilder.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerHelloDone.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerKeyExchangeBuilder.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerKeyExchangeParams.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerNameList.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerPSKParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerRSAParams.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SessionImpl.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SignatureAlgorithm.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SimpleSessionContext.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/TruncatedHMAC.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/TrustedAuthorities.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/X500PrincipalList.java
Removed Paths:
-------------
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestInputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestOutputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Enumerated.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extensions.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/GNUSecurityParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JCESecurityParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JessieDHPrivateKey.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JessieDHPublicKey.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JessieRSAPrivateKey.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/JessieRSAPublicKey.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/KeyPool.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/OverflowException.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/RecordInput.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/RecordInputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/RecordOutputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/RecordingInputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLRSASignature.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLServerSocket.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLServerSocketFactory.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLSocket.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLSocketFactory.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLSocketInputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SSLSocketOutputStream.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SecurityParameters.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Session.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SessionContext.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/SynchronizedRandom.java
trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/XMLSessionContext.java
Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Context.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -1,330 +0,0 @@
-/* Context.java -- SSLContext implementation.
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is a 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 of the License, 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; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl.provider;
-
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStoreException;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContextSpi;
-import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-import gnu.javax.net.ssl.NullManagerParameters;
-import gnu.javax.net.ssl.SRPTrustManager;
-import gnu.javax.net.ssl.StaticTrustAnchors;
-
-/**
- * This is Jessie's implementation of a {@link javax.net.ssl.SSLContext}
- * engine, and is available under the algorithm names ``SSLv3'', ``SSL'',
- * ``TLSv1'', and ``TLS''.
- */
-public final class Context extends SSLContextSpi
-{
-
- // Fields.
- // -------------------------------------------------------------------------
-
- private SessionContext clientSessions;
- private SessionContext serverSessions;
- private X509KeyManager keyManager;
- private X509TrustManager trustManager;
- private SRPTrustManager srpTrustManager;
- private SecureRandom random;
-
- // Constructor.
- // -------------------------------------------------------------------------
-
- public Context()
- {
- String codec = Util.getSecurityProperty("jessie.clientSessionContext.codec");
- String codecClass = null;
- if (codec == null)
- {
- codec = "null";
- }
- if (codec.equalsIgnoreCase("xml"))
- {
- codecClass = "gnu.javax.net.ssl.provider.XMLSessionContext";
- }
- else if (codec.equalsIgnoreCase("jdbc"))
- {
- codecClass = "gnu.javax.net.ssl.provider.JDBCSessionContext";
- }
- else if (codec.equalsIgnoreCase("null"))
- {
- codecClass = "gnu.javax.net.ssl.provider.SessionContext";
- }
- else
- {
- throw new IllegalArgumentException("no such codec: " + codec);
- }
- try
- {
- ClassLoader cl = Context.class.getClassLoader();
- if (cl == null)
- {
- cl = ClassLoader.getSystemClassLoader();
- }
- clientSessions = (SessionContext) cl.loadClass(codecClass).newInstance();
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- throw new IllegalArgumentException(ex.toString());
- }
-
- codec = Util.getSecurityProperty("jessie.serverSessionContext.codec");
- if (codec == null)
- {
- codec = "null";
- }
- if (codec.equalsIgnoreCase("xml"))
- {
- codecClass = "gnu.javax.net.ssl.provider.XMLSessionContext";
- }
- else if (codec.equalsIgnoreCase("jdbc"))
- {
- codecClass = "gnu.javax.net.ssl.provider.JDBCSessionContext";
- }
- else if (codec.equalsIgnoreCase("null"))
- {
- codecClass = "gnu.javax.net.ssl.provider.SessionContext";
- }
- else
- {
- throw new IllegalArgumentException("no such codec: " + codec);
- }
- try
- {
- ClassLoader cl = Context.class.getClassLoader();
- if (cl == null)
- {
- cl = ClassLoader.getSystemClassLoader();
- }
- serverSessions = (SessionContext) cl.loadClass(codecClass).newInstance();
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- throw new IllegalArgumentException(ex.toString());
- }
- }
-
- // Engine methods.
- // -------------------------------------------------------------------------
-
- protected SSLSessionContext engineGetClientSessionContext()
- {
- return clientSessions;
- }
-
- protected SSLSessionContext engineGetServerSessionContext()
- {
- return serverSessions;
- }
-
- protected javax.net.ssl.SSLServerSocketFactory engineGetServerSocketFactory()
- {
- if (keyManager == null || (trustManager == null && srpTrustManager == null)
- || random == null)
- {
- throw new IllegalStateException();
- }
- return new SSLServerSocketFactory(trustManager, srpTrustManager, keyManager,
- random, serverSessions);
- }
-
- protected javax.net.ssl.SSLSocketFactory engineGetSocketFactory()
- {
- if (keyManager == null || trustManager == null || random == null)
- {
- throw new IllegalStateException();
- }
- return new SSLSocketFactory(trustManager, keyManager, random, clientSessions);
- }
-
- protected void engineInit(KeyManager[] keyManagers,
- TrustManager[] trustManagers, SecureRandom random)
- throws KeyManagementException
- {
- keyManager = null;
- trustManager = null;
- srpTrustManager = null;
- if (keyManagers != null)
- {
- for (int i = 0; i < keyManagers.length; i++)
- {
- if (keyManagers[i] instanceof X509KeyManager)
- {
- keyManager = (X509KeyManager) keyManagers[i];
- break;
- }
- }
- }
- if (keyManager == null)
- {
- keyManager = defaultKeyManager();
- }
- if (trustManagers != null)
- {
- for (int i = 0; i < trustManagers.length; i++)
- {
- if (trustManagers[i] instanceof X509TrustManager)
- {
- if (trustManager == null)
- {
- trustManager = (X509TrustManager) trustManagers[i];
- }
- }
- else if (trustManagers[i] instanceof SRPTrustManager)
- {
- if (srpTrustManager == null)
- {
- srpTrustManager = (SRPTrustManager) trustManagers[i];
- }
- }
- }
- }
- if (trustManager == null && srpTrustManager == null)
- {
- trustManager = defaultTrustManager();
- }
- if (random != null)
- {
- this.random = random;
- }
- else
- {
- this.random = defaultRandom();
- }
- }
-
- // Own methods.
- // -------------------------------------------------------------------------
-
- private X509KeyManager defaultKeyManager() throws KeyManagementException
- {
- KeyManagerFactory fact = null;
- try
- {
- fact = KeyManagerFactory.getInstance("JessieX509", "Jessie");
- }
- catch (NoSuchAlgorithmException nsae)
- {
- throw new KeyManagementException();
- }
- catch (NoSuchProviderException nspe)
- {
- throw new KeyManagementException();
- }
- try
- {
- fact.init(null, null);
- return (X509KeyManager) fact.getKeyManagers()[0];
- }
- catch (NoSuchAlgorithmException nsae) { }
- catch (KeyStoreException kse) { }
- catch (UnrecoverableKeyException uke) { }
- catch (IllegalStateException ise) { }
-
- try
- {
- fact.init(new NullManagerParameters());
- return (X509KeyManager) fact.getKeyManagers()[0];
- }
- catch (Exception shouldNotHappen)
- {
- throw new Error(shouldNotHappen.toString());
- }
- }
-
- private X509TrustManager defaultTrustManager() throws KeyManagementException
- {
- try
- {
- TrustManagerFactory fact =
- TrustManagerFactory.getInstance("JessieX509", "Jessie");
- fact.init(StaticTrustAnchors.CA_CERTS);
- return (X509TrustManager) fact.getTrustManagers()[0];
- }
- catch (NoSuchAlgorithmException nsae)
- {
- throw new KeyManagementException(nsae.toString());
- }
- catch (NoSuchProviderException nspe)
- {
- throw new KeyManagementException(nspe.toString());
- }
- catch (InvalidAlgorithmParameterException kse)
- {
- throw new KeyManagementException(kse.toString());
- }
- }
-
- private SecureRandom defaultRandom() throws KeyManagementException
- {
- String alg = Util.getSecurityProperty("jessie.secure.random");
- if (alg == null)
- {
- alg = "Fortuna";
- }
- SecureRandom rand = null;
- try
- {
- rand = SecureRandom.getInstance(alg);
- }
- catch (NoSuchAlgorithmException nsae)
- {
- throw new KeyManagementException(nsae.toString());
- }
-
- return rand;
- }
-}
Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestInputStream.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestInputStream.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestInputStream.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -1,103 +0,0 @@
-/* DigestInputStream.java -- digesting input stream.
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is a 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 of the License, 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; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl.provider;
-
-import java.io.FilterInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-
-import gnu.java.security.hash.IMessageDigest;
-
-final class DigestInputStream extends FilterInputStream
-{
-
- // Fields.
- // -------------------------------------------------------------------------
-
- private IMessageDigest md5, sha;
- private boolean digesting;
-
- // Constructor.
- // -------------------------------------------------------------------------
-
- DigestInputStream(InputStream in, IMessageDigest md5, IMessageDigest sha)
- {
- super(in);
- if (md5 == null || sha == null)
- throw new NullPointerException();
- this.md5 = md5;
- this.sha = sha;
- digesting = true;
- }
-
- // Instance methods.
- // -------------------------------------------------------------------------
-
- void setDigesting(boolean digesting)
- {
- this.digesting = digesting;
- }
-
- public int read() throws IOException
- {
- int i = in.read();
- if (digesting && i != -1)
- {
- md5.update((byte) i);
- sha.update((byte) i);
- }
- return i;
- }
-
- public int read(byte[] buf) throws IOException
- {
- return read(buf, 0, buf.length);
- }
-
- public int read(byte[] buf, int off, int len) throws IOException
- {
- int ret = in.read(buf, off, len);
- if (digesting && ret != -1)
- {
- md5.update(buf, off, ret);
- sha.update(buf, off, ret);
- }
- return ret;
- }
-}
Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestOutputStream.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestOutputStream.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/DigestOutputStream.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -1,107 +0,0 @@
-/* DigestOutputStream.java -- digesting output stream.
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is a 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 of the License, 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; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl.provider;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import gnu.java.security.hash.IMessageDigest;
-
-final class DigestOutputStream extends FilterOutputStream
-{
-
- // Fields.
- // -------------------------------------------------------------------------
-
- private IMessageDigest md5, sha;
- private boolean digesting;
-
- // Constructor.
- // -------------------------------------------------------------------------
-
- DigestOutputStream(OutputStream out, IMessageDigest md5, IMessageDigest sha)
- {
- super(out);
- this.md5 = md5;
- this.sha = sha;
- digesting = true;
- }
-
- // Instance methods.
- // -------------------------------------------------------------------------
-
- void setDigesting(boolean digesting)
- {
- this.digesting = digesting;
- }
-
- public void write(int b) throws IOException
- {
- if (digesting)
- {
- md5.update((byte) b);
- sha.update((byte) b);
- }
- out.write(b);
- }
-
- public void write(byte[] buf) throws IOException
- {
- write(buf, 0, buf.length);
- }
-
- public void write(byte[] buf, int off, int len) throws IOException
- {
- if (buf == null)
- {
- throw new NullPointerException();
- }
- if (off < 0 || len < 0 || off+len > buf.length)
- {
- throw new ArrayIndexOutOfBoundsException();
- }
- if (digesting)
- {
- md5.update(buf, off, len);
- sha.update(buf, off, len);
- }
- out.write(buf, off, len);
- }
-}
Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Enumerated.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Enumerated.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Enumerated.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -1,79 +0,0 @@
-/* Enumerated.java -- Interface to enumerated types.
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is a 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 of the License, 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; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl.provider;
-
-/**
- * An enumerated type in the SSL protocols. Enumerated values take on
- * one of a set of possible numeric values, which are not specifically
- * ordered, and may be extensible to a maximum value.
- *
- * <pre>enum { e1(v1), e2(v2), ... [[, (n) ]] }</pre>
- *
- * <p>Enumerated types are encoded as big-endian multibyte integers,
- * which take up the least possible number of bytes. Thus, an
- * enumeration with up to 255 values will be encoded in a single byte,
- * and so on.
- *
- * @author Casey Marshall (rs...@me...)
- */
-interface Enumerated
-{
-
- /**
- * Returns the encoded value of this enumerated value, which is
- * appropriate to send over-the-wire.
- *
- * @return The encoded value.
- */
- byte[] getEncoded();
-
- /**
- * Returns the numeric value of this enumerated value.
- *
- * @return The numeric value.
- */
- int getValue();
-
- /**
- * Returns a string representation of this enumerated value.
- *
- * @return The string.
- */
- String toString();
-}
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExchangeKeys.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExchangeKeys.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExchangeKeys.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -0,0 +1,54 @@
+/* ExchangeKeys.java -- key exchange values.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl.provider;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public abstract class ExchangeKeys implements Constructed
+{
+
+ protected ByteBuffer buffer;
+
+ public ExchangeKeys (final ByteBuffer buffer)
+ {
+ if (buffer != null)
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
+ }
+}
\ No newline at end of file
Modified: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extension.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extension.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extension.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -38,136 +38,190 @@
package gnu.javax.net.ssl.provider;
-import java.io.EOFException;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
-final class Extension implements Constructed
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * An SSL hello extension.
+ *
+ * <pre>
+ * struct {
+ * ExtensionType extension_type;
+ * opaque extension_data<0..2^16-1>;
+ * } Extension;</pre>
+ *
+ * @author cs...@gn...
+ */
+public final class Extension implements Builder, Constructed
{
// Fields.
// -------------------------------------------------------------------------
- private final Type type;
- private final byte[] value;
+ private ByteBuffer buffer;
// Constructor.
// -------------------------------------------------------------------------
- Extension(Type type, byte[] value)
- {
- if (type == null || value == null)
+ public Extension(final ByteBuffer buffer)
{
- throw new NullPointerException();
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
}
- this.type = type;
- this.value = value;
+
+ public Extension(final Type type, final Value value)
+ {
+ ByteBuffer valueBuffer = value.buffer();
+ int length = 2 + 2 + valueBuffer.remaining();
+ buffer = ByteBuffer.allocate(length);
+ buffer.putShort((short) type.getValue());
+ buffer.putShort((short) valueBuffer.remaining());
+ buffer.put(valueBuffer);
+ buffer.rewind();
}
- // Class method.
+ // Instance methods.
// -------------------------------------------------------------------------
- static Extension read(InputStream in) throws IOException
+ public int length ()
{
- Type t = Type.read(in);
- int len = (in.read() & 0xFF) << 8 | (in.read() & 0xFF);
- byte[] v = new byte[len];
- int count = 0;
- while (count < len)
+ return (buffer.getShort (2) & 0xFFFF) + 4;
+ }
+
+ public ByteBuffer buffer()
{
- int l = in.read(v, count, len - count);
- if (l == -1)
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
+
+ public Type type()
{
- throw new EOFException("unexpected end of extension");
+ return Type.forValue (buffer.getShort (0) & 0xFFFF);
}
- count += l;
+
+ public byte[] valueBytes()
+ {
+ int len = buffer.getShort (2) & 0xFFFF;
+ byte[] value = new byte[len];
+ ((ByteBuffer) buffer.duplicate ().position (4)).get (value);
+ return value;
}
- return new Extension(t, v);
+
+ public ByteBuffer valueBuffer()
+ {
+ int len = buffer.getShort(2) & 0xFFFF;
+ return ((ByteBuffer) buffer.duplicate().position(4).limit(len+4)).slice();
}
- // Instance methods.
- // -------------------------------------------------------------------------
+ public Value value()
+ {
+ switch (type ())
+ {
+ case SERVER_NAME:
+ return new ServerNameList(valueBuffer());
- public void write(OutputStream out) throws IOException
+ case MAX_FRAGMENT_LENGTH:
+ switch (valueBuffer().get() & 0xFF)
{
- out.write(type.getEncoded());
- out.write(value.length >>> 8 & 0xFF);
- out.write(value.length & 0xFF);
- out.write(value);
+ case 1: return MaxFragmentLength.LEN_2_9;
+ case 2: return MaxFragmentLength.LEN_2_10;
+ case 3: return MaxFragmentLength.LEN_2_11;
+ case 4: return MaxFragmentLength.LEN_2_12;
+ default:
+ throw new IllegalArgumentException("invalid max_fragment_len");
+ }
+
+ case TRUNCATED_HMAC:
+ return new TruncatedHMAC();
+
+ case CLIENT_CERTIFICATE_URL:
+ return new CertificateURL(valueBuffer());
+
+ case TRUSTED_CA_KEYS:
+ return new TrustedAuthorities(valueBuffer());
+
+ case STATUS_REQUEST:
+ return new CertificateStatusRequest(valueBuffer());
+
+ case SRP:
+ case CERT_TYPE:
+ }
+ return new UnresolvedExtensionValue(valueBuffer());
}
- Type getType()
+ public void setLength (final int newLength)
{
- return type;
+ if (newLength < 0 || newLength > 65535)
+ throw new IllegalArgumentException ("length is out of bounds");
+ buffer.putShort (2, (short) newLength);
}
- byte[] getValue()
+ public void setType (final Type type)
{
- return value;
+ buffer.putShort(0, (short) type.getValue());
}
+ public void setValue (byte[] value)
+ {
+ setValue (value, 0, value.length);
+ }
+
+ public void setValue (final byte[] value, final int offset, final int length)
+ {
+ if (length != length ())
+ throw new IllegalArgumentException ("length is different than claimed length");
+ ((ByteBuffer) buffer.duplicate().position(4)).put(value, offset, length);
+ }
+
public String toString()
{
+ return toString(null);
+ }
+
+ public String toString(String prefix)
+ {
StringWriter str = new StringWriter();
PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print (prefix);
out.println("struct {");
- out.println(" type = " + type + ";");
+ if (prefix != null) out.print (prefix);
+ out.println(" type = " + type () + ";");
+ if (prefix != null) out.print (prefix);
+ String subprefix = " ";
+ if (prefix != null) subprefix = prefix + subprefix;
out.println(" value =");
- out.println(Util.hexDump(value, " "));
- out.println("} Extension;");
+ out.println(value().toString(subprefix));
+ if (prefix != null) out.print (prefix);
+ out.print("} Extension;");
return str.toString();
}
- // Inner class.
+ // Inner classes.
// -------------------------------------------------------------------------
- static final class Type implements Enumerated
+ public static enum Type
{
+ SERVER_NAME (0),
+ MAX_FRAGMENT_LENGTH (1),
+ CLIENT_CERTIFICATE_URL (2),
+ TRUSTED_CA_KEYS (3),
+ TRUNCATED_HMAC (4),
+ STATUS_REQUEST (5),
+ SRP (6),
+ CERT_TYPE (7);
- // Constants and fields.
- // -----------------------------------------------------------------------
-
- static final Type SERVER_NAME = new Type(0);
- static final Type MAX_FRAGMENT_LENGTH = new Type(1);
- static final Type CLIENT_CERTIFICATE_URL = new Type(2);
- static final Type TRUSTED_CA_KEYS = new Type(3);
- static final Type TRUNCATED_HMAC = new Type(4);
- static final Type STATUS_REQUEST = new Type(5);
- static final Type SRP = new Type(6);
- static final Type CERT_TYPE = new Type(7);
-
private final int value;
- // Constructor.
- // -----------------------------------------------------------------------
-
private Type(int value)
{
this.value = value;
}
- // Class methods.
- // -----------------------------------------------------------------------
-
- static Type read(InputStream in) throws IOException
+ public static Type forValue (final int value)
{
- int i = in.read();
- if (i == -1)
+ switch (value & 0xFFFF)
{
- throw new EOFException("unexpected end of input stream");
- }
- int value = (i & 0xFF) << 8;
- i = in.read();
- if (i == -1)
- {
- throw new EOFException("unexpected end of input stream");
- }
- value |= i & 0xFF;
- switch (value)
- {
case 0: return SERVER_NAME;
case 1: return MAX_FRAGMENT_LENGTH;
case 2: return CLIENT_CERTIFICATE_URL;
@@ -176,39 +230,17 @@
case 5: return STATUS_REQUEST;
case 6: return SRP;
case 7: return CERT_TYPE;
- default: return new Type(value);
+ default: return null;
}
}
- // Instance methods.
- // -----------------------------------------------------------------------
-
- public byte[] getEncoded()
- {
- return new byte[] {
- (byte) (value >>> 8 & 0xFF), (byte) (value & 0xFF)
- };
- }
-
public int getValue()
{
return value;
}
+ }
- public String toString()
+ public static abstract class Value implements Builder, Constructed
{
- switch (value)
- {
- case 0: return "server_name";
- case 1: return "max_fragment_length";
- case 2: return "client_certificate_url";
- case 3: return "trusted_ca_keys";
- case 4: return "truncated_hmac";
- case 5: return "status_request";
- case 6: return "srp";
- case 7: return "cert_type";
- default: return "unknown(" + value + ")";
- }
- }
}
}
Added: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExtensionList.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExtensionList.java (rev 0)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/ExtensionList.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -0,0 +1,290 @@
+package gnu.javax.net.ssl.provider;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A list of extensions, that may appear in either the {@link ClientHello} or
+ * {@link ServerHello}. The form of the extensions list is:
+ *
+ * <tt> Extension extensions_list<1..2^16-1></tt>
+ *
+ * @author csm
+ */
+public class ExtensionList implements Builder, Iterable<Extension>
+{
+ private final ByteBuffer buffer;
+ private int modCount;
+
+ public ExtensionList (ByteBuffer buffer)
+ {
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
+ modCount = 0;
+ }
+
+ public ExtensionList(List<Extension> extensions)
+ {
+ int length = 2;
+ for (Extension extension : extensions)
+ length += extension.length();
+ buffer = ByteBuffer.allocate(length);
+ buffer.putShort((short) (length - 2));
+ for (Extension extension : extensions)
+ buffer.put(extension.buffer());
+ buffer.rewind();
+ }
+
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
+
+ public Extension get (final int index)
+ {
+ int length = length ();
+ int i;
+ int n = 0;
+ for (i = 2; i < length && n < index; )
+ {
+ int l = buffer.getShort (i+2) & 0xFFFF;
+ i += l + 4;
+ n++;
+ }
+ if (n < index)
+ throw new IndexOutOfBoundsException ("no elemenet at " + index);
+ int el = buffer.getShort (i+2) & 0xFFFF;
+ ByteBuffer b = (ByteBuffer) buffer.duplicate().position(i).limit(i+el+4);
+ return new Extension(b.slice());
+ }
+
+ /**
+ * Returns the number of extensions this list contains.
+ *
+ * @return The number of extensions.
+ */
+ public int size ()
+ {
+ int length = length ();
+ if (length == 0)
+ return 0;
+ int n = 0;
+ for (int i = 2; i < length; )
+ {
+ int len = buffer.getShort (i+2) & 0xFFFF;
+ i += len + 4;
+ n++;
+ }
+ return n;
+ }
+
+ /**
+ * Returns the length of this extension list, in bytes.
+ *
+ * @return The length of this extension list, in bytes.
+ */
+ public int length ()
+ {
+ return (buffer.getShort (0) & 0xFFFF) + 2;
+ }
+
+ /**
+ * Sets the extension at index <i>i</i> to <i>e</i>. Note that setting an
+ * element at an index <b>may</b> invalidate any other elements that come
+ * after element at index <i>i</i>. In other words, no attempt is made to
+ * move existing elements in this list, and since extensions are variable
+ * length, you can <em>not</em> guarantee that extensions later in the list
+ * will still be valid.
+ *
+ * <p>Thus, elements of this list <b>must</b> be set in order of increasing
+ * index.
+ *
+ * @param index The index to set the extension at.
+ * @param e The extension.
+ * @throws java.nio.BufferOverflowException If setting the extension overflows
+ * the buffer.
+ * @throws IllegalArgumentException If it isn't possible to find the given index
+ * in the current list (say, if no element index - 1 is set), or if setting
+ * the extension will overflow the current list length (given by {@link
+ * #length()}).
+ */
+ public void set (final int index, Extension e)
+ {
+ int length = length();
+ int n = 0;
+ int i;
+ for (i = 2; i < length && n < index; )
+ {
+ int len = buffer.getShort(i+2) & 0xFFFF;
+ i += len + 4;
+ n++;
+ }
+ if (n < index)
+ throw new IllegalArgumentException("nothing set at index " + (index-1)
+ + " or insufficient space");
+ if (i + e.length() + 2 > length)
+ throw new IllegalArgumentException("adding this element will exceed the "
+ + "list length");
+ buffer.putShort(i, (short) e.type().getValue());
+ buffer.putShort(i+2, (short) e.length());
+ ((ByteBuffer) buffer.duplicate().position(i+4)).put (e.valueBuffer());
+ modCount++;
+ }
+
+ /**
+ * Reserve space for an extension at index <i>i</i> in the list. In other
+ * words, this does the job of {@link #set(int, Extension)}, but does not
+ * copy the extension value to the underlying buffer.
+ *
+ * @param index The index of the extension to reserve space for.
+ * @param t The type of the extension.
+ * @param eLength The number of bytes to reserve for this extension. The total
+ * number of bytes used by this method is this length, plus four.
+ */
+ public void set (final int index, Extension.Type t, final int eLength)
+ {
+ int length = length ();
+ int n = 0;
+ int i;
+ for (i = 2; i < length && n < index; )
+ {
+ int len = buffer.getShort (i+2) & 0xFFFF;
+ i += len + 4;
+ n++;
+ }
+ if (n < index)
+ throw new IllegalArgumentException ("nothing set at index " + (index-1)
+ + " or insufficient space");
+ if (i + eLength + 2 > length)
+ throw new IllegalArgumentException ("adding this element will exceed the "
+ + "list length");
+ buffer.putShort(i, (short) t.getValue());
+ buffer.putShort(i+2, (short) eLength);
+ modCount++;
+ }
+
+ /**
+ * Set the total length of this list, in bytes.
+ *
+ * @param newLength The new list length.
+ */
+ public void setLength (final int newLength)
+ {
+ if (newLength < 0 || newLength > 65535)
+ throw new IllegalArgumentException ("invalid length");
+ buffer.putShort (0, (short) newLength);
+ modCount++;
+ }
+
+ public Iterator<Extension> iterator()
+ {
+ return new ExtensionsIterator();
+ }
+
+ public String toString()
+ {
+ return toString (null);
+ }
+
+ public String toString(final String prefix)
+ {
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("ExtensionList {");
+ if (prefix != null) out.print(prefix);
+ out.print(" length = ");
+ out.print(length());
+ out.println(";");
+ String subprefix = " ";
+ if (prefix != null)
+ subprefix = prefix + subprefix;
+ for (Extension e : this)
+ out.println(e.toString(subprefix));
+ if (prefix != null) out.print(prefix);
+ out.print("};");
+ return str.toString();
+ }
+
+ /**
+ * List iterator interface to an extensions list.
+ *
+ * @author cs...@gn...
+ */
+ public final class ExtensionsIterator implements ListIterator<Extension>
+ {
+ private final int modCount;
+ private int index;
+ private final int size;
+
+ public ExtensionsIterator ()
+ {
+ this.modCount = ExtensionList.this.modCount;
+ index = 0;
+ size = size ();
+ }
+
+ public boolean hasNext()
+ {
+ return index < size;
+ }
+
+ public boolean hasPrevious()
+ {
+ return index > 0;
+ }
+
+ public Extension next() throws NoSuchElementException
+ {
+ if (modCount != ExtensionList.this.modCount)
+ throw new ConcurrentModificationException ();
+ if (!hasNext ())
+ throw new NoSuchElementException ();
+ return get (index++);
+ }
+
+ public Extension previous() throws NoSuchElementException
+ {
+ if (modCount != ExtensionList.this.modCount)
+ throw new ConcurrentModificationException ();
+ if (!hasPrevious ())
+ throw new NoSuchElementException ();
+ return get (--index);
+ }
+
+ public int nextIndex()
+ {
+ if (hasNext ())
+ return index + 1;
+ return index;
+ }
+
+ public int previousIndex()
+ {
+ if (hasPrevious ())
+ return index - 1;
+ return -1;
+ }
+
+ public void add(Extension e)
+ {
+ throw new UnsupportedOperationException ("cannot add items to this iterator");
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException ("cannot remove items from this iterator");
+ }
+
+ public void set(Extension e)
+ {
+ ExtensionList.this.set (index, e);
+ }
+ }
+}
Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extensions.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extensions.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Extensions.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -1,159 +0,0 @@
-/* Extensions.java -- various static extension utilities.
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is a 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 of the License, 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; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, 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 gnu.javax.net.ssl.provider;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.security.auth.x500.X500Principal;
-
-import gnu.java.security.x509.X500DistinguishedName;
-
-final class Extensions
-{
-
- // Constants.
- // -------------------------------------------------------------------------
-
- private static final Integer _512 = new Integer(512),
- _1024 = new Integer(1024), _2048 = new Integer(2048),
- _4096 = new Integer(4096);
-
- // Class methods only.
- private Extensions() { }
-
- // Class methods.
- // -------------------------------------------------------------------------
-
- static List getServerName(Extension ex)
- {
- LinkedList l = new LinkedList();
- byte[] buf = ex.getValue();
- int pos = 0;
- try
- {
- while (pos < buf.length)
- {
- if (buf[pos++] != 0)
- break;
- int len = (buf[pos++] & 0xFF) << 8;
- len |= buf[pos++] & 0xFF;
- l.add(new String(buf, pos, len, "UTF-8"));
- pos += len;
- }
- }
- catch (Exception x)
- {
- }
- return Collections.unmodifiableList(l);
- }
-
- static List getClientCertTypes(Extension ex) throws IOException
- {
- List l = new LinkedList();
- ByteArrayInputStream in = new ByteArrayInputStream(ex.getValue());
- final int len = in.read() & 0xFF;
- for (int i = 0; i < len; i++)
- {
- l.add(CertificateType.read(in));
- }
- return Collections.unmodifiableList(l);
- }
-
- static CertificateType getServerCertType(Extension ex) throws IOException
- {
- return CertificateType.read(new ByteArrayInputStream(ex.getValue()));
- }
-
- static Integer getMaxFragmentLength(Extension ex)
- {
- switch (ex.getValue()[0] & 0xFF)
- {
- case 1: return _512;
- case 2: return _1024;
- case 3: return _2048;
- case 4: return _4096;
- }
- throw new IllegalArgumentException();
- }
-
- static Object[] getTrustedCA(Extension ex)
- {
- byte[] buf = ex.getValue();
- int type = buf[0] & 0xFF;
- try
- {
- switch (type)
- {
- case 0:
- return new Object[] { new Integer(type), null };
- case 1:
- case 3:
- return new Object[] { new Integer(type),
- Util.trim(buf, 1, 20) };
- case 2:
- return new Object[] { new Integer(type),
- new X500Principal(Util.trim(buf, 1, 20)) };
- }
- }
- catch (Exception x)
- {
- }
- throw new IllegalArgumentException();
- }
-
- static String getSRPUsername(Extension ex)
- {
- int len = ex.getValue()[0] & 0xFF;
- if (len > ex.getValue().length - 1)
- throw new IllegalArgumentException();
- try
- {
- return new String(ex.getValue(), 1, len, "UTF-8");
- }
- catch (UnsupportedEncodingException uee)
- {
- throw new Error(uee.toString());
- }
- }
-}
Modified: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Finished.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Finished.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/Finished.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -38,106 +38,136 @@
package gnu.javax.net.ssl.provider;
-import java.io.DataInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+
final class Finished implements Handshake.Body
{
// Fields.
// -------------------------------------------------------------------------
- /** TLSv1.x verify data. */
- private final byte[] verifyData;
+ private final ByteBuffer buffer;
+ private final ProtocolVersion version;
- /** SSLv3 message digest pair. */
- private final byte[] md5, sha;
-
// Constructor.
// -------------------------------------------------------------------------
- Finished(byte[] verifyData)
+ Finished (final ByteBuffer buffer, final ProtocolVersion version)
{
- this.verifyData = verifyData;
- md5 = sha = null;
+ buffer.getClass ();
+ version.getClass ();
+ this.buffer = buffer;
+ this.version = version;
}
- Finished(byte[] md5, byte[] sha)
+ // Instance methods.
+ // -------------------------------------------------------------------------
+
+ public int length ()
{
- this.md5 = md5;
- this.sha = sha;
- verifyData = null;
+ if (version.compareTo(ProtocolVersion.TLS_1) >= 0)
+ return 12;
+ if (version == ProtocolVersion.SSL_3)
+ return 36;
+ throw new IllegalArgumentException ("length for this version unknown");
}
- // Class methods.
- // -------------------------------------------------------------------------
+ byte[] verifyData()
+ {
+ if (version.compareTo(ProtocolVersion.TLS_1) >= 0)
+ {
+ byte[] verify = new byte[12];
+ buffer.position (0);
+ buffer.get (verify);
+ return verify;
+ }
+ throw new IllegalArgumentException ("not TLSv1.0 or later");
+ }
- static Finished read(InputStream in, CipherSuite suite)
- throws IOException
+ byte[] md5Hash()
{
- DataInputStream din = new DataInputStream(in);
- if (suite.getVersion().equals(ProtocolVersion.SSL_3))
+ if (version == ProtocolVersion.SSL_3)
{
byte[] md5 = new byte[16];
- byte[] sha = new byte[20];
- din.readFully(md5);
- din.readFully(sha);
- return new Finished(md5, sha);
+ buffer.position (0);
+ buffer.get (md5);
+ return md5;
}
- else
- {
- byte[] buf = new byte[12];
- din.readFully(buf);
- return new Finished(buf);
- }
+ throw new IllegalArgumentException ("not SSLv3");
}
- // Instance methods.
- // -------------------------------------------------------------------------
-
- public void write(OutputStream out) throws IOException
+ byte[] shaHash()
{
- if (verifyData != null)
- out.write(verifyData);
- else
+ if (version == ProtocolVersion.SSL_3)
{
- out.write(md5);
- out.write(sha);
+ byte[] sha = new byte[20];
+ buffer.position (16);
+ buffer.get (sha);
+ return sha;
}
+ throw new IllegalArgumentException ("not SSLv3");
}
- byte[] getVerifyData()
+ void setVerifyData (final byte[] verifyData, final int offset)
{
- return verifyData;
+ if (version == ProtocolVersion.SSL_3)
+ throw new IllegalArgumentException ("not TLSv1");
+ buffer.position (0);
+ buffer.put (verifyData, offset, 12);
}
- byte[] getMD5Hash()
+ void setMD5Hash (final byte[] md5, final int offset)
{
- return md5;
+ if (version != ProtocolVersion.SSL_3)
+ throw new IllegalArgumentException ("not SSLv3");
+ buffer.position (0);
+ buffer.put (md5, offset, 16);
}
- byte[] getSHAHash()
+ void setShaHash (final byte[] sha, final int offset)
{
- return sha;
+ if (version != ProtocolVersion.SSL_3)
+ throw new IllegalArgumentException ("not SSLv3");
+ buffer.position (16);
+ buffer.put (sha, offset, 20);
}
- public String toString()
+ public String toString ()
{
- String nl = System.getProperty("line.separator");
- if (verifyData != null)
+ return toString (null);
+ }
+
+ public String toString (final String prefix)
+ {
+ StringWriter str = new StringWriter ();
+ PrintWriter out = new PrintWriter (str);
+ if (prefix != null)
+ out.print (prefix);
+ out.println ("struct {");
+ if (prefix != null)
+ out.print (prefix);
+ if (version.compareTo(ProtocolVersion.TLS_1) >= 0)
{
- return "struct {" + nl +
- " verifyData = " + Util.toHexString(verifyData, ':') + ";" + nl +
- "} Finished;" + nl;
+ out.print (" verifyData = ");
+ out.print (Util.toHexString (verifyData (), ':'));
}
- else
+ else if (version == ProtocolVersion.SSL_3)
{
- return "struct {" + nl +
- " md5Hash = " + Util.toHexString(md5, ':') + ";" + nl +
- " shaHash = " + Util.toHexString(sha, ':') + ";" + nl +
- "} Finished;" + nl;
+ out.print (" md5 = ");
+ out.print (Util.toHexString (md5Hash (), ':'));
+ out.println (';');
+ if (prefix != null)
+ out.print (prefix);
+ out.print (" sha = ");
+ out.print (Util.toHexString (shaHash (), ':'));
}
+ out.println (';');
+ if (prefix != null)
+ out.print (prefix);
+ out.print ("} Finished;");
+ return str.toString ();
}
}
Deleted: trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/GNUSecurityParameters.java
===================================================================
--- trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/GNUSecurityParameters.java 2007-01-07 12:48:35 UTC (rev 3019)
+++ trunk/core/src/classpath/gnu/gnu/javax/net/ssl/provider/GNUSecurityParameters.java 2007-01-07 12:50:40 UTC (rev 3020)
@@ -1,490 +0,0 @@
-/* GNUSecurityParameters.java -- SSL security parameters.
- Copyright (C) 2006 Free Software Foundation, Inc.
-
-This file is a 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 of the License, or (at
-your option) any later version.
-
-GNU Classpath is distributed in the hope that it will b...
[truncated message content] |